使用TesterWithdrawal() 函数模拟利润提取·综合运用
💸

使用TesterWithdrawal() 函数模拟利润提取·综合运用

(3/3)· 从单笔提款到完整 EA 的资金管理模拟,多数人只测了盈利曲线却漏算了出金

进阶 第 3/3 篇

回测里净值一路向北,实盘却总在提现后节奏全乱——因为标准测试默认资金只进不出。TesterWithdrawal() 正是补上这最后一环的工具,让出金成为可被验证的变量而非盘后拍脑袋。

「把回测摘要写进报告文件」

这段逻辑干的事很直接:把策略测试后的关键数值落盘到报告文件,方便你开 MT5 跑完 EA 后直接翻文本核对,而不是只盯终端里的摘要表。 初始入金、净利、毛利、毛亏先用 DoubleToString 统一保留两位小数输出;毛亏在 GrossLoss>0.0 时才参与计算,盈利因子 ProfitFactor 也只在有亏损时写出,避免除零。 相对回撤用 StringFormat 压成「百分比 (金额)」双精度格式,例如 12.34% (123.45),一眼能看出权益峰谷杀伤。 若开启周期出金(WDR_ENABLE),代码按 day/week/month/quarter/year 映射周期名,再区分固定额与「占入金百分比」两种出金方式;出金次数与累计出金额也一并记录。外汇与贵金属测试请记住:历史回测的高盈利因子不代表实盘概率,杠杆品种回撤可能超预期。 文件写完统一 FileClose 收尾,漏关句柄在 MT5 里会卡住后续写入,建议复制时核对自己的句柄变量名。

MQL5 / C++
  TimeToString(tick.time,TIME_DATE) + "\t\t\t|");
  WriteToReportFile(str);
  class=class="str">"cmt">//----
  WriteToReportFile("| Initial deposit \t\t\t"+DoubleToString(initial_deposit, class="num">2));
  WriteToReportFile("| Total net profit\t\t\t"+DoubleToString(SummaryProfit, class="num">2));
  WriteToReportFile("| Gross profit\t\t\t"+DoubleToString(GrossProfit, class="num">2));
  WriteToReportFile("| Gross loss\t\t\t"+DoubleToString(-GrossLoss, class="num">2));
  if(GrossLoss > class="num">0.0)
    WriteToReportFile("| Profitability\t\t"+DoubleToString(ProfitFactor,class="num">2));
  WriteToReportFile("| Relative drawdown of equity \t"+
                    StringFormat("%class="num">1.2f%% (%class="num">1.2f)", RelEquityDrawdownPercent, MaxEquityDrawdown));
  if(WDR_ENABLE)
    {
     StringInit(msg, class="num">10, class="num">0);
     class="kw">switch(WDR_PERIOD)
       {
        case day:     msg = "day";     break;
        case week:    msg = "week";    break;
        case month:   msg = "month";   break;
        case quarter: msg = "quarter"; break;
        case year:    msg = "year";    break;
       }
     WriteToReportFile(str);
     WriteToReportFile("| Periodicity of withdrawing\t" + msg);
     if(WDR_TYPE == fixed) msg = DoubleToString(WDR_VALUE, class="num">2);
     else msg = DoubleToString(WDR_VALUE, class="num">1) + " % from deposit " + DoubleToString(initial_deposit, class="num">2);
     WriteToReportFile("| Amount of money withdrawn\t" + msg);
     WriteToReportFile("| Number of withdrawal operations \t" + IntegerToString(wdr_count));
     WriteToReportFile("| Withdrawn from account\t" + DoubleToString(wdr_summa, class="num">2));
    }
  WriteToReportFile(str);
  WriteToReportFile(" ");
  FileClose(hReportFile);
}

TesterWithdrawal 对回测对比的干扰与纯化

从多组已执行试验的结果看,在策略测试器里调用 TesterWithdrawal() 会触发计算逻辑的算法变更。若同时对比多个 EA,其中仅部分内置了出金机制,那么按相对回撤做横向比较就会失真——数值里混入了人为抽走资金的噪声。 这个函数真正的价值在于:给定可接受的净值回撤百分比,你能实算出账户可周期性提取多少资金。它相当于给测试注入一种综合不稳定因素,用来压测 EA 在资金被抽离时的生存能力,尤其当你的仓位逻辑依赖余额或净值水平时,多一次出金测试就多一条调参依据。 如果想排除干扰,用前文给出的算法在不计提取的前提下重算相对回撤,就能拿到不受该函数影响的纯值。外汇与贵金属杠杆高、滑点跳空频繁,这类纯值才适合作为跨 EA 对比的基准线。

◍ 最后说句实在话

TesterWithdrawal() 在 MT5 策略测试器里只管「出金」这一件事:调用后测试账户净值按提取额递减,回测曲线会真实反映资金抽离后的权益变化。目前 MQL5 没有对应的反向入金函数,给 TesterWithdrawal() 传负值会被直接忽略,想模拟持续注资得自己改测试框架。 附带 testexpert.mq5(61.54 KB)是可跑的样例,下载进 MT5 按 F7 编译、开策略测试器就能看到出金对净值算法的扰动。外汇与贵金属杠杆品种回测本身高风险,出金模拟不等于实盘资金调度,参数验证请以你自己终端跑出的结果为准。

让小布替你跑这套出金回测
把重复劳动交给小布,你专注决策:小布盯盘已内置策略测试的资金流诊断,打开对应品种页即可看到提款后的净值回撤与再投资边界,不必手动逐次加函数调用。

常见问题

不能。该函数仅在策略测试器中模拟提款,不会影响正常模式下 EA 的实盘账户资金,实盘出金仍需通过券商端操作。
可以。小布盯盘的资金流模块能解析测试报告中的 Withdrawal 费用项,自动标注提款后的可用预付款红线与心理介入阈值,省去人工比对日志。
提取不会执行,返回值表示失败,Journal 打印未成功条目,Results 与报告中不增加 Withdrawal 总额,净值与余额均不变。
设计上不鼓励依赖外部注资的系统,要求存款持续增长的策略本身已偏离稳健资金管理,因此语言层未提供存入模拟函数。
关于单函数参数与基础调用的完整讨论见《使用TesterWithdrawal() 函数模拟利润提取·基础篇》,EA 嵌入示例见《使用TesterWithdrawal() 函数模拟利润提取·实战篇》。