TB持倉信號和真實賬戶持倉不同步的調(diào)整模塊
作者:開拓者 TB 來源:cxh99.com 發(fā)布時間:2012年10月24日
- 咨詢內(nèi)容: 本人開發(fā)了一套策略,歷史數(shù)據(jù)回測什么都很好,接下來要做到計算機自動交易。現(xiàn)在萬里長征還差最后一步,就是TB持倉信號和真實賬戶持倉不同步的調(diào)整模塊,由于都是A_函數(shù)只有在實時行情的時候才能測試,從上周到現(xiàn)在花了好幾個交易日,也改了好幾次代碼但還是有重復發(fā)單或者持倉不足等情況,今天收盤后針對發(fā)生的問題又改進了一下,也不知道明天能不能順利通過。心里沒底所以把這部分代碼公開出來,希望管理員或有自動交易實盤經(jīng)驗的高手指點一下。
If((BarInterval==1 And Time!=0.1514) Or (BarInterval==5 And Time!=0.1510) Or (BarInterval==15 And Time!=0.1500))
{
TickCnt1=15; //等待TickCnt1次后如不成交采取相應措施
If(GetGlobalVar(2)==InvalidNumeric) //對全局變量初始賦值(包括意外網(wǎng)絡中斷、賬戶斷開等情況后的初始化賦值)
{
SetGlobalVar(2,0);
}
If(MarketPosition==1)
{
If(OrderWaitCounts!=TickCnt1 And A_GetOpenOrderCount==0) //沒有未成交委托單時計數(shù)器歸零
{
SetGlobalVar(2,0);
}
If(A_BuyPosition>0)
{
If(A_BuyPosition>Abs(CurrentContracts)) //真實賬戶相對TB信號有多余持倉
{
If(A_GetOpenOrderCount!=0)
{
OrderWaitCounts=GetGlobalVar(2)+1; //計數(shù)器記錄未成交委托單存在的Tick數(shù)
SetGlobalVar(2,OrderWaitCounts);
}else if(A_GetOpenOrderCount==0 And GetGlobalVar(2)==0) //沒有委托單時直接發(fā)單平掉多余持倉
{
A_SendOrder(Enum_Sell,Enum_Exit,A_BuyPosition-Abs(CurrentContracts),Q_BidPrice);
SetGlobalVar(2,0);
}
If(OrderWaitCounts==TickCnt1) //如果委托單持續(xù)TickCnt1個Tick數(shù)后仍沒成交
{
A_DeleteOrder(); //撤所有委托單
A_SendOrder(Enum_Sell,Enum_Exit,A_BuyPosition-Abs(CurrentContracts),Q_BidPrice); //重新發(fā)單平掉多余持倉
SetGlobalVar(2,0); //重置全局變量
}
}else if(A_BuyPosition<Abs(CurrentContracts))
{
If(A_GetOpenOrderCount!=0)
{
OrderWaitCounts=GetGlobalVar(2)+1; //計數(shù)器記錄未成交委托單存在的Tick數(shù)
SetGlobalVar(2,OrderWaitCounts);
}else if(A_GetOpenOrderCount==0 And GetGlobalVar(2)==0)
{
A_SendOrder(Enum_Buy,Enum_Entry,Abs(CurrentContracts)-A_BuyPosition,Q_AskPrice);
SetGlobalVar(2,0);
}
If(OrderWaitCounts==TickCnt1)
{
A_DeleteOrder();
A_SendOrder(Enum_Buy,Enum_Entry,Abs(CurrentContracts)-A_BuyPosition,Q_AskPrice);
SetGlobalVar(2,0);
}
}else if(A_BuyPosition==Abs(CurrentContracts)) //真實賬戶和TB信號持倉同步的時候
{
If(A_GetOpenOrderCount!=0) //如果還有未成交委托單全部撤單,重置全局變量
{
A_DeleteOrder();
SetGlobalVar(2,0);
}else if(GetGlobalVar(2)!=0)
{
SetGlobalVar(2,0);
}
}
}else if(A_SellPosition>0)
{
If(A_GetOpenOrderCount!=0)
{
OrderWaitCounts=GetGlobalVar(2)+1;
SetGlobalVar(2,OrderWaitCounts);
}else if(A_GetOpenOrderCount==0 And GetGlobalVar(2)==0)
{
A_SendOrder(Enum_Buy,Enum_Exit,A_SellPosition,Q_AskPrice);
SetGlobalVar(2,0);
}
If(OrderWaitCounts==TickCnt1)
{
A_DeleteOrder();
A_SendOrder(Enum_Buy,Enum_Exit,A_SellPosition,Q_AskPrice);
SetGlobalVar(2,0);
}
}else if(A_BuyPosition==0 And A_SellPosition==0)
{
If(A_GetOpenOrderCount!=0)
{
OrderWaitCounts=GetGlobalVar(2)+1;
SetGlobalVar(2,OrderWaitCounts);
}else if(A_GetOpenOrderCount==0 And GetGlobalVar(2)==0)
{
A_SendOrder(Enum_Buy,Enum_Entry,Abs(CurrentContracts),Q_AskPrice);
SetGlobalVar(2,0);
}
If(OrderWaitCounts==TickCnt1)
{
A_DeleteOrder();
A_SendOrder(Enum_Buy,Enum_Entry,Abs(CurrentContracts),Q_AskPrice);
SetGlobalVar(2,0);
}
}
}else if(MarketPosition==-1)
{
If(OrderWaitCounts!=TickCnt1 And A_GetOpenOrderCount==0) //沒有未成交委托單時計數(shù)器歸零
{
SetGlobalVar(2,0);
}
If(A_BuyPosition>0)
{
If(A_GetOpenOrderCount!=0)
{
OrderWaitCounts=GetGlobalVar(2)+1;
SetGlobalVar(2,OrderWaitCounts);
}else if(A_GetOpenOrderCount==0 And GetGlobalVar(2)==0)
{
A_SendOrder(Enum_Sell,Enum_Exit,A_BuyPosition,Q_BidPrice);
SetGlobalVar(2,0);
}
If(OrderWaitCounts==TickCnt1)
{
A_DeleteOrder();
A_SendOrder(Enum_Sell,Enum_Exit,A_BuyPosition,Q_BidPrice);
SetGlobalVar(2,0);
}
}else if(A_SellPosition>0)
{
If(A_SellPosition>Abs(CurrentContracts))
{
If(A_GetOpenOrderCount!=0)
{
OrderWaitCounts=GetGlobalVar(2)+1; //計數(shù)器記錄未成交委托單存在的Tick數(shù)
SetGlobalVar(2,OrderWaitCounts);
}else if(A_GetOpenOrderCount==0 And GetGlobalVar(2)==0)
{
A_SendOrder(Enum_Buy,Enum_Exit,A_SellPosition-Abs(CurrentContracts),Q_AskPrice);
SetGlobalVar(2,0);
}
If(OrderWaitCounts==TickCnt1)
{
A_DeleteOrder();
A_SendOrder(Enum_Buy,Enum_Exit,A_SellPosition-Abs(CurrentContracts),Q_AskPrice);
SetGlobalVar(2,0);
}
}else if(A_SellPosition<Abs(CurrentContracts))
{
If(A_GetOpenOrderCount!=0)
{
OrderWaitCounts=GetGlobalVar(2)+1; //計數(shù)器記錄未成交委托單存在的Tick數(shù)
SetGlobalVar(2,OrderWaitCounts);
}else if(A_GetOpenOrderCount==0 And GetGlobalVar(2)==0)
{
A_SendOrder(Enum_Sell,Enum_Entry,Abs(CurrentContracts)-A_SellPosition,Q_BidPrice);
SetGlobalVar(2,0);
}
If(OrderWaitCounts==TickCnt1)
{
A_DeleteOrder();
A_SendOrder(Enum_Sell,Enum_Entry,Abs(CurrentContracts)-A_SellPosition,Q_BidPrice);
SetGlobalVar(2,0);
}
}else if(A_SellPosition==Abs(CurrentContracts))
{
If(A_GetOpenOrderCount!=0)
{
A_DeleteOrder();
SetGlobalVar(2,0);
}else if(GetGlobalVar(2)!=0)
{
SetGlobalVar(2,0);
}
}
}else if(A_BuyPosition==0 And A_SellPosition==0)
{
If(A_GetOpenOrderCount!=0)
{
OrderWaitCounts=GetGlobalVar(2)+1;
SetGlobalVar(2,OrderWaitCounts);
}else if(A_GetOpenOrderCount==0 And GetGlobalVar(2)==0)
{
A_SendOrder(Enum_Sell,Enum_Entry,Abs(CurrentContracts),Q_BidPrice);
SetGlobalVar(2,0);
}
If(OrderWaitCounts==TickCnt1)
{
A_DeleteOrder();
A_SendOrder(Enum_Sell,Enum_Entry,Abs(CurrentContracts),Q_BidPrice);
SetGlobalVar(2,0);
}
}
}else if(MarketPosition==0)
{
If(OrderWaitCounts!=TickCnt1 And A_GetOpenOrderCount==0) //沒有未成交委托單時計數(shù)器歸零
{
SetGlobalVar(2,0);
}
If(A_BuyPosition>0)
{
If(A_GetOpenOrderCount!=0)
{
OrderWaitCounts=GetGlobalVar(2)+1;
SetGlobalVar(2,OrderWaitCounts);
}else if(A_GetOpenOrderCount==0 And GetGlobalVar(2)==0)
{
A_SendOrder(Enum_Sell,Enum_Exit,A_BuyPosition,Q_BidPrice);
SetGlobalVar(2,0);
}
If(OrderWaitCounts==TickCnt1)
{
A_DeleteOrder();
A_SendOrder(Enum_Sell,Enum_Exit,A_BuyPosition,Q_BidPrice);
SetGlobalVar(2,0);
}
}else if(A_SellPosition>0)
{
If(A_GetOpenOrderCount!=0)
{
OrderWaitCounts=GetGlobalVar(2)+1;
SetGlobalVar(2,OrderWaitCounts);
}else if(A_GetOpenOrderCount==0 And GetGlobalVar(2)==0)
{
A_SendOrder(Enum_Buy,Enum_Exit,A_SellPosition,Q_AskPrice);
SetGlobalVar(2,0);
}
If(OrderWaitCounts==TickCnt1)
{
A_DeleteOrder();
A_SendOrder(Enum_Buy,Enum_Exit,A_SellPosition,Q_AskPrice);
SetGlobalVar(2,0);
}
}else if(A_BuyPosition==0 And A_SellPosition==0)
{
If(A_GetOpenOrderCount!=0)
{
A_DeleteOrder();
SetGlobalVar(2,0);
}else if(GetGlobalVar(2)!=0)
{
SetGlobalVar(2,0);
}
}
}
}
前面部分在MarketPosition==1情況下做了些注釋,后面邏輯是一致的。基本思路就是發(fā)覺TB信號與實際持倉不一致的時候,先檢查是不是已有委托單(可能是其他模塊用Buy Sell命令發(fā)送的),如果已有委托單等待TickCnt1時間,如果該時間后沒有成交則撤單用A_SendOrder發(fā)送。同時繼續(xù)用OrderWaitCounts記錄委托單發(fā)出未成的時間,如果過了TickCnt1時間還是沒成交,繼續(xù)撤單重發(fā),直至實際持倉與TB信號同步。同步后檢查是否還有未成交的委托單,如果有全部撤單并重置全局變量。
不同步的問題測試起來實在很麻煩,所以懇請高手回復,看看以上代碼有無邏輯錯誤,會不會導致重復發(fā)單或其他問題。多謝了,加急!!!
- TB技術人員: 不是有數(shù)據(jù)回放嗎?可以多試試的現(xiàn)在,以前沒有回放的時候我也很糾結。。。
- TB客服: 回放只顯示行情,對實際賬戶持倉測試沒用的
- 網(wǎng)友回復: 額,好吧,忘記自己沒用A函數(shù)了。。
- 網(wǎng)友回復: 今天實時行情繼續(xù)測試中,問題比之前少了些,不過還是有很多警告,而且都是連續(xù)發(fā)出的警告,持倉不足、資金不足和相應委托不能撤銷這三類都有。我分析了一下代碼,選前一段一起看一下:
If(A_BuyPosition>0)
{
If(A_BuyPosition>Abs(CurrentContracts)) //真實賬戶相對TB信號有多余持倉
{
If(A_GetOpenOrderCount!=0)
{
OrderWaitCounts=GetGlobalVar(2)+1; //計數(shù)器記錄未成交委托單存在的Tick數(shù)
SetGlobalVar(2,OrderWaitCounts);
}else if(A_GetOpenOrderCount==0 And GetGlobalVar(2)==0) //沒有委托單時直接發(fā)單平掉多余持倉
{
A_SendOrder(Enum_Sell,Enum_Exit,A_BuyPosition-Abs(CurrentContracts),Q_BidPrice);
SetGlobalVar(2,0);
}
If(OrderWaitCounts==TickCnt1) //如果委托單持續(xù)TickCnt1個Tick數(shù)后仍沒成交
{
A_DeleteOrder(); //撤所有委托單
A_SendOrder(Enum_Sell,Enum_Exit,A_BuyPosition-Abs(CurrentContracts),Q_BidPrice); //重新發(fā)單平掉多余持倉
SetGlobalVar(2,0); //重置全局變量
}
}
我估計問題出在
If(OrderWaitCounts==TickCnt1) //如果委托單持續(xù)TickCnt1個Tick數(shù)后仍沒成交
{
A_DeleteOrder(); //撤所有委托單
A_SendOrder(Enum_Sell,Enum_Exit,A_BuyPosition-Abs(CurrentContracts),Q_BidPrice); //重新發(fā)單平掉多余持倉
SetGlobalVar(2,0); //重置全局變量
}
這段里,因為里面有撤銷委托操作和發(fā)單操作,如果是開倉單頻繁發(fā)單就會導致資金不足警告,如果是平倉單就會導致持倉不足警告。我設計的思路是當OrderWaitCounts==TickCnt1的時候只要求發(fā)送一次,因為發(fā)送完全局變量就被重置為0了,這樣即使不成交再進入該條件OrderWaitCounts又要重新開始計數(shù)等待,如果等到TickCnt1時再撤單重發(fā)。但實際情況是這段代碼并沒有只發(fā)送一次,還是頻繁在發(fā)送,百思不其解,請管理員或諸位高手幫忙解答,謝謝了!