平单信号不对

写了一个套利策略,但是平仓的信号不太对跟自己打印的log有所出入

 

策略代码:

Params
     Numeric numeratorSubStartTime(20210913.100500);  // 期货比例中的分子期货(菜粕) 订阅的开始时间
     string numeratorSubFreq("5m");   // 期货比例中的分子期货(菜粕) 订阅频率 'mon':月,'w':周,'d':日,'h':时,'m':分,'s':秒,'tick':tick,字符串前面可以添加数字     
     String numeratorSymbol("RM201.CZCE");  // 期货比例中的分子期货(菜粕)     
     Numeric numeratorOrderNumb(1);   // 期货比例中的分子期货(菜粕) 默认开单的数量     
     Numeric denominatorOrderNumb(1);   // 期货比例中的分母期货(豆粕) 默认开单的数量     
     Numeric datum(0.8);    // 基准值 
     Numeric tolerance(0.001);   // 比例容错值
     Array<Numeric> upLevels([0.82,0.84,0.86]); // 高于基准的等级 数组的数据必须高于基准值
     Array<Numeric> downLevels([0.78,0.76,0.74]); // 低于基准的等级 数组的数据必须低于基准值
     
Vars
    Global Array<Integer> layers;  // 记录订阅BAR之后返回的图层号
     // [10,5,0,20]  
     // Params1 : 分母 开多仓的量. Params2 : 分母 开空仓的量. Params3 : 分子 开多仓的量. Params4 : 分子 开空仓的量.
    Global Array<Array<Numeric>>  aresOrder;
 
Defs       
    // 1:分子 2:分母   direction 0:开多 1:开空  2.平多仓 3.平空仓
     Integer OpenPosition(Integer direction1, Integer direction2){
          
         if(direction1 == 0){
             // 开多仓
             // Print(Data1.Symbol + ": 开多仓");
             Data1.Buy(numeratorOrderNumb, Data1.Close);
         }
         else if(direction1 == 1){
             // 开空仓
             // Print(Data1.Symbol + ": 开空仓");
             Data1.SellShort(numeratorOrderNumb, Data1.Close);
         }
         else if(direction1 == 2){
            // 平多仓
            Data1.Sell(numeratorOrderNumb, Data1.Close);
         }
         else if(direction1 == 3){
            // 平空仓
            Data1.BuyToCover(numeratorOrderNumb, Data1.Close);
         }
         else {
           // do nothing       
         }
         
         if(direction2 == 0){
             // 开多仓
             // Print(Data0.Symbol + ": 开多仓");
             Data0.Buy(denominatorOrderNumb, Data0.Close);
         }
         else if(direction2 == 1){
             // 开空仓
             // Print(Data0.Symbol + ": 开空仓");
             Data0.SellShort(denominatorOrderNumb, Data0.Close);
         }
         else if(direction2 == 2){
            // 平多仓
            Data0.Sell(denominatorOrderNumb, Data0.Close);
         }
         else if(direction2 == 3){
            // 平空仓
            Data0.BuyToCover(denominatorOrderNumb, Data0.Close);
         }
         else {
           // do neting        
         }
         
         return 0;
    }
    
    // 平仓
    Bool ClosePosition(ArrayRef<Numeric> orderArr)
    {
        Print("开始平仓");
        if(GetArraySize(orderArr) != 4)
           return false;
           
        if(orderArr[0] != 0){
            // 平多仓 (分母)
            // Print(Data0.Symbol +  "平多仓");
            Data0.Sell(orderArr[0],Data0.Close);            
        }
        
        if(orderArr[1] != 0){
            // 平空仓 (分母)
            // Print(Data0.Symbol +  "平空仓");
            Data0.BuyToCover(orderArr[1],Data0.Close);            
        }
        
        if(orderArr[2] != 0){
            
            // 平多仓 (分子)
            // Print(Data1.Symbol +  "平多仓");
            Data1.Sell(orderArr[2],Data1.Close);            
        }
        
        If(orderArr[3] != 0){
            // 平空仓 (分子)
            // Print(Data1.Symbol +  "平空仓");
            Data1.BuyToCover(orderArr[3],Data1.Close);            
        }
    
        orderArr = [0,0,0,0];
        return true;
    }
    

    // 将开单的数据保存到数据库中 返回操作的结果
    Bool SaveOrderData(Array<Array<Numeric>> postionData){
        String saveStr;
        String splitStr = "|";
        Integer i = 0;
        For i  To (GetArraySize(postionData) - 1) {
            if(i != 0){
               splitStr = "|";
            }
            else {
                splitStr = "";
            }
            
            saveStr = saveStr + splitStr  +  Text(postionData[i][0]) + "," + Text(postionData[i][1]) + "," + Text(postionData[i][2]) + "," + Text(postionData[i][3]);
        }
        
        // save 
        SetTBProfileString(Symbol,"Position", saveStr);
        
        return True;
    }    
    
    // 读取数据库中的订单数据并解析成二维数组并返回
    Bool ParsingOrderData(ArrayRef<Array<Numeric>> postionData){
        
         // 数据库存储的数据格式: 20,0,0,0|1,0,1,0|1,0,9,8|1,2,3,4
         String orderDataStr = GetTBProfileString(Symbol,"Position");
         Print("orderDataStr = " + orderDataStr);
         if(orderDataStr == "N/A"){
              return false;
         }
         
         Array<String> splitsStr;
         // 解析数据: 
         StringSplit(orderDataStr,"|",splitsStr);         
         
         if(GetArraySize(splitsStr) != GetArraySize(upLevels) + GetArraySize(downLevels)){
             return false;
         }
         
         Integer i = 0;
         for i To (GetArraySize(splitsStr) -1)
         {
             // 解析
             Array<String> itemStrArr;
             StringSplit(splitsStr[i],",",itemStrArr);
            if(GetArraySize(itemStrArr) != 4){
                return false;
            }
            
            postionData[i][0] = Value(itemStrArr[0]);
            postionData[i][1] = Value(itemStrArr[1]);
            postionData[i][2] = Value(itemStrArr[2]);
            postionData[i][3] = Value(itemStrArr[3]);
            Print("postionData = " + TextArray(postionData));         
         }
         
         return true;
    }
    
