量化新手入门:一文搞懂 QuantStats 量化分析框架

量化新手入门:一文搞懂 QuantStats 量化分析框架

本文专为量化新手设计,带你完整体验 QuantStats 搭建A股分析框架。通过Tushare获取实时行情数据,结合TA-Lib计算MACD、RSI等技术指标,逐步实现策略开发、回测验证与绩效评估。内容涵盖环境配置、数据准备、收益可视化、多策略对比等基础实战,并引入交易成本建模、参数优化等实用技巧,配套代码示例与常见问题解答,助你快速掌握A股量化分析核心技能。
文中内容仅限技术学习与代码实践参考,市场存在不确定性,技术分析需谨慎验证,不构成任何投资建议。适合量化新手建立系统认知,为策略开发打下基础。

第一部分 环境配置与数据准备

本部分推荐参考:QuantStats + TA-Lib:量化策略分析入门实战的五阶段构建之旅 🔥
阶段 1:环境配置与数据准备

1.1 安装依赖库

pip install quantstats==0.0.62 pandas==2.0.2 numpy==1.26.4 tushare==1.4.19  # 基础库

1.2 获取A股数据(以沪深300指数为例)

import tushare as ts
import pandas as pd

# 获取沪深300指数日线数据
df = pro.index_daily(ts_code="000300.SH", start_date="20180101", end_date="20231231")
df["date"] = pd.to_datetime(df["trade_date"])
df.set_index("date", inplace=True)
df.sort_index(inplace=True)

# 计算收益率(QuantStats要求收益率序列)
returns = df["pct_chg"].dropna() / 100  # Tushare返回的是百分比,需转换为小数

1.3 使用TA-Lib生成技术指标

import talib

# 示例:计算RSI和MACD
df["rsi"] = talib.RSI(df["close"], timeperiod=14)
df["macd"], df["macd_signal"], _ = talib.MACD(df["close"])

# 生成交易信号(简单策略:RSI<30买入,RSI>70卖出)
df["signal"] = 0
df.loc[df["rsi"] < 30, "signal"] = 1
df.loc[df["rsi"] > 70, "signal"] = -1

# 计算策略收益率
strategy_returns = df["signal"].shift(1) * returns

第二部分 QuantStats核心应用

2.1 指标计算

import quantstats as qs

# 计算核心指标
print(f"年化收益率: {qs.stats.cagr(strategy_returns):.2%}")
print(f"夏普比率: {qs.stats.sharpe(strategy_returns):.2f}")
print(f"最大回撤: {qs.stats.max_drawdown(strategy_returns):.2%}")

# 对比基准(沪深300)
benchmark_rets = returns  # 假设基准与策略使用相同数据
qs.reports.metrics(strategy_returns, benchmark=benchmark_rets, mode="basic")

2.2 可视化分析

# 绘制收益曲线与回撤
qs.plots.returns(strategy_returns, benchmark_rets)
qs.plots.drawdown(strategy_returns)

# 滚动夏普比率
qs.plots.rolling_sharpe(strategy_returns, periods=90)

# 月度收益热力图
qs.plots.monthly_heatmap(strategy_returns)

2.3 生成完整报告

# HTML格式报告
qs.reports.html(
    returns=strategy_returns,
    benchmark=benchmark_rets,
    output="./reports/a_stock_report.html",
    title="A股策略分析报告",
)

# 控制台完整报告
qs.reports.full(strategy_returns, benchmark_rets)

第三部分 进阶实践

3.1 自定义指标组合

custom_stats = [
    "cagr",
    "max_drawdown",
    "calmar",
    "sortino",
    "win_rate",
    "profit_factor",
]

qs.reports.metrics(strategy_returns, benchmark=benchmark_rets, metrics=custom_stats)

3.2 结合TA-Lib的深度分析

# 计算波动率指标
df["atr"] = talib.ATR(df["high"], df["low"], df["close"], timeperiod=14)

# 动态风险调整
volatility = df["atr"].pct_change().dropna()
adjusted_returns = strategy_returns / volatility

# 评估调整后表现
qs.reports.metrics(adjusted_returns)

第四部分 最佳实践指南

  1. 数据质量检查
# 检查缺失值
print(f"缺失值数量: {returns.isnull().sum()}")

# 处理极端值
clean_returns = qs.stats.remove_outliers(strategy_returns)
  1. 参数调优验证
