多周期-if条件判断失败,找不到原因

步骤1:在图表上加载画图公式1//------------------------------------------------------------------------ // 简称: test_if // 名称: 怎么c>o判断失效 // 类别: 策略应用 // 类型: 用户应用 // 输出: Void //------------------------------------------------------------------------ Params //此处添加参数 Vars //此处添加变量 plot Plt_ZT; Defs //此处添加策略函数 Events //此处实现事件函数 //初始化事件函数,策略运行期间,首先运行且只有一次 OnInit() { } //Bar更新事件函数,参数indexs表示变化的数据源图层ID数组 OnBar(ArrayRef<Integer> indexs) { range[0:DataSourceSize-1] { if(close > open And close[1] > open[1] And close[2] > open[2]) { Plt_ZT.icon("support", date + time, low, "ICO72"); //画个西瓜 } if(close < open And close[1] < open[1] And close[2] < open[2]) { Plt_ZT.icon("resistance", date + time, high, "ICO25"); //画个哭脸 } } } //------------------------------------------------------------------------ // 编译版本 2025/12/3 93440 // 版权所有 quantL // 更改声明 TradeBlazer Software保留对TradeBlazer平台 // 每一版本的TradeBlazer策略修改和重写的权利 //------------------------------------------------------------------------单独使用这个画图,确认图表信号没有问题,在多晶硅1日线,9月15日,无标记步骤2:图表同时加载公式2(含多周期的公式)//------------------------------------------------------------------------ // 简称: TBDBmaTrade2 // 名称: 双均线交易 // 类别: 策略应用 // 类型: 用户应用 // 输出: Void //------------------------------------------------------------------------ //策略规则: //买入开仓:收盘价短期(参数Length1)均线上穿长期(参数Length1+Length2)均线,在下一个开盘价买入开仓 //卖出开仓:收盘价短期(参数Length1)均线下破长期(参数Length1+Length2)均线,在下一个开盘价卖出开仓 Params Numeric Length1(5,5,30,5); //短周期 Numeric Length2(15,5,30,5); //长周期 Numeric Amount(1); //交易手数,负数为交易金额 Numeric Capital(100); //账户资金 Vars Series<Numeric> Lots(0,2); Series<Numeric> MA1(0,2); //短周期均价 Series<Numeric> MA2(0,2); //长周期均价 Series<Numeric> indayEntry(0,2); //日内进场次数 Plot plt1; Defs Bool TradeLots(Numeric TradeAmount) { if(TradingDate <> TradingDate[1] Or CurrentBar == 0) //当日第一根bar { Numeric TempUnitMoney = Open / rollover * ContractUnit * BigPointValue; //每手市值,以开盘价计算 Lots = Round(10000 * TradeAmount / TempUnitMoney / baseshares, 0) * baseshares; } Return True; } Events OnInit() { SubscribeBar(Symbol,"15m", BeginDateTime, EndDateTime); //原始代码这里是1d,且hide Data1.SetBasePeriod(Data0.Frequency); // Data1.Hide; Range[0:DataCount-1] { AddDataFlag(Enum_Data_RolloverBackWard()); //设置后复权 AddDataFlag(Enum_Data_RolloverRealPrice()); //是否映射真实价格 AddDataFlag(Enum_Data_AutoSwapPosition()); //设置自动换仓 AddDataFlag(Enum_Data_IgnoreSwapSignalCalc()); //设置忽略换仓信号计算 } SetInitCapital(Capital*10000); } OnBar(ArrayRef<Integer> indexs) { //计算交易头寸,Amount小于0,按照金额计算手数,Amount大于0就直接作为手数 If(Amount < 0) TradeLots(Abs(Amount)); Else Lots = Amount; //计算均价 Range[1:1] { //尝试输出close值确认ma应用的close是否对应 Integer i; for i=0 to Length1-1 { print(DateTimeToString(data0.date + data0.time) + "--data1.close["+text(i) + "]:" + text(close[i])); //在日线上打印按照setperiod运行时对应的data0的bar时间 //print(DateTimeToString(data0.date + data0.time) + "--data1.close["+text(i) + "]:" +text(data1.close[i])); //对比一下是不是真的取的data1的值 Commentary("序号" + text(i) +":"+ text(data1.close[i])); //为什么在data1上commentary不出来 } print("--均价--" + text(Average(Close, Length1))); print("data1.CurrentBar:"+text(data1.CurrentBar)); data1.Commentary("data1.CurrentBar:"+text(data1.CurrentBar)); print("--------------------"); //原始代码 MA1 = Average(Close, Length1); MA2 = Average(Close, Length1 + Length2); } //原始代码 MA1 = Data1.MA1; MA2 = Data1.MA2; //输出测试 print("data0.close0:"+text(close)); print("data0.close1:"+text(close[1])); print("data0.close2:"+text(close[2])); print("data0.close3:"+text(close[3])); print("data0.close4:"+text(close[4])); print("均价计算:"); print("data0.ma1:"+text(data0.MA1)); print("data0.ma2:"+text(data0.MA2)); print("data1.ma1:"+text(data1.MA1)); print("data1.ma2:"+text(data1.MA2)); print("data0.CurrentBar:"+text(data0.CurrentBar)); print("————————————————————————————————————"); Commentary("data0.CurrentBar:"+text(data0.CurrentBar)); Commentary("data1.CurrentBar:"+text(data1.CurrentBar)); //为什么在data0上输出data1的currentbar,在日内居然会变动 //range[0:DataSourceSize-1] //{ //PlotNumeric("ma1", data0.ma1); //PlotNumeric("ma2", data0.ma2); //} //有"MA1 = Data1.MA1;",理论上画图出来的图形状应该是一样的 PlotNumeric("data1计算的值放到data0图层ma1", data1.ma1); PlotNumeric("data1计算的值放到data0图层ma2", data1.ma2); data1.PlotNumeric("data1计算的值自己画ma1", data1.ma1); data1.PlotNumeric("data1计算的值自己画ma2", data1.ma2); //后面没有测试代码了 //控制日内进场次数 If(TradingDate<>TradingDate[1]) //新交易日 { indayEntry = 0; } //交易 If(MA1[1] > MA2[1] And MarketPosition<>1 And indayEntry==0) { Buy(lots, Open); indayEntry = 1; } If(MA1[1] < MA2[1] And MarketPosition<> -1 And indayEntry==0) { SellShort(lots, Open); indayEntry = 1; } //以下画指标 plt1.line("MA1", MA1); plt1.line("MA2", MA2); } //------------------------------------------------------------------------ // 编译版本 2024/10/31 205152 // 版权所有 tbsh // 更改声明 TradeBlazer Software保留对TradeBlazer平台 // 每一版本的TradeBlazer策略修改和重写的权利 //------------------------------------------------------------------------加载这个公式后,在多晶硅1日线,9月15日,标记"ICO72",就是这个西瓜根据画图的判断,这里不该画这是什么原理?公式2换过几个含多周期公式,有的标记无误,有的标记不对,找不到规律用于展示这个异常的公式2是资源里面的(subscribe改成了15m,取消hide)

