关于模型改写 (文华财经WH8赢智V8.2)

投资者咨询:关于模型改写 (文华财经WH8赢智V8.2)
来源:文华财经  日期:2018-5-30 21:43

 老师,能否将下面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;

 

图片点击可在新窗口打开查看
技术人员回复
日期:2018-5-30 22:07
由于MC编写语言和我们编写语言差异巨大,并不能直接改写成功的

但您这是网格交易,一般需要使用算法模型编写,可以给您一个范例,您参考下

GLOBAL_VAR COD; //合约编码
GLOBAL_VAR BKM,SKM; //下单手数
GLOBAL_VAR FLG; //多空委托标识
GLOBAL_VAR NUM; //交易次数统计
GLOBAL_VAR OPEN; //开盘价
GLOBAL_VAR M; //价格差
GLOBAL_VAR NEWP; //最新价
GLOBAL_VAR CST; //服务器时间
GLOBAL_VAR BRP,SRP; //组件多空头可用持仓
GLOBAL_VAR QCFLG; //清仓标志

VOID MAIN()
{
   VLFUN(); //执行变量赋值函数
   OPFUN(); //执行开盘处理函数
}

//----------------------自定义函数--------------------//

VOID VLFUN() //变量赋值函数
{
   COD = "rb1805"; //合约编码
   OPEN = Price(COD,"Open"); //开盘价
   M = 50; //涨跌价格差
   NEWP = Price(COD,"New"); //最新价
   CST = CurrentServerTime(COD); //服务器时间
   BRP = AL_BuyRemainPosition(COD); //组件多头可用持仓
   SRP = AL_SellRemainPosition(COD); //组件空头可用持仓
}

VOID OPFUN() //开盘处理函数
{
   IF(T_IsExchangeOpen(COD) == 1) //如果当前状态为开盘
   {
      IF(FLG == 0)
      {
         IF(NEWP >= OPEN + M) //到达开多仓位
         {
            NUM = NUM + 1;
            BKFUN();
         }
         IF(NEWP <= OPEN - M) //到达开空仓位
         {
            NUM = NUM + 1;
            SKFUN();
         }
      }
      ELSE IF(FLG == 1 && NEWP <= OPEN - M) //如果上次开仓为多仓,且满足空仓条件
      {
         NUM = NUM + 1;
         SKFUN();
      }
      ELSE IF(FLG == 2 && NEWP >= OPEN + M) //如果上次开仓为空仓,且满足多仓条件
      {
         NUM = NUM + 1;
         BKFUN();
      }
   }
   ELSE IF(T_IsExchangeOpen(COD) != 1) //如果当前状态不是开盘
   {
      IF(QCFLG == 1)
      {
         QCFLG = 0;
      } 
   }
}


//-------------------------买开-----------------------//

VOID BKFUN() //买开函数
{
   BKM = NUM;
   MessageOut("【买开委托发出!】");
   T_Deal1(COD,0,0,BKM,LIMIT_ORDER); //以市价发出买开手数的买开委托
   FLG = 1;
}

//-------------------------卖开-----------------------//

VOID SKFUN() //卖开函数
{
   SKM = NUM;
   MessageOut("【卖开委托发出!】");
   T_Deal1(COD,1,0,SKM,LIMIT_ORDER); //以市价发出卖开手数的卖开委托
   FLG = 2;
}

//-------------------------清仓-----------------------//

VOID QCFUN() //买平函数
{
   IF(SRP > 0) //如果有空头可用持仓
   {
      MessageOut("【清仓:买平委托发出!】");
      IF(T_IsSHCode(COD) == 1) //如果当前合约是上海市场合约
      {
         T_Deal1(COD,0,2,SRP,LIMIT_ORDER); //以市价发出空头可用持仓手数的买平今仓委托
      }
      ELSE //如果当前合约不是上海市场合约
      {
         T_Deal1(COD,0,1,SRP,LIMIT_ORDER); //以市价发出空头可用持仓手数的买平委托
      }
   }
   IF(BRP > 0) //如果有多头可用持仓
   {
      MessageOut("【清仓:卖平委托发出!】");
      IF(T_IsSHCode(COD) == 1) //如果当前合约是上海市场合约
      {
         T_Deal1(COD,1,2,BRP,LIMIT_ORDER); //以市价发出多头可用持仓手数的卖平今仓委托
      }
      ELSE //如果当前合约不是上海市场合约
      {
         T_Deal1(COD,1,1,BRP,LIMIT_ORDER); //以市价发出多头可用持仓手数的卖平委托
      }
   }
}
 
投资者咨询:关于模型改写 (文华财经WH8赢智V8.2)
来源:文华财经  日期:2018-5-30 21:43
 那请问老师,我一楼的模型可以用MQ改写吗?如果可以,麻烦写一下,谢谢!
技术人员回复
日期:2018-5-30 22:31
 不行的,编写语言差异太大了,不能直接改写,请理解

简单的网格交易给您的范例WH8足够实现的,您试下