用 Python 量化工具 AkShare 快速捕捉 A 股趋势:6 大技术分析实例

·

关键词:AkShare、Pandas、TA-Lib、Python 量化、技术分析、移动平均线、MACD、RSI、Bollinger、KDJ、A 股数据


当下 A 股波动频繁,散户和专业投资者都希望在第一时间找到“可交易的信号”。本文带你用 AkShare 拉取实时行情,再用 Pandas 清洗,借助 TA-Lib 的 Python 封装 ta,一口气玩转 6 种经典技术分析方法。我们以 贵州茅台 (600519) 为例,用完整可运行代码呈现每一步逻辑,帮助你快速复用到其他股票或期货场景。


一、为什么用 Python 做技术分析?

传统看盘软件虽然直观,却难以批量化、回测甚至跨品种对比。而 Python 生态提供了三大杀器:

三者搭配,能在 5 分钟内跑完过去一年的完整策略,比人工盯盘省时省力 20 倍以上


二、一步到位:一键拉取贵州茅台数据

import akshare as ak
import pandas as pd

stock_code = "600519"
start_date = "20240101"
end_date   = "20241018"

df = ak.stock_zh_a_hist(symbol=stock_code,
                        period="daily",
                        start_date=start_date,
                        end_date=end_date,
                        adjust="")          # qfq: 前复权;不填默认为不复权
df['日期'] = pd.to_datetime(df['日期'])
df.set_index('日期', inplace=True)
df.sort_index(inplace=True)                 # 让时间升序

执行后你会得到一个标准 OHLCV(开高低收量)DataFrame,接下来所有技术指标都基于此表计算。


三、6 大技术分析方法实战

下面每个策略展示 计算逻辑 → 信号生成 → 可视化 → 注意事项,全部可复制直接运行。

3.1 快慢移动平均线组合(20 & 50)

from ta.trend import SMAIndicator

df['SMA20'] = SMAIndicator(close=df['收盘'], window=20).sma_indicator()
df['SMA50'] = SMAIndicator(close=df['收盘'], window=50).sma_indicator()

# 信号:20日均线上穿50日视为多头,反之空头
df['SMA_Signal'] = 0
cond_long  = df['SMA20'] > df['SMA50']
cond_short = df['SMA20'] < df['SMA50']
df.loc[cond_long,  'SMA_Signal'] =  1
df.loc[cond_short, 'SMA_Signal'] = -1
df['SMA_Change'] = df['SMA_Signal'].diff()

实操提示:

👉 查看如何搭配波动率过滤假突破 →


3.2 移动平均线 + MACD 双重过滤

from ta.trend import MACD

macd      = MACD(close=df['收盘'])
df['MACD']        = macd.macd()
df['MACD_Signal'] = macd.macd_signal()

df['MACD_Bull'] = (df['MACD'] > df['MACD_Signal']) & (df['MACD'] < 0)
df['MACD_Bear'] = (df['MACD'] < df['MACD_Signal']) & (df['MACD'] > 0)

# 与 50 日均线共振
df['MM_Signal'] = 0
df.loc[cond_long & df['MACD_Bull'], 'MM_Signal'] =  1
df.loc[cond_short & df['MACD_Bear'], 'MM_Signal'] = -1

优势:减少单一指标“追高杀跌”,提高 盈亏比


3.3 RSI 超买超卖极限反转

from ta.momentum import RSIIndicator

df['RSI14'] = RSIIndicator(close=df['收盘'], window=14).rsi()

df['RSI_Long']  = df['RSI14'] < 30      # 超卖反弹
df['RSI_Short'] = df['RSI14'] > 70      # 超买回落

df['RSI_Signal'] = 0
df.loc[df['RSI_Long'] & cond_long.shift(), 'RSI_Signal']  =  1
df.loc[df['RSI_Short'] & cond_short.shift(), 'RSI_Signal'] = -1

风险提示:单边行情里 RSI 会长期钝化,务必与趋势线配合确认。


3.4 Bollinger Band 通道突破

from ta.volatility import BollingerBands

bb = BollingerBands(close=df['收盘'], window=20, window_dev=2)
df['BB_Upper'] = bb.bollinger_hband()
df['BB_Lower'] = bb.bollinger_lband()

