价格行为分析工具箱开发(第三部分):分析大师 EA(基础篇)
「这套EA到底在解决什么」
这一篇是价格行为分析工具箱系列的第三部,主角从指标、脚本换成了EA:分析大师。前面两篇里我们做过手动或半自动的工具,这一篇把它固化成可在MT5里自动跑的分析型EA。 原文给出的发布时间是2025年8月12日10:40,社区里显示阅读量1182、评论9条,作者Christian Benjamin。也就是说,这套东西不是纸上谈兵,已有一定实盘读者基数在盯。 本小节只是开篇定位:回顾原有分析工具、给出分析大师的概览、随后直接进EA代码分解与测试。外汇与贵金属市场高杠杆、滑点无常,任何自动分析结论都只是概率参考,不能直接当入场指令。
从一次性脚本到常驻EA的跨越
早先做的分析评论脚本在社区里用得不少,但它有个硬伤:只能在手动启动时跑一次,把指标写进图表后就结束,后续市场变了它不会自己更新。 为了补这个洞,我写了“分析大师”EA。它把原脚本的分析能力保留下来,还额外挂了更多指标,并且每两小时自动刷新一次——脚本做不到持续写入,EA可以常驻后台持续跑。 把两者摆在一起看差异就很清楚:脚本几乎瞬间执行完就终止,不响应报价或计时器事件;EA能监听 OnTick、OnTimer、OnTrade,对市场变化实时反应。脚本若不开仓后就不盯仓位,EA能动态管未平单、跟条件、拉移动止损。 性能上脚本跑完就释放,EA常驻会多吃 CPU 和内存,尤其管很多单或跑复杂算法时。外汇和贵金属波动快、杠杆高,用常驻EA前先想清楚这台机器扛不扛得住持续开销。
◍ 上一版评论脚本到底画了什么
早先那版分析评论脚本,只干一件事:把前一交易日的关键字段摊在图表的竖排表格里。它抓的是前一日开盘价、前一日收盘价、前一日成交量,再叠上当日成交量,以及脚本自己算出来的支撑位和阻力位。 除了表格,脚本还会按前几日的开盘、收盘和交易量推算一个倾向性走势,并在图上直接拉出趋势线。从实盘截图看,它标出的支撑阻力位置基本贴在价格回踩区,方向预测当时呈现偏多倾向,但只是概率性提示,不代表后市必涨。 外汇和贵金属波动受消息面扰动大,这类基于历史量的静态推算在高波动时段容易失效,拿去 MT5 加载时建议先切到日线回看标记贴合度。
「EA比脚本多算的那几件事」
把之前的脚本升级成EA后,原来那些基础读数还会保留,但EA额外扛起了几件脚本干不了的事:实时算市场波动率、点差、账户净值与余额,再按余额倒推出当前能开的最小和最大手数。对做价格行为的老手来说,这几个数不知道,单子就不该点下去。 波动率是统计上数据围绕均值的离散程度。EA内部按标准差思路跑,年化版本就是标准差乘一年交易天数的平方根,常数取约252。它把这套计算自动化,不用你手敲表格。 点差就是买价卖价之差。窄点差意味着进出场成本低、执行更干净,做高频或一天十几笔的人尤其敏感;宽点差直接吃利润,可能逼你换品种或改策略。外汇和贵金属杠杆高,点差跳一动就是实打实的风险,下单前必须看一眼。 手数计算走的是风险管理逻辑:用账户余额、单笔想扛的风险比例、止损距离来反推仓位。函数会先量支撑阻力或入场到止损的间距,StopLossMultiplier还能缩放这个距离。EA每两小时刷一次上述所有数据,你开MT5挂上就能对比自己算的hand数。
把分析EA拆开看内部构造
这段EA把盘前盘后的统计、方向判断、画线以及仓位控制全塞进一个文件里。它会在每次报价触发时调用 UpdateMetrics(),把前一日与当日的开盘、收盘、高低、成交量抓出来,再按价格变动推断市场倾向,并在图上留趋势线。 风险管理部分给了三个外部参数:RiskPercentage 默认 1.0,即单笔按账户余额的 1% 去估风险;StopLossMultiplier 默认 1.0,用来拉伸止损距离;ATR_Period 默认 14,是常见的平均真实波幅窗口。外汇与贵金属杠杆高,实盘把 RiskPercentage 直接拉满极易爆仓,建议先开 MT5 用 0.1 这类小值回测。 OnInit 只做一件事——把 lastUpdateTime 清零;OnDeinit 则 ObjectsDeleteAll(0) 清掉本图表所有对象,避免残留线条干扰下一轮加载。下面代码逐行拆一下关键声明与框架。
class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Analytics Master EA.mq5| class=class="str">"cmt">//| Copyright class="num">2024, Christian Benjamin| class=class="str">"cmt">//| https://www.mql5,com| class=class="str">"cmt">//+------------------------------------------------------------------+ class="macro">#class="kw">property copyright "class="num">2024, MetaQuotes Software Corp." class="macro">#class="kw">property link "[MQL5官方文档] class="macro">#class="kw">property description "EA for market analysis and commenting" class="macro">#class="kw">property version "class="num">1.0" class="macro">#class="kw">property strict class=class="str">"cmt">// Inputs for risk management input class="type">class="kw">double RiskPercentage = class="num">1.0; class=class="str">"cmt">// Percentage of account balance to risk per trade input class="type">class="kw">double StopLossMultiplier = class="num">1.0; class=class="str">"cmt">// Multiplier for determining the stop loss distance input class="type">int ATR_Period = class="num">14; class=class="str">"cmt">// Period for ATR calculation class=class="str">"cmt">// Global variables for storing values class="type">class="kw">datetime lastUpdateTime = class="num">0; class="type">class="kw">double previousDayOpen, previousDayClose, previousDayHigh, previousDayLow; class="type">class="kw">double previousDayVolume; class="type">class="kw">double currentDayVolume; class="type">class="kw">double support, resistance; class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Expert initialization function | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">int OnInit() { lastUpdateTime = class="num">0; class=class="str">"cmt">// Set the initial update time class="kw">return INIT_SUCCEEDED; } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Expert deinitialization function | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void OnDeinit(const class="type">int reason) { ObjectsDeleteAll(class="num">0); class=class="str">"cmt">// Clean up any drawn objects on the current chart } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Expert tick function | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void OnTick() { UpdateMetrics(); class=class="str">"cmt">// Call to the function that fetches and displays the metrics } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Update metrics and display them | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void UpdateMetrics() { class=class="str">"cmt">// Check if class="num">2 hours have passed since the last update