线性EA变幂系统实战教程
📈

线性EA变幂系统实战教程

用固定分数仓位管理提升MQL5交易系统收益

MQL5 编程 难度 · 进阶 2026-06-25 7 分钟阅读
#MQL5#资金管理#固定分数#面向对象#EA开发

一、什么是线性交易系统与幂交易系统

在MQL5社区语境中,线性交易系统是指那些在一段时间内使用固定手数、其资产净值曲线近似呈现直线上升或平稳形态的策略EA。这类系统经过历史验证能够盈利,但资金增长受限于固定仓位,无法随账户膨胀而加速。幂交易系统(又称指数化系统)则通过仓位规模与账户净值成比例变动的资金管理模型,使净值曲线呈抛物线或指数形态增长。本文所说的“取幂”并非数学严格幂运算,而是指让下单规模适应风险、以几何级数放大收益的资金管理思想。

将线性系统提升为幂系统的核心价值在于:在不改变原交易信号逻辑的前提下,仅替换资金管理模块,就可能让同样胜率的策略在复利效应下获得更高绝对收益。但必须强调,这种提升依赖于原系统本身是正期望的,若原系统亏损,指数化只会加速破产。

二、常见资金管理模型对比

资金管理模型是交易者关于仓位规模、止损设置、预付款与交易成本决策的框架。经典模型包括固定手数、固定分数、固定比率、Kelly百分比以及实际成本法等。固定手数最简单,每单相同手数,净值曲线线性;固定分数让每笔风险为净值的固定比例;固定比率由Ryan Jones提出,以每笔盈利增加合约;Kelly根据胜率与赔率计算最优下注比例;实际成本法考虑点差佣金后定仓。本文专注固定分数的一种MQL5变体。

⚠ 理论局限
社区评论指出Ralph Vince为理论家,其固定分数并非万能。Edward Thorp的实践表明,某些策略需大量交易才显优势,且市场离散性(最小手数、最小点值)会使非线性在微观退化线性。不可迷信任何模型。

三、固定分数模型原理与公式

固定分数仓位规模的核心思想是根据预估风险对操作分级,每笔交易风险占净值的相同百分比。基础方程:N = f * Equity / Trade Risk。其中N为合约数量,f为固定分数(0到1之间),Equity为当前账户净值,Trade Risk为单合约风险金额(如止损距离换算的金钱损失)。该模型有趣属性是:因规模与余额成比例,理论上不会亏光,破产风险为零;但低比例下连赢连输对曲线影响温和。

在MQL5实现中,我们采用变体:净值增长到所谓“水平十”前指数扩大,之后转线性,但始终保持仓位与净值曲线比例增大的基本理念。这避免了极端复利在实盘因手数离散无法执行的尴尬。

四、获取并审视你的线性交易系统

升级前需一个已验证的线性系统作为“幂底”。例如代码库HawaiianTsunamiSurfer在2012年1至3月净值近似直线。本文不从头开发信号,而是假设你已用面向对象范式写出类似EA。若尚未掌握OOP,应先读《另一个MQL5 OOP类》《建立自动新闻交易者》打下基础。你的系统应有状态管理、信号判断与下单模块,我们将注入资金管理层。

✦ 实操建议
用Strategy Tester对原线性系统做至少1年以上回测,确认夏普为正、回撤可控,再谈升级。仅3个月曲线漂亮可能是运气。

五、CEvolution类:面向对象资金管理中心

我们沿用之前文章的CExpansion设计,新增CEvolution类追踪临时信息并实现资金逻辑。因固定分数风险比例随净值变化,仓位可变,故逻辑必须置于CEvolution内。类保护成员含m_status(EA状态)、m_expEquityLevel(指数净值级别枚举)、m_originalEquity(初始净值)、m_lotSize(当前手数)。构造时记录原始净值:m_originalEquity=AccountInfoDouble(ACCOUNT_EQUITY)。

CalcEquityGrowth计算相对原始净值的增长百分比:return NormalizeDouble(currentEquity*100/m_originalEquity-100,2)。RefreshExpEquityLevel依增长刷新级别(LEVEL_ONE至LEVEL_TEN),RefreshLotSize依级别刷新手数。级别枚举如下:

enum ENUM_EXP_EQUITY_CURVE_LEVEL
  {
   LEVEL_ONE,
   LEVEL_TWO,
   LEVEL_THREE,
   LEVEL_FOUR,
   LEVEL_FIVE,
   LEVEL_SIX,
   LEVEL_SEVEN,
   LEVEL_EIGHT,
   LEVEL_NINE,
   LEVEL_TEN
  };

类头文件节选展示结构:

