在 MetaTrader 5 里使用 HedgeTerminal (对冲终端) 面板进行双向交易和仓位对冲, 第二部分(基础篇)
📘

在 MetaTrader 5 里使用 HedgeTerminal (对冲终端) 面板进行双向交易和仓位对冲, 第二部分(基础篇)

第 1/3 篇

「用 HedgeTerminal 在 MT5 里做双向挂单」

在 MT5 里加载 HedgeTerminal 面板后,可以在同一品种上同时挂出 buy stop 与 sell stop,实现双向仓位布局。该面板将对冲逻辑可视化,省去手动在终端里反复开仓的繁琐,适合需要快速切换多空的交易者。 根据社区 2015-10-29 发布的实操记录,这篇关于 HedgeTerminal 双向交易与对冲的第二部分内容,当时获得 4255 次查看、6 条评论,说明这类面板化对冲方案在 MT5 用户中确有需求。 打开 MT5 的「市场」标签页搜索 HedgeTerminal,安装到图表后,右键面板选择添加双向挂单,设置好止损间距即可。外汇与贵金属杠杆交易波动剧烈,双向挂单也可能两边都被扫损,实盘前务必用模拟账户验证。

◍ HedgeTerminal API 文档脉络

这篇技术文围绕 HedgeTerminal API 展开,整体拆成四大块:EA 与该面板的交互实战、API 函数手册、异步交易基础、MT5 集成开发环境中的多线程编程。 第一章覆盖从安装 HedgeTerminalAPI、EA 集成、事务选择,到双向仓位改平、同步/异步模式,以及经纪商虚拟重复品种等 13 个小节,偏工程落地。 第二章是纯手册式枚举,列出事务选择、属性获取、错误处理、SendTradeRequest 及对应的 ENUM_* 枚举,共 10 节,适合开 MT5 后边查边写。 第三章讲同步与异步订单的组织方案,并给出异步执行速度这一可验证数据点;第四章以 UnitedExchangeQuotes 报价收集器为例演示多线程,以及 EA 间通过多线程交互。 想在 MT5 里用 EA 控 HedgeTerminal 面板,先把第二章函数名和枚举过一遍,比直接抄例程少踩坑。

EA 怎么接进对冲终端的 API

这一节承接前文对 HedgeTerminal 面板的介绍,重点转向 EA 及各类 MQL5 程序如何接入 HedgeTerminalAPI 程序库。读懂这部分,你就能在熟悉的编码环境里直接写出支持双向开仓与仓位对冲的自动化策略,而不必在面板界面上手动点来点去。 除了程序库调用方式,文中第三、四节会铺开讲异步交易基础和多线程编程。即便你对锁仓、对冲这类玩法没兴趣,只要写 MQL5 机器人,这两块内容也值得翻——异步下单能避开主线程阻塞,多线程则关乎回测与实盘里的资源调度。 目标读者很明确:得是懂 MQL5 语法、写过 EA 的人。零基础的话先回去看第一部分,那里用图解把程序库原理和面板交互讲透了,再回来啃代码集成才不会卡壳。

「把 HedgeTerminalAPI 接进你的 EA」