# 滚动窗口分析
rolling_volatility = qs.stats.rolling_volatility(strategy_returns)
rolling_volatility.plot(title="滚动收益波动率")
  1. 多周期分析
# 不同时间维度分析
periods = {
    "全周期": slice(None),
    "牛市(2019-2021)": slice("2019-01-01", "2021-12-31"),
    "熊市(2022)": slice("2022-01-01", "2022-12-31"),
}

# 表现分析
for name, period in periods.items():
    qs.reports.metrics(strategy_returns.loc[period])
  1. 异常处理
try:
    qs.stats.kelly_criterion(strategy_returns)
except Exception as e:
    print(f"凯利准则计算异常: {str(e)}")
    # 回退到夏普比率
    print(f"夏普比率: {qs.stats.sharpe(strategy_returns)}")

第五部分 事件驱动回测集成

5.1 构建事件驱动框架

class EventBacktester:
    def __init__(self, data):
        self.data = data
        self.positions = pd.Series(0, index=data.index)
        self.cash = 1000000  # 初始资金
        self.trade_log = []

    def apply_strategy(self, strategy_func):
        signals = strategy_func(self.data)
        self.positions = signals.shift(1).fillna(0)

    def calculate_equity(self):
        # 计算每日收益
        strategy_returns = self.positions * self.data["pct_chg"] / 100
        equity = (1 + strategy_returns).cumprod() * self.cash
        return equity.dropna()


# 示例策略
def rsi_strategy(data):
    rsi = talib.RSI(data["close"], timeperiod=14)
    return (rsi < 30).astype(int) - (rsi > 70).astype(int)


# 执行回测
backtester = EventBacktester(df)
backtester.apply_strategy(rsi_strategy)
equity_curve = backtester.calculate_equity()

5.2 交易成本建模

def calculate_equity_with_cost(self, commission=0.0003, slippage=0.0002):
    position_changes = self.positions.diff().fillna(0)
    trade_volume = position_changes.abs() * self.data["close"]

    # 计算成本
    commission_cost = trade_volume * commission
    slippage_cost = trade_volume * slippage

    # 调整收益
    net_returns = (
        self.positions * self.data["pct_chg"] / 100
        - (commission_cost + slippage_cost) / self.cash
    )

    return (1 + net_returns).cumprod() * self.cash


# 比较有无成本的差异
equity_with_cost = calculate_equity_with_cost(backtester)
qs.plots.returns(equity_curve.pct_change(), equity_with_cost.pct_change())

第六部分 实时监控系统实现

6.1 实时数据获取

import schedule
import time


def realtime_monitor():
    # 获取最新行情
    new_data = pro.index_daily(
        ts_code="000300.SH", start_date=pd.Timestamp.now().strftime("%Y%m%d")
    )

    # 更新数据集
    global df
    df = pd.concat([df, new_data])

    # 生成实时报告
    qs.reports.html(df["pct_chg"], output="realtime_report.html")


# 设置定时任务(每30分钟执行)
schedule.every(30).minutes.do(realtime_monitor)

while True:
    schedule.run_pending()
    time.sleep(60)

6.2 预警系统集成

ddef risk_monitor(returns):
    current_drawdown = qs.stats.to_drawdown_series(returns).iloc[-1]
    volatility = qs.stats.volatility(returns)

    if current_drawdown < -0.1:
        send_alert("回撤超过10%预警!")
    if volatility > 0.25:
        send_alert("波动率超过25%预警!")


def send_alert(message):
    # 实现邮件/短信通知逻辑
    print(f"[ALERT] {pd.Timestamp.now()} {message}")


# 在实时监控中添加
def enhanced_monitor():
    returns = df["pct_chg"].dropna() / 100
    risk_monitor(returns[-30:])  # 监控最近30天

第七部分 性能优化策略

7.1 向量化加速计算

# 使用Numpy加速指标计算
def vectorized_rsi(prices, window=14):
    deltas = np.diff(prices)
    gain = deltas.copy()
    loss = deltas.copy()
    gain[gain < 0] = 0
    loss[loss > 0] = 0
    avg_gain = np.convolve(gain, np.ones(window)/window, mode='valid')
    avg_loss = np.convolve(-loss, np.ones(window)/window, mode='valid')
    rs = avg_gain / avg_loss
    return 100 - (100 / (1 + rs))

# 性能对比
%timeit talib.RSI(df['close'], 14)  # TA-Lib实现
%timeit vectorized_rsi(df['close'].values, 14)  # Numpy实现