class CEvolution
  {
protected:
   ENUM_STATUS_EA                   m_status;
   ENUM_EXP_EQUITY_CURVE_LEVEL      m_expEquityLevel;
   double                           m_originalEquity;
   double                           m_lotSize;
public:
   CEvolution(ENUM_STATUS_EA status,ENUM_EXP_EQUITY_CURVE_LEVEL exp_equity_level);
   ~CEvolution(void);
   ENUM_STATUS_EA                   GetStatus(void);
   double                           GetLotSize(void);
   double                           CalcEquityGrowth(double currentEquity);
   void                             RefreshExpEquityLevel(double currentEquity);
   void                             RefreshLotSize();
  };

构造函数示例:

CEvolution::CEvolution(ENUM_STATUS_EA status,ENUM_EXP_EQUITY_CURVE_LEVEL exp_equity_level)
  {
   m_status=status;
   m_expEquityLevel=exp_equity_level;
   RefreshLotSize();
   m_originalEquity=AccountInfoDouble(ACCOUNT_EQUITY);
  }

增长计算方法:

double CEvolution::CalcEquityGrowth(double currentEquity)
  {
   return NormalizeDouble(currentEquity * 100 / m_originalEquity - 100,2);
  }

六、在EA中集成与调用幂逻辑

在EA的OnTick中,先刷新进化对象再下单。典型调用:

GetEvolution().RefreshExpEquityLevel(AccountInfoDouble(ACCOUNT_EQUITY));
GetEvolution().RefreshLotSize();

下单时用手数获取方法替代固定值,例如:

switch(GetEvolution().GetStatus())
     {
      case BUY:
         tp = ask + m_takeProfit * _Point;
         sl = bid - m_stopLoss * _Point;
         GetTrade().PositionOpen(GetBrain().GetSymbol(),ORDER_TYPE_BUY,m_evolution.GetLotSize(),ask,sl,tp);
         break;
      case SELL:
         sl = ask + m_takeProfit * _Point;
         tp = bid - m_stopLoss * _Point;
         GetTrade().PositionOpen(GetBrain().GetSymbol(),ORDER_TYPE_SELL,m_evolution.GetLotSize(),bid,sl,tp);
         break;
      case DO_NOTHING:
         break;
     }

我们将指数化系统重命名为ExponentialHawaiian,以区分原线性版本。注意手数需经NormalizeDouble与经纪商最小手数对齐,否则OrderSend报错。

七、回测验证与稳定性边界

添加OO逻辑后必须回测。ExponentialHawaiian在2012年1-3月净值曲线呈指数,原系统线性。关键警告:当指数条件不再成立(如曲线转跌或震荡),系统不稳定,理论破产风险再现。因此实盘需监控净值级别,若跌破LEVEL_ONE应考虑暂停或降f值。

⚠ 回测坑点
仅用3个月回测展示优势具误导性。应跑10年或多品种多周期。且MT5测试器若用固定点差,忽略离散手数限制,实盘可能不及预期。

八、与其他方案及社区争议的思考

社区用户GaryKa指出:对价格图表非线性缩放终归头寸管理,但市场离散使长期退化线性。Yury Reshetov强调Vince非实战家,Thorp的Kelly实践更可靠,固定分数非普适。我们认同:本文提供的是工具而非圣杯。若原系统期望为负,任何幂化加速死亡。建议读者结合自己系统测试,而非盲目崇拜理论。

对比直接改手数公式的面向过程写法,OO的CEvolution优势在状态封装、易扩展(如加LEVEL_ELEVEN)、与现有Brain/Trade类解耦。若你系统非OO,可提取函数但不如重构优雅。

九、部署检查清单与结语

今天我们学会通过固定分数变体将线性系统升级为幂系统。再次提醒:先读OOP基础文章,严格测试。资金管理放大的是概率优势,而非创造优势。愿你的净值曲线优雅向上。

常见问题

创建CEvolution类,构造时记录m_originalEquity=AccountInfoDouble(ACCOUNT_EQUITY);在OnTick调用RefreshExpEquityLevel与RefreshLotSize,用GetLotSize()替代固定手数下单,并归一化到经纪商最小手数。
固定分数仅理论破产风险为零,若原系统负期望或指数条件失效(如净值跌破LEVEL_ONE),仓位仍按比例放大亏损。需多周期回测并实盘监控级别,不可迷信模型。
它是ENUM_EXP_EQUITY_CURVE_LEVEL枚举的第十级,代表净值增长到达某阈值后系统从指数扩仓转为线性,避免极端手数无法执行。具体阈值在RefreshExpEquityLevel内依据CalcEquityGrowth百分比映射。
固定分数每笔风险为净值固定比例f,简单稳健;Kelly按胜率赔率算最优比,波动大。实战常折半Kelly。若策略交易次数少、离散性高,固定分数变体更务实,如本文MQL5实现。