风险提示 本文仅供技术学习,不构成投资建议;文中举例用到的 $AAPL 仅作示范,非任何推荐。阅读前请牢记风险管理原则。
支撑线和阻力线是技术分析的“地基”。当股价在支撑位止跌、或在阻力位受阻,往往意味着趋势即将反转,为交易者提供了精准进出场信号。本文将手把手教你用 Python 在 AAPL 日线 上完成 支撑与阻力识别 的全流程,力求做到“能跑、能看、能复现”,同时避开常见坑点。
一、为什么用 Python?三大优势一次说清
- 免费开源:
scipy、pandas、mplfinance全零成本。 - 灵活改装:参数、阈值、数据源随调随改,适配 日内 5min、周线 等任何周期。
- 数据通道直连:借助
yahooquery一行代码拉取历史,无需手动下载 CSV。
若你正研究 股价交易策略 或 量化回测,这篇教程将成为你在 GitHub 上能直接引用的模板。
二、环境准备:五步到位
# 创建独⽴虚拟环境(可选但推荐)
python -m venv env
source env/bin/activate # Windows 用 env\Scripts\activate
pip install yahooquery pandas scipy mplfinance numpy仅需 4 个库 即覆盖数据→计算→绘图全链路,后续无需额外依赖。
三、拉取 AAPL 日线,先画图再看指标
import numpy as np
from yahooquery import Ticker
import pandas as pd
from scipy.signal import find_peaks
import mplfinance as mpf
ticker = Ticker('AAPL')
df = ticker.history(start='2022-01-01', interval='1d').reset_index(level=0)
# 为了让 mplfinance 识别时间维度
df.index = pd.to_datetime(df.index)
mpf.plot(df, type='candle', style='charles', title='AAPL 日线 K 线', volume=True)首次运行若提示缺失字体,请 pip install matplotlib 后重启。
四、阻力位识别:三步拆分“强阻力”与“一般阻力”
关键词:阻力位、价格峰值、冲高回落
Step 1 定位“强阻力”——用 prominence 淘汰窄幅噪音
STRONG_DISTANCE = 60 # 60 根 K 线间隔
STRONG_PROMINENCE = 20 # 价格突出度≥20 美元视为强
strong_peaks, _ = find_peaks(
df['high'],
distance = STRONG_DISTANCE,
prominence = STRONG_PROMINENCE
)
strong_levels = df.iloc[strong_peaks]['high'].tolist()
# 额外加入 52 周高点作补充
yearly_high = df['high'].iloc[-252:].max()
strong_levels.append(yearly_high)得到的 strong_levels 约等于 中长期投资者试错 2 次以上 的高抛区间。
Step 2 “一般阻力”——短线黄金分割线
GEN_DISTANCE = 5 # 相邻峰值 ≥5 根 K 线
GEN_WIDTH = 2 # 垂直距离≤2 美元归为一组
RANK_MIN = 3 # 同一价位回测≥3 次
peaks, _ = find_peaks(df['high'], distance=GEN_DISTANCE)
# 用字典统计每处峰值被“撞”的次数
pivot_score = {p:0 for p in peaks}
for i, idx1 in enumerate(peaks):
for idx2 in peaks[:i]:
if abs(df.iloc[idx1]['high']-df.iloc[idx2]['high']) <= GEN_WIDTH:
pivot_score[idx1] += 1
# 只收录满足次数的价位
res_candidates = [df.iloc[p]['high'] for p, v in pivot_score.items() if v >= RANK_MIN]
res_candidates += strong_levels # 叠加强阻力
res_candidates = np.unique(np.round(res_candidates, 2)).tolist()Step 3 合并极近距离水准,输出“洁净”阻力榜
bins = []
curr = [res_candidates[0]]
for r in res_candidates[1:]:
if r - curr[-1] < GEN_WIDTH:
curr.append(r)
else:
bins.append(curr)
curr = [r]
bins.append(curr)
clean_res = [round(np.mean(group), 2) for group in bins]此时绘制 clean_res 即得到 不含锯齿 的阻力水平线:
addplot = [mpf.make_addplot(np.full(df.shape[0], v), color='r', linestyle='--') for v in clean_res]
mpf.plot(df, type='candle', style='charles', title='叠加阻力线的 AAPL 日线', addplot=addplot, volume=True)五、支撑位镜像复现:把 low 换成 -low 即可
troughs, _ = find_peaks(-df['low'], distance=5)
sup_candidates = [df.iloc[t]['low'] for t in troughs]后续合并逻辑与阻力完全一致,只需把 high 全部替换为 low,不再赘述。下方为最终叠加 支撑线 与 阻力线 的 K 线图:
代码略,绘图效果可参考金融博客图示,干净且一目了然。
六、完整脚本一键跑通
将以下脚本保存为 support_resistance.py,python support_resistance.py AAPL 2022-01-01 即可:
import sys, datetime
if len(sys.argv) < 3: # 容错提示
exit("Usage: python support_resistance.py 股票代码 起始日期,如 AAPL 2022-01-01")
symbol, start = sys.argv[1:]
df = Ticker(symbol).history(start=start, interval='1d').reset_index(level=0)
...如此便实现了 参数化 调用,研究多只股票秒切。
常见问题 FAQ
Q1:短线 5 分钟数据也能用这套代码?
完全可以!只需将 interval 改成 '5m',并把 GEN_DISTANCE 缩小(如 20~30 根),即可捕捉 日内高频阻力支撑。
Q2:为何加入 52 周高点?
既是心理压力位,也常成为机构回补缺口的关键节点,可防止长期交易者遗漏重要水平。
Q3:prominence 设成 15 会怎样?
数值越小,水平线 越密集;过小易导致过拟合。初次回测可保持 20,再通过回测迭代微调。
Q4:能不能一次性画 30 只股票?
循环拉取数据→跑算法→导出 clean_res 列表为 JSON,再用 Dash 或 Streamlit 实时展示即可。
Q5:算法会把历史最高点也砍掉吗?
不会。只要满足 prominence ≥20,最高点即被保留;合并步骤仅切除极近距离冗余。
七、退而求其次,还有 Web 级脚本快速体验
如果你不想本地折腾环境,👉 一键在线体验零安装计算支撑阻力(仅填写股票代码与周期,即可生成交互式图,支持导出高清 PNG)。
至此,你已获得从零到一的 Python 支撑/阻力分析框架。只需修改参数,就能直接塞进 交易策略回测 或 实时风控 系统。