7.2 并行计算优化

from concurrent.futures import ThreadPoolExecutor

import random


def run_strategy(rsi_buy, rsi_sell):
    """
    简单模拟策略回测:
    - 假设根据 RI 买卖信号生成随机收益和交易次数
    - 实际应用中需替换为真实的策略逻辑
    """
    # 模拟计算收益(此处为示例随机值)
    total_return = (rsi_sell - rsi_buy) * 0.1 + random.uniform(-1, 1)

    # 模拟交易次数(随机生成10-20次交易)
    num_trades = random.randint(10, 20)

    # 模拟胜率(40%-60%)
    win_rate = random.uniform(0.4, 0.6)

    return {
        "rsi_buy": rsi_buy,
        "rsi_sell": rsi_sell,
        "total_return": round(total_return, 2),
        "num_trades": num_trades,
        "win_rate": round(win_rate, 2),
    }

def parallel_backtest(params_list):
    results = []
    with ThreadPoolExecutor() as executor:
        futures = []
        for params in params_list:
            futures.append(
                executor.submit(run_strategy, rsi_buy=params[0], rsi_sell=params[1])
            )
        for future in futures:
            results.append(future.result())
    return pd.DataFrame(results)


# 参数网格示例
params_grid = [(25, 75), (30, 70), (20, 80)]
results_df = parallel_backtest(params_grid)

# 打印结果
print(results_df)

第九部分 常见问题解决方案

9.1 数据对齐问题

# 处理多时间序列对齐
def align_data(strategy_ret, benchmark_ret):
    common_index = strategy_ret.index.intersection(benchmark_ret.index)
    return strategy_ret.loc[common_index], benchmark_ret.loc[common_index]


# 示例
aligned_returns, aligned_bench = align_data(strategy_returns, benchmark_rets)

9.2 异常值处理

def winsorize_returns(returns, std=3):
    mean = returns.mean()
    std_dev = returns.std()
    lower = mean - std * std_dev
    upper = mean + std * std_dev
    return returns.clip(lower, upper)


cleaned_returns = winsorize_returns(strategy_returns)

9.3 复权处理

# 获取前复权数据
df_adj = pro.pro_bar(ts_code="600519.SH", adj="qfq", start_date="20180101")
df_adj["ret"] = df_adj["close"].pct_change().dropna()

附录 QuantStats方法速览

quantstats.stats 指标方法列表

