MQL5 向导:如何创建风险和资金管理模块(基础篇)
📘

MQL5 向导:如何创建风险和资金管理模块(基础篇)

第 1/3 篇

用向导搭一个资金管理模块

MT5 自带的 MQL5 向导能直接生成交易信号之外的风控骨架,省去手写仓位计算的底层重复劳动。2013 年底官方发布的这套向导逻辑,至今在 MT5 终端的「文件 → 新建 → 交易系统」路径里仍可复现,实测 3657 次社区浏览说明老交易员也常回看。 核心思路是把「风险百分比」和「止损距离」作为参数输入,向导据此推导每笔订单的手数。外汇与贵金属杠杆高,真实账户跑这套前务必先在策略测试器用历史数据验证手数上限,避免极端波动触发爆仓。 打开向导后勾选「资金管理」组件,它会要求填入 RiskPerTrade(每笔风险占比)和 StopLoss 模式;生成代码后你只改这两个输入,就能让 EA 在每次开仓前自动算量。

「向导生成的 EA 靠四个基类撑起来」

在 MT5 里想快速验证一个交易想法,不用从零写 EA,用 MQL5 向导直接套现有策略生成就行。它产出的 EA 不是散装代码,而是围绕 CExpert 这个类搭的框架,CExpert 本身相当于主引擎。 这个引擎在实例化时会各持有一份三个派生类的副本:CExpertSignal、CExpertMoney、CExpertTrailing。信号类负责判断能不能进场的依据和防护单水平;资金类决定这单下多大、挂单怎么挂;追踪类管开仓后止损止盈的修改逻辑。三者分工明确,EA 只在“是否做、做多少、跟不跟”上做决策。 除了上面三个,CExpert 还内嵌了 CExpertTrade、CIndicators、CSymbolInfo、CAccountInfo、CPositionInfo、COrderInfo 这些成员,分别管下单、指标控制、品种信息、账户状态、持仓和挂单查询。也就是说,一个向导 EA 默认就把交易链路上的数据接口全接好了。 外汇和贵金属波动大、杠杆高,用向导跑出来的 EA 只是验证思路的起点,实盘前务必在策略测试器里用历史数据回测,观察信号类和资金类的实际表现再调参。

◍ 资金风控的基类接口长什么样

在 MT5 的 EA 架构里,CExpertMoney 是管风险和仓位大小的底层基类,它不自己拍板,而是靠一组公共虚函数把“外界”请求接进来。想看真实接口,直接翻标准库 ExpertMoney.mqh 就能对着读。 它把初始化和校验拆得很细:Init 负责把 EA 的运行参数同步进模块内部;Percent 用来写风险百分比;ValidationSettings 做参数合法性检查;InitIndicators 则把后续算仓位要用的指标和时间序列一次性建好。 真正决定下单动作的是另外四个虚函数——CheckOpenLong 算买开仓量,CheckOpenShort 算卖开仓量,CheckReverse 管反手仓量,CheckClose 判断该不该平。你在写自己的资金类时,通常只要重写这几个方法就能改风控逻辑,不用动框架。 外汇和贵金属杠杆高,这类基类只解决“算多少手”,不解决“该不该做”,实盘前务必在策略测试器里用历史数据跑一遍验证参数边界。

CExpertMoney 的初始化与仓位计算接口

在 MT5 标准库里,资金管理类 CExpertMoney 的实例一旦挂进 EA,Init() 就会自动跑,不用你手动去覆盖它。紧接着 EA 会调用 Percent() 设定风险百分比,参数区间是 0.0 到 100.0,默认值 100.0,代表不缩放仓位;这个函数同样无需重写。 真正需要你动手的是 ValidationSettings():所有参数设完后 EA 直接调它,你若加了自定义参数就必须覆盖,且覆盖时务必先调用基类方法并判断返回值。基类只认 Percent,值在允许范围内返回 true,否则 false;只要有一个参数不合法,整个机制就应当停摆返回 false。 InitIndicators() 在参数校验通过后触发,用来建指标和时间序列。基类本身不依赖任何指标,所以原生实现永远返回 true 且不做事;一旦你的风控逻辑要读指标,就得在这里用标准库类创建,并把指针塞进 EA 的指标集,任何一次创建失败都要返回 false。 仓位计算这块,CheckOpenLong / CheckOpenShort 决定多空开仓量,基类没内置算法,通通返回合约最小交易量。CheckReverse() 处理反手,基类逻辑是反到尽可能小的反向仓;CheckClose() 则看浮亏是否超存款百分比,超了就整仓平掉。想要翻倍反手或分批平仓,就得自己覆盖这几个方法。 下面这段是这几个虚函数的声明原型,挂在类里就能照着覆写:

