撤单命令提交后,撤单成功延迟很长很长,甚至都成交两个单了。单子都成交了才撤单。请老师看下什么问题,怎么解决

OnBar(ArrayRef<Integer> indexs)
{
if (BarStatus == 2)
{
// 预埋卖单的撤单条件
if(delta_che_flag == False && cond_sell == 1 && cond_buy == 1 && cond2 == 1 && (High >= last_chengjiao_price + delta_che))
{
ret = A_DeleteOrderEx(oid_sell);
if (ret == True)
{
print( Text( oid_sell) + "预埋卖单的撤单条件");
delta_che_flag = True;
}
else
{
print(Text( oid_sell) + "预埋卖单的撤单条件失败");
}
}
}
}
//委托更新事件函数,参数ord表示更新的委托结构体
OnOrder(OrderRef ord)
{
if (ord.status == Enum_Canceled && delta_che_flag == True)
{
cond_sell = -1;
delta_che_flag = False;
print(Text( oid_sell) +"预埋卖单撤单成功");
}
}
}
请老师看下今天下午的运行情况,依然是这个问题:

用a函数了,别人就帮不上什么忙了。
就算是问我们,我们也是拿到全部代码以后,在模型加大量的输出语句,形成模型运行日志,通过分析日志去推断当时发生了什么。
而这些工作,理论上来说,如果你用a函数去做订单管理,那这些打断点,以及通过驱动域机制去分析运行过程的能力应该是必备的。
我能提的建议,只有更加细致地输出断点信息,比如加上时间戳,还有哪个订单驱动的事件域,驱动的是什么事件域等等,把模型运行细节进一步明确。这种东西看是看不出来的,除了运行起来调试,没有什么别的办法
在程序里撤单只能用a函数吗?
我只想实现对指定oid的撤单功能,有没有其它推荐方法。。。断点信息目前能想到的就是提交撤单指令、onorder接收到撤单成功信号😅
我只想实现对指定oid的撤单功能,有没有其它推荐方法。。。断点信息目前能想到的就是提交撤单指令、onorder接收到撤单成功信号😅
只能用a函数。
你想做订单管理只能通过a函数处理。
出问题的原因无非两种,要么是客观bug,要么是主观自己没用对。
如果是客观bug,你是可以通过一个简单demo去稳定复现这个现象的。
如果不能稳定复现,那就是自己的用法不对。
目前我也不知道你对a函数,事件域驱动,变量特征等常识的掌握情况如何,无法判断你是否存在方法错误的情况。
所以这个问题只能你自己诊断了
你好,这是完整、简单的demo复现,经常出现撤单指令发送成功,但未成交单撤单不成功。欢迎复现跑测,确实要用,谢谢
Vars
Global Integer cancelId;
Global Bool openOrder(False);
Global Array<Integer> oid; //记录order ID的数组
Global Integer oid_buy;//买单编号
Global Integer oid_sell;//卖单编号
Events
OnBar(ArrayRef<Integer> indexs)
{
if(BarStatus == 2 && !openOrder)
{//发开仓单
//针对当前策略应用的帐户、商品发送委托单
Bool ret = A_SendOrderEx(enum_buy, Enum_Entry, 1, 20, oid);
Print("A_buyOrder:" + IIFString(ret, "True", "False"));
if(ret)
{
openOrder = True;
oid_sell = oid[0];
Print("订单号"+Text(oid_sell));
}
cancelId=createTimer(50);
}
}
OnTimer(Integer tid,Integer intervalMillsecs)
{
if(tid == cancelId)
{//撤单
Array<Integer> orderIds;
//获取未完成的报单数组
//A_GetUnFillOrderIDs(Symbol, ids, "", i);
Bool ret = A_GetUnFillOrderIDs(orderIds, "", 0);
if (ret==True)
{
Integer i;
For i = 0 To GetArraySize(orderIds) - 1
{
Print("accountIndex:" + A_AccountID(0) + ",orderId:" + Text(orderIds[i]));
if(orderIds[i] != oid_sell)
{
Print("订单编号不一致"+Text(orderIds[i]));
}
else
{
print("订单一致");
}
}
}
ret = A_DeleteOrderEx(oid_sell,"buy");//撤指定报单索引的委托单
Print("A_DeleteOrderEx:" + IIFString(ret, "True", "False"));
StopTimer(cancelId);
}
}
OnOrder(OrderRef ord)
{
if (ord.status == 6 and ord.cancelSource == "buy")
{
print("撤单成功");
openOrder = False;
}
}
本周四直播会提前到两点三十分开始,现场测试你的这个demo问题
好勒,我用的tbquant 1.4.4.1 标准版
请用这个demo,依然撤单时而成功时而不行:
Vars
Global Integer cancelId;
Global Bool openOrder(False);
Global Array<Integer> oid; //记录order ID的数组
Global Integer oid_buy;//买单编号
Global Integer oid_sell;//卖单编号
Events
OnBar(ArrayRef<Integer> indexs)
{
if(BarStatus == 2 && !openOrder)
{
//发开仓单
//针对当前策略应用的帐户、商品发送委托单
Bool ret = A_SendOrderEx(enum_buy, Enum_Entry, 1, 20, oid, "");
Print("A_buyOrder:" + IIFString(ret, "True", "False"));
if(ret)
{
openOrder = True;
oid_sell = oid[0];
Print("订单号" + Text(oid_sell));
}
cancelId = createTimer(50);
}
}
OnTimer(Integer tid,Integer intervalMillsecs)
{
if(tid == cancelId && openOrder == True)
{//撤单
Array<Integer> orderIds;
//获取未完成的报单数组
Bool ret = A_GetUnFillOrderIDs(Symbol, orderIds, "", 0);
//Bool ret = A_GetUnFillOrderIDs(orderIds, "test", 0);
if (ret==True)
{
Integer i;
For i = 0 To GetArraySize(orderIds) - 1
{
Print("accountIndex:" + A_AccountID(0) + ",orderId:" + Text(orderIds[i]));
if(orderIds[i] != oid_sell)
{
Print("订单编号不一致"+Text(orderIds[i]));
}
else
{
print("订单一致");
}
}
}
ret = A_DeleteOrderEx(oid_sell,"buy");//撤指定报单索引的委托单
Print("A_DeleteOrderEx:" + IIFString(ret, "True", "False"));
StopTimer(cancelId);
}
}
OnOrder(OrderRef ord)
{
//print("order状态" + Text(ord.status));
if (ord.status == 6 and ord.orderId == oid_sell)
{
print("撤单成功");
openOrder = False;
}
}
到底用哪个
现在两点五十了,已经直播测试了二十分钟这个代码了。
提交的demo里,改了两个地方,一个是报单的价格,20肯定是不合适的,改成了对手盘减去两跳。第二个地方是timer的时间间隔,50ms太快了,改成了5000ms和1000ms。
经过测试,报单数百条之后,并没有复现撤单发生延迟的情况。