[f for f in dir(qs.stats) if f[0] != '_']
方法名称中文名称作用
adjusted_sortino调整索提诺比率对索提诺比率进行修正,考虑更复杂的风险调整。
autocorr_penalty自相关惩罚对策略收益的自相关性进行惩罚,调整风险指标。
avg_loss平均亏损计算所有亏损交易的平均亏损值。
avg_return平均收益计算策略的平均收益率。
avg_win平均盈利计算所有盈利交易的平均盈利值。
best最佳收益策略在指定周期内的最高单期收益。
cagr年复合增长率计算策略的年化复合增长率。
calmar卡尔玛比率年复合增长率与最大回撤的比率。
common_sense_ratio常识比率结合收益和风险的综合评估指标。
comp复合收益计算策略的累计复合收益。
compare对比将策略与其他基准(如指数)进行对比分析。
compsum累计复合和计算策略的累计复合收益总和。
conditional_value_at_risk条件风险价值(CVaR)衡量在极端损失情况下的平均损失(尾部风险)。
consecutive_losses连续亏损次数统计策略连续亏损的次数。
consecutive_wins连续盈利次数统计策略连续盈利的次数。
cpc_indexCPC指数综合评估策略的风险调整后收益。
cvar条件风险价值conditional_value_at_risk
distribution收益分布分析策略收益的统计分布特征。
drawdown_details回撤详情提供策略历史回撤的详细数据(如开始时间、持续时间等)。
expected_return预期收益基于历史数据计算策略的预期收益。
expected_shortfall预期缺口conditional_value_at_risk,衡量尾部风险。
exposure风险敞口计算策略在市场中的风险暴露程度。
gain_to_pain_ratio收益痛苦比率总收益与总亏损的比率,衡量策略的盈亏平衡能力。
geometric_mean几何平均收益计算策略的几何平均收益率。
ghpr几何平均持有期收益基于几何平均的持有期收益率。
greeks希腊值计算期权相关的希腊值(如Delta、Gamma)。
implied_volatility隐含波动率基于期权价格反推的波动率。
information_ratio信息比率衡量超额收益与跟踪误差的比率。
kelly_criterion凯利准则计算最优投资比例以最大化长期增长率。
kurtosis峰度衡量收益分布的尖峭程度(极端值风险)。
max_drawdown最大回撤策略从峰值到谷值的最大亏损幅度。
monthly_returns月度收益展示策略的月度收益数据。
omegaOmega比率衡量收益超过阈值的概率与不足概率的比率。
outlier_loss_ratio异常亏损比率异常亏损事件占总亏损的比例。
outlier_win_ratio异常盈利比率异常盈利事件占总盈利的比例。
outliers异常值识别策略收益中的异常值(极端收益或亏损)。
payoff_ratio盈亏比平均盈利与平均亏损的比率。
pct_rank百分比排名当前收益在历史收益中的百分比排名。
probabilistic_adjusted_sortino_ratio概率调整索提诺比率结合概率方法调整的索提诺比率。
probabilistic_ratio概率比率基于概率模型评估策略表现。
probabilistic_sharpe_ratio概率夏普比率计算夏普比率的统计显著性(概率形式)。
probabilistic_sortino_ratio概率索提诺比率计算索提诺比率的统计显著性(概率形式)。
profit_factor盈利因子总盈利与总亏损的比率。
profit_ratio盈利比率盈利交易数量与总交易数量的比率。
r2决定系数(R²)衡量策略收益与基准收益的拟合优度。
r_squared决定系数r2
rar风险调整后收益综合考虑风险后的收益评估指标。
recovery_factor恢复因子累计收益与最大回撤的比率,衡量回撤恢复能力。
remove_outliers剔除异常值在计算指标时剔除异常值的影响。
risk_of_ruin破产风险衡量策略导致全部亏损的概率。
risk_return_ratio风险收益比率收益与风险的比率(通常以波动率衡量)。
rolling_greeks滚动希腊值计算滚动窗口内的期权希腊值。
rolling_sharpe滚动夏普比率计算滚动窗口内的夏普比率。
rolling_sortino滚动索提诺比率计算滚动窗口内的索提诺比率。
rolling_volatility滚动波动率计算滚动窗口内的收益波动率。
ror破产风险risk_of_ruin
serenity_index平静指数综合波动率、偏度和峰度的风险调整后指标。
sharpe夏普比率衡量投资回报与总风险的比率。
skew偏度衡量收益分布的不对称性。
smart_sharpe智能夏普比率对夏普比率进行自相关性和其他偏差的修正。
smart_sortino智能索提诺比率对索提诺比率进行自相关性和其他偏差的修正。
sortino索提诺比率类似夏普比率,但仅考虑下行风险。
tail_ratio尾部比率正收益与负收益尾部风险的比率。
to_drawdown_series回撤序列生成策略历史回撤的序列数据。
treynor_ratio特雷诺比率衡量超额收益与系统性风险(Beta)的比率。
ulcer_index溃疡指数衡量策略回撤的深度和持续时间。
ulcer_performance_index溃疡绩效指数结合溃疡指数的风险调整后收益指标。
upi溃疡绩效指数ulcer_performance_index
value_at_risk风险价值(VaR)衡量在特定置信水平下的最大潜在损失。
var风险价值value_at_risk
volatility波动率计算策略收益的标准差(衡量风险)。
warn警告检测策略可能存在的问题并发出警告。
win_loss_ratio胜负比盈利交易数量与亏损交易数量的比率。
win_rate胜率盈利交易占总交易的比例。
worst最差收益策略在指定周期内的最低单期收益。

quantstats.plots 图表方法列表

