MT5 EA交易期货-挂单撤单
本例子演示在買一價往上10個跳的價格上掛空單, 掛單后10秒后撤單。
與外匯交易不同,為了防止盤口愰騙,各交易所都將頻繁撤單列入異常交易管理規范請注意。
EA是通過調用mt5ctp.dll進行期貨交易,所以EA需要先引用mt5ctp.dll,該DLL的頭文件mt5ctp.mqh在\MQL5\Include目錄下。
#property copyright "www.wewin28.com 1145412@qq.com" #property link "http://www.wewin28.com" #property version "1.1" #include <mt5ctp.mqh>對于非主連合約如rb2209可以通過Symbol()屬性獲得當前圖表的合約,但對于主連合約如rb9999,則需要通過SYMBOL_ISIN屬性獲得主連合約現在對應的合約(rb2301),當主連合約rb9999隨著時間發生換月后,通過SYMBOL_ISIN屬性得到的合約就會自動變為rb2305。使用后者的寫法可以讓EA在主連合約和非主連合約的圖表上都能獲得當前圖表的合約。
通過SYMBOL_EXCHANGE屬性獲得該合約對應的交易所, 如獲得rb2301所屬的交易所SHFE即上期所。
通過SYMBOL_TRADE_TICK_SIZE屬性獲得該合約每一跳的大小,如螺紋鋼是1,股指期貨是0.2。
string symbol=SymbolInfoString(Symbol(), SYMBOL_ISIN); //獲取合約(如果是主力合約的話取對應的合約) string exchange=SymbolInfoString(symbol, SYMBOL_EXCHANGE); //該品種的交易所 double tickSize=SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE); //該品種每跳大小 tick size定義了幾個全局變量:
orderSysId是用來保存CTP掛單回調中的CTP訂單編號,這個變量在之后的撤單中需要使用。
eaOrderRef是EA報單編號,作用類似外匯EA的魔術號碼。
placeOrderDateTime是記錄掛單成功的時間,該時間過了10秒后會撤單。
orders是記錄當前掛單的數量。
splitCommma是代表逗號。
string orderSysId=""; //交易所訂單編號 CTP order Id long eaOrderRef=0; //EA報單編號 magic number datetime placeOrderDateTime=D'1970.01.01 00:00'; //掛單時間 place order datetime int orders=0; //掛單數量 how many ea orders ushort splitCommma=StringGetCharacter(",",0);如果當前沒有掛單,就發送報單:
先獲得最新買一價,將報單價格定位買一價+10個跳,報單手數1手。
調用mt5ctp.dll getOrderRefCTP函數生成EA報單編號并保存在eaOrderRef變量,期貨交易所對報單編號格式有規定,不能像外匯EA的魔術號碼可隨意自行指定, 否則報單會失敗,所以EA需先調用getOrderRefCTP函數生成EA報單編號再報單。
調用mt5ctp.dll sendOrderLimit函數發送限價報單,其中第一個參數是合約,第二個參數是mt5ctp.mqh頭文件中定義的枚舉ENUM_CTP_SELL_ORDER(代表空單),第三個參數是mt5ctp.mqh頭文件中定義的枚舉ENUM_CTP_OPEN_POSITION(代表開倉),第四個參數是報單的價格,第五個參數是報單的手數,第六個參數是EA報單編號,第七個參數是mt5ctp.mqh頭文件中定義的枚舉ENUM_CTP_ACCOUNT_SPECULATION(代表開戶的期貨賬號是投機)。
void OnTick(){ //---if(orders==0) //如果沒有就掛單{ double ask=getAsk(); //取得買1價double price=ask+10*tickSize; 買1價+10個跳int vol=1; //手數 quantityeaOrderRef=getOrderRefCTP(); //生成EA報單編號 generate EA magic numberint res=sendOrderLimit(symbol, ENUM_CTP_SELL_ORDER, ENUM_CTP_OPEN_POSITION, price, vol, (string)eaOrderRef, ENUM_CTP_ACCOUNT_SPECULATION); //買1價+10個跳價格掛空單 place limit order at ask+10 tick size//0 代表本地報單成功 local ok //-1 表示網絡連接失敗 network disconect//-2,表示未處理請求超過許可數 request too much //-3,表示每秒發送請求數超過許可數 request too fast within one secondif(res!=0){printf("sendOrderLimit error %d", 1);} }sendOrderLimit函數調用后會同步返回本地電腦發送報單請求的結果,0是本地電腦向交易所成功發送報單,-1是網絡連接失敗,-2是未處理請求超過許可數,-3是每秒發送請求數超過許可數。但即使sendOrderLimit函數返回0(只是完成了下圖中1和2),也不代表已經成功在交易所掛單,還需要等待交易所異步返回對EA報單的撮合結果即報單回調和成交回調(即下圖3)。這與外匯交易有不同,更多請看MT5Future:MT5 EA交易期貨2-期貨與外匯交易機制。
MT5通過mt5ctp.dll得到交易所對該報單的處理結果(即報單回調),然后把報單回調作為MQL圖表事件發送給打開的全部圖表,EA 通過MQL圖表事件響應函數OnChartEvent得到這些回調(即下圖4)。
MQL期貨圖表事件的ID都是3000,EA需要在OnChartEvent函數中只處理ID是3000的事件。
void OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam) {if(id==3000) //只處理MT5 CTP的事件 process MT5 CTP events only{報單回調是一個字符串,格式如下:
OnRtnOrder, 交易所, 合約, EA報單編號, CTP報單編號, 多空, 開平, 報單狀態枚舉, 報單狀態信息, 報單價格, 報單手數, 成交手數, 報單時間, 撤單時間,FrontID,SessionID,e
EA通過OnChartEvent函數的sparam參數獲得圖表事件中的交易所報單回調。把sparam對應的字符串按逗號拆分后保存到字符數組chartEvents[]。因為在OnChartEvent函數中ID是3000的事件包括了各種的交易所回調(如報單回調,成交回調,撤單回調,錯誤回調,倉位回調,資金回調), 所以EA需要先根據chartEvents[0]="OnRtnOrder"篩選出其中的報單回調。
void OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam) {if(id==3000) //只處理MT5 CTP的事件 process MT5 CTP events only{ string chartEvents[]; int n=StringSplit(sparam,splitCommma,chartEvents); //CTP成交回調中的各個數據用逗號分隔if(n>0){string eventType=chartEvents[0]; if(eventType=="OnRtnOrder") //CTP報單回調 send order callback{chartEvents數組的第4個元素是EA報單編號。如果有多個EA同時在不同的圖表上運行并報單,本圖表的OnChartEvent也會接收到其他圖表上的EA產生的報單回調,之前EA已經生成并記錄了本次報單編號在eaOrderRef變量中,所以只有報單回調中的EA報單編號等于eaOrderRef變量才是本EA的報單回調(作用類似于外匯EA中的魔術號碼)。
void OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam) {if(id==3000) //只處理MT5 CTP的事件 process MT5 CTP events only{ string chartEvents[]; int n=StringSplit(sparam,splitCommma,chartEvents); //CTP成交回調中的各個數據用逗號分隔if(n>0){string eventType=chartEvents[0]; if(eventType=="OnRtnOrder") //CTP報單回調 send order callback{printf(sparam);string orderRef=chartEvents[3]; //CTP報單回調中的報單編號 ea order id in callback if(orderRef==(string)eaOrderRef) //CTP報單回調中的訂單編號是本EA的報單編號 is my ea order{EA獲得報單回調中的CTP報單編號,報單做多或做空,報單開倉或平倉,和交易所對這次報單的撮合結果。
當交易所撮合結果是3(未成交還在隊列中)或 4(未成交不在隊列中),就是掛單成功了,記錄當前掛單的數量為1,并記錄成功掛單的時間。
當交易所撮合結果是5(撤單),就是撤單成功了。
if(orderRef==(string)eaOrderRef) //CTP報單回調中的訂單編號是本EA的報單編號 is my ea order{orderSysId=chartEvents[4]; //CTP報單回調中的交易所訂單編號 exchange order id in callbackstring buySell=chartEvents[5]; //多/空 buy/sell string combOffsetFlag=chartEvents[6]; //開/平 open/close/*orderStatus 枚舉 enum:0 = 全部成交 all filled 1 = 部分成交還在隊列中 part filled in the queue 2 = 部分成交不在隊列中 part filled not in the queue 3 = 未成交還在隊列中 not yet fill in the queue 4 = 未成交不在隊列中 not yet fill not in the queue 5 = 撤單 canceled 'a' = 未知 unknown'b' = 尚未觸發 not touched 'c' = 已觸發 touched*/string orderStatus=chartEvents[7]; //報單狀態 exchange order statusif(orderStatus=="3" || orderStatus=="4") //該報單已經掛單還沒全部成交 my ea order not yet fill and pending{orders=1;placeOrderDateTime=TimeCurrent();printf("掛單成功 pending order successfully");} if(orderStatus=="5") //該報單撤單 canceled {orders=0;printf("撤單成功 cancel order successfully");}string statusMsg=chartEvents[8]; //報單狀態信息 exchange order status description printf("my ea order %s", orderSysId);}掛單成功10秒后會撤銷這個掛單,調用mt5ctp.dll的cancelOrderCTP函數進行撤單,其中第一個參數是該合約屬于的交易所,第二個參數是合約,第三個參數是CTP報單編號。
cancelOrderCTP函數調用后會同步返回本地電腦處理撤單請求的結果,0是本地向交易所成功發送撤單,-1是網絡連接失敗,-2是未處理請求超過許可數,-3是表示每秒發送請求數超過許可數。但即使cancelOrderCTP函數返回0(只是完成了1和2),也不代表已經成功在交易所撤單,還需要等待交易所異步返回對撤單的處理結果即撤單回調(即下圖3),MT5通過mt5ctp.dll得到交易所的撤單回調,并把撤單回調作為MQL圖表事件發送給全部圖表,EA 通過MQL圖表事件響應函數OnChartEvent得到這些回調(即下圖4)。如何取得和處理撤單回調與上面處理報單回調同理。
if(orders>0) //10秒后撤單 cancel order in 10 seconds{if(TimeCurrent()-placeOrderDateTime>10){printf("10秒后撤單 cancel my order in 10 seconds");int res=cancelOrderCTP(exchange, symbol, orderSysId); //0 代表報單成功 send order ok //-1 表示網絡連接失敗 network disconect//-2,表示未處理請求超過許可數 request too much //-3,表示每秒發送請求數超過許可數 request too fast within one secondif(res!=0){printf("cancelOrderCTP error %s", res);} } }總結
以上是生活随笔為你收集整理的MT5 EA交易期货-挂单撤单的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: EasyAdmin CURD命令大全
- 下一篇: MQL5 初学者:EA 交易技术指标使用