要让 HedgeTerminal 的程序库在 MT5 里跑起来,不能像拖面板那样直接挂,得写个最小 EA 去调 HedgeTerminalInstall()。库文件固定落在 \MQL5\Experts\Market\HedgeTerminalApi.ex5,EA 里只需在 OnInit() 调一次安装函数即可,黄色标记的那几行就是干这个的。 没买库只想验证接口也行:把 EA 丢进策略测试器跑,安装器不启动,API 走单用户模式,无需配置文件。测试一结束,终端公用目录 c:\Users\<用户名>\AppData\Roaming\MetaQuotes\Terminal\Common\Files\HedgeTerminal\ 下会生成 \MQL5\Include\Prototypes.mqh 和 \MQL5\Experts\Chaos2.mq5,把它们拷回对应目录,EA 里 #include <Prototypes.mqh> 就能用。 HT 的函数是 lazy 初始化——第一次调用最慢。想让首笔响应不卡,可在 OnInit() 里先调一次 TransactionTotal() 预热,外汇与贵金属杠杆高,实盘里这种延迟可能直接错过入场。 面板和 EA 是实时通信。用 API 下的单会自动显在 HedgeTerminal 面板;想多显示 EA 名,去 Settings.xml 取消 <Magic> 注释,再在 ExpertAliases.xml 写别名映射,比如魔幻数 123847 对应 "ExPro 1.1",重启面板后活跃/历史表就多一列可读名字。 遍历事务和 MT4 搜订单类似,但 HT 里挂单、对冲仓都算事务。先 TransactionSelect() 再 TransactionType() 判别,循环里用 HEDGE_POSITION_STATE 看是否被 POSITION_STATE_FROZEN 锁住——锁了就别在当前线程改属性,等解锁再试。

MQL5 / C++
class="macro">#include <Prototypes.mqh>
class="type">int OnInit()
  {
   HedgeTerminalInstall();
   Print(TransactionTotal());
   class="kw">return(INIT_SUCCEEDED);
  }
上面这段编译后,Experts 栏会打出当前持仓总数,是验证库是否接好的最快办法。 嵌套事务是 HT 和 MT5 原生最大的差别:一个历史对冲仓可能由两笔订单、各带一笔成交组成。想抠某笔成交的执行价,得先选仓、再 HedgeOrderSelect() 选订单、拿成交号,最后定位成交取价。下面例程查的是成交 #1197610 的价格:
MQL5 / C++
TransactionSelect(class="num">5917888, MODE_HISTORY);
HedgeOrderSelect(class="num">6389111);
class="type">ulong deal = HedgeOrderGetInteger(HEDGE_ORDER_DEALS_TOTAL);
class=class="str">"cmt">// 循环匹配 deal == class="num">1197610 后
Print(HedgeDealGetDouble(HEDGE_DEAL_PRICE_EXECUTED));
日志会先选仓 #5917888、再选订单 #6389111,命中后输出执行价。 出错别瞎猜。TransactionType() 返回 TRANS_NOT_DEFINED 基本就是忘写 TransactionSelect(),接 GetHedgeError() 拿错误 ID 就清楚。所有错误码在 ENUM_HEDGE_ERR 里列着。 SendTradeRequest() 改带止损的注释实际是取消旧挂单+下新挂单两个子任务,可能只成一半。用 TotalActionsTask() 拿子任务数,for 里挨个 GetActionResult() 看哪步失败——比如新止价太贴现价被拒,仓位就裸奔没保护,这种漏洞在贵金属跳空时概率不低。

MQL5 / C++
class="macro">#include <Prototypes.mqh>
class="type">int OnInit()
  {
   HedgeTerminalInstall();
   Print(TransactionTotal());
   class="kw">return(INIT_SUCCEEDED);
  }

◍ 异步任务状态与同步模拟器的取舍

对比交易服务器返回的标准修饰符号码,常见现象是挂单被成功移除,但新订单放置失败并返回错误码 10015(不正确的价格),本质是当前价与停止价距离过近。EA 据此可主动约束停止位,只通过 SendTradeRequest() 做平仓动作。 每次交易任务可能由任意数量子任务顺序组成。异步模式下单个任务会传递若干代码,也可能“冻结”,所以必须跟踪执行状态。用 HEDGE_POSITION_TASK_STATUS 修饰符调 HedgePositionGetInteger(),返回 ENUM_TASK_STATUS 枚举的当前仓位任务状态;例如平仓订单发送后出错、仓位还在,就要拉任务状态排查。 同步模式靠“同步操作模拟器”跑复合任务:子任务发起后模拟器不把线程交还 EA,而是等一段时间期待交易环境变化,再重读环境,确认上一步成了才进下一步。这会拖慢总性能,但把复杂任务拆成顺序单函数调用,几乎不用分析执行记录。 HedgeTerminal 交易默认走同步模拟器;若 HedgeTradeRequest 里显式置 asynch_mode=true,才切异步。异步任务独立于主线程,但目前 EA 与 HedgeTerminal 异步算法交互尚未完整实现。同步模拟器延迟的根因是 MT5 交易环境反馈需要时间,且模拟器模式下进不了 OnTradeTransaction() 事件。 外汇与贵金属杠杆高、滑点跳空频繁,异步失败率随波动放大,生产 EA 建议先以同步模式验证逻辑,再评估是否切异步。

