老师,能否将下面MC的网格策略改写成文华WH8?
input: pricevalue(close), length(200), flag_bar(60), buyp(10), sloss(2), lots(1);
var: flag1(0), flag2(-flag_bar), mp(0), leg(0),mid(0), b1(0), b2(0), b3(0), b4(0), s1(0), s2(0), s3(0), s4(0), zhs_b(0), zhs_s(0), cur_bar(1);
array: arr_num[8](0);
mp=marketposition;
if getappinfo(aistrategyauto)=1 then
if not lastbaronchart_s then
cur_bar=currentbar+1
else once cur_bar=currentbar;
if (postradeexitname(1,postradecount(1)-1)="zhs_s" or postradeexitname(1,postradecount(1)-1)="zhs_b") and mp[1]<>0 and mp=0 then
flag2=currentbar;
if mp=0 and currentbar>=cur_bar then
flag1=flag1+1
else flag1=0;
if cur_bar=currentbar or (mp<>mp[1] and mp=0) or flag1=flag_bar or flag2+flag_bar=currentbar then begin
value11=highest(pricevalue,length);
value22=lowest(pricevalue,length);
leg=intportion(((value11-value22)/(minmove*1 point))/8);
mid=(value11+value22)/2;
// mid=close;
b1=mid-1*leg*(minmove*1 point);
b2=mid-2*leg*(minmove*1 point);
b3=mid-3*leg*(minmove*1 point);
b4=mid-4*leg*(minmove*1 point);
s1=mid+1*leg*(minmove*1 point);
s2=mid+2*leg*(minmove*1 point);
s3=mid+3*leg*(minmove*1 point);
s4=mid+4*leg*(minmove*1 point);
zhs_s=b4-sloss*leg*(minmove*1 point);
zhs_b=s4+sloss*leg*(minmove*1 point);
arr_num[0]=TL_new_bn(currentbar,mid,currentbar,mid);
arr_num[1]=tl_new_bn(currentbar,b1,currentbar,b1);
arr_num[2]=tl_new_bn(currentbar,b2,currentbar,b2);
arr_num[3]=tl_new_bn(currentbar,b3,currentbar,b3);
arr_num[4]=tl_new_bn(currentbar,b4,currentbar,b4);
arr_num[5]=tl_new_bn(currentbar,s1,currentbar,s1);
arr_num[6]=tl_new_bn(currentbar,s2,currentbar,s2);
arr_num[7]=tl_new_bn(currentbar,s3,currentbar,s3);
arr_num[8]=tl_new_bn(currentbar,s4,currentbar,s4);
tl_setcolor(arr_num[0],blue);
flag1=0;
end;
if currentbar>=cur_bar and flag2+flag_bar<=currentbar then begin
if close>b1-minmove*4 point then
buy("b1") lots shares next bar at b1 limit;
if close>b2-minmove*4 point then
buy("b2") lots shares next bar at b2 limit;
if close>b3-minmove*4 point then
buy("b3") lots shares next bar at b3 limit;
if close>b4-minmove*4 point then
buy("b4") lots shares next bar at b4 limit;
if close<s1+minmove*4 point then
sellshort("s1") lots shares next bar at s1 limit;
if close<s2+minmove*4 point then
sellshort("s2") lots shares next bar at s2 limit;
if close<s3+minmove*4 point then
sellshort("s3") lots shares next bar at s3 limit;
if close<s4+minmove*4 point then
sellshort("s4") lots shares next bar at s4 limit;
setstopcontract;
setprofittarget(lots*bigpointvalue*minmove*leg point);
sell("zhs_s") next bar at zhs_s stop;
buytocover("zhs_b") next bar at zhs_b stop;
tl_setend_bn(arr_num[0],currentbar,mid);
tl_setend_bn(arr_num[1],currentbar,b1);
tl_setend_bn(arr_num[2],currentbar,b2);
tl_setend_bn(arr_num[3],currentbar,b3);
tl_setend_bn(arr_num[4],currentbar,b4);
tl_setend_bn(arr_num[5],currentbar,s1);
tl_setend_bn(arr_num[6],currentbar,s2);
tl_setend_bn(arr_num[7],currentbar,s3);
tl_setend_bn(arr_num[8],currentbar,s4);
end;
网格策略的思路(下文中提到的图一见附件):
一、 网格策略概况
网格策略擅长于振荡行情捕捉噪声,较适合于价差套利或低波动性品种,而在趋势行情中可能会导致爆仓。一个好网格策略取决于风险控制,而风险控制可以通过以下的方法来达到,而这正是网格策略的难点所在:
Ø 动静态调整网格间距,以控制单边风险暴露的速度(网格间距太大,盈利太慢;网格间距太小,风险太大)
Ø 动态调整网格的价格中枢,以增强网格的时效性(缺乏时效性的网格遇到趋势行情时很可能就会爆仓,因为价格不可能永远在网格中枢上下一定范围内波动)
网格策略有水平网格策略(Horizontal Grid)和垂直网格策略(Vertical Grid),水平网格策略也就是我们通常认识的网格策略,大体可以分成5小类,如下图所示:
图1 网格策略
二、 策略逻辑
本策略(如图1中编号为1的网格策略)基于收盘价计算200根bar的价格区间,取价格区间的中间价(也可以取当根bar的收盘价)作为网格策略的价格中枢,将价格区间等分成8份以确定网格间距,在价格中枢上方每一个网格处委托限价卖单,在价格中枢下方每一个网格处委托限价买单,委托单只设止盈不设止损。
为控制风险,本策略采用了几下几种操作:
Ø 每笔委托单的委托手数是相等的,每笔进场单的止盈金额也是相等的;
Ø 在最下方网格线下方两倍网格间距处设置止损,在最上方网格线上方两倍网格间距处设置止损;
Ø 策略会在以下几种情况下调整网格中枢和网格间距:第一次初始化、60根bar没有交易、由持仓转变为空仓、止损后60根bar后。
三、 策略代码
(注意:在策略属性中设置“最多允许4笔与目前仓位同向的进场”并且“当委托由不同的进场语句产生”;在策略属性中勾选“优化委托执行”;策略属性中最大bar设置成200)
input: pricevalue(close), length(200), flag_bar(60), buyp(10), sloss(2), lots(1);
var: flag1(0), flag2(-flag_bar), mp(0), leg(0),mid(0), b1(0), b2(0), b3(0), b4(0), s1(0), s2(0), s3(0), s4(0), zhs_b(0), zhs_s(0), cur_bar(1);
array: arr_num[8](0);
{Flag_bar根bar未交易,则调整网格间距和网格中枢,通过变量flag1来控制;网格间距是基于最近length根bar的pricevalue价格计算出来的;leg表示网格间距的大小;mid表示网格中枢的价格;b1表示网格中枢下方第一根网格线的价格,即买1价,s1表示网格中枢上方第一根网格线的价格,即卖1价,b2、b3、b4、s2、s3、s4以此类推;zhs_b和zhs_s分别代表上方的止损价和下方的止损价格;数组arr_num用于存储网格线的编号,用于后面网格线的延长}
mp=marketposition;
if getappinfo(aistrategyauto)=1 then
if not lastbaronchart_s then
cur_bar=currentbar+1
else once cur_bar=currentbar;
{这段代码用于使图表部位与图表上的网格线同步;如果这段代码去除,那么当您开启自动交易后,假设这里开启自动交易的位置在编号为1000的bar上,那么从编号为200到1000的bar中间,还有会有网格线存在,但是没有进场部位存在,这样就会导致不一致了;这段代码的存在就是为了解决这个图表显示问题,使在开启自动交易之后,在编号为1000的bar之后才开启画网格线}
if (postradeexitname(1,postradecount(1)-1)="zhs_s" or postradeexitname(1,postradecount(1)-1)="zhs_b") and mp[1]<>0 and mp=0 then
flag2=currentbar;
{上面这段代码,是用于识别止损;当止损出现时,将当根bar的编号赋值给变量flag2,后面flag_bar不再交易、也不再画网格线}
if mp=0 and currentbar>=cur_bar then
flag1=flag1+1
else flag1=0;
{上面这段代码,是用于识别多少根bar不交易,flag1会统计连续不交易的bar的数量}
if cur_bar=currentbar or (mp<>mp[1] and mp=0) or flag1=flag_bar or flag2+flag_bar=currentbar then begin
{这里的if判断用于识别调整网格中枢和网格间距的条件是否满足,上面已经提到了,当第一次画网络线时会调整一次、由持仓转变为空仓会调整一次、flag_bar根bar不交易会调整一次、止损后flag_bar会调整一次}
value11=highest(pricevalue,length);
value22=lowest(pricevalue,length);
{将最近length根bar的最高的pricevalue价格存储在value11上,在最近length根bar的最低的pricevalue价格存储在value22上}
leg=intportion(((value11-value22)/(minmove*1 point))/8);
{将value11与value22等分8份之后,再转换成跳数存储到leg上;也就是网格间距是多少跳,因为不同的商品合约的价格数值的精度是不一样的,所以以跳数来衡量}
mid=(value11+value22)/2;
//以中间价作为网格中枢,当然也可以使用收盘价作为网格中枢
// mid=close;
b1=mid-1*leg*(minmove*1 point);
b2=mid-2*leg*(minmove*1 point);
b3=mid-3*leg*(minmove*1 point);
b4=mid-4*leg*(minmove*1 point);
s1=mid+1*leg*(minmove*1 point);
s2=mid+2*leg*(minmove*1 point);
s3=mid+3*leg*(minmove*1 point);
s4=mid+4*leg*(minmove*1 point);
zhs_s=b4-sloss*leg*(minmove*1 point);
zhs_b=s4+sloss*leg*(minmove*1 point);
{上面分别计算网格线处的价格和止损价}
arr_num[0]=TL_new_bn(currentbar,mid,currentbar,mid);
arr_num[1]=tl_new_bn(currentbar,b1,currentbar,b1);
arr_num[2]=tl_new_bn(currentbar,b2,currentbar,b2);
arr_num[3]=tl_new_bn(currentbar,b3,currentbar,b3);
arr_num[4]=tl_new_bn(currentbar,b4,currentbar,b4);
arr_num[5]=tl_new_bn(currentbar,s1,currentbar,s1);
arr_num[6]=tl_new_bn(currentbar,s2,currentbar,s2);
arr_num[7]=tl_new_bn(currentbar,s3,currentbar,s3);
arr_num[8]=tl_new_bn(currentbar,s4,currentbar,s4);
tl_setcolor(arr_num[0],blue);
flag1=0;
{将新建的走势线的编号分别存储在数组变量中,同时将网格中枢线的颜色调整成蓝色;将flag1变量赋值为0,重新统计连续不交易的bar的数量}
end;
if currentbar>=cur_bar and flag2+flag_bar<=currentbar
{这里通过flag2+flag_bar<=currentbarg来控制,使止损之后flag_bar数量的bar不交易}
then begin
if close>b1-minmove*4 point then
{这里将限价的发单条件控制在一定的价格范围内,避免出现当市价在b1价下方时频繁进出场的情况,其它限价单的处理类似}
buy("b1") lots shares next bar at b1 limit;
if close>b2-minmove*4 point then
buy("b2") lots shares next bar at b2 limit;
if close>b3-minmove*4 point then
buy("b3") lots shares next bar at b3 limit;
if close>b4-minmove*4 point then
buy("b4") lots shares next bar at b4 limit;
if close<s1+minmove*4 point then
sellshort("s1") lots shares next bar at s1 limit;
if close<s2+minmove*4 point then
sellshort("s2") lots shares next bar at s2 limit;
if close<s3+minmove*4 point then
sellshort("s3") lots shares next bar at s3 limit;
if close<s4+minmove*4 point then
sellshort("s4") lots shares next bar at s4 limit;
setstopcontract;
setprofittarget(lots*bigpointvalue*minmove*leg point);
{使用setprofittarget进行分笔止盈}
sell("zhs_s") next bar at zhs_s stop;
buytocover("zhs_b") next bar at zhs_b stop;
tl_setend_bn(arr_num[0],currentbar,mid);
tl_setend_bn(arr_num[1],currentbar,b1);
tl_setend_bn(arr_num[2],currentbar,b2);
tl_setend_bn(arr_num[3],currentbar,b3);
tl_setend_bn(arr_num[4],currentbar,b4);
tl_setend_bn(arr_num[5],currentbar,s1);
tl_setend_bn(arr_num[6],currentbar,s2);
tl_setend_bn(arr_num[7],currentbar,s3);
tl_setend_bn(arr_num[8],currentbar,s4);
{上面这9行代码用于延长网格至当根bar的作用}
end;
