T9程序化模型编写、计算机制说明

模型根据从上至下,从左至右的顺序进行计算;编写中每一行计算,都能引用本次计算上面各行的计算结果

模型默认信号执行方式为指令价(出信号立即下单),也支持编写多样的信号执行方式
模型默认为一根K线一个信号的模型,也支持编写一根K线多个信号的模型
模型默认为一次建仓模型,也支持编写连续建仓模型
模型支持编写T+0策略和T+1策略,通过写入对应的指令实现

一、模型的机制

(一)模型指令
1、编写T+0策略,模型可使用BK\SK\BP\SP\BPK\SPK指令
2、编写T+1策略,模型可使用Buy\Sell指令

(二)信号执行方式
1、默认信号执行方式
一根K线的第一个信号有效;
出信号立即下单,下单后到k线走完的后续信号不再执行,K线走完后复核信号。
回测不考虑信号消失成本。
避免信号消失的编写要点:
(1)K线走完确认信号下单,使用REF判断信号条件
(2)K线盘中执行,使用High/Low判断信号条件
例子:编写模型阳线买入开仓,阴线卖出平仓

Begin
If(Ref(IsUp,1)) //前一根K线确认为阳线,买入开仓
BK;
If(Ref(IsDown,1))//前一根K线确认为阴线,卖出平仓
SP;
End

Begin
If(High>Open)//当根K线盘中为阳线时,买入开仓
BK;
If(Low<Open)//当根K线盘中为阴线时,卖出平仓
SP;
End

2、通过环境设置函数设定多样化的信号执行方式
(1)设置一根k线多信号的指令价方式
写入MultSig/MultSig_Min
出信号N秒下单,不进行信号复核;
可以设置一根K线多个信号;
回测方式为逐笔或逐分钟回测,不存在信号消失,回测与实盘运行结果一致
例:
Setting
MultSig:0,0,2,0;//出信号立即下单,不进行复核,一根K线最多可以出现2个信号
Vars
NumericSeries MA1;
NumericSeries MA2;
begin
MA1=Ma(Close,5);
MA2=Ma(Close,10);
if(CrossUp(Close,MA1))
BK;
if(Close>BKPrice+10*MinPrice || Close<BKPrice-5*MinPrice)
SP;
PlotLine("MA1",MA1,White);
PlotLine("MA2",MA2,Yellow);
End
(2)SignalNoTrading 设置模型信号是否执行
如果软件自带的信号执行方式还不能满足您的需求,您可以通过自编信号执行方式实现。
不支持回测

(三)模型类型
1、一次建仓模型
默认为一次建仓模型,不允许连续出开仓信号,可以连续出平仓信号。
只有在持仓为0时才能开新仓,一次交易只能建一次仓,有多个开仓信号都满足条件的时候,取第一个信号作为有效信号,后面的K线上的同样信号将被过滤掉
编写要点:
(1)一开一平模型:开仓手数与平仓手数一致
(2)减仓模型:平仓手数小于开仓手数
例子:
①开平仓手数一致
Vars
NumericSeries MA1;
NumericSeries MA2;
begin
MA1=Ma(Close,5);
MA2=Ma(Close,10);
if(CrossUp(Close,MA1))
BK;
if(CrossUp(MA1,MA2))
BK;
if(Close>BKPrice+10*MinPrice || Close<BKPrice-5*MinPrice)
SP;
PlotLine("MA1",MA1,White);
PlotLine("MA2",MA2,Yellow);
End
②平仓手数小于开仓手数
Vars
NumericSeries MA1;
NumericSeries MA2;
begin
MA1=Ma(Close,5);
MA2=Ma(Close,10);
if(CrossUp(Close,MA1))
BK(2);
if(CrossUp(MA1,MA2))
BK(1);
if(Close>BKPrice+10*MinPrice || Close<BKPrice-5*MinPrice)
SP(1);
PlotLine("MA1",MA1,White);
PlotLine("MA2",MA2,Yellow);
End

2、连续建仓模型
模型通过写入AddTimes控制一次交易过程中的最大建仓次数,允许连续出开仓信号和平仓信号;
达到最大连续建仓次数后,平掉连续建仓的首次建仓,才能另开新仓。
例:
Setting
AddTimes:3;
Vars
NumericSeries MA1;
NumericSeries MA2;
begin
MA1=Ma(Close,5);
MA2=Ma(Close,10);
if(CrossUp(Close,MA1))
BK(2);
if(CrossUp(MA1,MA2))
BK(1);
if(Close>BKPrice+10*MinPrice || Close<BKPrice-5*MinPrice)
SP(1);
PlotLine("MA1",MA1,White);
PlotLine("MA2",MA2,Yellow);
End

二、编写常见问题

