王老师,刘老师:
你们好,我有这样一个问题,就是撤单重发我不想在所有程序里处理,让另外一个程序处理,就是系统实例交易助手的程序,但是这个实例程序一但在一个策略单元上加载,它会对账户所有的单元撤单重发,而且发单价格是涨跌停价,所以没发用,目前我有一个高频策略,我的水平无法处理撤单从发的问题,能不能帮忙把这个程序改成策略单元通用型,就是我某个策略加载一个主程序,然后这个交易助手只处理这个策略单元的撤单重发,感谢你们百忙之中抽时间帮忙处理,衷心感谢谢
//------------------------------------------------------------------------
// 简称: 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公式修改和重写的权利
//------------------------------------------------------------------------
粗看了下,应该是不要订阅 过多的订单范围
对于你要管的程序 你的助手就和策略加载在一个单元里
老师,您好。我想追问。我也有把这个交易助手写到策略中的需求。但是想控制一下撤单次数。就像界面设置中的那个选项。怎么写?谢谢