步骤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已经可有可无了,即使不写,系统也是自动按最小周期执行的
还去看了文档,文档写的我也是按照我以为的方式理解

加了擦除语句 ,暂时目测符合预期了,再观察观察
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 );
}
}
}