全部 智大领峰 TBQuant功能 TBL语言 TB开户 问答专区 高手圈 其他
撤单重发以及自编交易助手问题
2022-07-11 17:48

王老师,刘老师:

        你们好,我有这样一个问题,就是撤单重发我不想在所有程序里处理,让另外一个程序处理,就是系统实例交易助手的程序,但是这个实例程序一但在一个策略单元上加载,它会对账户所有的单元撤单重发,而且发单价格是涨跌停价,所以没发用,目前我有一个高频策略,我的水平无法处理撤单从发的问题,能不能帮忙把这个程序改成策略单元通用型,就是我某个策略加载一个主程序,然后这个交易助手只处理这个策略单元的撤单重发,感谢你们百忙之中抽时间帮忙处理,衷心感谢谢

 

//------------------------------------------------------------------------
// 简称: demo_EventTradeHelper
// 名称: 事件驱动_交易助手实例
// 类别: 公式应用
// 类型: 内嵌应用
//------------------------------------------------------------------------
Params
    //此处添加参数
    Numeric intervalSecs(15);    //监控间隔
    Numeric priceOffset(0);        //重新委托价格偏移
Vars
    //此处添加变量
    Numeric tmp;    //系统时间
    Integer cnt(0);    //账户个数
    Integer i(0);    //遍历数组
    Integer j(0);    //遍历数组
    Order tmpOrder;    //委托
    Array<Integer> orderIds;            //委托ID
    Array<Integer> activeMapKeys;     //未成交委托map的key,用于遍历map
    Global Integer timerId;                //定时器ID
    Global Map<Integer, Order>    activeOrderMap;     //未成交的委托
    Global Map<String, Integer> accountIdMap;        //已经同步过委托的账户
     Numeric Minpoint;
Defs
    //此处添加公式函数
    //log输出
    Integer LogFile(StringRef str)
    {
        FileAppend(FormulaName()+".txt","["+Text(SystemDateTime())+"] "+ str);
        Return 0;
    }
    //检查未成交委托,根据委托时间撤单
    Integer CheckActiveOrder()
    {
        LogFile("检查未成交委托数量:"+Text(GetMapSize(activeOrderMap)));
        //获取Map变量中所有的Key集合
        GetMapKeys(activeOrderMap,activeMapKeys);
        //遍历Key集合访问Map变量的key对应的Value
        For i=0 To GetArraySize(activeMapKeys)-1
        {
            tmpOrder=activeOrderMap[activeMapKeys[i]];
            tmp=SystemDateTime();
            //非交易时段忽略
            If(!IsTradingTime(tmpOrder.symbol,tmp))
            {
                Continue;
            }
            if(DateDiff(IntPart(tmpOrder.localDateTime),IntPart(tmp))*24*3600+TimeDiff(tmpOrder.localDateTime,tmp)> intervalSecs)
            {
                LogFile("撤单:"+tmpOrder.accountId+",index="+Text(tmpOrder.orderId)    );
                A_DeleteOrderEx(activeMapKeys[i]);
            }
        }
        Return 0;
    }    
