欢迎光临散文网 会员登陆 & 注册

MT5 EA交易期货-限价单开仓平仓

2022-11-04 14:34 作者:wewin28  | 我要投稿

期货的订单类型和外汇不一样,国内期货交易所只有限价单和市价单。

限价单就是比如交易者报限价单4000做多螺纹钢,则交易所只会在4000或4000以下撮合该多单,所以如果能成交,成交价格只会在4000或4000以下。

比如交易者报限价单8000做空苹果,则交易所只会在8000或8000以上撮合该空单,所以如果能成交,成交价格只会在8000或8000以上。

也就是说限价单会在交易者指定的价格上成交,超出了该价格则不成交。更多请看期货与外汇交易机制的不同

本例子的源代码在"EA交易" -> "Examples"下,演示了EA如何报限价单做多,成交后10秒平仓。

EA是通过调用mt5ctp.dll进行期货交易,所以EA需要先引用mt5ctp.dll,该DLL头文件mt5ctp.mqh在\MQL5\Include目录下。

EA获取当前图表的合约。对于非主连合约如rb2209可以通过Symbol()属性获得当前图表的合约,但对于主连合约如rb9999,则需要通过SYMBOL_ISIN属性获得主连合约现在对应的合约(rb2301),当主连合约rb9999随着时间发生换月后,通过SYMBOL_ISIN属性得到的合约就会自动变为rb2305。使用后者的写法可以让EA在主连合约和非主连合约的图表上都能获得当前图表的合约。

通过SYMBOL_EXCHANGE属性获得该合约对应的交易所, 如获得rb2301所属的交易所SHFE(上期所)。

通过SYMBOL_DIGITS属性获得该合约的小数后位数,如螺纹钢是0,股指是1。

splitCommma是代表逗号。

定义报单时间全局变量entryTime,用来判断是否已经报单。定义仓位全局变量,如果pos等于0就是空仓,如果大于0就是持仓。eaOrderRef是EA报单编号,作用类似外汇EA的魔术号码。

EA判断如果还没有报单和空仓就报单,先取得当前最新的MqlTick结构体:

getLastMQLTick函数首先获得现在的格林威治时间,将格林威治时间转成北京时间,获得3个小时之前的时间(比如当前是12点就是9点),将之前3个小时以来的全部跳复制到ticks[]数组(MqlTick结构体)访问ticks[]数组的最后一个元素,即获得并返回最新价格的MqlTick结构体。

通过最新的MqlTick结构体取得最新成交价,设置报单手数1手,调用mt5ctp.dll getOrderRefCTP函数生成EA报单编号并保存在eaOrderRef变量,CTP对报单编号格式有格式要求,不能像外汇EA的魔术号码可随意自行指定, 否则报单会失败,所以EA需先调用getOrderRefCTP函数生成EA报单编号再报单。

EA调用mt5ctp.dll sendOrderLimit函数发送限价报单,其中第一个参数是合约,第二个参数是mt5ctp.mqh头文件中定义的枚举ENUM_CTP_BUY_ORDER(代表多单),第三个参数是mt5ctp.mqh头文件中定义的枚举ENUM_CTP_OPEN_POSITION(代表开仓),第四个参数是报单的价格,第五个参数是报单的手数,第六个参数是EA报单编号,第七个参数是mt5ctp.mqh头文件中定义的枚举ENUM_CTP_ACCOUNT_SPECULATION(代表开户的期货账号是投机)。


请注意sendOrderLimit函数调用后会同步返回本地电脑发送报单请求的结果,0是本地电脑向交易所成功发送报单,-1是网络连接失败,-2是未处理请求超过许可数,-3是每秒发送请求数超过许可数。但即使sendOrderLimit函数返回0(即完成下图中的1和2),也不代表已经成功在交易所挂单,还需要等待交易所异步返回对EA报单的撮合结果即报单回调和成交回调(即下图中的3)。更多请看交易所异步回调

MT5通过mt5ctp.dll得到报单回调和成交回调,然后把这些回调作为MQL图表事件发送给全部图表,EA 通过MQL图表事件响应函数OnChartEvent得到这些回调(即上图中的4)。

期货发出的MQL图表事件ID都是3000,EA需要在OnChartEvent函数中只处理ID是3000的事件。


EA是通过OnChartEvent函数的sparam参数获得图表事件中的交易所报单回调。

报单回调是一个字符串,格式如下:

OnRtnOrder, 交易所, 合约, EA报单编号, CTP报单编号, 多空, 开平, 报单状态枚举, 报单状态信息, 报单价格, 报单手数, 成交手数, 报单时间, 撤单时间,FrontID,SessionID,e

EA通过OnChartEvent函数的sparam参数获得MQL图表事件中的交易所报单回调。把sparam对应的字符串按逗号拆分后保存到字符数组chartEvents[]。

因为在OnChartEvent函数中ID是3000的事件包括了各种的交易所回调(如报单回调,成交回调,撤单回调,错误回调,仓位回调,资金回调),更多请看交易所异步回调。 所以EA需要先根据chartEvents[0]="OnRtnOrder"筛选出其中的报单回调。

chartEvents数组的第4个元素是EA报单编号。如果有多个EA同时在不同的图表上运行并报单,本图表的OnChartEvent也会接收到其他图表上的EA产生的报单回调,在上面EA已经生成并记录了EA本次报单编号在eaOrderRef变量中,所以只有报单回调中的EA报单编号等于eaOrderRef变量才是本EA本次报单的回调(作用类似于外汇EA中的魔术号码)。

EA获得报单回调中的交易所、合约、EA报单编号、CTP报单编号、报单是做多或做空、报单是开仓或平仓,获得报单价格,报单手数,报单成交手数,报单时间,撤单时间和交易所对这次报单的撮合结果。

如果报单成交了,EA接着会收到交易所的成交回报。

成交回调是一个字符串,格式如下:

OnRtnTrade, 交易所, 合约, EA报单编号, CTP报单编号, 成交编号, 多空, 开平, 成交价格, 成交手数, 成交时间,e

因为在OnChartEvent函数中ID是3000的事件包括了交易所的各种回调(如报单回调,成交回调,撤单回调,错误回调,仓位回调,资金回调), 所以EA需要先根据chartEvents[0]="OnRtnTrade"找出其中的成交回调。

EA取得成交回调中的EA报单编号。如果有多个EA同时在不同的图表上运行并报单,本图表的OnChartEvent也会接收到其他图表上的EA产生的成交回调,在上面eaOrderRef变量已经记录了这次报单的编号,所以成交回调中的EA报单编号等于该变量才是本EA本次报单的成交回调(作用类似于外汇EA中的魔术号码)。

EA就可以获得成交回调中的交易所、合约、CTP报单编号、CTP成交编号、报单是做多还是做空、报单是开仓还是平仓)、报单的成交价格、报单的成交手数、报单成交时间。

然后根据报单成交回调计算EA多空仓位并用全局变量pos记录。

如果交易所拒绝了EA的报单, EA通过报单错误回调获得该报单被拒绝的原因。

报单错误回调过程


持仓10秒后买一价报限价空单平仓,平仓程序和开仓同理。


MT5 EA交易期货-限价单开仓平仓的评论 (共 条)

分享到微博请遵守国家法律