BigQuant使用文档

多品种策略

由qxiao创建,最终由qxiao 被浏览 3 用户

多品种回测使用指南

多品种回测的核心思路:**在单一回测框架内,同时持有并管理股票、基金、期货、期权等不同品种。**主框架入口不变,通过"品种声明 + 独立账户 + 指定下单账户"三步扩展到多品种。

核心规律

  1. instruments 里声明所有品种 这是多品种回测的数据入口。所有需要行情数据的品种,无论是 ETF、期货合约还是期权,都必须在 params["instruments"] 里提前声明。引擎只为声明过的品种加载数据。
# 股票 + ETF 基金
params = {
    "instruments": list(df['instrument'].unique()) + ['518880.SH', '513100.SH', '513030.SH'],
    ...
}

# 股票 + 期货
params = {
    "instruments": list(df_factors["instrument"].unique()) + ["IF2506.CFE"],
    ...
}

2. 在 initialize 里用 add_account 开独立账户

非股票品种(基金除外)需要独立账户来隔离资金和保证金。在 initialize 里调用 context.add_account,并将返回的 account_id 保存到 context 上供后续使用。

def initialize(context: bigtrader.IContext):
    # 期货账户:独立保证金
    _, context.future_account_id = context.add_account(
        bigtrader.AccountType.FUTURE,
        capital_base=500_000,
    )

    # 基金账户:与股票同类型,但资金独立
    _, context.etf_account_id = context.add_account(
        bigtrader.AccountType.STOCK,
        capital_base=1_000_000,
    )
品种 AccountType 是否需要独立账户
股票 STOCK 默认账户,无需 add_account
ETF 基金 STOCK 按需,资金需隔离时开
期货 FUTURE 必须独立账户
期权 OPTION 必须独立账户

3. 下单时通过 account_id 指定账户

多账户体系下,下单必须通过 account_id 告知引擎走哪个账户。不传则默认走主账户(股票账户)。

def handle_data(context, data):
    # 期货下单 —— 指定期货账户
    context.buy_open(
        "IF2506.CFE",
        1,
        account_id=context.future_account_id,
    )

    # 股票下单 —— 走默认主账户,无需 account_id
    context.order_target_percent("600519.SH", 0.1)

    # ETF 下单 —— 指定 ETF 账户
    context.order_target_percent(
        "518880.SH",
        0.25,
        account_id=context.etf_account_id,
    )
  1. handle_data 里各品种逻辑独立管理

    每类品种的信号生成和调仓节奏完全独立,写在同一个 handle_data 里按顺序执行即可。

def handle_data(context, data):
    # --- 期货:维持固定手数多头 ---
    fut_pos = context.get_position("IF2506.CFE", direction="1",
                                    account_id=context.future_account_id)
    if fut_pos.current_qty < 1:
        context.buy_open("IF2506.CFE", 1, account_id=context.future_account_id)

    # --- 股票:因子选股,按周期调仓 ---
    if context.stock_rebalance_period.is_signal_date(data.current_dt.date()):
        # ... 选股逻辑 ...
        context.order_target_percent(ins, weight)

    # --- ETF:固定标的,等权持有 ---
    if context.etf_rebalance_period.is_signal_date(data.current_dt.date()):
        for ins in ['518880.SH', '513100.SH']:
            context.order_target_percent(ins, 0.5, account_id=context.etf_account_id)
  1. bigtrader.run 入口保持不变

    无论组合了多少品种,顶层调用方式不变。capital_base 是主账户(股票账户)的初始资金,其他账户的资金在 add_account 时单独设置。

performance = bigtrader.run(
    data=params,
    market=bigtrader.Market.CN_STOCK,   # 填主市场
    frequency=bigtrader.Frequency.DAILY,
    capital_base=1_000_000,             # 主账户(股票)资金
    initialize=initialize,
    handle_data=handle_data,
)

完整结构一览

params["instruments"]        ← 声明所有品种的行情数据
    │
initialize()
    ├── add_account(FUTURE)  ← 期货独立账户
    ├── add_account(STOCK)   ← 基金独立账户(可选)
    └── 调仓计划初始化
    │
handle_data()
    ├── 期货逻辑  → buy_open(..., account_id=future_account_id)
    ├── 股票逻辑  → order_target_percent(ins, weight)
    └── 基金逻辑  → order_target_percent(ins, weight, account_id=etf_account_id)
    │
bigtrader.run()              ← 入口不变

一句话记忆

instruments 声明品种 → add_account 开副账户 → 下单指定 account_id → handle_data 各管各的逻辑。

文档

股票 + 基金组合策略(高股息价值股 + 多资产 ETF 配置)股票+期权(日频双卖+股票买入并持有)
{link}