
本文介绍一种简洁高效的方法,用于在预定义的高低点序列中,根据当前标记价格(mark price)快速查找“下一个更高的高点”和“下一个更低的低点”,适用于量化交易中的动态支撑/阻力跟踪场景。
本文介绍一种简洁高效的方法,用于在预定义的高低点序列中,根据当前标记价格(mark price)快速查找“下一个更高的高点”和“下一个更低的低点”,适用于量化交易中的动态支撑/阻力跟踪场景。
在量化策略开发中,常需基于历史K线的高低点(如每4根K线一组取极值)构建动态参考区间,并实时响应价格突破——例如:当标记价上穿某组高点时,自动切换至前一组更高高点;下破某组低点时,则回退至后一组更低低点。但原始实现存在逻辑混乱、索引越界、状态冗余等问题,导致无法正确回溯或前移。
核心问题在于:不应手动维护复杂索引偏移与交叉标志(如 crossabove/crossbelow),而应将逻辑抽象为纯函数式查找——即在有序数组中,分别寻找小于 mark 的最大值(最近下方低点)和大于 mark 的最小值(最近上方高点)。
以下为推荐实现(已通过全部用例验证):
def find_next_high_low(mark: float, min_array: list, max_array: list) -> tuple:
"""
在给定的低点数组(升序)和高点数组(降序)中,
查找:
- 小于 mark 的最大低点(即“下一个更低低点”)
- 大于 mark 的最小高点(即“下一个更高高点”)
参数:
mark: 当前标记价格(如最新成交价或mark price)
min_array: 低点序列(按时间顺序排列,通常升序)
max_array: 高点序列(按时间顺序排列,通常降序)
返回:
(next_low, next_high): 元组形式的匹配结果
"""
# 查找小于 mark 的最大低点 → 使用 filter + max(安全处理空序列)
lows_below = [low for low in min_array if low < mark]
next_low = max(lows_below) if lows_below else min(min_array) # fallback
# 查找大于 mark 的最小高点 → 使用 filter + min
highs_above = [high for high in max_array if high > mark]
next_high = min(highs_above) if highs_above else max(max_array) # fallback
return next_low, next_high
# 示例验证
if __name__ == "__main__":
min_array = [2, 3.5, 5, 8.5, 9] # 历史低点(时间从左到右)
max_array = [20, 17, 9, 7, 5] # 历史高点(时间从左到右,数值递减)
print(find_next_high_low(3.6, min_array, max_array)) # → (3.5, 5)
print(find_next_high_low(5.1, min_array, max_array)) # → (5, 7)
print(find_next_high_low(3.4, min_array, max_array)) # → (2, 5)✅ 关键优势:
- 无状态依赖:每次调用独立计算,不依赖外部索引变量或交叉标志,彻底规避状态同步错误;
- 鲁棒性强:自动处理边界情况(如 mark 超出数组范围),提供合理 fallback;
- 可读性高:逻辑直白,符合“所见即所得”的工程直觉;
- 易扩展:若需支持滑动窗口(如最近 N 组),仅需预处理 min_array/max_array 即可,主体逻辑零修改。
⚠️ 注意事项:
- 确保 min_array 和 max_array 按实际时间顺序排列(而非排序后数组),否则语义将错乱;
- 若性能敏感(如高频调用),可对 max_array 预先升序排序后使用二分查找(bisect_left),将时间复杂度从 O(n) 优化至 O(log n);
- 实际 OHLCV 数据中,建议统一使用 candle[2](high)和 candle[3](low)提取,并按时间倒序切片生成极值数组,以保证“最近”语义一致。
该方法摒弃了易出错的手动索引管理,回归问题本质:一次查询,两个目标值——简洁、可靠、可维护,是支撑/阻力动态跟踪的理想基底。

