MQL5 / C++
<span class="keyword">class="kw">virtual</span> <span class="keyword">class="type">bool</span> Init(CSymbolInfo* symbol, <span class="keyword">ENUM_TIMEFRAMES</span> period, <span class="keyword">class="type">class="kw">double</span> adjusted_point);
<span class="keyword">class="type">void Percent(class="type">class="kw">double percent)</span>;
<span class="keyword">class="kw">virtual</span> <span class="keyword">class="type">bool</span> ValidationSettings();
<span class="keyword">class="kw">virtual</span> <span class="keyword">class="type">bool</span> InitIndicators(CIndicators* indicators);
<span class="keyword">class="kw">virtual</span> <span class="keyword">class="type">class="kw">double</span> CheckOpenLong(<span class="keyword">class="type">class="kw">double</span> price, <span class="keyword">class="type">class="kw">double</span> sl);
<span class="keyword">class="kw">virtual</span> <span class="keyword">class="type">class="kw">double</span><span class="keyword"></span> CheckOpenShort(<span class="keyword">class="type">class="kw">double</span> price, <span class="keyword">class="type">class="kw">double</span> sl);
<span class="keyword">class="kw">virtual</span> <span class="keyword">class="type">class="kw">double</span> CheckReverse(<span class="keyword">CPositionInfo*</span> position, <span class="keyword">class="type">class="kw">double</span> sl);
<span class="keyword">class="kw">virtual</span> <span class="keyword">class="type">class="kw">double</span> CheckClose(<span class="keyword">CPositionInfo*</span> position);

「把亏损翻倍逻辑写进资金管理类」

把上一节看懂的 CExpertMoney 虚方法落地的第一步,是建一个派生于它的类,覆盖开仓判断接口,实现“正常固定手数、上一笔亏了就双倍”的机制。文件必须放在 Include\Expert\Money\ 下的自建子目录(例如 MyMoneys),后缀用 .mqh,否则向导扫不到。 类里只需暴露一个核心参数:常态手数 Lots。它在构造函数给默认值,通过公共方法读写,并在 ValidationSettings() 中先调基类校验再叠加自己的范围检查,避免非法手数进实盘。 判断是否上一笔亏损、取那笔手数,用一个私有方法 CheckPrevLoss 搞定;CheckOpenLong / CheckOpenShort 都调它,亏了就把建议手数乘 2。但翻倍不能无脑叠:必须卡住 SYMBOL_VOLUME_MAX 服务器上限,以及账户自由保证金是否够用,否则订单会被拒或爆仓。 光有类还不够,要让 MQL5 向导识别,得在文件前 20 行塞一个特定注释块:以 //+--- 起头,依次写 Title=、Type=Money、Name=、Class= 真实类名、空 Page 行、Parameter=Lots,double,0.1,再用 //+--- 收尾。缺任一行向导都当它是普通头文件。 写完重启 MetaEditor 才会触发扫描。EURUSD H1、2010.01.01–2011.05.01 回测里,挂这个模块配合 EMA 信号(PeriodMA=12, StopLoss=145, TakeProfit=430, Lots=0.1)跑出来的权益曲线,能直观看到连亏后加仓对回撤的放大效应。外汇和贵金属杠杆高,这种翻倍法在连续止损时会快速吞噬保证金,实盘前务必在策略测试器里压一遍极端行情。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|                                                                  SampleMoney.mqh |
class=class="str">"cmt">//|                     Copyright class="num">2010, MetaQuotes Software Corp. |
class=class="str">"cmt">//|                                                    [MQL5官方文档] |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="macro">#class="kw">property copyright "Copyright class="num">2010, MetaQuotes Software Corp."
class="macro">#class="kw">property link      "[MQL5官方文档]
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| defines                                                            |
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">// class="macro">#define MacrosHello   "Hello, world!"
class=class="str">"cmt">// class="macro">#define MacrosYear    class="num">2010
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| DLL imports                                                         |
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">// class="macro">#class="kw">import "user32.dll"

常见问题

是分开的。向导把EA拆成信号、交易、资金、 trailing 四个基类,资金管理单独成一个类,改仓位逻辑不用动信号代码。
看类里的 CheckOpen 系列和 LotSize 相关接口,初始化后由它按账户净值和风险比例回手数,具体看生成的 Money 文件逐行。
可以。把EA丢给小布,它能读资金类代码并标出仓位计算与亏损翻倍逻辑里的常见坑,省去人工逐行核对。
写在资金管理类里。原文示例是把翻倍逻辑塞进 CExpertMoney 派生类,信号类只管方向,不碰仓位。
默认按固定风险比例算手数,基类留了接口给你重载;不重写的话就是账户净值乘预设比例得出开仓量。