df['BB_Long']  = df['收盘'] < df['BB_Lower']
df['BB_Short'] = df['收盘'] > df['BB_Upper']

df['BB_Signal'] = 0
df.loc[df['BB_Long'] , 'BB_Signal'] =  1
df.loc[df['BB_Short'], 'BB_Signal'] = -1

实战意义:Bollinger 宽度(Band Width)收窄往往预示后续波动加剧,可在低波动市布局。


3.5 KDJ(随机指标)金叉死叉

from ta.momentum import StochasticOscillator

sto = StochasticOscillator(high=df['最高'], low=df['最低'], close=df['收盘'])
df['K'] = sto.stoch()
df['D'] = sto.stoch_signal()

df['KDJ_Long']  = (df['K'] < 20) & (df['K'] > df['D'])
df['KDJ_Short'] = (df['K'] > 80) & (df['K'] < df['D'])

df['KDJ_Signal'] = 0
df.loc[df['KDJ_Long'],  'KDJ_Signal'] =  1
df.loc[df['KDJ_Short'], 'KDJ_Signal'] = -1

适合短线快进快出,但需设置 硬止损 避免“地板接飞刀”。


3.6 ATR 动态止损(波动率管理)

from ta.volatility import AverageTrueRange

atr = AverageTrueRange(high=df['最高'], low=df['最低'], close=df['收盘'])
df['ATR14'] = atr.average_true_range()

# 入场后止损价为当日收盘 - 2*ATR
df['Long_Stop']  = df['收盘'] - 2 * df['ATR14']
df['Short_Stop'] = df['收盘'] + 2 * df['ATR14']

3.2 的 MM_Signal 与 ATR 结合,可得到“宽幅止损 + 均线过滤”的成熟模型。

👉 一键复现完整量化代码并验证不同品种表现 →


四、可视化策略:一眼看懂多空格局

import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

plt.figure(figsize=(16,9))
plt.plot(df.index, df['收盘'], label='收盘')
plt.plot(df.index, df['SMA20'], label='20日SMA')
plt.plot(df.index, df['SMA50'], label='50日SMA')

# 标记买入/卖出
long_sig  = df[df['SMA_Change'] ==  2]    # 0→1 的 diff 为 2
short_sig = df[df['SMA_Change'] == -2]    # 0→-1 的 diff 为 -2

plt.scatter(long_sig.index,  long_sig['收盘'], marker='^', color='green', label='买入')
plt.scatter(short_sig.index, short_sig['收盘'], marker='v', color='red'  , label='卖出')
plt.legend()
plt.show()

五、典型 FAQ

Q1:AkShare 抓不到某些股票分钟线怎么办?
A:先确认该股票是否在交易所实时交易;若分钟线缺失,可改用 ak.stock_zh_a_tick_tx() 抓腾讯分钟补全。

Q2:用 ta 库输出的字段全是 NaN?
A:查看 DataFrame 最前面若干行。滑窗(如 50 日均线)前 50 行会因为数据不足返回 NaN,强制填充或延迟触发信号即可。

Q3:如何避免策略在震荡市频繁开平仓?
A:可在信号前加上 df['ATR14'].rolling(10).mean() < threshold 宽度条件过滤,或在 成交量 跌破均量时禁止交易。

Q4:回测需要哪些额外字段?
A:至少需“开高低收量”+“可复权因子”。若考虑滑点则增加分时挂单队列数据;考虑分红则需复权。

Q5:能否一次性跑 5000 只 A 股?
A:可以。把代码放 for stock_code in stock_list: 外层循环即可。注意控制并发次数,AkShare 站点对爬虫频率有限制。

Q6:MACD 和 KDJ 哪个更适合超短线?
A:KDJ 变动灵敏度更高,但假信号更多;MACD 滞后段略长,却能捕捉波段起点。两者结合 分时成交量 效果更佳。


六、结语:把灵感转化成可回测的工程

通过以上 6 种经典技术分析方法,你已经掌握了“数据获取 → 指标计算 → 信号生成 → 回测框架”的完整工作流。下一步只需把策略写成函数、配合 backtrader、vectorbt 等框架即可全市场回测。在量化里,代码即信念,数据即武器。祝你 2025 交易长虹!