Python实现资产牛熊市识别:标普500熊市区间判定咨询
熊市周期识别代码优化方案
判定规则
当证券价格较其52周高点下跌20%及以上时标志熊市开启,当证券价格较近期低点上涨20%及以上时标志熊市结束。
计算目标
基于Yahoo Finance获取的标普500期货(标的代码ES=F)行情数据,输出以下核心指标:
- 熊市开始日期
- 对应区间价格峰值
- 熊市结束日期
- 对应区间价格谷底
原代码问题说明
原实现存在4个核心逻辑漏洞,会直接导致结果偏差:
- 谷底计算窗口错误:使用固定21天滚动窗口取最小值,不符合熊市周期内全局谷底的判定要求
- 日期匹配逻辑缺陷:遇到重复价格值时会错误匹配到非周期内的历史日期
- 缺失熊市结束判定:仅筛选了回撤超20%的时点,未实现「从低点反弹20%即结束」的规则,会重复拆分同一段熊市
- 运行效率低:逐行循环匹配日期的写法可通过简化逻辑大幅降低计算开销
优化后实现代码
import yfinance as yf import pandas as pd import numpy as np # 阈值配置 DRAWDOWN_THRESHOLD = 0.2 # 熊市开启回撤阈值 REBOUND_THRESHOLD = 0.2 # 熊市结束反弹阈值 START_DATE = "1990-1-1" TICKER = "ES=F" # 获取行情数据 df = yf.download(tickers=TICKER, start=START_DATE) close = df["Close"].squeeze() # 兼容yfinance新版本多级列返回格式 # 初始化状态变量 bear_markets = [] in_bear = False current_peak = np.nan current_peak_date = None current_trough = np.nan current_trough_date = None # 状态机逻辑逐行识别周期,无歧义 for date, price in close.items(): # 非熊市状态:监控熊市开启信号 if not in_bear: # 计算过去52周(约365天)滚动最高价 window_start = date - pd.Timedelta(days=365) window_data = close.loc[window_start:date] rolling_peak = window_data.max() rolling_peak_date = window_data.idxmax() # 达到20%回撤阈值,标记熊市开启 if price <= rolling_peak * (1 - DRAWDOWN_THRESHOLD): in_bear = True current_peak = rolling_peak current_peak_date = rolling_peak_date current_trough = price current_trough_date = date continue # 熊市状态:更新谷底,监控结束信号 # 更新本轮熊市周期内的谷底值 if price < current_trough: current_trough = price current_trough_date = date # 判定是否从谷底反弹20%,达到则结束本轮熊市 if price >= current_trough * (1 + REBOUND_THRESHOLD): bear_markets.append({ "Start_Date": current_peak_date, "Peak": round(current_peak, 2), "End_Date": date, "Trough": round(current_trough, 2), "Peak_To_Trough(%)": round(100*(current_trough/current_peak - 1), 2), "Num_Days": (date - current_peak_date).days }) # 重置状态,等待下一轮熊市信号 in_bear = False current_peak = np.nan current_peak_date = None current_trough = np.nan current_trough_date = None # 转为结构化DataFrame输出 result_df = pd.DataFrame(bear_markets) print(result_df)
逻辑说明
- 采用状态机思路实现,清晰区分「非熊市」「熊市」两种状态,避免逻辑交叉混乱
- 熊市开启前,实时计算过去52周滚动高点,回撤达标即标记周期起点和对应峰值
- 熊市存续期间持续更新周期内最低点,直到价格从最低点反弹20%,立即标记周期终点
- 自动去重,不会将同一段熊市拆分为多条重复记录
- 结果直接输出结构化的熊市周期列表,无冗余数据
内容的提问来源于stack exchange,提问作者Boris Mikanikrezai
相关产品推荐
相关产品推荐

