平单信号不对

写了一个套利策略,但是平仓的信号不太对跟自己打印的log有所出入 策略代码: Params Numeric numeratorSubStartTime(20210913.100500); // 期货比例中的分子期货(菜粕) 订阅的开始时间 string numeratorSubFreq("5m"); // 期货比例中的分子期货(菜粕) 订阅频率 &#39;mon&#39;:月,&#39;w&#39;:周,&#39;d&#39;:日,&#39;h&#39;:时,&#39;m&#39;:分,&#39;s&#39;:秒,&#39;tick&#39;: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); } } }

代码搞混了

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

第一 如果开了委托偏移 那么报单价格是对手价加偏移点数报单 这就可能与交易命令里的所谓程序价格不一致 第二 如果没有开委托偏移 那么需要通过写log确认这个单子是从哪一行的交易命令报出来的,进而对这个交易命令里的价格变量进行诊断

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