MT4自动交易系统EA源码解析:从策略骨架到二次开发

发布时间:2026/10/18 11:45:04
MT4自动交易系统EA源码解析:从策略骨架到二次开发
简介面向MT4平台的外汇自动交易学习与应用这套资源整合了多个自动交易系统EA及其配套文档适合希望借助程序化策略提升交易效率、降低情绪干扰的初学到进阶交易者。压缩包共151个文件包含53个mq4策略源码、51个ex4可执行文件以及tpl模板、doc说明、rar打包脚本与txt配置等整体约16.99MB便于在MetaTrader 4中直接导入、测试与修改。已有998人下载学习可参考他人使用反馈。资源中既有海豚交易系统等成熟策略的规则讲解与录音对照也有正确理解亏损、交易损失提示等风控与纪律文档并附有多个EA源码与编译版本方便用户理解逻辑、回测优化或直接挂载运行。通过这套资料读者可以掌握EA的编写、安装、监控与参数调整思路同时建立对自动交易风险的正确认知为实盘应用打下基础。1. MT4 自动交易系统一个 EA 包拆开之后的真实骨架把 EA 拖进 MT4 图表、点亮自动交易按钮账户就开始自己开仓平仓——这个画面听着很爽但真正上手的人都知道网上能找到的 EA 十个里有八个要么不开单、要么一开单就亏剩下两个还是加密过的黑匣子想改一行参数都无从下手。这套资源包是某开发者长期跑过的 MT4 自动交易系统合集包含六个可直接编译的 EA 源码和配套说明覆盖趋势跟踪、网格、突破、马丁格尔四类主流策略。对想研究 EA 自动交易、需要一套「能跑起来还能二次开发」模板的人来说它比那种下载下来只有 ex4 文件的资源靠谱得多。2. 项目构成与技术栈MQL4 文件体系、订单生命周期和六个策略的分工2.1 MQL4 编程模型EA 的四个入口函数MQL4 是 MT4 平台内置的类 C 语言EA 本质上是一个事件驱动脚本平台的行情推送会触发对应的回调函数。新版 build 600 之后的 MT4 全部采用事件函数模型核心入口有四个OnInit()负责参数初始化和资源申请OnDeinit()负责卸载时清理指标句柄、定时器等资源OnTick()是策略主函数、每个报价进来都会触发一次OnTimer()则适合那些不依赖报价、按固定时间间隔运行的系统。一个最精简的 EA 骨架长这样#property strict input double RiskPercent 1.0; // 每笔交易占用账户净值的百分比 input int MagicNumber 202401; // 订单标识用来区分是不是本EA下的单 int OnInit() { // 在这里加载指标句柄、读取外部文件 return INIT_SUCCEEDED; } void OnDeinit(const int reason) { // 释放 IndicatorBuffers、删除定时器 } void OnTick() { // 每个新报价进来都会触发一次 }注意#property strict这一行。旧版 MQL4 允许隐式声明变量加上 strict 之后所有变量必须显式声明编译器会帮你抓出很多手误。参数区用input关键字声明这样 EA 拖到图表上时参数会出现在输入框里不用改代码就能调。MagicNumber 是整个订单管理体系里最关键的数字。一个账户可能同时挂三个不同品种的 EA平台不会帮你区分订单是谁创建的只能靠 MagicNumber 过滤。后面所有订单统计函数都会带上这个参数它相当于每个 EA 实例的身份证号。2.2 六个 EA 的文件清单与策略分工这套资源包不是单一策略而是一个策略组合。拆开目录后你会看到以下文件文件策略类型适用行情风险等级TrendFollowEA.mq4双均线趋势跟踪趋势明朗的单边行情低GridEA.mq4网格交易震荡行情中BreakoutEA.mq4唐奇安通道突破趋势启动初期中高MartingaleEA.mq4马丁格尔加仓震荡行情高CommonLib.mqh公共函数库订单管理 / 资金管理—ReadMe.txt使用说明与参数表——四个策略的定位差异很明确。TrendFollowEA 是主力适合挂在欧美这种波动相对平滑的主流品种上慢慢跑GridEA 和 MartingaleEA 都是赚震荡的钱但一个靠固定间距挂单、一个靠逆势加仓摊薄成本两者风险模型完全不同BreakoutEA 赌的是「横盘结束的那一下」开仓频率低但单笔利润预期高。设计上这六套 EA 共享同一个CommonLib.mqh里面集中了订单统计、手数计算、日志输出这类公共逻辑。二次开发时改公共库所有 EA 同时生效这也是我在源码里优先看CommonLib.mqh的原因。2.3 订单统计倒序遍历与双重过滤公共库里第一个值得看的函数是订单统计。所有 EA 在下单前都要先问一句「我是不是已经持有仓位了」这个问题看起来简单但实现上有几个细节容易翻车int CountOpenOrders(int magic) { int count 0; for(int i OrdersTotal() - 1; i 0; i--) { if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue; if(OrderSymbol() Symbol() OrderMagicNumber() magic) count; } return count; }第一循环必须倒着来。OrdersTotal()返回当前账户所有挂单和持仓的总数如果在循环体内部平仓或删单订单集合的长度会变化正序遍历会漏单。第二OrderSelect的第三个参数MODE_TRADES表示只扫描已成交的持仓单挂单属于MODE_PENDING这是两个集合。第三OrderSymbol() Symbol()这句过滤很关键——一个 EA 挂在 EURUSD 图表上不应该去数 GBPUSD 的订单数否则两个品种各挂一个 EA 就会互相干扰。MagicNumber 的过滤是第二道保险。即使你把同一个 EA 分别挂在 EURUSD 和 GBPUSD 两个图表上只要两边的 MagicNumber 设置成不同值各自统计到的订单就是独立的。2.4 架构上的一个设计取舍参数集中到 input 区我拆这套 EA 时注意到一个习惯所有可调参数全部用input暴露出来代码里几乎看不到硬编码的数字。以 TrendFollowEA 为例输入参数区是这样的input int FastMAPeriod 10; // 快线均线周期 input int SlowMAPeriod 30; // 慢线均线周期 input int InitialStopPips 250; // 初始止损点数 input int TakeProfitPips 500; // 初始止盈点数 input int UseTrailingStopPips 150; // 移动止损触发距离 input double RiskPercent 1.0; // 风险比例 input int MagicNumber 202401; // 订单标识这个设计直接决定了后续调优的体验。回测优化器需要反复修改参数组合如果策略逻辑里混了硬编码数值优化器根本碰不到那个变量。把参数全部提到 input 区策略测试器可以在几万组参数组合里自动搜索最优解不需要一行一行改代码。这算是一个架构层面的成熟标志。3. 核心代码逐段拆解趋势 EA 从信号判断到移动止损的完整链路3.1 信号生成双均线交叉用「收盘确认」写法TrendFollowEA 下单逻辑的第一步是判断方向。双均线交叉是最简单的趋势信号——快线上穿慢线做多快线下穿慢线做空。问题是怎么判断「上穿」才算数。很多新手 EA 直接对比当前 K 线的两条均线值只要快线在慢线上方就开多结果一根 K 线内部均线可能反复交叉好几次单量瞬间翻倍。这套 EA 用的是收盘确认写法bool BuySignal() { // 用已收盘K线判断不使用当前正在形成的K线 double fast1 iMA(Symbol(), 0, FastMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 1); double slow1 iMA(Symbol(), 0, SlowMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 1); double fast2 iMA(Symbol(), 0, FastMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 2); double slow2 iMA(Symbol(), 0, SlowMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 2); return (fast2 slow2 fast1 slow1); }iMA的参数顺序是品种、周期、均线周期、位移、均线类型、价格类型、K线序号。最后这个 shift 参数是核心——1表示上一根已收盘 K 线2表示再上一根。信号成立的条件是「第二根 K 线收盘时快线还在慢线下方第一根 K 线收盘时快线已经上穿慢线」也就是交叉发生在上一个已完成周期内。这套写法的价值在于它把信号确定在了「某根 K 线收盘的那一刻」。回测和实盘用的是同一套数据不会出现实盘中 K 线走了一半均线交叉、信号闪烁的问题。这是一个避免信号重绘的血泪经验。3.2 开仓与止损OrderSend 的参数顺序不能记错信号确认后进入开仓流程。趋势 EA 通常在下单的同时就把初始止损和止盈带进去避免「先开仓再改单」的中间状态void TryOpenTrade() { if(CountOpenOrders(MagicNumber) 0) return; double lot CalcLotSize(RiskPercent); if(BuySignal()) { double entry Ask; double sl entry - PipsToPrice(InitialStopPips); double tp entry PipsToPrice(TakeProfitPips); int ticket OrderSend(Symbol(), OP_BUY, lot, entry, 3, sl, tp, TrendFollowEA, MagicNumber, 0, clrGreen); if(ticket 0) Print(开仓失败错误码, GetLastError()); } else if(SellSignal()) { double entry Bid; double sl entry PipsToPrice(InitialStopPips); double tp entry - PipsToPrice(TakeProfitPips); int ticket OrderSend(Symbol(), OP_SELL, lot, entry, 3, sl, tp, TrendFollowEA, MagicNumber, 0, clrRed); if(ticket 0) Print(开仓失败错误码, GetLastError()); } }OrderSend的十一个参数按顺序是品种、订单类型、手数、开仓价格、最大滑点、止损价、止盈价、订单注释、MagicNumber、过期时间、箭头颜色。新手最容易栽在「开仓价格」上——做多要用Ask做空要用Bid方向反了订单会被直接拒掉。滑点参数填的是允许的价格偏差点数回测时可以填 0实盘建议填 3 到 5太小会频繁出现 requote 导致订单提交失败。止损止盈的计算逻辑是做多时止损在入场价下方、止盈在入场价上方做空反过来。代码里PipsToPrice负责把「点数」换算成「价格差」因为不同品种的小数位不一样后面会单独讲。开仓失败时Print输出错误码这一步不是为了美观是为了在 MT4 的「专家」标签页里快速定位问题。GetLastError()返回 130 表示止损距离过近返回 138 表示重新报价返回 146 表示交易繁忙常见错误码我后面避坑章节会再说。3.3 移动止损用已收盘 K 线跟踪利润固定止盈只能拿住一小段利润趋势行情里最忌讳提前下车。这套 EA 的移动止损模块负责在行情朝有利方向走时不断抬高止损线把浮动利润锁住void TrailingStop() { double dist PipsToPrice(UseTrailingStopPips); for(int i OrdersTotal() - 1; i 0; i--) { if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue; if(OrderSymbol() ! Symbol() || OrderMagicNumber() ! MagicNumber) continue; if(OrderType() OP_BUY) { double newSL High[1] - dist; double oldSL OrderStopLoss(); if(newSL oldSL _Point) OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrNONE); } else if(OrderType() OP_SELL) { double newSL Low[1] dist; if(newSL OrderStopLoss() - _Point || OrderStopLoss() 0) OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrNONE); } } }High[1]是上一根已收盘 K 线的最高价Low[1]是最低价。用已收盘 K 线而不是当前实时价格能避免盘中瞬间插针造成的虚高或虚低——价格拉一个长上影再回落移动止损应该以收盘为锚点而不是被影线骗一次。修改止损前先判断newSL oldSL _Point加一个最小变化量的判断。这个细节很重要如果不检查就直接OrderModify行情每跳动一次就会触发一次止损修改请求不仅消耗平台 API 调用次数某些经纪商还会对频繁修改订单收额外费用。3.4 手数计算以损定量的仓位管理仓位管理直接决定账户能不能活过连续亏损。这套 EA 用的是「以损定量」模型——先确定这单我愿意亏多少钱再根据止损距离反推手数double PipsToPrice(int pips) { int factor (_Digits 5 || _Digits 3) ? 10 : 1; return pips * _Point * factor; } double CalcLotSize(double riskPercent) { double riskMoney AccountBalance() * riskPercent / 100.0; double stopDist PipsToPrice(InitialStopPips); double tickValue MarketInfo(Symbol(), MODE_TICK_VALUE); double rawLot riskMoney / (stopDist * tickValue); double minLot MarketInfo(Symbol(), MODE_MINLOT); double maxLot MarketInfo(Symbol(), MODE_MAXLOT); double lotStep MarketInfo(Symbol(), MODE_LOTSTEP); double lot MathFloor(rawLot / lotStep) * lotStep; return NormalizeDouble(MathMax(minLot, MathMin(maxLot, lot)), 2); }PipsToPrice里那个 factor 是很多新手算错的地方。5 位报价的品种_Point是 0.00001一个标准点pip等于 10 个 point4 位报价的品种_Point是 0.0001一个标准点等于 1 个 point。如果不做这个换算止损距离会差 10 倍仓位计算也跟着全错。CalcLotSize的核心逻辑是账户余额 × 风险百分比 ÷止损距离 × 每手每点价值 手数。MODE_TICK_VALUE表示每手一个 point 变动对应的货币价值这个值由经纪商根据品种计算不能拍脑袋写死。算出来的原始手数还要做三件事向下取整到lotStep的整数倍、限制在MODE_MINLOT和MODE_MAXLOT之间、NormalizeDouble修正浮点误差。这一系列代码组合起来就是这套趋势 EA 的完整交易链路收盘确认信号 → 以损定量算手数 → 带止损止盈开仓 → 收盘 K 线跟踪移动止损。理解这条链路后面改任何参数都有抓手。4. 部署与运行把 EA 装进 MT4、回测验证到挂载图表的完整流程4.1 文件放置与编译拿到源码后第一步不是直接打开 MT4 拖文件而是先找到数据目录。MT4 的安装目录和可写数据目录可能是分离的最稳妥的方法是打开 MT4 客户端菜单栏「文件 → 打开数据文件夹」这才是当前账户真正使用的目录。打开后按路径放置文件# 目录结构 MQL4/ ├── Experts/ # 放 .mq4 源码和 .ex4 编译产物 │ ├── TrendFollowEA.mq4 │ ├── GridEA.mq4 │ ├── BreakoutEA.mq4 │ └── MartingaleEA.mq4 └── Include/ # 放公共头文件 └── CommonLib.mqh放置完用 MetaEditor 打开 .mq4 文件按 F7 或点工具栏上的「编译」按钮。编译成功会在同一目录生成同名 .ex4 文件底部信息栏显示「0 errors, 0 warnings」。如果报错先看是不是CommonLib.mqh没放进 Include 目录——这个头文件找不到是最常见的编译错误来源。这里有个值得强化的习惯永远保留源码而不是直接用下载来的 .ex4。MT4 每个 build 版本对 ex4 的兼容性要求很严格旧版编译的 ex4 在新版客户端会被拒载。手上有 .mq4 源码换电脑、换平台、升级客户端之后自己重新编译一次就能继续用这是「源码在手、心里不慌」的道理。4.2 挂载到图表并开启自动交易编译通过后回到 MT4左侧「导航器」窗口展开「智能交易系统」能看到刚才编译的 TrendFollowEA。把它直接拖到目标品种图表上会弹出参数设置界面快线均线周期、慢线均线周期默认 10 和 30如果做 H4 级别可以放大到 20 和 50初始止损点数、初始止盈点数按止损比例 1:2 设置移动止损触发距离建议不小于初始止损的 60%风险比例默认 1.0意思是每单最多亏账户净值的 1%MagicNumber每次挂载实例必须改成不同值确认弹窗里有「允许实时自动交易」选项勾选它。同时检查工具条上的「自动交易」按钮必须显示为绿色图标。这两处任何一个没开启EA 都不会真正下单。挂载完成后图表右上角显示一个笑脸图标表示 EA 正常运行显示哭脸说明策略报错或禁止交易。此时打开「工具箱」窗口的「专家」标签页能看到 EA 的初始化日志和每次开仓失败的错误信息这里就是 EA 的黑匣子探针。4.3 策略测试器回测按策略类型选择报价模型回测是验证 EA 能不能跑的第一步。在 MT4 里按 CtrlR 打开策略测试器选择要测试的 EA、品种、周期、时间范围和初始资金最关键的一步是设定「模型」类型模型类型原理适用场景每个报价Every tick按历史逐笔报价回放网格 / 马丁等高频加仓策略1分钟OHLC用1分钟K线的四个价格模拟趋势跟踪类中低频策略控制点Control Points只按生成的点位执行快速粗筛结果偏差大趋势 EA 用「1分钟OHLC」大体够用但网格 EA 和马丁 EA 必须用「每个报价」模式。后者的开仓逻辑对价格路径极其敏感——先插针还是先震荡直接决定加仓次数和浮亏深度用 1 分钟 OHLC 会严重低估风险。回测跑完看报告时不要只盯着净利润。重点看三个指标获利因子Profit Factor最好大于 1.5、最大回撤Max Drawdown不能超过账户的 30%、恢复因子Recovery Factor越高越好。如果净利润很高但回撤也很大这个 EA 离爆仓只差一次连续亏损。回测报告还有一个容易被忽略的细节交易次数。一个策略如果回测五年只开了十几次仓样本量太小统计上没有说服力。趋势 EA 尤其容易这样遇到这种情况可以适度缩小均线周期或放宽信号滤波条件让交易频率提高到至少一个月 4 到 5 次再重新评估结果。4.4 参数优化的边界遗传算法不是万能钥匙策略测试器的「优化」功能可以自动搜索最优参数组合。勾选优化、设定每个参数的起止范围和步进MT4 会穷举或使用遗传算法跑几千组组合。这个功能好用但也最容易把人带进过拟合的坑。我见过太多人把回测里的最优参数组合直接搬上实盘结果实盘表现和回测差一大截。原因是优化器搜索的是「历史数据上表现最好」的参数但未来行情不会完全复刻历史。一个负责任的优化流程是这样的先把数据分成两段前 70% 用来优化找参数后 30% 用来验证参数如果验证段的表现跟优化段差距不大才说明参数有泛化能力。这套流程叫 out-of-sample 验证在 MT4 里就是跑两次回测、换不同的起始时间而已。5. 实战踩坑排查回测盈利但实盘亏损的五个常见原因5.1 回测曲线很漂亮一上实盘就稳定亏损现象是策略测试器里跑出漂亮的资金曲线年化回报 40%最大回撤不到 15%结果挂到真实小账户上跑了一个月稳定亏损连回测十分之一的水平都达不到。问题通常出在三个环节。第一是信号用了未来函数比如用当前正在形成的 K 线去判断均线交叉回测时这条 K 线的最终收盘数据已经存在了程序「偷看」了未来数据。第二是回测模型太粗糙用了「仅开盘价」或「1分钟OHLC」去跑一个对价格路径高度敏感的策略。第三是回测里没计入点差和滑点每次开仓平仓都少算几美元一百笔交易下来差距就出来了。解决方法是回头逐项排查。信号计算里所有 K 线序号必须大于等于 1绝不使用当前未收盘 K 线回测模型切到「每个报价」模式点差设置为当前品种的常见水平EURUSD 通常在 10 到 15 个 point同一参数在细模式下重跑一次如果结果和粗模式差异超过 30%说明策略对报价噪声太敏感需要加滤波条件。5.2 EA 拖到图表上没有任何反应现象是图表右上角没有笑脸图标或者图标有了但「专家」标签页里没有任何输出日志EA 像一块石头。原因就那么几个。最常见的 .mq4 没编译、导航器里显示的是源码文件而不是可执行 EA其次是工具条上的「自动交易」按钮是红色禁用状态还有一种情况是参数里把 MagicNumber 设成了跟已有持仓一样的值导致CountOpenOrders返回数量大于 0开仓条件被自己堵死。解决流程先在 MetaEditor 里按 F7 确认编译生成 .ex4再确认自动交易按钮是绿色最后打开「专家」标签页看有没有报错日志。一个合格 EA 的OnInit()里应该至少输出一行参数摘要比如用Print(TrendFollowEA loaded, SlowMA, SlowMAPeriod)连初始化日志都没有的 EA调试起来等于蒙着眼睛找路。5.3 多图表挂载同一 EA 重复开仓现象是同时把 TrendFollowEA 挂在 EURUSD 的 H1 和 M15 两张图表上结果一个信号来了两个实例同时开仓仓位直接翻倍。根源是 MagicNumber 没区分。两个实例都用了默认的 202401各有各的持仓统计CountOpenOrders互相统计不到对方。另一个常见根源是信号本身没有做「单根 K 线只触发一次」的限制即使只有一个图表均线交叉信号在当前 K 线内反复满足条件OnTick 每次报价都会触发一次开仓逻辑。解决方法是双管齐下。第一每个图表实例设置独立的 MagicNumber第二在 OnTick 里记录上一次开仓的 K 线时间只有 K 线时间发生变化才重新评估信号。判断逻辑可以这样写datetime lastBarTime 0; void OnTick() { if(lastBarTime Time[0]) return; lastBarTime Time[0]; // 后续策略逻辑 }5.4 换了一家经纪商同一套 EA 表现完全不同现象是这个 EA 在某经纪商回测表现良好换另一家之后同样的品种、同样的参数信号频繁错位开仓点位完全对不上。核心原因是不同经纪商的 MT4 服务器时区不一样。有的服务器用 GMT2有的用 GMT3K 线的开盘时间因此错开一两个小时。日线级别的差异还不明显H1 以下的策略入场点会被明显影响。另一个问题是报价精度——5 位报价和 4 位报价的差价不同_Point值不同点位换算和止损距离全要重新校准。解决思路是放弃对绝对时间的依赖改用 K 线本身的结构来定义信号。止损距离这类参数也从固定点数改成动态计算常见的做法是用 ATR 自适应。iATR取最近 N 根 K 线的平均波幅作为止损距离价格精度和时区差异就不再影响核心逻辑了。5.5 网格和马丁 EA 扛不过单边行情现象是网格 EA 在震荡行情里稳定盈利账户净值曲线平滑向上结果遇上一次几百点的单边行情连续加仓把净值和保证金一起打穿直接爆仓。这不是 EA 的 bug而是策略模型本身的数学特性。网格和马丁的盈利逻辑建立在「价格最终会回到持仓均价附近」的假设上震荡行情里这个假设成立一旦进入单边趋势每一层加仓都扩大浮亏仓位越重、回本需要的反弹幅度越大最终超出账户承受极限。解决这个风险要从参数层面做硬限制。至少三个参数必须强制设置最大加仓层数MaxLevels、最大总手数占净值比例MaxTotalLotsPercent、净值回撤保护阈值EquityProtectionPercent。我一般会把马丁 EA 的净值保护阈值设为 30%一旦浮亏触及立即全部平仓宁可亏损出局也不深套。回测时专门找历史长周期里最极端的单边行情把回测起止时间对准那段走势专门检验仓位模型能不能扛过去。扛不住就降加仓倍数或缩小间距这是马丁类 EA 唯一的保命手段。6. 二次开发技巧从均线改成布林带外加仓位保护改造想把这套资源变成自己的东西最简单的起点是改造 TrendFollowEA 的信号模块。均线交叉换成布林带突破只需要替换BuySignal()和SellSignal()两个函数其他开仓、止损、手数计算全部复用。原版用两条均线判断趋势方向改成布林带后逻辑变成「价格突破上轨做多、突破下轨做空」bool BuySignal() { double upper iBands(Symbol(), 0, 20, 2, 0, PRICE_CLOSE, MODE_UPPER, 1); double prevUpper iBands(Symbol(), 0, 20, 2, 0, PRICE_CLOSE, MODE_UPPER, 2); // 上一根K线收盘价突破上轨且再上一根还没突破 return (Close[1] upper Close[2] prevUpper); }iBands的参数依次是品种、周期、均线周期 20、标准差倍数 2、位移 0、价格类型、轨道类型、K线序号。MODE_UPPER取上轨MODE_MAIN取中轨MODE_LOWER取下轨。逻辑上要求Close[2] prevUpper确保突破只发生在上一个已收盘周期内延续了收盘确认的无未来函数纪律。另一个值得加的改造是账户级净值保护。原版 EA 只控制单笔风险但如果连续亏损账户还是可能快速缩水。在OnTick()最前面加一段void OnTick() { double equity AccountEquity(); double balance AccountBalance(); if(balance 0 equity balance * 0.3) { CloseAllOrders(MagicNumber); Print(净值回撤超过阈值全部平仓保护); return; } // 原有策略逻辑 }CloseAllOrders的写法和CountOpenOrders对称遍历所有持仓、按 MagicNumber 过滤后逐个调OrderClose。用AccountEquity而不是只看浮亏是因为保证金占用和点差变化也会影响实际权益。改完一定要验证。我的习惯是先把原版和改版在同一个时间段、同一个测试参数下各跑一遍回测对比获利因子和最大回撤而不是只看净利润谁高。然后手动把回测模式切到「每个报价」剔除掉信号闪烁带来的虚假收益。从那以后我每次改策略都强制走一遍这个流程布林带版和均线版在趋势行情里各有优势但至少我能说清楚区别在哪而不是靠感觉拍板。希望帮到你。本文还有配套的精品资源点击获取