如何编码获取Moving Average Crossover后最高价及Crossunder后最低价
获取均线金叉后最高价与死叉后最低价的代码实现
核心思路
- 计算两条目标移动平均线(比如短期MA5和长期MA20)
- 精准识别金叉(短期均线上穿长期均线)和死叉(短期均线下穿长期均线)的信号节点
- 对每个金叉信号,跟踪从信号日到下一个信号日(或数据末尾)区间内的最高价;死叉则跟踪对应区间的最低价
纯手动实现(无依赖第三方库)
适合无法安装TA-Lib的环境,完全基于Pandas实现:
import pandas as pd import numpy as np def calculate_sma(data, window): """计算简单移动平均线""" return data['close'].rolling(window=window).mean() def detect_crossover_crossunder(ma_short, ma_long): """识别金叉和死叉信号""" # 金叉:短期均线今日>长期,昨日<=长期 crossover = (ma_short > ma_long) & (ma_short.shift(1) <= ma_long.shift(1)) # 死叉:短期均线今日<长期,昨日>=长期 crossunder = (ma_short < ma_long) & (ma_short.shift(1) >= ma_long.shift(1)) return crossover, crossunder def get_post_crossover_highs(data, crossover_signals): """提取每个金叉后的区间最高价""" post_highs = [] signal_dates = data[crossover_signals].index for idx in range(len(signal_dates)): start_date = signal_dates[idx] # 确定区间结束点:下一个信号日或数据最后一天 if idx < len(signal_dates) - 1: end_date = signal_dates[idx+1] else: end_date = data.index[-1] # 提取区间内最高价 interval_high = data.loc[start_date:end_date, 'high'].max() post_highs.append((start_date.date(), round(interval_high, 2))) return post_highs def get_post_crossunder_lows(data, crossunder_signals): """提取每个死叉后的区间最低价""" post_lows = [] signal_dates = data[crossunder_signals].index for idx in range(len(signal_dates)): start_date = signal_dates[idx] if idx < len(signal_dates) - 1: end_date = signal_dates[idx+1] else: end_date = data.index[-1] interval_low = data.loc[start_date:end_date, 'low'].min() post_lows.append((start_date.date(), round(interval_low, 2))) return post_lows # 示例运行 if __name__ == "__main__": # 模拟K线数据(实际可从CSV/API读取) dates = pd.date_range(start='2023-01-01', periods=100) close = pd.Series(np.arange(100) + np.random.randn(100)*5, index=dates) data = pd.DataFrame({ 'high': close + np.random.randn(100)*2, 'low': close - np.random.randn(100)*2, 'close': close }) # 计算均线 ma5 = calculate_sma(data, 5) ma20 = calculate_sma(data, 20) # 识别信号 crossover, crossunder = detect_crossover_crossunder(ma5, ma20) # 获取结果 crossover_highs = get_post_crossover_highs(data, crossover) crossunder_lows = get_post_crossunder_lows(data, crossunder) # 输出 print("金叉后区间最高价:") for date, high in crossover_highs: print(f"金叉日期:{date},后续最高价:{high}") print("\n死叉后区间最低价:") for date, low in crossunder_lows: print(f"死叉日期:{date},后续最低价:{low}")
基于TA-Lib的简化实现
如果可以安装TA-Lib,能大幅简化信号识别逻辑:
import pandas as pd import numpy as np import talib # 模拟数据同上 dates = pd.date_range(start='2023-01-01', periods=100) close = pd.Series(np.arange(100) + np.random.randn(100)*5, index=dates) data = pd.DataFrame({ 'high': close + np.random.randn(100)*2, 'low': close - np.random.randn(100)*2, 'close': close }) # 计算均线 ma5 = talib.SMA(data['close'], timeperiod=5) ma20 = talib.SMA(data['close'], timeperiod=20) # 直接用TA-Lib识别金叉/死叉 crossover_signals = talib.CROSSOVER(ma5, ma20) == 1 # 金叉返回1 crossunder_signals = talib.CROSSOVER(ma20, ma5) == 1 # 死叉等价于长期上穿短期 # 复用之前的高低价提取函数 crossover_highs = get_post_crossover_highs(data, crossover_signals) crossunder_lows = get_post_crossunder_lows(data, crossunder_signals) # 输出结果 print("金叉后区间最高价:") for date, high in crossover_highs: print(f"金叉日期:{date},后续最高价:{high}") print("\n死叉后区间最低价:") for date, low in crossunder_lows: print(f"死叉日期:{date},后续最低价:{low}")
注意事项
- 确保数据包含
high和low字段,否则无法计算区间高低价 - 若需要限定信号后固定N个交易日的高低价,可修改
end_date为start_date + pd.Timedelta(days=N),注意处理超出数据范围的情况 - 信号识别时的
shift(1)是关键,确保只捕捉上穿/下穿的瞬间,而非持续在均线上方/下方的状态
内容的提问来源于stack exchange,提问作者Vt.kuntanut
相关产品推荐
相关产品推荐