Events
OnInit()
{   
    // 订阅菜粕 5m的 bar 数据
    layers[0] = SubscribeBar(numeratorSymbol, numeratorSubFreq, numeratorSubStartTime);
    
}

OnReady()
{
    Bool ref = ParsingOrderData(aresOrder);
    if(!ref){
        Integer i = 0;
        For i To (GetArraySize(upLevels) + GetArraySize(downLevels) - 1){
           aresOrder[i] = [0,0,0,0];
        }
    }
    
    Print("aresOrder: " + TextArray(aresOrder) + "Ref =" + IIFString(ref, "TRUE", "FALSE"));
}

Onbar(ArrayRef<Integer> indexs) 
{
    Numeric rate = Data1.Close / Data0.Close; 
    Commentary(Text(rate));
    
     // 处理基线附近的仓位   
    if(Abs(rate - datum) <= tolerance){
        
         Integer upCount = GetArraySize(upLevels);
         if(SummationArray(aresOrder[0]) > 0){
             Print("基线平仓:平上的数量:" + Text(SummationArray(aresOrder[0])) + "当前比例:" + Text(rate));
            ClosePosition(aresOrder[0]);                  
         }
 
         if(SummationArray(aresOrder[upCount]) > 0){
             Print("基线平仓:平下的数量:" + Text(SummationArray(aresOrder[upCount])) + "当前比例:" + Text(rate));
            ClosePosition(aresOrder[upCount]);         
         }
         
         SaveOrderData(aresOrder);
         
    }
    
    Integer i = 0;
    
    // 处理基线以上的区间 
    For i TO (GetArraySize(upLevels) -1){

        if(Abs(rate - upLevels[i]) > tolerance){
            Continue;
        }     
        
        Numeric currentCount = SummationArray(aresOrder[i]);
        
        if(currentCount == 0){
            // 开仓
            OpenPosition(1,0);
            aresOrder[i][1] = numeratorOrderNumb;
            aresOrder[i][2] = denominatorOrderNumb; 
            Print("上线开仓:开仓数量:" + Text(SummationArray(aresOrder[i])) + ", 开仓的Index:" + Text(i) + "当前比例:" + Text(rate));
         }
            
        if(i != GetArraySize(upLevels) -1){
            // 非最高点检测是否需要平仓
           Numeric nextCount = SummationArray(aresOrder[i + 1]);
           if(nextCount > 0){
               // 平仓
               Print("上线平仓:平上的数量:" + Text(nextCount) + ", 平仓的位置 :" + Text(i + 1) + "当前位置:i =" + Text(i) + "当前比例:" + Text(rate));
               ClosePosition(aresOrder[i + 1]);
           }
        }
        
        SaveOrderData(aresOrder);
    }
    
    Integer upLevelsCount = GetArraySize(upLevels);
    i = upLevelsCount;
    // 处理基线以下的区域
    For i To (upLevelsCount + GetArraySize(downLevels) - 1){        
        if(Abs(rate - downLevels[i - upLevelsCount]) > tolerance){
            Continue;
         }
         
         Numeric currentDownCount = SummationArray(aresOrder[i]);        
         if(currentDownCount == 0){
             // 开仓
             OpenPosition(0, 1);
             aresOrder[i][0] = numeratorOrderNumb;
            aresOrder[i][3] = denominatorOrderNumb; 
            Print("下线开仓:开仓数量:" + Text(SummationArray(aresOrder[i])) + ", 开仓的Index:" + Text(i) + "当前比例:" + Text(rate));
         }
         
         if(i != upLevelsCount + GetArraySize(downLevels) - 1){
              // 非最高点 检测是否需要平仓
              Numeric nextDownCount = SummationArray(aresOrder[i + 1]);
           if(nextDownCount > 0){
               // 平仓
               ClosePosition(aresOrder[i + 1]);
               Print("上线平仓:平下的数量:" + Text(nextDownCount) + ", 平仓的位置 :" + Text(i + 1) + "当前位置:i =" + Text(i) + "当前比例:" + Text(rate));
           }
           
           SaveOrderData(aresOrder);
         }
    }
   
}

麻烦老师把文字部分(先平掉所有空单再开多单,先平掉所有多单再开空单)
手动空平后,信号再次空平
【发单】平多的指令成了开空单
策略图表信号不对
模拟交易价格是按照策略,,但是信号不对
换月仓位不对
A函数多单策略 信号出现空头头寸
如何判断是否有委托单来防止信号闪烁
)挎号不对,是照着视频例子看的。怎么就不对呢
条件单

代码搞混了

代码逻辑问题。 没有枚举,用0 1 代替 弄混了

第一 如果开了委托偏移 那么报单价格是对手价加偏移点数报单 这就可能与交易命令里的所谓程序价格不一致

第二 如果没有开委托偏移 那么需要通过写log确认这个单子是从哪一行的交易命令报出来的,进而对这个交易命令里的价格变量进行诊断

代码逻辑问题, 没有枚举 用 0 1 代替 弄混了