MT5 EA交易期货-止盈止损

该例子演示EA开空仓后,赚5个跳止盈或者亏4个跳止损。

EA是通过调用mt5ctp.dll进行期货交易,所以EA需要先引用mt5ctp.dll的头文件mt5ctp.mqh,该头文件在\MQL5\Include目录下。
EA获取当前图表的合约。对于非主连合约如rb2209可以通过Symbol()属性获得当前图表的合约,但对于主连合约如rb9999,则需要通过SYMBOL_ISIN属性获得主连合约现在对应的合约(rb2301),当主连合约rb9999随着时间发生换月后,通过SYMBOL_ISIN属性得到的合约就会自动变为rb2305。使用后者的写法可以让EA在主连合约和非主连合约的图表上都能获得当前图表的合约。
通过SYMBOL_EXCHANGE属性获得该合约对应的交易所, 如获得rb2301所属的交易所SHFE(上期所)。
通过SYMBOL_TRADE_TICK_SIZE属性获得该合约每一跳的大小,如螺纹钢是1,股指期货是0.2。
通过SYMBOL_TRADE_TICK_VALUE属性获得该合约每一跳是多少钱,如螺纹钢每一跳是10元,股指期货每一跳是60元。
定义了几个全局变量:vol是报单的手数,entryPrice是报单的手数,pos是当前持仓,eaOrderRef是EA报单编号,作用类似外汇EA的魔术号码。splitCommma是代表逗号。
在OnTick()事件中,如果没有持仓就马上报单
报单前需获得当前最新价格的MqlTick结构体:
首先获得当前的格林威治时间,将格林威治时间转成北京时间,获得3个小时之前的时间(比如当前是12点就是9点),将之前3个小时以来的全部跳复制到ticks[]数组(MqlTick结构体),访问ticks[]数组的最后一个元素,获得并返回最新价格的MqlTick结构体。
然后EA就可以取得当前最新价格结构体中的买一价报单。
EA调用mt5ctp.dll的接口函数getOrderRefCTP生成EA报单编号并保存在eaOrderRef变量,CTP对报单编号格式有规定,不能像外汇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(代表开户的期货账号是投机)。
sendOrderLimit函数调用后会同步返回本地电脑处理报单请求的结果,0是本地处理报单请求成功,-1是网络连接失败,-2是未处理请求超过许可数,-3是每秒发送请求数超过许可数。但即使sendOrderLimit函数返回0,也不代表已经成功在交易所报单(只是完成下图中的1和2),还需要等待交易所异步返回对报单的撮合结果即报单回调(即下图中的3)。这与外汇交易的机制有不同,更多请看交易所异步回调。
期货发出的MQL图表事件的ID都是3000,EA需要在OnChartEvent函数中只处理ID是3000的事件。EA通过OnChartEvent函数的sparam参数获得MQL图表事件中的交易所成交回调。
成交回调是一个字符串,格式如下:
OnRtnTrade, 交易所, 合约, EA报单编号, CTP报单编号, 成交编号, 多空, 开平, 成交价格, 成交手数, 成交时间,e
定义一个字符串数组chartEvents。
MT5通过mt5ctp.dll得到交易所对该报单的处理结果(即报单回调),之后会把这些回调作为MQL图表事件发送给全部图表,EA 通过MQL图表事件响应函数OnChartEvent得到这些回调(即下图中的4)。

把sparam对应的字符串按逗号拆分后保存到字符数组chartEvents[],这样chartEvents[0]就是"OnRtnTrade"。因为在OnChartEvent函数中ID是3000的事件包括了各种的交易所回调(如报单回调,成交回调,撤单回调,错误回调,仓位回调,资金回调), 所以EA需要先根据chartEvents[0]="OnRtnTrade"找出其中的成交回调。
chartEvents数组的第4个元素是EA报单编号。如果有多个EA同时在不同的图表上运行并报单,本图表的OnChartEvent也会接收到其他图表上的EA报单后产生的成交回调,在第52行eaOrderRef变量已经记录了EA报单编号,所以成交回调中的EA报单编号等于该变量才是本EA的成交回调(作用类似于外汇EA中的魔术号码)。
遍历chartEvents数组,取出成交回调中的合约,多空,开平,成交价格,成交手数,成交时间。
根据成交回调中的成交手数计算仓位。
获得成交回调中的成交价格用于计算仓位盈亏。
持仓后开始计算止盈:
获得当前最新价格的MqlTick结构体。
获得当前最新价格的MqlTick结构体中的最新价。
获得当前最新价格的MqlTick结构体中的卖一价。
当最新价小于空仓开仓价格4个跳就平仓止盈。
也可以用钱计算止盈,先计算最新价小于空仓开仓价格多少个跳, 再乘以每跳多少钱,如果大于50元就平仓止盈。
生成平空多单的eaOrderRef EA报单编号。
因为本例子是10秒后平仓,即是平今仓,而上期所和能源中心区分平今仓昨仓,所以这些交易所的合约参数需要使用mt5ctp.mqh头文件中定义的枚举ENUM_CTP_CLOSE_POSITION_TODAY, 其他交易所合约不用区分平今仓昨仓,参数用mt5ctp.mqh头文件中定义的枚举ENUM_CTP_CLOSE_POSITION。
上期所、能源中心和中金所没有市价单,这些交易所的合约用涨停价发限价单平仓,其他交易所则发市价单平仓。
通过SYMBOL_SESSION_PRICE_LIMIT_MAX属性获得涨停价。
如果达到止盈条件,则调用mt5ctp.dll的接口函数sendOrderLimit用涨停价报限价单平仓。
持仓后开始计算止损:
当最新价大于空仓开仓价格3个跳就平仓止损
也可以用钱计算止损,计算当最新价大于空仓开仓价格多少个跳, 再乘以每跳多少钱,如果大于50元就平仓止损。
止损其余程序和止盈同理。