日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

MT5 EA交易期货-挂单撤单

發(fā)布時間:2023/12/29 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MT5 EA交易期货-挂单撤单 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本例子演示在買一價往上10個跳的價格上掛空單, 掛單后10秒后撤單。

與外匯交易不同,為了防止盤口愰騙,各交易所都將頻繁撤單列入異常交易管理規(guī)范請注意。

EA是通過調(diào)用mt5ctp.dll進(jìn)行期貨交易,所以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()屬性獲得當(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。

string symbol=SymbolInfoString(Symbol(), SYMBOL_ISIN); //獲取合約(如果是主力合約的話取對應(yīng)的合約) string exchange=SymbolInfoString(symbol, SYMBOL_EXCHANGE); //該品種的交易所 double tickSize=SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE); //該品種每跳大小 tick size

定義了幾個全局變量:

orderSysId是用來保存CTP掛單回調(diào)中的CTP訂單編號,這個變量在之后的撤單中需要使用。

eaOrderRef是EA報單編號,作用類似外匯EA的魔術(shù)號碼。

placeOrderDateTime是記錄掛單成功的時間,該時間過了10秒后會撤單。

orders是記錄當(dāng)前掛單的數(shù)量。

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; //掛單數(shù)量 how many ea orders ushort splitCommma=StringGetCharacter(",",0);

如果當(dāng)前沒有掛單,就發(fā)送報單:

先獲得最新買一價,將報單價格定位買一價+10個跳,報單手?jǐn)?shù)1手。

調(diào)用mt5ctp.dll getOrderRefCTP函數(shù)生成EA報單編號并保存在eaOrderRef變量,期貨交易所對報單編號格式有規(guī)定,不能像外匯EA的魔術(shù)號碼可隨意自行指定, 否則報單會失敗,所以EA需先調(diào)用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ī))。

void OnTick(){ //---if(orders==0) //如果沒有就掛單{ double ask=getAsk(); //取得買1價double price=ask+10*tickSize; 買1價+10個跳int vol=1; //手?jǐn)?shù) 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 表示網(wǎng)絡(luò)連接失敗 network disconect//-2,表示未處理請求超過許可數(shù) request too much //-3,表示每秒發(fā)送請求數(shù)超過許可數(shù) request too fast within one secondif(res!=0){printf("sendOrderLimit error %d", 1);} }

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)。這與外匯交易有不同,更多請看MT5Future:MT5 EA交易期貨2-期貨與外匯交易機(jī)制。

MT5通過mt5ctp.dll得到交易所對該報單的處理結(jié)果(即報單回調(diào)),然后把報單回調(diào)作為MQL圖表事件發(fā)送給打開的全部圖表,EA 通過MQL圖表事件響應(yīng)函數(shù)OnChartEvent得到這些回調(diào)(即下圖4)。

MQL期貨圖表事件的ID都是3000,EA需要在OnChartEvent函數(shù)中只處理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{

報單回調(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[]。因為在OnChartEvent函數(shù)中ID是3000的事件包括了各種的交易所回調(diào)(如報單回調(diào),成交回調(diào),撤單回調(diào),錯誤回調(diào),倉位回調(diào),資金回調(diào)), 所以EA需要先根據(jù)chartEvents[0]="OnRtnOrder"篩選出其中的報單回調(diào)。

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成交回調(diào)中的各個數(shù)據(jù)用逗號分隔if(n>0){string eventType=chartEvents[0]; if(eventType=="OnRtnOrder") //CTP報單回調(diào) send order callback{

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ù)號碼)。

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成交回調(diào)中的各個數(shù)據(jù)用逗號分隔if(n>0){string eventType=chartEvents[0]; if(eventType=="OnRtnOrder") //CTP報單回調(diào) send order callback{printf(sparam);string orderRef=chartEvents[3]; //CTP報單回調(diào)中的報單編號 ea order id in callback if(orderRef==(string)eaOrderRef) //CTP報單回調(diào)中的訂單編號是本EA的報單編號 is my ea order{

EA獲得報單回調(diào)中的CTP報單編號,報單做多或做空,報單開倉或平倉,和交易所對這次報單的撮合結(jié)果

當(dāng)交易所撮合結(jié)果是3(未成交還在隊列中)或 4(未成交不在隊列中),就是掛單成功了,記錄當(dāng)前掛單的數(shù)量為1,并記錄成功掛單的時間。

當(dāng)交易所撮合結(jié)果是5(撤單),就是撤單成功了。

if(orderRef==(string)eaOrderRef) //CTP報單回調(diào)中的訂單編號是本EA的報單編號 is my ea order{orderSysId=chartEvents[4]; //CTP報單回調(diào)中的交易所訂單編號 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' = 尚未觸發(fā) not touched 'c' = 已觸發(fā) touched*/string orderStatus=chartEvents[7]; //報單狀態(tài) exchange order statusif(orderStatus=="3" || orderStatus=="4") //該報單已經(jīng)掛單還沒全部成交 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]; //報單狀態(tài)信息 exchange order status description printf("my ea order %s", orderSysId);}

掛單成功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)同理。

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 表示網(wǎng)絡(luò)連接失敗 network disconect//-2,表示未處理請求超過許可數(shù) request too much //-3,表示每秒發(fā)送請求數(shù)超過許可數(shù) request too fast within one secondif(res!=0){printf("cancelOrderCTP error %s", res);} } }

總結(jié)

以上是生活随笔為你收集整理的MT5 EA交易期货-挂单撤单的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。