【免责声明】 本文内容仅供技术交流和学习参考,不构成任何投资建议。金融市场存在风险,投资需谨慎。任何基于本文内容的交易决策,均由投资者自行承担风险和责任。
在量化交易的世界里,有一个被很多交易者忽视但极其重要的概念——市场记忆区域。这些区域是价格曾经快速移动或发生重要结构变化的地方,往往成为未来价格回归的关键点位。今天,我们来深入探讨如何通过算法识别这些市场记忆区域。
什么是市场记忆区域?
市场记忆区域(Market Memory Zones)是指价格图表上那些具有特殊意义的区域。当价格快速离开这些区域时,往往会在未来某个时刻重新回到这些区域进行测试。这个概念源于市场微观结构理论,认为价格在特定区域的行为会留下"记忆"。
从技术实现的角度来看,我们主要识别四种类型的记忆区域:
- 位移区域(Displacement Zones):大型冲动性K线形成的区域
- 未填充区域(Unfilled Areas):价格效率缺口,即Fair Value Gap
- 结构转换区域(Structure Transition Zones):市场结构发生变化的转折点
- 流动性扫荡区域(Liquidity Sweep Origins):流动性被扫荡后的反转起点
市场记忆区域示意图如上图所示,不同类型的记忆区域在图表上以不同颜色标记,帮助我们直观地识别价格可能回归的关键位置。
核心算法:位移区域的识别
位移区域是最直观的一种记忆区域。当市场出现一根巨大的K线,且这根K线与前后K线的重叠度很低时,就形成了一个位移区域。
boolIsDisplacementCandle(int bar, constdouble &high[], constdouble &low[],constdouble &open[], constdouble &close[],constlong &tick_volume[], double avg_volume){// 1. 检查最小K线尺寸(基于ATR)double candle_size = high[bar] - low[bar];double min_size = g_current_atr_value * inp_min_candle_size_atr;if (candle_size < min_size) return (false);// 2. 检查与前一根K线的重叠度double overlap_with_prev = CalculateOverlap(high[bar], low[bar], high[bar+1], low[bar+1]);if (overlap_with_prev > 0.3) return (false); // 超过30%重叠则排除// 3. 检查与后一根K线的重叠度if (bar > 0) {double overlap_with_next = CalculateOverlap(high[bar], low[bar], high[bar-1], low[bar-1]);if (overlap_with_next > 0.3) return (false); }// 4. 可选:成交量确认if (inp_filter_by_volume) {double volume_ratio = (double)tick_volume[bar] / avg_volume;if (volume_ratio < 1.5) return (false); // 成交量需达到平均值的150% }// 5. 判断是否为冲动性K线(强烈的方向性移动)bool is_bullish_impulse = (close[bar] > open[bar]) && ((close[bar] - open[bar]) > candle_size * 0.6);bool is_bearish_impulse = (close[bar] < open[bar]) && ((open[bar] - close[bar]) > candle_size * 0.6);return (is_bullish_impulse || is_bearish_impulse);}
这个算法的核心逻辑是:只有当K线足够大(至少是ATR的1.5倍),且与相邻K线的重叠度低于30%时,才被认为是有效的位移区域。同时,我们还可以选择性地加入成交量确认,确保这个位移是有真实资金推动的。
Fair Value Gap:价格效率缺口
Fair Value Gap(FVG)是ICT(Inner Circle Trader)交易理论中的核心概念。它指的是三根K线形成的价格缺口,中间那根K线的价格区间没有被前后两根K线完全覆盖。
boolIsUnfilledArea(int bar, constdouble &high[], constdouble &low[],constdouble &open[], constdouble &close[]){// 寻找Fair Value Gap模式(三根K线形成)if (bar < 2) return (false);// 看涨FVG:中间K线的最高价低于前后两根K线的最低价if (low[bar-1] > high[bar] && low[bar-2] > high[bar]) {return (true); }// 看跌FVG:中间K线的最低价高于前后两根K线的最高价if (high[bar-1] < low[bar] && high[bar-2] < low[bar]) {return (true); }// 替代模式:大K线后跟小重叠K线double candle1_size = high[bar] - low[bar];double candle2_size = high[bar-1] - low[bar-1];if (candle1_size > g_current_atr_value && candle2_size < g_current_atr_value * 0.5) {// 检查第二根K线是否没有填充第一根K线的大部分区间double fill_ratio = CalculateOverlap(high[bar], low[bar], high[bar-1], low[bar-1]);if (fill_ratio < 0.3) return (true); }return (false);}
FVG之所以重要,是因为它代表了价格快速移动时留下的"真空地带"。市场往往会在后续走势中回填这些缺口,这就为我们提供了潜在的交易机会。
结构转换:市场趋势的转折点
结构转换区域识别的是市场趋势发生根本性变化的位置。比如从上升趋势转为下降趋势,或者从下降趋势转为上升趋势。
boolIsStructureTransition(int bar, constdouble &high[], constdouble &low[]){// 至少需要5根K线来确定结构if (bar < 5) return (false);// 检测摆动点bool is_swing_high = IsSwingHigh(bar, high, 3);bool is_swing_low = IsSwingLow(bar, low, 3);if (!is_swing_high && !is_swing_low) return (false);// 检查结构突破if (is_swing_high) {// 检查是否突破前期结构(从更高高点转为更低高点)double prev_swing_high = FindPrevSwingHigh(bar, high, 3);if (prev_swing_high > 0 && high[bar] < prev_swing_high) {return (true); // 形成更低高点 } }if (is_swing_low) {// 检查是否突破前期结构(从更低低点转为更高低点)double prev_swing_low = FindPrevSwingLow(bar, low, 3);if (prev_swing_low > 0 && low[bar] > prev_swing_low) {return (true); // 形成更高低点 } }return (false);}
结构转换的关键在于识别摆动高点和摆动低点的变化。当市场从"更高高点"转为"更低高点"时,通常意味着上升趋势的结束;反之,当市场从"更低低点"转为"更高低点"时,可能预示着下降趋势的结束。
流动性扫荡:市场陷阱的识别
流动性扫荡是市场中最具欺骗性的行为之一。价格会先突破关键支撑或阻力位,触发止损单,然后迅速反转。识别这些流动性扫荡的起点,可以帮助我们找到高质量的反转机会。
boolIsLiquiditySweep(int bar, constdouble &high[], constdouble &low[], constdouble &close[], constdouble &open[]){if (bar < 2) return (false);// 看涨流动性扫荡:扫荡前期低点后收盘高于该低点if (low[bar] < low[bar+1] && close[bar] > low[bar+1] && close[bar] > close[bar+1]) {// 检查反转模式if (close[bar] > open[bar] && (close[bar] - open[bar]) > (high[bar] - low[bar]) * 0.5) {return (true); } }// 看跌流动性扫荡:扫荡前期高点后收盘低于该高点if (high[bar] > high[bar+1] && close[bar] < high[bar+1] && close[bar] < close[bar+1]) {// 检查反转模式if (close[bar] < open[bar] && (open[bar] - close[bar]) > (high[bar] - low[bar]) * 0.5) {return (true); } }return (false);}
流动性扫荡的核心特征是:价格先突破关键水平,然后迅速反转。这种模式往往伴随着强烈的方向性K线,为我们提供了高概率的反转信号。
区域强度的计算
每个识别出的记忆区域都有一个强度评分(0-1之间),这个评分基于多个因素:
// 计算基于K线尺寸相对于ATR的强度double candle_size = high[bar] - low[bar];g_zones[g_zone_count].m_strength = MathMin(candle_size / (g_current_atr_value * 2), 1.0);// 调整区域边界以便更好地可视化double range = g_zones[g_zone_count].m_high - g_zones[g_zone_count].m_low;g_zones[g_zone_count].m_high += range * 0.05; // 增加5%的填充g_zones[g_zone_count].m_low -= range * 0.05;
强度评分越高,说明这个区域的重要性越大,价格回归的概率也相对更高。
实际应用中的注意事项
在实际使用市场记忆区域指标时,有几个关键点需要注意:
区域的有效性:不是所有识别出的区域都会有效。价格可能会完全穿越某些区域,这些区域就会被标记为"已缓解"(mitigated),不再显示。
时间周期选择:不同的时间周期会识别出不同级别的记忆区域。通常建议在多个时间周期上同时观察,找到共振的区域。
结合其他技术指标:记忆区域最好与其他技术分析工具结合使用,比如趋势线、支撑阻力位、成交量分析等。
风险管理:即使识别出了高质量的记忆区域,也不意味着价格一定会回归。始终要做好风险管理,设置合理的止损。
技术实现的关键细节
在代码实现中,我们使用ATR(Average True Range)作为动态的波动性衡量标准。这样可以确保在不同市场环境下,识别标准都能适应:
// 更新ATR值g_current_atr_value = iATR(_Symbol, inp_analysis_tf, 14);// 使用ATR来判断K线大小double min_size = g_current_atr_value * inp_min_candle_size_atr;
同时,我们还需要处理区域的动态更新。当价格完全穿越某个区域时,这个区域就不再有效:
boolIsZoneMitigated(double current_high, double current_low){// 如果价格完全穿越了整个区域,则认为区域已缓解return (current_low <= m_low && current_high >= m_high);}
写在最后
市场记忆区域是一个强大的技术分析工具,它帮助我们理解价格行为背后的市场微观结构。通过算法识别这些区域,我们可以更客观地找到潜在的价格回归点。
当然,技术分析只是交易系统的一部分。成功的交易需要结合市场理解、风险管理、心理控制等多个方面。如果你对量化交易和算法开发感兴趣,欢迎关注"超哥量化"公众号,我们会持续分享更多量化交易的技术细节和实战经验。同时,我们也提供专业的量化策略开发和定制服务,帮助交易者构建属于自己的交易系统。
记住,市场没有圣杯,任何技术工具都需要在实践中不断验证和完善。保持学习,保持谨慎,这才是长期在市场中生存的关键。