因为跨周期以后,日线一根bar的执行次数不再是一次了,对应的小周期有几根bar,那么执行几次,而且驱动执行的对应bar数据也不是大周期收盘的数据,而是小周期bar收盘时,对应大周期bar当时的数据执行。而plot是一种不擦除的作图工具,也就是一根bar上如果执行过作图,那么后面tick如果没执行,也不会擦除这个作图结果。总结来说,这是一种信号闪烁

回复:我想 如果只是运行次数 那么同样订阅了多周期的其他公式,因为大周期运行次数一样,结果也应该是一样的但试了另外一个公式,不会出现判断跟预期不一致的问题多周期公式: (就是在系统的DualMA公式里面加了个订阅小周期)//------------------------------------------------------------------------ // 简称: subscribe // 名称: 订阅 // 类别: 策略应用 // 类型: 用户应用 // 输出: Void //------------------------------------------------------------------------ //------------------------------------------------------------------------ // 简称: DualMA // 名称: 双均线交易系统 // 类别: 策略应用 // 类型: 内建应用 //------------------------------------------------------------------------ Params Numeric FastLength(5);// 短期指数平均线参数 Numeric SlowLength(20);// 长期指数平均线参数 Vars Series<Numeric> AvgValue1; Series<Numeric> AvgValue2; Events OnInit() { SubscribeBar(Symbol,"15m",BeginDateTime); } OnReady() { //Range[0:DataSourceSize() - 1] //{ //SetBackBarMaxCount(1+Max(FastLength,SlowLength)); //setPlotOption("MA1", "begin-bar", FastLength); //setPlotOption("MA2", "begin-bar", SlowLength); //} } OnBar(ArrayRef<Integer> indexs) { Range[0:DataSourceSize-1] { AvgValue1 = AverageFC(Close, FastLength); AvgValue2 = AverageFC(Close, SlowLength); PlotNumeric("MA1", AvgValue1); PlotNumeric("MA2", AvgValue2); If(MarketPosition <>1 && AvgValue1[1] > AvgValue2[1]) { Buy(0, Open); } If(MarketPosition <> -1 && AvgValue1[1] < AvgValue2[1]) { SellShort(0, Open); } } } //------------------------------------------------------------------------ // 编译版本 GS2010.12.08 // 版权所有 TradeBlazer Software 2003-2025 // 更改声明 TradeBlazer Software保留对TradeBlazer平 // 台每一版本的TradeBlazer公式修改和重写的权利 //------------------------------------------------------------------------ //------------------------------------------------------------------------ // 编译版本 2025/12/3 100100 // 版权所有 quantL // 更改声明 TradeBlazer Software保留对TradeBlazer平台 // 每一版本的TradeBlazer策略修改和重写的权利 //------------------------------------------------------------------------或者整个公式只有一句订阅,也没有异常 SubscribeBar(Symbol,"15m",BeginDateTime);我自己写的公式,有的有,有的没有,排查不出来到底是哪个语句或者用法的问题

