demo_EventArbitrage例子中我发现一个问题,再次跟老师讨论下。是我搞错了,还是真有不妥的地方
//委托更新事件函数,参数ord表示更新的委托结构体
OnOrder(OrderRef ord)
{
LogFile(\"OnOrder:\"+ ord.symbol + \",\" + Text(ord.orderId));
//1.如果是左腿单,有成交,则锁定对手合约下单
if(ord.symbol==data0.Symbol())
{
If(!MapContain(leftOrderMap, ord.orderId))//如果这个orderid不在leftOrderMap中,说明没记录,那就直接返回
{
//防止收到重复的委托
Return;
}
leftOrderMap[ord.orderId]=ord;//如果order订单状态更新了,则重新更新leftOrderMap里面对应的订单信息
If(!isOrdersFinished(leftOrderMap))// 如果所有挂单还没都成交,则直接返回,等到所有单子都成交了,再往下执行,
{
Return;
}
fillVolume = sumFillVolume(leftOrderMap);//计算所有左腿单的总下单量
If(fillVolume <= 0)
{
//左腿没有成交量
finishArbitrage();
Return;
}
size=fillVolume-sumOrderVolume(rightOrderMap);//计算左腿总下单量-右腿总下单量,看看右腿还差多少手
if(size>0)
{
sendRightOrder(size);//再补多少手右腿的单子
}
Return;
}
//2.如果是右腿单,则判断否完成套利,如果完成清理缓存,重新挂单
if(ord.symbol==data1.Symbol())
{
If(!MapContain(rightOrderMap, ord.orderId))
{
//防止收到重复的委托
Return;
}
rightOrderMap[ord.orderId]=ord;
If(!isOrdersFinished(rightOrderMap)) //下面红色代码部分应该移动到这里
{
Return;
}
//2.1判断右腿委托是否满足,如果不满足,则继续委托
size=sumFillVolume(leftOrderMap)-sumOrderVolume(rightOrderMap);
if(size>0)
{
sendRightOrder(size);
Return;
}
If(!isOrdersFinished(rightOrderMap)) //这个红色字体的代码应该放到上面蓝色的地方
{
Return;
}
//2.2判断左右腿委托是否完成,如果都完成,则清空缓存,重新挂单
size=sumFillVolume(leftOrderMap)-sumFillVolume(rightOrderMap);
if(size==0)
{
finishArbitrage();
}
}
}
总得来说:就是把 2.如果是右腿单,则判断否完成套利 里面的 If(!isOrdersFinished(rightOrderMap))这个代码移动到上面去,要先确保rightOrderMap里面所有单子已经完结(要么成交,要么被删)。 再计算左腿总单量和右腿总单量的差,进行判断如果为0就套利完成,如果还有差额就补挂右腿单。
否则的话,右腿开单挂的单子都没有完结呢,你就开始判断差额了。那这个差额不用算了肯定等于左腿单了。也就是肯定等于0的。基本等于没用这个功能。
你们这个例子里 有很多地方 都没有注释的,刘老师讲过,不过有些地方的 细节还没讲透。
demo_EventArbitrage这个 就是最基本的套利例子,而且是你们官方提供的这个例子。
我研究这个例子比较好。我提的问题 就是这个例子里的疑问啊。
我建议你用实测碰到问题,举具体的例子
sumFillVolume功能是获取成交的总量
sumOrderVolume 这个功能是什么?发起委托的总量吗?发起委托的总量就是sendRightOrder(size);这里的size值吧。sumFillVolume(leftOrderMap)-sumOrderVolume(rightOrderMap)那这个值不是肯定等于0了。什么情况下 会不等于0呢。
事前是sumFillVolume(leftOrderMap)-sumOrderVolume(rightOrderMap);
事后是sumFillVolume(leftOrderMap)-sumFillVolume(rightOrderMap);
前后判断并不同
sumFillVolume是计算的成交的总量,你得等待这个单子成交后再去统计啊。
进入onorder事件,是所有状态都会进入的,包括单子刚刚报送也会进入啊。
但是,单子刚刚报送的时候,还没成交呢?你就用sumFillVolume来获取这个单子的成交总量。这能行吗?获取到的数据不对啊,所以必须先执行:
If(!isOrdersFinished(rightOrderMap))
{
Return;
}
这样单子肯定都执行完了,再下面代码写sumFillVolume,才能获取到准确的成交的总量啊。
所以必须等单子执行完了,再判断size啊。如果单子还在报送的过程中,你就获取size,单子还不一定报送成功呢,你获取到的size是准确的吗?也许单子最后报送不成功呢?
这里onorder的事件驱动不存在什么等待成交
复杂程序建议举例说明,因为不一定都是错的
要确定是否有问题要经过调试
如果你有用例可以提供
If(!isOrdersFinished(rightOrderMap))
{
Return;
}
只是判断非完全成交,废除,撤单,然后返回
判断是否完成的是看size的计算结果