能正常回测的应用,但无法在实盘运行,请老师帮忙排查问题。是因为SubscribeBar中把起始时间写得太早的原因吗?
Params
//此处添加参数
Integer N(5);//天数,默认取5天
Numeric Ks(0.3);
Numeric Kx(0.3);
Integer x(10);
Integer ma(5);
Numeric jysjz(0.1415);//效果时间止
//Numeric scope(4); //当天涨跌幅
Numeric cover_time(100);//开平仓时间点
Vars
//此处添加变量
Numeric avg;
Global Numeric time1_data1;
Global Numeric close1_data1;
Global Integer timerId;
Global Numeric HH;
Global Numeric LC;
Global Numeric HC;
Global Numeric LL;
Global Numeric R;
Global Numeric U;
Global Numeric D;
Global Numeric Ks_temp(3);
Global Numeric Kx_temp(3);
Global Integer lot(1);
Integer s_time(20220721);
Integer e_time(20221231);//订阅起始时间
Events
//此处实现事件函数
//初始化事件函数,策略运行期间,首先运行且只有一次,应用在订阅数据等操作
OnInit()
{
SubscribeBar("000300.SSE","1d",s_time,e_time);//订阅沪深300指数(000300.SSE)日K线行情
SubscribeBar("000300.SSE","5m",s_time,e_time);//订阅沪深300指数1分钟K线行情
SubscribeBar("IF888.CFFEX","5m",s_time,e_time);//订阅沪深300期货1分钟K线行情
//与数据源有关
Range[0:DataCount-1]
{
//=========数据源相关设置==============
AddDataFlag(Enum_Data_RolloverBackWard()); //设置后复权
AddDataFlag(Enum_Data_RolloverRealPrice()); //设置映射真实价格
AddDataFlag(Enum_Data_AutoSwapPosition()); //设置自动换仓
AddDataFlag(Enum_Data_IgnoreSwapSignalCalc()); //设置忽略换仓信号计算
//=========交易相关设置==============
MarginRate rate;
rate.ratioType = Enum_Rate_ByFillAmount; //设置保证金费率方式为成交金额百分比
//rate.longMarginRatio = 0.1; //设置保证金率为10%
rate.shortMarginRatio = 0.2; //设置保证金率为20%
SetMarginRate(rate);
CommissionRate tCommissionRate;
tCommissionRate.ratioType = Enum_Rate_ByFillAmount;
tCommissionRate.openRatio = 0.23; //设置开仓手续费为成交金额的5%%
tCommissionRate.closeRatio = 0.23; //设置平仓手续费为成交金额的2%%
tCommissionRate.closeTodayRatio = 0.23; //设置平今手续费为0
SetCommissionRate(tCommissionRate); //设置手续费率
SetSlippage(Enum_Rate_PointPerHand,2); //设置滑点为2跳/手
SetOrderPriceOffset(2); //设置委托价为叫买/卖价偏移2跳
SetOrderMap2MainSymbol(); //设置委托映射到主力
}
}
//Bar更新事件函数,参数indexs表示变化的数据源图层ID数组
OnBar(ArrayRef<Integer> indexs)
{
Range[0:0]
{
Ks_temp=Ks;
Kx_temp=Kx;
If(data0.Close[1]>=data0.Average(Close[1],ma))
{
Ks_temp=Ks-x*0.01; //如果沪深300在10日均线之上,则将触发看涨的阀值降低
}
If(data0.Close[1]<data0.Average(Close[1],ma))
{
Kx_temp=Kx-x*0.01; //如果沪深300在0日均线之下,则将触发看跌的阀值降低
}
HH = Highest(data0.High[1],N);
LC = Lowest(data0.Close[1],N);
HC = Highest(data0.Close[1],N);
LL = Lowest(data0.Low[1],N);
R = Max(HH-LC,HC-LL);
U = data0.Open[0] + Ks_temp*R;
D = data0.Open[0] - Kx_temp*R;
}
//来描述震荡区间的大小。其中HH是N日最大的最高价,LC是N日最低的收盘价,HC是N日最大的收盘价,LL是N日最小的最低价。
//当价格向上突破上轨时,如果当时持有空仓,则先平仓,再开多仓;如果没有仓位,则直接开多仓;
Range[1:1]
{
PlotNumeric("上轨",U,0,Red);
PlotNumeric("下轨",D,0,Blue);
time1_data1 = Time;
close1_data1 = close[1];
}
Range[2:2]
{
If(close1_data1 > U //当向上突破时
AND time1_data1 >= 0.1 AND time1_data1 <= 0.1415) //当天9:45之后,14:45分之前(是否需要修改成>=0.0945,<=0.1400?)
{
If(MarketPosition==0)
{
Buy(lot,max(close[1],open[0]));
FileAppend("c://DualThrust_GY_HC_Debug","time=" + TimeToString(time1_data1) + "向上突破,无空单,开多");
FileAppend("c://DualThrust_GY_HC_Debug",datetostring(CurrentDate()) + TimeToString(CurrentTime()) + "向上突破,无空单,开多");
}
Else if (MarketPosition==-1)
{
BuyToCover(lot,data2.Open[0]);
Buy(lot,data2.Open[0]);
FileAppend("c://DualThrust_GY_HC_Debug","time=" + TimeToString(time1_data1) + "向上突破,平空开多");
FileAppend("c://DualThrust_GY_HC_Debug",datetostring(CurrentDate()) + TimeToString(CurrentTime()) + "向上突破,平空开多");
}
}
else If(close1_data1 < D
and time1_data1 >= 0.1 and time1_data1 <= 0.1415) //当向下突破并且无多单时,开空单
{
Commentary("data1.time=" + TimeToString(time1_data1) + "cover_time*0.001=" + Text(0.1));
If(MarketPosition==0)
{
FileAppend("c://DualThrust_GY_HC_Debug","time=" + TimeToString(time1_data1) + "向下突破,无多单,开空");
FileAppend("c://DualThrust_GY_HC_Debug",datetostring(CurrentDate()) + TimeToString(CurrentTime()) + "向下突破,无多单,开空");
SellShort(lot,data2.open[0]);
}
Else if (MarketPosition==1)
{
Sell(lot,Open[0]);
SellShort(lot,Open[0]);
FileAppend("c://DualThrust_GY_HC_Debug","time=" + TimeToString(time1_data1) + "向下突破,有多单,平多开空");
FileAppend("c://DualThrust_GY_HC_Debug",datetostring(CurrentDate()) + TimeToString(CurrentTime()) + "向下突破,有多单,平多开空");
}
}
Else if (time1_data1==0.1 AND time1_data1<=jysjz
and close1_data1 >= D and close1_data1 <=U AND MarketPosition<>0)//如果在9:50分没有向上或向下突破,且昨日有持仓,则平仓
{
Commentary("data1.time=" + TimeToString(time1_data1) + "cover_time*0.001=" + Text(0.1));
If(MarketPosition==1)
{
FileAppend("c://DualThrust_GY_HC_Debug","time=" + TimeToString(time1_data1) + "未向上突破,平掉之前持有的多单");
FileAppend("c://DualThrust_GY_HC_Debug",datetostring(CurrentDate()) + TimeToString(CurrentTime()) + "未向上突破,平掉之前持有的多单");
Sell(lot,Open[0]);
}
Else If(MarketPosition==-1)
{
FileAppend("c://DualThrust_GY_HC_Debug","time=" + TimeToString(time1_data1) + "未向下突破,平掉之前持有的空单");
FileAppend("c://DualThrust_GY_HC_Debug",datetostring(CurrentDate()) + TimeToString(CurrentTime()) + "未向下突破,平掉之前持有的空单");
BuyToCover(lot,Open[0]);
}
}
}
}
file记录的结果很奇怪,如下图所示:
从回测应用到实盘运行,代码要作哪些改造,要注意什么问题,求指导
6
已经排查出问题,是因为我的变量名定义时错误地用了D,与关键字重复,所以引发了一系列奇怪的问题。
我把onini()中的
// SubscribeBar("000300.SSE","1d",s_time,e_time);//订阅沪深300指数(000300.SSE)日K线行情
// SubscribeBar("000300.SSE","5m",s_time,e_time);//订阅沪深300指数1分钟K线行情
// SubscribeBar("IF888.CFFEX","5m",s_time,e_time);//订阅沪深300期货1分钟K线行情
代码全部注释,改为在策略应用时手动添加相应的3个图层和起止时间(2022年7月1日起),再次进行尝试,但依旧出错。
下图是交易记录的截图:
第一个框是bar的date,为7月1日,下面的为currentdate,则是7月14日,已经在实盘中应用,为何还会出现历史的K线数据,实在不明白是为何,头疼,究竟是哪里配置错误,抑或是对tb的机制理解错误,求老师指导。
不要用全局变量 状态变量可以用序列变量
可以先学习一下数据结构的特点 掌握了再写
谢谢老师,我刚才把全局变量的定义全部修改到onbar中,尝试回测收益跟之前一样,但实盘好像还是有同样的问题。
刘老师好,我已经尝试把全部全局变量都变成了局部变量,但仍无法实盘,请老师继续指导问题在哪
你的buysell 是要交易if吧?那前缀data2呢?
我按老师教的写法,把不同图层的操作用 range[0:0] ,[1:1] , [2:2]分开写了。您说的buy,sell代码,都写在range[2:2]中,所以不需要加data2