1、如何定义策略中使用的全局变量
(1)趋势策略
①NumericSeries、StringSeries定义序列型变量
盘中运行:记录下每根K线的运算结果,用于下根K线的计算
回测:支持回测

例子:通过序列变量控制一天之内总的开仓次数(开多+开空)
Setting
AddTimes:5;  
Params
Numeric Length(3); // 周期
Vars
NumericSeries BarN; //当日K线根数
NumericSeries myflag; // 交易次数
Begin

// ------------------- 取当日K线根数及交易次数 -----------------
If(date!=date[1])
  {
    BarN= 1 ;
    myflag =0;
  }
else BarN= BarN[1]+1;

// ----------------------- 多头开仓--------------------
If (MarketPosition!=-1  And Vol > 0 )
  {
    If(Every(IsUp,Length) And BarN>=Length And CloseMinute>=5 And myflag<= 5) //连续三根收阳,则开多单,最多连续开5次。
      {
      BPK;
      myflag = myflag+1;
    }
  }

// ------------------------ 空头开仓-----------------
If (MarketPosition!=1  And Vol > 0 )
  {
    If(Every(IsDown,Length) And BarN>=Length And CloseMinute>=5 And myflag<= 5) //连续三根收阴,则开空单,最多连续开5次。
    {  
      SPK;
      myflag = myflag+1;
    }
}
If(CloseMinute<=5 And BarsSinceEntry > 0 And Vol > 0)
  {
// ------------------------- 尾盘多头平仓----------------
    If(MarketPosition == 1 )
    SP;
// ---------------------- 尾盘空头平仓-------------
    If(MarketPosition == -1)
    BP;
  }
End

②GetGlobalVar(Index)、SetGlobalVar(Index,Val);GetGlobalVar2(Str)、SetGlobalVar2(Str,Val)
盘中运行:记录下每笔TICK的运算结果,用于之后的计算
回测:不支持回测

(2)订单流策略
Global_Numeric、Global_NumericArray、Global_String、Global_StringArray定义全局变量或使用GetGlobalVar(Index)、SetGlobalVar(Index,Val);GetGlobalVar2(Str)、SetGlobalVar2(Str,Val)
盘中运行:记录下每笔TICK的运算结果,用于之后的计算
回测:支持订单流策略回测
例子:通过全局变量,控制交易重复执行
(1)
Data  
    data0:"m1801";
Vars
    Global_Numeric type;
Begin  
    If(data0.A_BuyProfitLoss()>5000&&type == 0) //如果该合约多头盈亏大于5000,加仓1手
    {
       data0.A_SendOrder(Enum_Buy,Enum_Entry,1,data0.price("Ask1"));
       type = 1; //加仓后type重新赋值,避免重复执行
    }
End
(2)
Data  
data0:"m1801";
Begin  
    If(data0.A_BuyProfitLoss()>5000 && GetGlobalVar(0) == 0) //如果该合约多头盈亏大于5000,加仓1手
    {
       data0.A_SendOrder(Enum_Buy,Enum_Entry,1,data0.price("Ask1"));
       SetGlobalVar(0,1); //加仓后全局变量第一个位置重新赋值,避免重复执行
    }
End

2、如何定义布尔型变量
使用Numeric、NumericSeries定义数值型变量代替
变量返回值:1代表True;0代表Flse
例子:通过设置决定是否启用按资金比例下单
Vars
NumericSeries  Ma5;    //5周期均线
NumericSeries  Ma10;   //10周期均线
Numeric  Buytype(0);//是否启用按资金比例下单
Numeric  lots;//下单手数
Begin  
If(Buytype ==0 )
  {
    lots = 5;//固定5手开仓
  }
Else If(Buytype == 1 )
  {
    lots = MoneyTot*0.2/(Close*ContractUnit*MarginRatio);//按资金的百分之20开仓
  }
Ma5 = Ma(Close,5);
Ma10 = Ma(Close,10);
If(Ref( CrossUp(Ma5,Ma10) ,1) )
  {
    BPK(lots);
  }
Else If(Ref( CrossDown(Ma5,Ma10) ,1) )
  {
    SPK(lots);
  }
End

3、如何定义数组型变量
使用NumericArray、StringArray、Global_StringArray定义不同类型的数组变量
例子:取得最近10根K线内最高价小于当前K线,最低价大于当前K线的K线数量
Vars
NumericArray deep;
Numeric i;
Numeric j;
Numeric k;
Begin
For i =0 To 9
  {
  If( High>High[i])
  {
    deep[j]=Low[i];
    j = j+1;//装入最近的10根K线内小于当根最高价的K线的最低价
  }
}
For i =0 To j-1
  {
    If( Low<deep[i])
     k = k+1;
  }
PlotNumeric("根数",k);
End