A_deleteorder和A_deleteorderV2撤单失效

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


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_DeleteOrder(oid[0]撤单成功
撤单经常失效
主连合约888用A_DeleteOrder撤单不成功
A_DeleteOrder和A_GETORDER中的参数orderid
挂单和撤单
撤单
用A函数撤单问题---
FileDelete是否失效?
使用交易助手撤单
A_DeleteOrder 是不是可以撤掉 超过默认手数单子呢

用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。

经过测试,报单数百条之后,并没有复现撤单发生延迟的情况。