Panda Backtest 模块深度分析
src/panda_backtest 是量化平台的回测引擎核心,采用事件驱动架构,支持股票和期货策略的历史回测。它不仅复用了实盘交易的接口定义,还提供了完善的模拟撮合、风控管理和结果统计功能。
1. 目录结构概览
src/panda_backtest/ ├── api/ # [接口] 策略开发API (api.py, stock_api.py, future_api.py) ├── backtest_common/ # [核心] 回测系统通用组件 │ ├── constant/ # 常量定义 (redis_key, strategy_constant) │ ├── data/ # 内部数据结构与实现 │ │ ├── fund/ # 基金相关数据结构 │ │ ├── future/ # 期货相关数据结构 │ │ ├── stock/ # 股票相关数据结构 │ │ ├── order/ # 订单列表管理 (work_order_list) │ │ ├── quotation/ # 行情数据结构 (bar_map, quotation_data) │ │ └── result/ # 结果集结构 (portfolio) │ ├── exception/ # 异常类定义 │ │ └── code/ # 错误码 │ ├── exchange/ # 交易所模拟逻辑 (stock, future, fund) │ ├── model/ # 数据模型定义 (account, position, order, trade) │ ├── order/ # 订单校验与构建逻辑 (verify, builder) │ ├── result/ # 结果计算基类 │ ├── risk/ # 风控管理模块 │ ├── system/ # 系统底层架构 (event, context, compile) │ ├── type/ # 类型定义 │ └── util/ # 工具函数 ├── config/ # [配置] 环境初始化与配置 (dev_init.py) ├── data/ # 数据与上下文定义 │ ├── context/ # 策略上下文 (strategy_context) │ └── quotation/ # 行情数据源 (bar_data_source) ├── extensions/ # [扩展] 具体回测模式实现 │ ├── common_api/ # 通用计算指标 │ └── trade_reverse_future/ # 期货/股票反向跟单模式(主要回测实现) ├── node/ # 节点定义 ├── router/ # 路由定义 ├── server/ # 服务端工具(结果导出) ├── strategy/ # 策略示例库 ├── system/ # 系统日志配置 ├── util/ # 全局工具 ├── main_run.py # 通用回测启动入口 ├── main_workflow_future.py # 期货工作流回测入口 ├── main_workflow_stock.py # 股票工作流回测入口 └── main_local.py # 本地回测入口
2. 核心子模块详解
2.1 根目录与入口文件
-
main_run.py- 功能: 回测的通用启动入口。
- 逻辑: 负责接收命令行参数或配置字典,初始化
CoreContext,加载策略文件,并启动事件引擎循环。它是连接前端请求与后台回测逻辑的桥梁。
-
main_local.py- 功能: 本地调试入口。
- 逻辑: 允许开发者在本地 IDE 中直接运行策略,方便调试。
-
main_workflow_future.py- 功能: 专为工作流设计的期货回测启动脚本。
- 逻辑: 从工作流节点中解析特定的期货参数(如保证金率、手续费),配置回测环境,并调用底层的运行逻辑。
-
main_workflow_stock.py- 功能: 专为工作流设计的股票回测启动脚本,支持多因子选股策略的自动化回测。
start函数核心流程:- 参数解析: 接收
back_test_id,start_capital,df_factor(因子数据) 等关键参数。 - 上下文初始化:
- 创建
StrategyContext并注入因子数据 (init_factor_params)。 - 初始化
CoreContext单例,作为全局状态容器。
- 创建
- 环境准备: 调用
DevInit初始化日志系统,确保日志能正确输出和远程上报。 - 策略加载: 使用
FileStrategyLoader动态加载策略代码文件,构建全局参数global_args。 - 扩展加载: 动态导入
trade_reverse_future扩展模块,这是实际执行回测逻辑的“反向跟单”引擎。 - 启动运行: 实例化
Engine并调用run()方法,进入事件循环。 - 异常处理: 捕获运行时的所有异常并记录堆栈信息,确保日志系统的正确关闭。
- 参数解析: 接收
2.2 api - 策略开发接口
此目录定义了策略开发者在编写策略时可以直接调用的 API。为了方便策略层直接使用,系统采用装饰器模式将常用函数注入到全局命名空间。
-
api.py-
功能: 通用交易与控制接口,是策略编写时最常用的模块。
-
核心机制 (
append_to_api_list): 这是一个装饰器,用于将被装饰的函数自动注册到api_list并注入到globals()中。这使得策略代码可以直接调用如order_shares而无需繁琐的导入语句。 -
关键 API:
order_shares(account_id, id_or_ins, quantity, ...): 股票下单核心函数。它会进行参数解析(如将正负数转换为买卖方向),并调用底层的CoreContext进行下单。init_risk_control(api): 初始化风控组件接口。init_sr_logger(): 初始化远程日志记录器- 特殊说明,官方文档中的API列表不全,剩余的API可在此文件中查找,例如卖出平空
- 完整 API 列表补充:
- 股票交易:
order_shares(account_id, id_or_ins, quantity, ...): 指定股数交易。order_values(account_id, id_or_ins, amount, ...): 指定金额交易。cancel_order(account_id, order_id): 撤销股票订单。sub_stock(symbol_list): 订阅股票行情。target_stock_group_order(account, symbol_dict, price_type=0): 股票批量目标下单。get_today_order(account_id, order_id): 获取当日股票订单。get_today_work_order(account_id): 获取当日未完成股票订单。
- 期货交易:
buy_open(account_id, id_or_ins, amount, ...): 期货买入开仓。sell_open(account_id, id_or_ins, amount, ...): 期货卖出开仓。sell_close(account_id, id_or_ins, amount, ...): 期货卖出平仓。buy_close(account_id, id_or_ins, amount, ...): 期货买入平仓。cancel_future_order(account_id, order_id): 撤销期货订单。long_future_target(account_id, id_or_ins, target_amount, ...): 期货多头调仓至目标手数。short_future_target(account_id, id_or_ins, target_amount, ...): 期货空头调仓至目标手数。target_future_group_order(account, long_symbol_dict, short_symbol_dict): 期货批量目标下单。get_today_future_order(account_id, order_id): 获取当日期货订单。get_today_work_future_order(account_id): 获取当日未完成期货订单。auto_retry_cancel_future_order(order, max_retry=15): 自动重试撤单追单。
- 基金交易:
purchase(account_id, symbol, amount, ...): 基金申购。redeem(account_id, symbol, quantity, ...): 基金赎回。
- 通用与辅助:
subscribe(id_or_symbols, frequency='1d'): 订阅行情数据。export_data_to_file(data_frame): 导出数据到文件。cash_moving(from_account, to_account, cash, move_type): 账户间资金划转。draw(data): 绘图数据推送。pub_data(pub_key, json_data): 推送策略消息。sub_data(sub_keys, call_back): 订阅策略消息。
- 股票交易:
-
-
stock_api.py- 功能: 股票专用数据接口。
- 关键 API:
stock_api_quotation: 获取股票历史行情 (Open/High/Low/Close/Volume)。stock_api_pre_close: 获取股票昨日收盘价,常用于计算涨跌停板或持仓市值。
-
future_api.py- 功能: 期货专用数据接口。
- 关键 API:
future_api_quotation: 获取期货多周期行情 (1m, 5m, 1d 等)。future_api_domain_symbol: 查询主力合约代码。
2.3 backtest_common - 核心系统组件
此目录包含了回测引擎的底层基础设施,不依赖于具体的交易品种。
2.3.1 constant (常量定义)
集中管理系统中的枚举值和静态常量,避免硬编码。
strategy_constant.py: 交易核心常量。定义了买卖方向 (SIDE_BUY,SIDE_SELL)、订单类型 (MARKET,LIMIT)、交易所代码 (MKT_SZ,MKT_SH等) 以及订单状态机 (WAIT,FILLED,CANCELLED)。redis_key.py: Redis 键名规范定义。string_constant.py: 通用字符串常量。
2.3.2 data (数据访问层)
策略交互层。此模块并不存储底层数据,而是作为策略层与底层数据模型之间的适配器(View Layer)。为了适配回测和实盘(或仿真)环境,部分模块分拆为 back_test 和 real_time 两个子目录。
fund/&stock/&future/:- Common: 定义了抽象基类(如
BaseFundAccount),规范了账户必须具备的接口(如cash,positions)。 back_test/: 回测专用的账户 (...Account) 和持仓 (...Positions) 实现。它们适配了回测引擎的数据结构,通常从dailyResult等层级获取历史数据。real_time/: 实盘/仿真专用的账户和持仓实现。它们直接适配实时状态数据结构(如xb_back_test_account),并可能包含针对实时环境的特殊逻辑。
- Common: 定义了抽象基类(如
quotation/:quotation_data.py: 单例容器,作为当前时间切片行情数据 (bar_dict) 的全局访问点。back_test/: 回测专用的行情数据源实现(如BarMap),负责从历史数据库中加载数据。
order/:common/work_order_list.py: 通用的待成交订单列表管理,基于内存字典实现,适用于回测。real_time/: 包含StockWorkOrderList和FutureWorkOrderList。引入了数据库持久化机制(如 MongoDB),确保在实盘/仿真环境下即使进程重启,订单状态也不会丢失。
result/:back_test/portfolio.py: 回测模式下的投资组合信息。从每日结算的历史结果中聚合资金和盈亏数据。real_time/portfolio.py: 实盘模式下的投资组合信息。直接从当前的实时账户状态中聚合数据。
2.3.3 exception (异常体系)
统一系统的错误处理与异常定义。
error_exception.py: 定义了标准异常基类ErrorException,包含错误码 (code)、错误信息 (message) 和服务源 (service)。risk_control_exception.py: 风控阻断异常。当风控规则触发时抛出此异常,阻断下单流程。code/error_code.py: 系统全局错误码定义。
2.3.4 exchange (交易所模拟)
模拟交易所的核心逻辑,处理订单撮合、结算、资金划转等。为了支持不同的运行模式,各资产目录下通常分为 back_test(回测模式)和 real_time(实时模式)两个子模块。
common/: 通用模拟驱动组件。back_test/trade_time_manager.py: 回测时间驱动器。负责构建和管理回测的时间轴 (all_date_list)。它从数据库加载交易日历,根据设定的回测频率(日线/分钟)推进时间,是整个回测循环的“时钟”。back_test/quotation_subscribe.py: 行情驱动器。配合时间驱动器工作,在每个时间切片上,根据策略订阅的股票、期货或基金代码,从数据源拉取最新行情。它负责发布QUOTATION_CHANGE(行情更新)和ORDER_CROSS(尝试撮合)事件,从而驱动交易所模块处理挂单。
stock/:back_test/:stock_exchange.py: 股票交易所模拟。维护一个work_order列表,处理每日分红 (dividend_manager)、ETF 拆分 (etf_split_manager) 和收盘后的未成交单撤单。dividend_manager.py: 股票分红管理逻辑。etf_split_manager.py: ETF 拆分管理逻辑。
real_time/:stock_order_quotation_verify.py: 实时行情订单校验。在实盘或仿真环境中,利用实时行情数据(如盘口价格)对订单价格进行修正(如市价单转限价)和有效性检查。
future/:back_test/:future_exchange.py: 期货交易所模拟。处理期货特有的结算 (future_settle_manager)、保证金计算 (future_margin_map) 和开平仓拆分 (future_order_split_manager)。它通过add_order_verify机制挂载校验逻辑。future_settle_manager.py: 期货每日结算逻辑。future_rate_manager.py: 期货费率管理。
real_time/:future_order_quotation_verify.py: 实时行情订单校验。负责在实时环境下检查行情有效性,并将市价单根据最小变动价位转换为限价单。
fund/:back_test/:fund_exchange.py: 基金交易模拟。fund_rate_manager.py: 基金费率管理。
- 根目录:
fund_bonus_manager.py: 基金分红管理。fund_split_manager.py: 基金拆分管理。
2.3.5 model (数据模型)
定义了回测系统中的底层数据实体。与 data 模块不同,这里定义的是实际存储数据的类,通常与数据库表结构或底层传输协议一一对应。
info/:run_info.py: 策略运行配置信息。包含回测 ID、起止日期、资金初始值、滑点、手续费倍率、运行频率(日线/分钟)以及运行模式(回测/模拟)等关键配置。它是整个回测任务的元数据描述。
quotation/:bar_quotation_data.py: K线数据模型。定义了标准 OHLCV 字段,以及 ask/bid 盘口数据(支持多档)、涨跌停板价等扩展字段。它是行情数据在系统内部流转的标准载体。dividend.py: 分红数据模型。..._split.py: ETF/基金拆分数据模型。
result/:- 通用模型:
panda_backtest_account.py: 账户状态实体(资金、权益)。panda_backtest_position.py: 持仓实体。panda_backtest_trade.py: 成交记录实体(回测结果专用)。order.py: 订单实体。panda_backtest_instrument.py: 合约信息实体。存储合约类型(股票/期货)、乘数、最小交易单位、保证金率、手续费率等基础属性。panda_backtest_profit.py: 回测收益概览实体。记录每日的策略累计收益率、基准收益率(如沪深300)、超额收益以及当日买卖总额。trade_data.py: 通用成交数据实体。相比panda_backtest_trade,它更偏向于底层或实盘接口的原始成交回报结构,包含tradeID,orderID,direction,offset等字段。
- 实盘/仿真专用 (
real/simulation):panda_real_daily_value.py: 实盘每日权益快照。记录每日的总权益、累计收益率、当日盈亏等,用于生成实盘资金曲线。panda_real_minute_value.py: 实盘分钟级权益快照。panda_simulation_minute_value.py: 模拟交易分钟级权益快照。panda_real_withdraw_deposit.py: 实盘出入金记录。用于精确计算实盘收益率(需剔除出入金影响)。
- 通用模型:
2.3.6 order (订单校验)
负责对发出的订单进行合规性校验和风控检查,确保订单在逻辑上有效且符合交易规则。该模块采用了责任链模式或组合模式,将不同的校验逻辑解耦。
order_verify.py: 校验基类。定义了OrderVerify抽象基类,所有具体的校验器(如资金校验、持仓校验、停牌校验)都必须实现can_submit_order接口。common/:order_risk_control_verify.py: 通用风控校验。通过事件总线发布RISK_CONTROL_ORDER_VERIFY事件,将订单提交给风控系统进行二次确认。order_quotation_verify.py: 通用行情校验。
stock/,future/,fund/:common/: 定义了该资产类别通用的校验逻辑和订单构建器。..._order_account_verify.py: 账户资金校验。检查账户是否有足够的可用资金(买入)或持仓(卖出/平仓)。..._order_builder.py: 订单构建器。负责将策略层的下单指令封装成标准的Order对象。stock_order_susp_verify.py(Stock特有): 停牌校验。检查股票当前是否处于停牌状态。
back_test/: 回测环境专用校验。..._order_limit_price_verify.py: 涨跌停板校验。回测中通常禁止在涨跌停板价位成交,模拟真实市场的流动性枯竭。..._order_volume_verify.py: 成交量校验。检查订单量是否超过了当根 Bar 的总成交量(防止回测过拟合)。
simulation/: 仿真/实盘环境专用校验。..._trade_time_verify.py: 交易时间校验。严格检查当前时刻是否在交易所规定的交易时间段内,防止非交易时间下单。..._order_limit_price_verify.py: 实盘环境下的价格限制校验。
2.3.7 risk (风控管理)
risk_control_manager.py: 风控管理器。从 MongoDB 加载风控规则,并在交易的关键生命周期(如handle_bar,order_verify)触发风控检查。它支持多级风控的动态加载和参数配置。risk_api.py: 定义了风控模块可调用的 API 接口。
2.3.8 result (结果计算)
负责回测结果的实时计算与状态维护。它不仅是数据的存储容器,更是核心的清算逻辑所在。该模块在每一个 Bar 结束时更新账户的权益、持仓盈亏,并处理分红、拆分等除权除息事件。
base_all_result.py: 总结果聚合器。管理所有子账户(股票、期货、基金)的结果对象,负责计算整体策略的净值曲线和风险指标。stock/,future/,fund/: 针对不同资产类别的具体清算逻辑。back_test/: 回测模式下的清算实现。base_trade_reverse_result.py(Stock): 股票清算基类。实现了股票特有的 T+1 交易制度、分红派息处理、交易成本计算等逻辑。base_future_reverse_result.py(Future): 期货清算基类。实现了期货特有的每日无负债结算制度(Mark-to-Market),处理保证金占用、浮动盈亏、交割结算等复杂逻辑。base_fund_reverse_result.py(Fund): 基金清算基类。
2.3.9 system (系统架构)
这是整个回测引擎的核心中枢,负责协调各个模块的运作。它采用了事件驱动架构 (Event-Driven Architecture) 和依赖注入模式,确保了系统的高度解耦和可扩展性(特别是支持回测与实盘模式的无缝切换)。
context/:core_context.py: 全局上下文管理器 (Singleton)。- 它是系统的“上帝对象”,持有并管理所有核心组件的实例,包括事件总线 (
event_bus)、策略上下文 (strategy_context)、事件处理器 (event_process)、操作代理 (operation_proxy) 和风控管理器 (risk_control_manager)。 - 通过单例模式,确保系统各处都能访问到统一的全局状态。
- 它是系统的“上帝对象”,持有并管理所有核心组件的实例,包括事件总线 (
event/:engine.py: 事件引擎。系统的动力核心,负责启动主循环并驱动事件流转。event.py: 事件总线与定义。EventBus: 实现了发布-订阅模式。策略函数、风控模块、交易模块都通过它进行解耦通信。ConstantEvent: 定义了系统中所有的事件类型,如STRATEGY_INIT(策略初始化),STRATEGY_HANDLE_BAR(行情切片到达),ORDER_CROSS(订单撮合),RISK_CONTROL_VERIFY(风控校验) 等。
compile/:strategy.py: 策略加载器。负责解析用户的策略代码,将用户定义的initialize,handle_data,before_trading等函数注册为EventBus上的事件回调。这解释了为什么用户只需要写这几个函数就能被系统自动调用。risk_control_loader.py: 风控模块加载器。
interface/:base_event_process.py: 事件处理抽象基类。定义了如何生成和分发事件。回测模式下由EventProcess实现(基于历史数据生成事件),实盘模式下则由实时行情驱动生成事件。base_operation_proxy.py: 操作代理抽象基类。定义了place_order,cancel_order,get_account_info等标准交易接口。- 在回测中,它调用模拟撮合引擎。
- 在实盘中,它调用真实的柜台交易接口 (CTP/XTP等)。
- 这种设计使得策略代码完全不需要修改即可在回测和实盘间切换。
2.3.10 type (类型定义)
定义强类型的参数对象,用于规范 API 调用,提供比字典更明确的类型约束。
order_type.py: 定义了订单风格类。LimitOrderStyle: 限价单风格,包含limit_price属性。MarketOrderStyle: 市价单风格。
2.3.11 util (通用工具)
提供独立于具体业务逻辑的基础工具函数。
date_util.py: 日期处理工具。核心功能是基于 MongoDB 中的交易日历表 (trading_calendar_all) 提供交易日推算功能,如get_pre_date(获取前 N 个交易日) 和get_next_trade_date(获取后 N 个交易日)。
2.4 extensions - 扩展模块
此目录包含系统的插件化扩展功能,用于适配不同的回测场景或提供通用计算能力。
-
common_api/: 通用指标计算。- 提供
IndexCalculate等工具类,用于计算 Alpha、Beta、Sharpe 等策略评价指标,支持独立调用或被其他模块集成。
- 提供
-
trade_reverse_future/: 反向跟单回测模式(核心实现)。- 这是系统当前默认的模拟交易引擎,通过“反向跟单”的逻辑模拟真实交易环境。
- 核心组件:
main.py: 扩展入口,负责将特定的事件处理器 (EventProcess) 和操作代理 (OperationProxy) 注入全局上下文。reverse_operation_proxy.py: 回测总控中心,协调行情驱动、风控检查与策略执行。reverse_event_process.py: 封装标准的回测事件流。trade/: 包含股票、期货和基金的模拟交易接口实现,负责将策略指令转化为模拟交易所的订单。result/: 负责各品种的每日结算与盈亏统计。
2.5 config - 环境配置模块
负责回测环境的初始化配置,特别是日志系统和运行模式的设定。
dev_init.py- 功能: 开发与运行环境初始化工具。
init_log_env(project_name): 初始化本地文件日志系统,设置日志路径和格式。init_remote_sr_log(...): 初始化远程日志 (SRLogger)。它会建立与日志服务器的连接,用于实时上报回测进度和关键错误信息,支持回测 ID (back_test_id) 的关联,方便后续追踪。
2.6 server & util&system - 辅助模块
-
server/tools.py- 功能: 结果导出工具。
- 逻辑: 包含
python2html(将 DataFrame 转为 HTML 表格用于前端展示)和save_dataframe_to_mongo(异步保存回测结果数据)。
-
system/panda_log.py: 系统的日志配置,定义了日志格式和输出级别。 -
util/annotation/singleton_annotation.py: 单例模式装饰器,用于保证 Context 等对象的全局唯一性。
2.7 data - 数据与上下文
此目录主要定义了回测运行时所需的数据容器和上下文对象,连接了底层数据源与上层策略逻辑。
-
context/strategy_context.py- 功能: 策略运行上下文对象。
- 核心职责:
- 状态容器: 持有所有的账户实例 (
stock_account_dict,future_account_dict,fund_account_dict) 和投资组合结果 (portfolio)。 - 运行配置: 通过
RunInfo对象记录回测的元数据(如起止日期、初始资金、手续费率等)。 - 数据访问: 提供了
df_factor(因子数据) 的访问接口。 - 辅助功能: 提供了时间管理 (
now,trade_date), 订阅管理 (sub_stock_symbol,sub_future_symbol) 以及判断是否为交易日等便捷方法。 - 策略交互: 它是策略代码中
context参数的实际载体,策略通过它获取账户资金、持仓信息和当前时间。
- 状态容器: 持有所有的账户实例 (
-
quotation/bar_data_source.py- 功能: 行情数据源适配器。
- 核心职责:
- 数据获取: 封装了对底层 MongoDB 数据库的访问逻辑,负责根据
symbol和date拉取日线或分钟线数据。 - 多级缓存: 实现了
stock_daily_bar,stock_minute_bar等内存字典缓存,避免对同一数据的重复数据库查询,提高回测性能。 - 多品种支持: 统一处理了股票 (
stock), 期货 (future), 基金 (fund) 以及指数/ETF 的不同数据集合 (collection) 映射逻辑。 - 数据标准化: 将数据库返回的原始字典转换为标准的
BarQuotationData对象,统一了open,high,low,close,volume等字段的访问方式。
- 数据获取: 封装了对底层 MongoDB 数据库的访问逻辑,负责根据
3. 关键工作流总结
- 启动:
main_run.py或main_workflow_stock.py初始化CoreContext,加载策略代码,实例化EventEngine。 - 初始化:
ReverseOperationProxy建立交易所模拟器 (Exchange) 和账户,注册事件监听。 - 运行:
Engine推进时间,发布BAR事件。ReverseOperationProxy捕获事件,更新BarDataSource。- 触发
RISK_CONTROL(风控) ->STRATEGY(策略)。
- 交易:
- 策略调用
context.order->api.py。 - 转发至
FutureTradeApi->FutureExchange。 Exchange调用OrderVerify链进行校验。- 校验通过后,订单进入
WorkOrderList等待撮合。
- 策略调用
- 结算: 每日收盘后,
Exchange处理结算,Result模块计算当日权益和风险指标。 - 输出: 回测结束,
tools.py将结果生成报表并存入 MongoDB。