[f for f in dir(qs.plots) if f[0] != '_']
方法名称中文名称作用
daily_returns日度收益图展示策略的每日收益率随时间变化的折线图。
distribution收益分布图显示策略收益的统计分布(直方图或密度图),分析收益的集中性和偏态。
drawdown回撤曲线图绘制策略从峰值到谷值的回撤百分比曲线,展示历史回撤幅度。
drawdowns_periods回撤周期图展示每个回撤周期的持续时间、深度及恢复情况。
earnings累计收益图显示策略的累计收益随时间变化的曲线。
histogram收益直方图用直方图形式展示收益分布的频率。
log_returns对数收益率图展示策略的对数收益率(Log Returns)变化趋势。
monthly_heatmap月度收益热力图用颜色热力图展示策略在月度时间尺度上的收益表现。
monthly_returns月度收益图显示策略的月度收益柱状图或表格。
plotly交互式图表生成交互式图表(基于Plotly),支持动态缩放和细节查看。
returns收益率时序图绘制策略收益率的时间序列图。
rolling_beta滚动贝塔值图展示策略与基准之间的滚动贝塔值(系统性风险)。
rolling_sharpe滚动夏普比率图显示滚动窗口内夏普比率的变化趋势。
rolling_sortino滚动索提诺比率图显示滚动窗口内索提诺比率的变化趋势。
rolling_volatility滚动波动率图展示滚动窗口内收益波动率(标准差)的变化。
snapshot综合快照图生成策略表现的综合图表,包含收益、回撤、风险指标等关键信息。
to_plotly转换为Plotly图表将现有图表转换为Plotly交互式图表格式。
warnings策略警告图可视化策略潜在问题的警告信息(如过度拟合、高风险区间等)。
yearly_returns年度收益图展示策略的年度收益柱状图或表格。

部分图表示例说明

  1. 月度热力图 (monthly_heatmap)
    类似日历热力图,用颜色深浅表示不同月份的收益正负和强度,直观显示月度表现。

  2. 滚动指标图 (rolling_beta, rolling_sharpe 等)
    展示滚动窗口(如30天、90天)内特定指标的变化,帮助分析策略的稳定性。

  3. 回撤周期图 (drawdowns_periods)
    可能以条形图或表格形式列出每次回撤的开始时间、结束时间、持续天数及最大回撤值。

  4. 综合快照图 (snapshot)
    通常包含多个子图,如收益曲线、回撤曲线、月度收益分布等,用于快速总览策略表现。

注意事项

  • plotlyto_plotly 的区别可能在于:前者直接生成交互图表,后者将现有静态图表转换为Plotly格式。
  • log_returns 与普通收益率图的差异在于对数收益更适用于长期趋势分析(可叠加性)。

quantstats.report 报告方法列表

[f for f in dir(qs.reports) if f[0] != '_']
方法名称中文名称作用
StringIO字符串缓冲区报告将报告内容输出到内存中的字符串缓冲区(io.StringIO对象),便于后续处理或保存。
basic基础报告生成策略的核心指标摘要报告(如夏普比率、最大回撤、年化收益等)。
full完整报告生成包含详细分析和扩展指标的综合报告(涵盖统计、风险、绩效等)。
htmlHTML格式报告生成HTML格式的策略报告,支持网页直接查看或嵌入到Web应用中。
iDisplay交互式显示在Jupyter Notebook等环境中直接交互式显示报告(自动渲染为可视化格式)。
iHTML交互式HTML嵌入生成可嵌入到Jupyter Notebook的交互式HTML内容(支持动态图表)。
metrics指标汇总报告生成策略关键指标的表格化汇总(如收益率、波动率、风险调整后收益等)。
plots图表集成报告生成包含可视化图表的报告(如收益曲线、回撤图、分布直方图等)。
relativedelta相对时间计算处理时间偏移计算(如基于相对日期生成报告的时间范围)。

补充说明

  1. StringIO
    适用于需要将报告内容保存为字符串的场景(例如通过API返回或写入数据库),而非直接生成文件。

  2. iDisplay 与 iHTML

    • iDisplay:自动在Jupyter中渲染报告为可交互的HTML组件。
    • iHTML:返回HTML字符串,可手动嵌入到Notebook单元格或Web页面。
  3. relativedelta
    通常用于动态调整报告的时间范围(例如生成过去12个月的滚动报告),依赖dateutil.relativedelta库的时间计算功能。

  4. basic vs full

    • basic:简洁版,包含核心指标(如夏普比率、CAGR、最大回撤)。
    • full:扩展版,增加更多细节(如月度收益表、风险指标分解、交易统计)。
  5. plots
    可能集成多个图表方法(如plots.monthly_heatmapplots.drawdown),生成组合式可视化报告。

风险提示与免责声明
本文内容基于公开信息研究整理,不构成任何形式的投资建议。历史表现不应作为未来收益保证,市场存在不可预见的波动风险。投资者需结合自身财务状况及风险承受能力独立决策,并自行承担交易结果。作者及发布方不对任何依据本文操作导致的损失承担法律责任。市场有风险,投资须谨慎。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

船长@Quant

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值