iT邦幫忙

2023 iThome 鐵人賽

DAY 19
0
SideProject30

從零開始的外匯自動程式交易系列 第 19

DAY19 建立下單類型與除錯(下)

  • 分享至 

  • xImage
  •  

接下來我們要說關於錯誤處理的部分,順便記錄一些交易資訊,而像是timeouts、connection errors這些錯誤有時候重試訂單時就會自動排除。

1.ErrorDescription

首先我們要Include <ErrorDescription.mqh>檔案來獲取錯誤描述,而我個人的預設檔裡沒有這個,所以我是從github找來的:
https://github.com/zephyrrr/MLEA/blob/master/MQL5/Include/Utils/ErrorDescription.mqh
這個能讓我們獲得錯誤的描述字串,可以方便我們整理錯誤。

2.創建列舉值

定義一個列舉值,來確定訂單是否成功

enum TradeResult {
    Trade_Success,
    Trade_Error,
    Trade_Retry,
};

3.創建CheckReturnCode函數

創建CheckReturnCode來檢查返回碼,根據獲得的返回代碼,從列舉值中返回常量。

int CheckReturnCode(uint pRetCode){
    
    int status;
    switch(pRetCode){
        case TRADE_RETCODE_REQUOTE:
		case TRADE_RETCODE_CONNECTION:
		case TRADE_RETCODE_PRICE_CHANGED:
		case TRADE_RETCODE_TIMEOUT:
		case TRADE_RETCODE_PRICE_OFF:
		case TRADE_RETCODE_REJECT:
		case TRADE_RETCODE_ERROR:
		
			status = Trade_Retry;
			break;
			
		case TRADE_RETCODE_DONE:
		case TRADE_RETCODE_DONE_PARTIAL:
		case TRADE_RETCODE_PLACED:
		case TRADE_RETCODE_NO_CHANGES:
		
			status = Trade_Success;
			break;
			
		default: status = Trade_Error;
    }
    return(status);
}

這邊先檢查了一些顯示機要成功或是非錯誤訊息的情況,若都不屬於這些則會返回Trade_Error

4.創建重試迴圈

前面有提到可以使用重試來避免超時或連接錯誤,讓我們能更專注的面對更重要的錯誤。

int checkCode = 0;
int retryCount = 0;
int maxRetryCount = 3;
int retryDelay = 3000;//延遲3秒

do
{
    OrderSend(request,result);
    checkCode = CheckReturnCode(result.retcode);

    if(checkCode == Trade_Success)break;

    else if(checkCode == Trade_Error){
        string errDesc = TradeServerReturnCodeDescription(result.retcode);
			Alert("Open market order: Error ",result.retcode," - ",errDesc);
			break;
    }

    else{
        Sleep(retryDelay);
			retryCount++;
    }

}
 while (retryCount < maxRetryCount);

 if(retryCount >= maxRetryCount)
	{
		string errDesc = TradeServerReturnCodeDescription(result.retcode);
		Alert("Max retries exceeded: Error ",result.retcode," - ",errDesc);
	}

這邊先設定最大重試次數為3,延遲為三秒。使用Do-while因為可以先循環一次,若為成功下單則直接跳出,錯誤則藉由ErrorDescription中的函數顯示錯誤訊息,當重試次數超過3時亦回傳錯誤訊息。

5.檢查訂單類型

在前面我們創好了排解錯誤,最後一步則是要將整個訂單訊息輸出到交易日誌中,方便辨識錯誤出自哪一個訂單,確定那些訂單是沒問題的。而在輸出之前我們要先創建一個函數來獲取訂單類型。

string CheckOrderType(ENUM_ORDER_TYPE pType)
{
	string orderType;
	if(pType == ORDER_TYPE_BUY) orderType = "buy";
	else if(pType == ORDER_TYPE_SELL) orderType = "sell";
	else if(pType == ORDER_TYPE_BUY_STOP) orderType = "buy stop";
	else if(pType == ORDER_TYPE_BUY_LIMIT) orderType = "buy limit";
	else if(pType == ORDER_TYPE_SELL_STOP) orderType = "sell stop";
	else if(pType == ORDER_TYPE_SELL_LIMIT) orderType = "sell limit";
	else if(pType == ORDER_TYPE_BUY_STOP_LIMIT) orderType = "buy stop limit";
	else if(pType == ORDER_TYPE_SELL_STOP_LIMIT) orderType = "sell stop limit";
	else orderType = "invalid order type";
	return(orderType);
}

6.輸出至交易日誌

string  orderType = CheckOrderType(pType);
	
	string errDesc = TradeServerReturnCodeDescription(result.retcode);

	Print("Open ",orderType," order #",result.deal,": ",result.retcode," - ",errDesc,", Volume: ",result.volume,", Price: ",result.price,", Bid: ",result.bid,", Ask: ",result.ask);
	

7.return值

因為這個OpenPosition函數不是以void宣告,所以必須回傳boolean值。

if(checkCode == Trade_Success) return(true);
else return(false);

上一篇
DAY18 建立下單類型與除錯(上)
下一篇
DAY20 停損與停利
系列文
從零開始的外匯自動程式交易30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言