A股量化回测框架入门指南:从零搭建到策略优化

1次阅读
没有评论

共计 2943 个字符,预计需要花费 8 分钟才能阅读完成。

image.webp

为什么需要量化回测

量化投资的核心在于通过历史数据验证策略的有效性。A 股市场由于 T + 1 交易、涨跌停限制等特殊规则,直接套用海外框架往往会出现水土不服。一个好的回测系统能帮我们:

A 股量化回测框架入门指南:从零搭建到策略优化

  • 验证策略逻辑是否具备统计显著性
  • 评估策略在不同市场环境下的稳定性
  • 优化参数组合避免过度拟合

主流框架对比

框架 优点 缺点 适用场景
Backtrader 事件驱动架构,支持多品种多时间帧 需要自行处理 A 股特有规则 中低频策略研发
Zipline 自带基本面数据,社区生态完善 对 A 股支持较弱,学习曲线陡峭 美股市场研究
PyAlgoTrade 代码简洁,易于上手 功能较为基础,扩展性有限 教育演示和小型策略测试

Backtrader 实战示例

1. 数据接口封装

import backtrader as bt
import pandas as pd

class AStockData(bt.feeds.PandasData):
    params = (('datetime', None),  # 使用索引列作为时间
        ('open', 'open'),
        ('high', 'high'),
        ('low', 'low'),
        ('close', 'close'),
        ('volume', 'volume'),
        ('openinterest', -1),  # A 股无持仓量概念
        ('preday_close', 'pre_close'),  # 前收盘价(处理涨跌停)
        ('is_trading', 'is_trading'),  # 当日是否可交易(处理停牌)
    )

    def __init__(self, df):
        # 确保包含涨跌停标志和停牌标志
        assert 'limit_up' in df.columns and 'limit_down' in df.columns
        super().__init__(dataname=df)

2. 均线策略实现

class MaCrossStrategy(bt.Strategy):
    params = (('fast_period', 5),   # 快线周期
        ('slow_period', 20),  # 慢线周期
        ('printlog', False),  # 是否打印交易日志
    )

    def __init__(self):
        # 计算双均线
        self.ma_fast = bt.indicators.SMA(self.data.close, period=self.p.fast_period)
        self.ma_slow = bt.indicators.SMA(self.data.close, period=self.p.slow_period)

        # 跟踪订单状态
        self.order = None

    def next(self):
        # 检查是否有未完成订单
        if self.order:
            return

        # 检查是否可交易(处理停牌)
        if not self.data.is_trading[0]:
            return

        # 金叉信号且未持仓
        if not self.position and \
           self.ma_fast[0] > self.ma_slow[0] and \
           self.ma_fast[-1] <= self.ma_slow[-1]:

            # 处理涨跌停无法买入的情况
            if self.data.limit_up[0]:
                return

            # 计算可买数量(处理 A 股 100 股整数倍)
            size = int(self.broker.getcash() / self.data.close[0] // 100) * 100
            if size > 0:
                self.order = self.buy(size=size)

        # 死叉信号且持有仓位
        elif self.position and \
             self.ma_fast[0] < self.ma_slow[0] and \
             self.ma_fast[-1] >= self.ma_slow[-1]:

            # 处理跌停无法卖出的情况
            if self.data.limit_down[0]:
                return

            self.order = self.close()

    def log(self, txt, dt=None):
        if self.p.printlog:
            dt = dt or self.datas[0].datetime.date(0)
            print(f'{dt.isoformat()}, {txt}')

3. 绩效评估模块

def analyze_results(cerebro):
    # 获取回测结果
    strat = cerebro.runstrats[0][0]

    # 打印最终组合价值
    portvalue = cerebro.broker.getvalue()
    print(f'最终资产: {portvalue:.2f}')

    # 计算年化收益率
    ret = (portvalue / cerebro.startingcash - 1) 
    years = len(cerebro) / 252
    annual_ret = (1 + ret) ** (1/years) - 1

    # 使用 PyFolio 生成专业分析报告
    import pyfolio as pf
    returns, positions, transactions = pf.utils.extract_rets_pos_txn_from_backtrader(cerebro)
    pf.create_returns_tear_sheet(returns)

A 股特有难题解决方案

涨跌停板处理

  • 买入控制 :当limit_up=True 时跳过交易信号
  • 卖出控制:持仓股票触发跌停时,次日优先挂单
  • 价格修正 :使用preday_close 字段计算合理价格区间

停复牌数据清洗

# 示例:标记停牌日

def clean_suspension(df):
    """
    处理停牌数据:1. 将停牌日的 OHLC 设为前收盘价
    2. 成交量设为 0
    3. 添加 is_trading 标志
    """suspend_days = df[df['volume'] == 0].index
    df.loc[suspend_days, ['open','high','low','close']] = df['pre_close']
    df['is_trading'] = ~df.index.isin(suspend_days)
    return df

滑点与手续费建模

# 在 Cerebro 引擎中设置
cerebro.broker.set_slippage_fixed(0.01)  # 固定滑点 1 分钱
cerebro.broker.setcommission(
    commission=0.0003,  # 万 3 佣金
    stamp=0.001,        # 千 1 印花税(仅卖出)
    margin=None,        # 不使用杠杆
    mult=1.0            # 价格乘数
)

生产环境建议

  1. 避免未来函数
  2. 禁用 .shift(-1) 等超前索引操作
  3. 使用 datetime.now() 替代预测时间

  4. 处理幸存者偏差

  5. 包含已退市股票数据
  6. 使用全市场历史成分股测试

  7. 多时间帧验证

    # 添加周线数据作为参考
    weekly_data = cerebro.resampledata(
        daily_data,
        timeframe=bt.TimeFrame.Weeks,
        compression=1
    )

下一步改进方向

尝试给示例策略添加以下增强功能:

  • 加入动态止盈止损逻辑
  • 结合成交量过滤虚假突破
  • 测试不同参数组合的稳定性

推荐学习资源:
– 书籍:《量化交易如何构建自己的算法交易业务》
– 社区:JoinQuant、Ricequant
– 进阶框架:vn.py (适合高频交易)

记住:回测只是量化投资的第一步,实盘前务必进行模拟交易验证!

正文完
 0
评论(没有评论)