量化交易軟件:交易機器人在市場發(fā)布前必須經(jīng)過的檢驗

怎樣快速捕捉和修復交易機器人中的錯誤
平臺中集成的策略測試器不僅允許回測交易系統(tǒng),而且可以用于發(fā)現(xiàn)交易機器人開發(fā)過程中的邏輯和算法錯誤,在測試中,所有有關(guān)交易操作的消息以及發(fā)現(xiàn)的錯誤都輸出在測試器的日志(Journal)中。使用特別的記錄閱讀器就可以很方便地分析這些消息, 它可以使用上下文菜單的命令調(diào)用出來。
編輯搜圖
在EA交易的測試之后,打開閱讀器并啟用"只顯示錯誤(Error only)"模式,如上圖所示。如果您的交易機器人包含錯誤,您就能立即看到它們。如果第一次沒有偵測到錯誤,可以在不同的交易品種/時段/輸入?yún)?shù)以及不同數(shù)量的初始存款情況下進行一系列的測試。使用這些簡單的技巧可以發(fā)現(xiàn) 99% 的錯誤,并且赫茲量化會在本文中討論它們。
赫茲量化可以使用在 MetaEditor 中的在歷史數(shù)據(jù)上做調(diào)試的功能來仔細研究發(fā)現(xiàn)的錯誤,通過這個方法,赫茲量化可以使用可視化測試模式,不僅監(jiān)控價格圖表和使用的指標,也能跟蹤程序在每個時刻的變量數(shù)值。這樣,您就能夠調(diào)試您的交易策略了,而不必在實時模式下花費很長時間。
資金不足以進行交易操作
在發(fā)送每個交易訂單之前,需要檢查賬戶是否有足夠的資金,缺乏資金以進行未來的建倉或者訂單會被認為是疏忽大意的。
請一定要記住就算設(shè)置一個掛單也可能會要求擔保 —?保證金。
編輯搜圖
赫茲量化推薦特意使用很小的初始存款來測試交易機器人,例如,1美元或者1歐元。
如果檢查顯示,資金不足以進行交易操作,就有必要在記錄中輸出一個錯誤消息而不是調(diào)用 OrderSend() 函數(shù)。檢驗實例:
MQL5
bool CheckMoneyForTrade(string symb,double lots,ENUM_ORDER_TYPE type)
??{//--- 取得建倉價格?? MqlTick mqltick;
?? SymbolInfoTick(symb,mqltick);
?? double price=mqltick.ask;
?? if(type==ORDER_TYPE_SELL)
??????price=mqltick.bid;//--- 所需以及可用保證金的數(shù)值?? double margin,free_margin=AccountInfoDouble(ACCOUNT_MARGIN_FREE);
?? //--- 調(diào)用檢驗函數(shù)?? if(!OrderCalcMargin(type,symb,lots,price,margin))
???? {
??????//--- 出錯了,發(fā)送報告并返回 false??????Print("有錯誤出現(xiàn)在 ",__FUNCTION__," 編號=",GetLastError());
??????return(false);
???? }
?? //--- 如果資金不夠進行操作?? if(margin>free_margin)
???? {
??????//--- 報告錯誤并返回 false??????Print("資金不足以進行 ",EnumToString(type)," ",lots," ",symb," 錯誤編號=",GetLastError());
??????return(false);
???? }//--- 檢驗成功?? return(true);
??}
MQL4
bool CheckMoneyForTrade(string symb, double lots,int type)
??{
?? double free_margin=AccountFreeMarginCheck(symb,type, lots);
?? //-- 如果資金不夠?? if(free_margin<0)
???? {
??????string oper=(type==OP_BUY)?"買入":"賣出";
??????Print("資金不足以進行", oper," ",lots, " ", symb, " 錯誤編號",GetLastError());
??????return(false);
???? }
?? //--- 檢驗成功?? return(true);
??}
交易操作中的無效交易量
在發(fā)送交易訂單之前,也有必要檢查在訂單中指定的交易量的正確性,EA交易中訂單設(shè)置的手數(shù)必須在調(diào)用 OrderSend() 函數(shù)之前進行檢查,交易品種所允許的最小和最大交易量,以及交易量之間的步長是在規(guī)格說明中指定的。在 MQL5 中, 這些數(shù)值可以通過ENUM_SYMBOL_INFO_DOUBLE?枚舉,在SymbolInfoDouble()函數(shù)的幫助下獲得。
SYMBOL_VOLUME_MIN
交易的最小交易量
SYMBOL_VOLUME_MAX
交易的最大交易量
SYMBOL_VOLUME_STEP
執(zhí)行交易時最小的交易量變化步長
檢查交易量正確性函數(shù)的實例
//+------------------------------------------------------------------+//|?檢查訂單交易量的正確性 ??????????????????? ? ? ? ? ? ? ? ? ? ? ? ??? |//+------------------------------------------------------------------+bool CheckVolumeValue(double volume,string &description)
??{//--- 交易操作允許的最小交易量?? double min_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
?? if(volume<min_volume)
???? {
??????description=StringFormat("交易量小于允許的最小交易量,SYMBOL_VOLUME_MIN=%.2f",min_volume);
??????return(false);
???? }//--- 交易操作允許的最大交易量 ?? double max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
?? if(volume>max_volume)
???? {
??????description=StringFormat("交易量大于允許的最大交易量,SYMBOL_VOLUME_MAX=%.2f",max_volume);
??????return(false);
???? }//--- 取得交易量變化的最小步長?? double volume_step=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP);
?? int ratio=(int)MathRound(volume/volume_step);
?? if(MathAbs(ratio*volume_step-volume)>0.0000001)
???? {
??????description=StringFormat("交易量不是最小交易步長的整數(shù)倍,SYMBOL_VOLUME_STEP=%.2f, 最接近的正確交易量是 %.2f",
?????????????????????????????? volume_step,ratio*volume_step);
??????return(false);
???? }
?? description="正確的交易量數(shù)值";
?? return(true);
??}
掛單的限制數(shù)量
賬戶中允許同時設(shè)置的活動掛單的數(shù)量可能也會有所限制。IsNewOrderAllowed() 函數(shù)的實例, 它用來檢查是否還允許繼續(xù)設(shè)置掛單。
//+------------------------------------------------------------------+//| 檢查是否還允許設(shè)置訂單 ? ? ? ? ? ? ????? ? ? ? ? ? ? ??????? ? ? ? ??|//+------------------------------------------------------------------+bool IsNewOrderAllowed()
??{//--- 取得賬戶中允許設(shè)置的掛單數(shù)量?? int max_allowed_orders=(int)AccountInfoInteger(ACCOUNT_LIMIT_ORDERS);//--- 如果沒有限制,返回 true; 您可以發(fā)送一個訂單?? if(max_allowed_orders==0) return(true);//--- 如果我們達到這一行,說明有限制; 找出已經(jīng)設(shè)置了多少掛單?? int orders=OrdersTotal();//--- 返回比較結(jié)果?? return(orders<max_allowed_orders);
??}
這個函數(shù)很簡單: 取得允許的最大訂單數(shù)并賦予max_allowed_orders變量; 如果它不等于0,把它與當前訂單數(shù)量做比較。但是,這個函數(shù)沒有考慮到另外的可能的限制 - 對某一特定交易品種開啟倉位總交易量的限制和掛單數(shù)量的限制。
某特定交易品種的手數(shù)限制
為了取得某一特定交易品種的開啟倉位的總交易量,首先您需要使用PositionSelect()函數(shù)來選擇一個倉位,之后您就可以使用PositionGetDouble()來得到已建倉位的交易量, 它可以返回雙精度類型的所選倉位的各種屬性。讓我們寫一個 PostionVolume() 函數(shù)來取得所需交易品種的倉位交易量。
//+------------------------------------------------------------------+//| 返回指定交易品種的倉位大小 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?|//+------------------------------------------------------------------+double PositionVolume(string symbol)
??{//--- 嘗試根據(jù)交易品種選擇倉位?? bool selected=PositionSelect(symbol);//--- 有倉位?? if(selected)
??????//--- 返回倉位交易量??????return(PositionGetDouble(POSITION_VOLUME));
?? else???? {
??????//--- 選擇倉位出錯報告??????Print(__FUNCTION__," 執(zhí)行 PositionSelect() 失敗,交易品種為 ",
? ? ? ? ? ?symbol," 錯誤編號 ",GetLastError());
??????return(-1);
???? }
??}
對于支持對沖的賬戶,還需要迭代當前交易品種所有的倉位。
在根據(jù)交易品種生成交易請求以設(shè)置掛單之前, 您應(yīng)該檢查在一個交易品種上的已開啟倉位和掛單總交易量的限制 - SYMBOL_VOLUME_LIMIT,如果沒有限制,那么掛單的總交易量不能超過使用SymbolInfoDouble()得到的最大交易量。