一步步学习如何利用公允价值缺口(FVG)或市场不平衡性来交易的策略:一种聪明资金的交易方法(基础篇)
「用 FVG 抓聪明资金的失衡缺口」
公允价值缺口(FVG)本质是三根 K 线构成的失衡区:当第三根 K 线的实体完全不回补第一根 K 线另一侧影线时,中间那根 K 线留下的空白就是机构订单没吃完的痕迹。在 MT5 的 M15 以上周期里,这种缺口被回补的概率通常低于 40%,更常见的是价格从中段或直接跳过继续原方向。 这套思路属于“聪明资金”玩法:假设大单不在最优价位成交,而是在失衡区分批吃单,留下可识别的真空带。实战里你开 MT5 调出任意直盘,把三根 K 线规则手动标一下,就能看见欧美对上周在 1.0850 附近留过一处上方 FVG,后续 48 小时内未被回补就走了 60 点。 外汇和贵金属杠杆高,FVG 只是概率倾向不是信号铁律;真要验证,先把图表周期切到 H1,数一周内出现的 FVG 中被回补与未被回补的比例,再决定要不要挂限价单在缺口边缘等。
◍ 用 FVG 搭 EA 前要先理清的事
做基于公允价值缺口(FVG)或市场不平衡性的 EA,本质是把价格行为里的「聪明资金」痕迹转成可执行的算法逻辑。它既不是纯画图分析,也不是只写代码,而是两者叠加:你得先在 K 线里认出失衡区,再把它变成 MT5 能跑的判断条件。 这篇系列会用 MQL5 作为 IDE 编码环境,所有文件最终在 MetaTrader 5 终端执行。所以动手前,本机必须装好 MT5 与 MQL5 编辑器,否则后面贴的代码你连编译都过不了。 我们会顺着几条线走:先定义什么算不平衡,再讲策略逻辑和蓝图,接着落进 MQL5 交易系统,最后给回测结果。你可以边看边开 MT5 新建一个 EA 空模板,把后续代码一段段贴进去验证。
FVG 是怎么被单边踩出来的
公允价值缺口(FVG)本质是买卖盘压力失衡留下的价格真空。当一端流动性被瞬间抽干,另一侧订单持续吞噬报价,就会出现一段没有对手盘承接的单向快拉或快砸。 这种失衡在图表上最直观的信号是实体极长的 K 线——往往伴随波动率骤升,把原有挂单层整个击穿。统计上,M15 周期里实体超过均值 3 倍标准差的 K 线,其后回补该段缺口的概率偏高,但具体回补深度要看后续成交量。 知道缺口由压力差形成,就能反过来用:把它当潜在均值回归区,或突破后的中继歇脚点。外汇与贵金属杠杆高,这类缺口被秒填或延续扩张都可能发生,下单前先在 MT5 历史中心回放验证。
「在 MT5 上认出三根 K 线里的 FVG 区域」
公允价值缺口(FVG)不是指标算出来的,而是价格行为里一段“没被回填”的真空区。它的硬约束是三根具有方向性的 K 线:第一根和第三根留出的引线间距,就是缺口本体。 先在图表找一根实体占比明显的长 K 线,经验上实体占整根 K 线(实体+引线)约 70% 才够“冲力”。这根大 K 线前后各一根相邻 K 线,不能和它完全重叠,但上下边缘允许轻微相交;相邻两根引线之间未覆盖的空间,才是 FVG。 下跌趋势里,前一根 K 线高低点之间的空白区即低估 FVG,价格低于公允值,倾向出现向上回补;上涨趋势反过来,大看涨 K 线后的空白是高估 FVG,市场过热,倾向先回调再延续。外汇与贵金属杠杆高,识别错误就是直接止损,必须在 M1~H1 多周期交叉确认。 出现大看跌 K 线伴随空白,是低估 FVG 信号;大看涨 K 线伴随空白,是高估 FVG。挂单别追在缺口中心,等价格回踩缺口边缘、且吞没形态确认后再动,止损放在第三根引线外。
◍ FVG多空触发与订单布置细则
策略里把FVG分成两类,核心都是先找一根实体显著的驱动K线,再核对其左右相邻K线是否确认了缺口结构。确认后按时间序列算第三根与第一根的差值,若差值落进预设阈值外,算法才把这段区域记为有效FVG并在图上画出来。 看涨FVG用青柠色标,价格回踩缺口下沿时直接市价买入;止盈挂在缺口上沿,止损放在开单价下方,风险回报比固定为1:3。看跌FVG用番茄色标,价格反抽触缺口上沿时市价卖出,止盈在缺口下沿,止损在开单价上方,风险回报比1:10。 两类形态都设了「预定义长度」的存活窗口:若价格在该长度内没回到缺口区,算法就放弃关注,不再挂单。外汇与贵金属杠杆高,这种回测逻辑只代表历史概率倾向,实盘仍需自验。
把FVG逻辑落进MT5的EA骨架
在MT5里写FVG自动识别,先按F4进MetaQuotes语言编辑器,新建时选EA模板,命名后一路下一步到完成,就能拿到空壳开始填策略。开头用 #include <Trade/Trade.mqh> 拿到CTrade类,再拿 #define 把矩形前缀和涨跌颜色固化下来,后面图表上所有FVG对象都靠这个前缀隔离,不会和其他EA画的图形打架。 判定的最低门槛先写成全局变量:minPts=100 点作为失衡最小跨度,FVG_Rec_Ext_Bars=10 表示矩形向右延展10根K线。四个动态数组 totalFVGs[]、barINDICES[]、barTIMEs[]、signalFVGs[] 分别存对象名、索引、时间、是否已发单信号,全程全局可见。 OnInit 只扫图表可见柱。先读 ChartGetInteger(0,CHART_VISIBLE_BARS) 拿到可见Bar数;若 ObjectsTotal 返回0说明图上没矩形,立刻把数组 ArrayResize 清成0,防止上次残留数据污染。随后用前缀删掉旧FVG重画,保证重启EA也能看到历史Set。 看涨FVG判定:第i根最低价 > 第i+2根最高价,且价差点数 > minPts;看跌反之。确认后取中柱(i+1)时间为time1,price1用三元运算符选边界,time2由time1加延展Bar数算出,price2取另一侧边界,对象名拼前缀+创建时间确保唯一。 画完用自写 CreateRec 函数落矩形,再 ArrayResize 扩数组存数据。溢出截断单独写 UpdateRec:若看跌FVG被上方最高价刺穿,就把第二坐标更新到突破K线;数组最后归零待 OnTick 用。 OnTick 只扫最近10根(当前索引+1起),用 fvgExist 标记是否有效。卖单例:看跌设定且买价高于上边界且为首信号,以0.01手市价卖,TP设FVG下边界,SL按1:10风险报酬比放在上方;同根再触不发。设定失效就用 ArrayRemove 删掉对应存储,释放空间。外汇与贵金属杠杆高,实盘前务必在策略测试器用历史数据验证信号逻辑。
class="macro">#include <Trade/Trade.mqh> CTrade obj_Trade; class="macro">#define FVG_Prefix "FVG REC " class="macro">#define CLR_UP clrLime class="macro">#define CLR_DOWN clrRed class="type">int minPts = class="num">100; class="type">int FVG_Rec_Ext_Bars = class="num">10; class="type">class="kw">string totalFVGs[]; class="type">int barINDICES[]; class="type">class="kw">datetime barTIMEs[]; class="type">bool signalFVGs[]; class="type">int visibleBars = (class="type">int)ChartGetInteger(class="num">0,CHART_VISIBLE_BARS); Print("Total visible bars on chart = ",visibleBars); if (ObjectsTotal(class="num">0,class="num">0,OBJ_RECTANGLE)==class="num">0){ Print("No FVGs Found, Resizing storage arrays to class="num">0 now!!!"); ArrayResize(totalFVGs,class="num">0); ArrayResize(barINDICES,class="num">0);