MT5 EA交易期貨-掛單撤單
該例子的源代碼在"EA交易" -> "Examples"下,本例子演示在買一價往上10個跳的價格上掛空單, 掛單10秒后撤單。
與外匯交易不同,為了防止盤口愰騙,各交易所都將頻繁撤單列入異常交易管理規(guī)范請注意。

EA是通過調(diào)用mt5ctp.dll進(jìn)行期貨交易,所以EA需要先引用mt5ctp.dll,該DLL的頭文件mt5ctp.mqh在\MQL5\Include目錄下。
對于非主連合約如rb2209可以通過Symbol()屬性獲得當(dāng)前圖表的合約,但對于主連合約如rb9999,則需要通過SYMBOL_ISIN屬性獲得主連合約現(xiàn)在對應(yīng)的合約(rb2301),當(dāng)主連合約rb9999隨著時間發(fā)生換月后,通過SYMBOL_ISIN屬性得到的合約就會自動變?yōu)閞b2305。使用后者的寫法可以讓EA在主連合約和非主連合約的圖表上都能獲得當(dāng)前圖表的合約。
通過SYMBOL_EXCHANGE屬性獲得該合約對應(yīng)的交易所, 如獲得rb2301所屬的交易所SHFE即上期所。
通過SYMBOL_TRADE_TICK_SIZE屬性獲得該合約每一跳的大小,如螺紋鋼是1,股指期貨是0.2。
定義了幾個全局變量:
orderSysId是用來保存CTP掛單回調(diào)中的CTP訂單編號,這個變量在之后的撤單中需要使用。
eaOrderRef是EA報單編號,作用類似外匯EA的魔術(shù)號碼。
placeOrderDateTime是記錄掛單成功的時間,該時間過了10秒后會撤單。
orders是記錄當(dāng)前掛單的數(shù)量。
splitCommma是代表逗號。
如果當(dāng)前沒有掛單,就發(fā)送報單:
先獲得最新買一價,將報單價格定位買一價+10個跳,報單手?jǐn)?shù)1手。
調(diào)用mt5ctp.dll getOrderRefCTP函數(shù)生成EA報單編號并保存在eaOrderRef變量,期貨交易所對報單編號格式有規(guī)定,不能像外匯EA的魔術(shù)號碼可隨意自行指定, 否則報單會失敗,所以EA需先調(diào)用mt5ctp.dll的getOrderRefCTP函數(shù)生成EA報單編號再報單。
調(diào)用mt5ctp.dll sendOrderLimit函數(shù)發(fā)送限價報單,其中第一個參數(shù)是合約,第二個參數(shù)是mt5ctp.mqh頭文件中定義的枚舉ENUM_CTP_SELL_ORDER(代表空單),第三個參數(shù)是mt5ctp.mqh頭文件中定義的枚舉ENUM_CTP_OPEN_POSITION(代表開倉),第四個參數(shù)是報單的價格,第五個參數(shù)是報單的手?jǐn)?shù),第六個參數(shù)是EA報單編號,第七個參數(shù)是mt5ctp.mqh頭文件中定義的枚舉ENUM_CTP_ACCOUNT_SPECULATION(代表開戶的期貨賬號是投機(jī))。
sendOrderLimit函數(shù)調(diào)用后會同步返回本地電腦發(fā)送報單請求的結(jié)果,0是本地電腦向交易所成功發(fā)送報單,-1是網(wǎng)絡(luò)連接失敗,-2是未處理請求超過許可數(shù),-3是每秒發(fā)送請求數(shù)超過許可數(shù)。但即使sendOrderLimit函數(shù)返回0(只是完成了下圖中1和2),也不代表已經(jīng)成功在交易所掛單,還需要等待交易所異步返回對EA報單的撮合結(jié)果即報單回調(diào)和成交回調(diào)(即下圖3)。這與外匯交易有不同,更多請看交易所異步回調(diào)。
MT5通過mt5ctp.dll得到交易所對該報單的處理結(jié)果(即報單回調(diào)),然后把報單回調(diào)作為MQL圖表事件發(fā)送給打開的全部圖表,EA 通過MQL圖表事件響應(yīng)函數(shù)OnChartEvent得到這些回調(diào)(即下圖4)。

期貨圖表事件的ID都是3000,EA需要在OnChartEvent函數(shù)中只處理ID是3000的事件。
報單回調(diào)是一個字符串,格式如下:
OnRtnOrder, 交易所, 合約, EA報單編號, CTP報單編號, 多空, 開平, 報單狀態(tài)枚舉, 報單狀態(tài)信息, 報單價格, 報單手?jǐn)?shù), 成交手?jǐn)?shù), 報單時間, 撤單時間,FrontID,SessionID,e
EA通過OnChartEvent函數(shù)的sparam參數(shù)獲得圖表事件中的交易所報單回調(diào)。把sparam對應(yīng)的字符串按逗號拆分后保存到字符數(shù)組chartEvents[]。因?yàn)樵贠nChartEvent函數(shù)中ID是3000的事件包括了各種的交易所回調(diào)(如報單回調(diào),成交回調(diào),撤單回調(diào),錯誤回調(diào),倉位回調(diào),資金回調(diào)), 所以EA需要先根據(jù)chartEvents[0]="OnRtnOrder"篩選出其中的報單回調(diào)。
chartEvents數(shù)組的第4個元素是EA報單編號。如果有多個EA同時在不同的圖表上運(yùn)行并報單,本圖表的OnChartEvent也會接收到其他圖表上的EA產(chǎn)生的報單回調(diào),之前EA已經(jīng)生成并記錄了本次報單編號在eaOrderRef變量中,所以只有報單回調(diào)中的EA報單編號等于eaOrderRef變量才是本EA的報單回調(diào)(作用類似于外匯EA中的魔術(shù)號碼)。
EA獲得報單回調(diào)中的CTP報單編號,報單做多或做空,報單開倉或平倉,和交易所對這次報單的撮合結(jié)果。
當(dāng)交易所撮合結(jié)果是3(未成交還在隊(duì)列中)或 4(未成交不在隊(duì)列中),就是掛單成功了,記錄當(dāng)前掛單的數(shù)量為1,并記錄成功掛單的時間。
當(dāng)交易所撮合結(jié)果是5(撤單),就是撤單成功了。
掛單成功10秒后會撤銷這個掛單,調(diào)用mt5ctp.dll的cancelOrderCTP函數(shù)進(jìn)行撤單,其中第一個參數(shù)是該合約屬于的交易所,第二個參數(shù)是合約,第三個參數(shù)是CTP報單編號。
cancelOrderCTP函數(shù)調(diào)用后會同步返回本地電腦處理撤單請求的結(jié)果,0是本地向交易所成功發(fā)送撤單,-1是網(wǎng)絡(luò)連接失敗,-2是未處理請求超過許可數(shù),-3是表示每秒發(fā)送請求數(shù)超過許可數(shù)。但即使cancelOrderCTP函數(shù)返回0(只是完成了1和2),也不代表已經(jīng)成功在交易所撤單,還需要等待交易所異步返回對撤單的處理結(jié)果即撤單回調(diào)(即下圖3),MT5通過mt5ctp.dll得到交易所的撤單回調(diào),并把撤單回調(diào)作為MQL圖表事件發(fā)送給全部圖表,EA 通過MQL圖表事件響應(yīng)函數(shù)OnChartEvent得到這些回調(diào)(即下圖4)。如何取得和處理撤單回調(diào)與上面處理報單回調(diào)同理。