Events    
    //初始化事件函数,策略运行期间,首先运行且只有一次
    OnInit()
    {
        timerId=createTimer(2000);
        A_SubscribeTradeByCreateId(Enum_Trade_Source_ALL);//订阅账户的所有委托,默认只触发本策略发出的委托
    }    

    //委托更新事件函数,参数ord表示更新的委托结构体
    OnOrder(OrderRef ord)
    {
        //如果没有同步过的账号委托,暂时不加入监控,要先在Timer同步
        //检查当前key是否已经添加到Map变量中
        If(!MapContain(accountIdMap, ord.accountId))
        {    
            Return;
        }
        //如果委托已经撤单,且撤单操作员是当前策略,则重新委托
        LogFile(" 委托更新:"+ord.accountId+",index="+Text(ord.orderId)+",exchOrdId="+ord.exchOrderId+",status="+Text(ord.status) + "," + ord.createSource +","+ord.cancelSource+","+FormulaName()+","+ord.note);
        iF(ord.status == Enum_Canceled)
        {
            //检查当前key是否已经添加到Map变量中
            If(MapContain(activeOrderMap, ord.orderId))
            {
                
                //根据Key删除当前记录
                MapErase(activeOrderMap, ord.orderId);
                LogFile(" 删除监控委托:"+ord.accountId+",oldindex="+Text(ord.orderId)+",exchOrdId="+ord.exchOrderId);
                 MinPoint = MinMove*PriceScale;
                If(ord.cancelSource == A_GetOrderCreateSource())
                {
                    If(ord.side==Enum_Buy)
                    {
                        A_SendOrderEx(ord.symbol,ord.side,ord.combOffset,ord.volume-ord.fillVolume,Q_AskPrice()+priceOffset*MINPOINT,orderIds,"","",A_AccountIndex(ord.accountId,ord.brokerId));
                    }
                    Else
                    {
                        A_SendOrderEx(ord.symbol,ord.side,ord.combOffset,ord.volume-ord.fillVolume,Q_BidPrice()-priceOffset*MINPOINT,orderIds,"","",A_AccountIndex(ord.accountId,ord.brokerId));
                    }
                    LogFile(" 撤单成功重新委托:"+ord.accountId+",oldindex="+Text(ord.orderId)+",exchOrdId="+ord.exchOrderId);
                }
            }
        }
        Else If(ord.status == Enum_Filled || ord.status == Enum_Deleted)
        {
            //检查当前key是否已经添加到Map变量中
            If(MapContain(activeOrderMap, ord.orderId))
            {
                //根据Key删除当前记录
                MapErase(activeOrderMap, ord.orderId);
                LogFile(" 删除监控委托:"+ord.accountId+",oldindex="+Text(ord.orderId)+",exchOrdId="+ord.exchOrderId);
            }
        }
        Else
        {
            activeOrderMap[ord.orderId] = ord;
        }
    }

    //定时器更新事件函数,参数id表示定时器的编号,millsecs表示定时间的间隔毫秒值
    OnTimer(Integer id,Integer millsecs)
    {
        //循环监控所有账号
        cnt = A_AccountCount();
        For i=0 To cnt-1
        {
            //检查是否已经同步过委托
            if(MapContain(accountIdMap,A_AccountID(i)))
            {
                Continue;
            }
            accountIdMap[A_AccountID(i)] = A_BrokerID(i);
            LogFile(A_AccountID(i)+" 开始同步委托");
            //同步未成交委托
            If(A_GetUnFillOrderIDs(orderIds,"",i))
            {
                For j=0 To GetArraySize(orderIds)-1
                {
                    If(A_GetOrder(orderIds[j], tmpOrder))
                    {
                        //放入Map 直接下标访问进行赋值 下标为Key必须唯一
                        activeOrderMap[orderIds[j]] = tmpOrder;
                        LogFile(A_AccountID(i)+" 同步委托:"+Text(orderIds[j]));
                    }
                }
            }
            LogFile(A_AccountID(i)+" 同步委托完成");
        }
        CheckActiveOrder();
    }    


//------------------------------------------------------------------------
// 编译版本    2019/07/26 125622
// 版权所有    TradeBlazer Software 2003-2025
// 更改声明    TradeBlazer Software保留对TradeBlazer平台
//            每一版本的TradeBlazer公式修改和重写的权利
//------------------------------------------------------------------------

 

 

 

 

 

wangkaiming

粗看了下,应该是不要订阅 过多的订单范围

对于你要管的程序 你的助手就和策略加载在一个单元里

2022-07-12 08:30
zhong_4619xd
@wangkaiming

老师,您好。我想追问。我也有把这个交易助手写到策略中的需求。但是想控制一下撤单次数。就像界面设置中的那个选项。怎么写?谢谢

2023-05-17 19:30
您未登录,请先 登录注册 后发表评论
顶部