回复:有一个机制我忘了我说过没有。就是quant3,对于单元内的所有图层,如果保证图层标识一致,样本空间一致,周期数可整除的同一个标的,会自动启用setbaseperiod启用的效果就是上面讲过的,大周期多次执行的时候,以bar内的数据状态进行驱动。如果图层标识不一致,那么没有setbaseperiod效果,大周期执行几次,都是以收盘数据状态计算。你上面的demo2,做了后复权对齐处理,所以d0d1其实自动生效了setbase机制而demo3,没有做复权的一致性处理,没有生效setbaseperiod效果,所以大周期一直按收盘状态计算,那就出不了西瓜。

回复:咦 还真是demo3加上一句 SetBasePeriod("15m");效果就变了那这个机制还得小心,我得想想怎么按照预期的实现画图还没有成熟的满意的策略,还比较依赖图表的写写画画来启发灵感的之前没注意,以为Q3里面,SetBasePeriod已经可有可无了,即使不写,系统也是自动按最小周期执行的还去看了文档,文档写的我也是按照我以为的方式理解 https://tbq.tbquant.net/helper?product_id=999&keyword=440&content_id=2595&selectedkey=3824&type=article#2.1-%E6%95%B0%E6%8D%AE%E7%9A%84%E5%AF%B9%E9%BD%90%E6%9C%BA%E5%88%B6

回复:加了擦除语句 ,暂时目测符合预期了,再观察观察 range[ 0:DataSourceSize - 1] { if(close > open And close[1] > open[1] And close[2] > open[2] ) { Plt_ZT.icon("support", date + time, low, "ICO72"); //画个西瓜 } else { Plt_ZT.clear("support", date + time , date + time ); } if(close < open And close[1] < open[1] And close[2] < open[2]) { Plt_ZT.icon("resistance", date + time, high, "ICO25"); //画个哭脸 } else { Plt_ZT.clear("resistance", date + time , date + time ); } } }