挂上对冲终端的空壳 EA 怎么写

想让 MT5 在加载 EA 时自动挂接对冲终端,核心不是画界面,而是用 #import 把外部编译好的 HedgeTerminalAPI.ex5 接进来。下面这段骨架 EA 跑起来不会下任何单,只在初始化时呼叫一次安装接口。 原始代码里 OnInit 直接 return INIT_SUCCEEDED,OnTick 和 OnDeinit 都是空函数,说明它纯粹是个『触发器』。真正的挂接动作只有一行:HedgeTerminalInstall()。 #property version "1.00" 标注了脚本版本,#import "HedgeTerminalAPI.ex5" 则声明了外部模块路径——这个 ex5 必须已经编译在同终端的 Libraries 目录下,否则 EA 加载会报无法解析导入。外汇与贵金属杠杆高,这类自动挂接工具仅作通道用途,不暗示任何收益可能。 把下面代码存成 InstallHedgeTerminalExpert.mq5 直接编译,拖进图表若日志无 import 报错,就代表终端安装函数已被调用过一次。

MQL5 / C++
class="macro">#class="kw">property copyright "Copyright class="num">2015, MetaQuotes Software Corp."
class="macro">#class="kw">property link "[MQL5官方文档]
class="macro">#class="kw">property version "class="num">1.00"
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| EA 初始化函数                                                     |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">int OnInit()
  {
class=class="str">"cmt">//---
class=class="str">"cmt">//---
   class="kw">return(INIT_SUCCEEDED);
  }
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| EA 逆初函数                                                       |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">void OnDeinit(const class="type">int reason)
  {
class=class="str">"cmt">//---
  }
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| EA 即时报价函数                                                   |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">void OnTick()
  {
class=class="str">"cmt">//---
  }
class=class="str">"cmt">//+------------------------------------------------------------------+
class="macro">#class="kw">property copyright "Copyright class="num">2015, MetaQuotes Software Corp."
class="macro">#class="kw">property link "[MQL5官方文档]
class="macro">#class="kw">property version "class="num">1.00"
class="macro">#class="kw">import "HedgeTerminalAPI.ex5"
   class="type">void HedgeTerminalInstall(class="type">void);
class="macro">#class="kw">import
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| EA 初始化函数                                                     |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">int OnInit()
  {
class=class="str">"cmt">//---
   HedgeTerminalInstall();
   class="kw">return(INIT_SUCCEEDED);
  }

常见问题

在 HedgeTerminal 面板里选中品种后,分别用 Buy Stop / Sell Stop 或 Buy Limit / Sell Limit 按钮各挂一张反向单即可;面板会按对冲账户规则独立显示两边仓位,互不抵消。
文档脉络通常是:连接与初始化、订单/仓位读写接口、异步任务提交与状态查询、同步模拟器开关。先通读初始化和读写接口,再碰异步部分。
可以。小布盯盘的 AIGC 能替你监控双向仓位敞口并提示异常挂单,打开对应品种页就能看到,你把决策留给人工就好。
先写个空壳 EA:在 OnStart 里调用终端 API 的初始化函数,注册回调,不跑交易逻辑;编译挂上终端确认联通,再逐步加策略。
回测或需要确定性的场景用同步模拟器;实盘追求不卡 UI 用异步任务轮询状态。两者不要混用同一笔订单的生命周期。