关于跨周期控制变量失效的问题

老师们好,最近在跨周期程序调试上,我都要吐了,按照教学视频我改写了海龟交易策略,但是控制变量总是在大周期的onbar结束后丢失,导致程序无法进行后续的交易控制,也都是按照视频教学在大周期上进行运算,小周期上交易,但是控制变量sendorderthisbar就算是发生了交易,在onbar的当根k线还是true,但是onbar结束之后就变成false了,就算是在当根k线的onbarclose打印出来都是false....

仔细检查了程序,没有发现其他赋值false的语句,不知道是怎么回事,请老师帮忙分析一下,感谢拉!


代码如下:

Params

   Array<String> Mysymbol([\"sc2408.INE\"]);         //品种参数

   Numeric TN(1);                           //周期数

   Enum<String> TT1([\"d\",\"h\",\"m\"]);         //周期1单位

   Enum<String> TT2([\"d\",\"h\",\"m\"]);         //周期2单位

   Numeric nEntries(3);                    // 最大建仓次数

   Numeric RiskRatio(1);                    // % Risk Per N ( 0 - 100)

   Numeric ATRLength(20);                    // 平均波动周期 ATR Length

   Numeric boLength(20);                    // 短周期 BreakOut Length

   Numeric fsLength(55);                    // 长周期 FailSafe Length

   Numeric teLength(10);                    // 离市周期 Trailing Exit Length

   Bool LastProfitableTradeFilter(True);    // 使用入市过滤条件

Vars

   Numeric i;

   Numeric MinPoint;                        // 最小变动单位

   Series<Numeric> AvgTR;                    // ATR

   Numeric N;                                // N 值

   Numeric TotalEquity;                    // 按最新收盘价计算出的总资产

   Numeric TurtleUnits;                    // 交易单位

   Series<Numeric> DonchianHi;                // 唐奇安通道上轨,延后1个Bar

   Series<Numeric> DonchianLo;                // 唐奇安通道下轨,延后1个Bar

   Series<Numeric> fsDonchianHi;            // 唐奇安通道上轨,延后1个Bar,长周期

   Series<Numeric> fsDonchianLo;            // 唐奇安通道下轨,延后1个Bar,长周期

   Numeric ExitHighestPrice;                // 离市时判断需要的N周期最高价

   Numeric ExitLowestPrice;                // 离市时判断需要的N周期最低价

   Numeric myEntryPrice;                    // 开仓价格

   Numeric myExitPrice;                    // 平仓价格

   Bool SendOrderThisBar;            // 当前Bar有过交易

   Series<Numeric> preEntryPrice(0);        // 前一次开仓的价格

   Series<Bool> PreBreakoutFailure(false);    // 前一次突破是否失败

Events

   OnInit()

   {


       //SetBasePeriod(\"1m\");

       For i=0 to GetArraySize(Mysymbol)-1

       {

           //SubscribeBar(Mysymbol[i],Text(TN)+TT1);

           

           SubscribeBar(Mysymbol[i],\"1h\",20240601);

           SubscribeBar(Mysymbol[i],\"1m\",20240601);

       }


   }

   OnBarOpen(ArrayRef<Integer> indexs)

   {        

       //If(GetArraySize(indexs) == 0) Return;




   }

   OnBar(ArrayRef<Integer> indexs)

   {

       print(\"++++++++++++++++++++++++++\");

    Numeric i;

    Numeric resultN = 1;


//如果大周期图层还在运行,小周期运行结束,则传输控制信号

/* if (data0.BarExistStatus == 1 && data1.BarExistStatus <> 1)

       {

           data0.SendOrderThisBar = data1.SendOrderThisBar;

           data0.PreBreakoutFailure = data1.PreBreakoutFailure;

       }*/

     

For i=0 to DataSourceSize -1

       {

           //SubscribeBar(Mysymbol[i],Text(TN)+TT1);

           

           resultN = resultN * data[i].BarExistStatus;

       }

       If(resultN <> 1)

return;

       If(BarStatus == 0)

       {

           data0.preEntryPrice = InvalidNumeric;

           data0.PreBreakoutFailure = false;

       }

       MinPoint = MinMove*PriceScale;

       AvgTR = XAverage(TrueRange,ATRLength);

       N = AvgTR[1];

       TotalEquity = Portfolio_CurrentCapital() + Portfolio_UsedMargin();

       TurtleUnits = (TotalEquity*RiskRatio/100) /(N * ContractUnit()*BigPointValue());

       TurtleUnits = IntPart(TurtleUnits); // 对小数取整

       data0.DonchianHi = HighestFC(data0.High[1],boLength);

       data0.DonchianLo = LowestFC(data0.Low[1],boLength);

       data0.fsDonchianHi = HighestFC(data0.High[1],fsLength);

       data0.fsDonchianLo = LowestFC(data0.Low[1],fsLength);

       data0.ExitLowestPrice = LowestFC(data0.Low[1],teLength);

       data0.ExitHighestPrice = HighestFC(data0.High[1],teLength);

       data0.PlotNumeric(\"DonchianHi\",data0.DonchianHi);

       data0.PlotNumeric(\"DonchianLo\",data0.DonchianLo);        

       data0.PlotNumeric(\"fsDonchianHi\",data0.fsDonchianHi,0,yellow);

       data0.PlotNumeric(\"fsDonchianLo\",data0.fsDonchianLo,0,blue);

       data0.Commentary(\"N=\"+Text(data0.N)+\",barnum=\"+Text(data0.CurrentBar));

       data0.Commentary(\"data0.preEntryPrice=\"+Text(data0.preEntryPrice));

       data0.Commentary(\"PreBreakoutFailure=\"+IIFString(data0.PreBreakoutFailure,\"True\",\"False\"));

       data0.Commentary(\"SendOrderThisBar=\"+IIFString(data0.SendOrderThisBar,\"True\",\"False\"));

       //print(\"SendOrderThisBar=\"+IIFString(data0.SendOrderThisBar,\"True\",\"False\"));

       // 当不使用过滤条件,或者使用过滤条件并且条件为data0.PreBreakoutFailure为True进行后续操作

       If(data0.MarketPosition == 0 && ((!LastProfitableTradeFilter) Or (data0.PreBreakoutFailure)))

       {

       

           print(\"111r=\"+IIFString(data0.SendOrderThisBar,\"True\",\"False\"));

           // 突破开仓

           If(High > data0.DonchianHi && TurtleUnits >= 1 && data0.SendOrderThisBar==false)

           {

            print(\"222=\"+IIFString(data0.SendOrderThisBar,\"True\",\"False\"));

               // 开仓价格取突破上轨+一个价位和最高价之间的较小值,这样能更接近真实情况,并能尽量保证成交

               data0.myEntryPrice = min(high,data0.DonchianHi + MinPoint);

               data0.myEntryPrice = IIF(myEntryPrice < Open, Open,data0.myEntryPrice); // 大跳空的时候用开盘价代替

               data0.preEntryPrice = data0.myEntryPrice;

               data1.Buy(TurtleUnits,data0.myEntryPrice);

               data0.SendOrderThisBar = True;

               data0.PreBreakoutFailure = False;

           }

           If(Low < data0.DonchianLo && TurtleUnits >= 1 && data0.SendOrderThisBar==false)

           {

            print(\"333=\"+IIFString(data0.SendOrderThisBar,\"True\",\"False\"));

               // 开仓价格取突破下轨-一个价位和最低价之间的较大值,这样能更接近真实情况,并能尽量保证成交

               data0.myEntryPrice = max(low,data0.DonchianLo - MinPoint);

               data0.myEntryPrice = IIF(myEntryPrice > Open, Open,data0.myEntryPrice); // 大跳空的时候用开盘价代替

               data0.preEntryPrice = data0.myEntryPrice;

               data1.SellShort(TurtleUnits,data0.myEntryPrice);

               data0.SendOrderThisBar = True;

               data0.PreBreakoutFailure = False;

           }

       }

       // 长周期突破开仓 Failsafe Breakout point

       If(data0.MarketPosition == 0)

       {

           data0.Commentary(\"fsDonchianHi=\"+Text(fsDonchianHi));

           

           If(High > data0.fsDonchianHi && TurtleUnits >= 1 && data0.SendOrderThisBar==false)

           {        

            print(\"444=\"+IIFString(data0.SendOrderThisBar,\"True\",\"False\"));

               // 开仓价格取突破上轨+一个价位和最高价之间的较小值,这样能更接近真实情况,并能尽量保证成交

               data0.myEntryPrice = min(high,data0.fsDonchianHi + MinPoint);

               data0.myEntryPrice = IIF(myEntryPrice < Open, Open,data0.myEntryPrice); // 大跳空的时候用开盘价代替

               data0.preEntryPrice = data0.myEntryPrice;

               data1.Buy(TurtleUnits,data0.myEntryPrice);

               data0.SendOrderThisBar = True;

               data0.PreBreakoutFailure = False;

           }

           data0.Commentary(\"fsDonchianLo=\"+Text(fsDonchianLo));

           If(Low < data0.fsDonchianLo && TurtleUnits >= 1 && data0.SendOrderThisBar==false)

           {

            print(\"5555=\"+IIFString(data0.SendOrderThisBar,\"True\",\"False\"));

               // 开仓价格取突破下轨-一个价位和最低价之间的较大值,这样能更接近真实情况,并能尽量保证成交

               data0.myEntryPrice = max(low,data0.fsDonchianLo - MinPoint);

               data0.myEntryPrice = IIF(myEntryPrice > Open, Open,data0.myEntryPrice); // 大跳空的时候用开盘价代替

               data0.preEntryPrice = data0.myEntryPrice;

               data1.SellShort(TurtleUnits,data0.myEntryPrice);

               data0.SendOrderThisBar = True;

               data0.PreBreakoutFailure = False;

               data0.Commentary(\"SendOrderThisBar=\"+IIFString(data0.SendOrderThisBar,\"True\",\"False\"));

           }

       }

       data0.Commentary(\"22SendOrderThisBar=\"+IIFString(data0.SendOrderThisBar,\"True\",\"False\"));

       If(data0.MarketPosition == 1) // 有多仓的情况

       {

           data0.Commentary(\"ExitLowestPrice=\"+Text(ExitLowestPrice));

           

           If(Low < data0.ExitLowestPrice && data0.SendOrderThisBar==false)

           {

               data0.myExitPrice = max(Low,data0.ExitLowestPrice - MinPoint);

               data0.myExitPrice = IIF(myExitPrice > Open, Open,data0.myExitPrice); // 大跳空的时候用开盘价代替

               data1.Sell(0,data0.myExitPrice);    // 数量用0的情况下将全部平仓

           }Else

           {

               If(data0.preEntryPrice!=InvalidNumeric && TurtleUnits >= 1)

               {

                   If(Open >= data0.preEntryPrice + 0.5*data0.N && CurrentEntries < nEntries && data0.SendOrderThisBar==false) // 如果开盘就超过设定的1/2N,则直接用开盘价增仓。

                   {

                       data0.myEntryPrice = Open;

                       data0.preEntryPrice = data0.myEntryPrice;

                       data1.Buy(TurtleUnits,data0.myEntryPrice);

                       data0.SendOrderThisBar = True;

                   }

                   while(High >= data0.preEntryPrice + 0.5*data0.N && CurrentEntries < nEntries && data0.SendOrderThisBar==false) // 以最高价为标准,判断能进行几次增仓

                   {

                       data0.myEntryPrice = data0.preEntryPrice + 0.5 * data0.N;

                       data0.preEntryPrice = data0.myEntryPrice;

                       if(False == data1.Buy(TurtleUnits,data0.myEntryPrice))

                       {

                           break;

                       }

                       data0.SendOrderThisBar = True;

                   }

               }

               // 止损指令

               If(Low <= data0.preEntryPrice - 2 * data0.N && data0.SendOrderThisBar == false) // 加仓Bar不止损

               {

                   data0.myExitPrice = data0.preEntryPrice - 2 * data0.N;

                   data0.myExitPrice = IIF(myExitPrice > Open, Open,data0.myExitPrice); // 大跳空的时候用开盘价代替

                   data1.Sell(0,data0.myExitPrice); // 数量用0的情况下将全部平仓

                   data0.PreBreakoutFailure = True;

               }

           }

       }Else If(data0.MarketPosition ==-1) // 有空仓的情况

       {

       

           // 求出持空仓时离市的条件比较值

           data0.Commentary(\"ExitHighestPrice=\"+Text(data0.ExitHighestPrice));

           If(High > data0.ExitHighestPrice && data0.SendOrderThisBar==false)

           {

               data0.myExitPrice = Min(High,data0.ExitHighestPrice + MinPoint);

               data0.myExitPrice = IIF(myExitPrice < Open, Open,data0.myExitPrice); // 大跳空的时候用开盘价代替

               data1.BuyToCover(0,data0.myExitPrice);    // 数量用0的情况下将全部平仓

           }Else

           {

               If(data0.preEntryPrice!=InvalidNumeric && TurtleUnits >= 1)

               {

                   If(Open <= data0.preEntryPrice - 0.5*data0.N && CurrentEntries < nEntries && data0.SendOrderThisBar==false) // 如果开盘就超过设定的1/2N,则直接用开盘价增仓。

                   {

                       data0.myEntryPrice = Open;

                       data0.preEntryPrice = data0.myEntryPrice;

                       data1.SellShort(TurtleUnits,data0.myEntryPrice);

                       data0.SendOrderThisBar = True;

                   }

                   while(Low <= data0.preEntryPrice - 0.5*data0.N && CurrentEntries < nEntries && data0.SendOrderThisBar==false) // 以最低价为标准,判断能进行几次增仓

                   {

                       data0.myEntryPrice = data0.preEntryPrice - 0.5 * data0.N;

                       data0.preEntryPrice = data0.myEntryPrice;

                       if(False == data1.SellShort(TurtleUnits,data0.myEntryPrice))

                       {

                           break;

                       }

                       data0.SendOrderThisBar = True;

                   }

               }

               // 止损指令

               If(High >= data0.preEntryPrice + 2 * data0.N && data0.SendOrderThisBar==false) // 加仓Bar不止损

               {

                   data0.myExitPrice = data0.preEntryPrice + 2 * data0.N;

                   data0.myExitPrice = IIF(myExitPrice < Open, Open,data0.myExitPrice); // 大跳空的时候用开盘价代替

                   data1.BuyToCover(0,data0.myExitPrice); // 数量用0的情况下将全部平仓

                   data0.PreBreakoutFailure = True;

               }

           }

       }

       data0.Commentary(\"CurrentEntries = \" + Text(CurrentEntries));

   }

   OnBarClose(ArrayRef<Integer> indexs)

   {

       

/* print(\"111r=\"+IIFString(data0.SendOrderThisBar,\"True\",\"False\"));

data0.SendOrderThisBar = data1.SendOrderThisBar;

data0.PreBreakoutFailure = data1.PreBreakoutFailure;

print(\"222r=\"+IIFString(data1.SendOrderThisBar,\"True\",\"False\"));   */



   

/*if (data0.BarExistStatus == 1)

       {

           data0.SendOrderThisBar = False;

           data0.PreBreakoutFailure = False;

           if(data1.BarExistStatus == 1)

           {

data1.SendOrderThisBar = False;

data1.PreBreakoutFailure = False;            

           }          

       }*/

   }


关于跨周期的问题
关于跨周期的问题
quant3关于跨周期引用的问题
关于跨周期报错的问题
请教跨周期订阅中的周期设置问题
关于策略选股里面,选股公式,跨周期问题
关于跨周期代码在行情页面加载运行的问题
请问老师关于跨周期信号闪烁问题
For语句控制变量赋值问题
TB跨周期MA的问题

刚开始最好用最简单的模型去学习、测试

海龟对初学者来说

已经过于复杂

多图层+各种逻辑控制涉及面太多了

还有

交易信号的闪烁都能搞到你精神崩塌

data-href=

上个帖子已经回你了

如果没有理解错的话

大周期的bar内只交易一次

小周期用来交易

在onbaropen中 是大周期触发的话 把全局变量赋值为False

有买卖就重置为True

如果一个全局不够

那就几个配合


局部类型的容器内容在本次驱动结束后就会清空,你为什么要用局部类型来作为状态变量?

全局变量不能用图层标识。。。所以用了局部变量。

用了全局变量会有一个问题,在小周期图层上,会多次修改全局控制变量,也一样的失去了控制的意义。

natural类型是多图层全局变量

建议零基础课程里再好好学学....

https://www.bilibili.com/video/BV1ZG411f7bt/?spm_id_from=333.999.0.0&vd_source=148cb1d807933f47bb50c46ed69d3c82

sendorderthisbar是局部类型?局部类型怎么做状态变量?