Files
sanguo_vnpy_v2/sanguo_portfolio/live_strategy.py
T

89 lines
3.5 KiB
Python

"""组合策略实盘适配文件(bullet_trade LiveEngine 加载的聚宽风格 strategy_file)。
bullet_trade 0.9.x LiveEngine 只认策略文件:本文件 ``initialize(context)`` 里把
sanguo_portfolio 的 StrategyTemplate 策略挂到 run_daily/run_monthly 定时器,
下单走 bullet_trade 顶层 API(live 模式自动路由 LiveEngine → QmtBroker)。
配置从 env 读(supervisor 注入,或手动 set 后直跑 ``python -m sanguo_portfolio.runner_live``):
SANGUO_LIVE_STRATEGY all_weather / momentum_timing / value_selection / small_cap
SANGUO_LIVE_MAX_POOL 选股池上限(默认 30)
数据 provider 由 runner_live ``set_data_provider`` 先行注入(miniQMT live 模式)。
"""
from __future__ import annotations
import logging
import os
logger = logging.getLogger(__name__)
def _build_live_strategy(provider):
"""env 配置 → StrategyTemplate 实例(对齐 runner_backtest._build_strategy)。"""
from sanguo_portfolio.strategies import (
AllWeatherConfig, AllWeatherStrategy,
ChannelTestConfig, ChannelTestStrategy,
MomentumTimingConfig, MomentumTimingStrategy,
SmallCapConfig, SmallCapStrategy,
ValueSelectionConfig, ValueSelectionStrategy,
)
name = os.environ.get("SANGUO_LIVE_STRATEGY", "all_weather")
max_pool = int(os.environ.get("SANGUO_LIVE_MAX_POOL", "30") or 30)
factories = {
"all_weather": lambda: AllWeatherStrategy(
provider=provider, config=AllWeatherConfig(max_pool=max_pool)),
"momentum_timing": lambda: MomentumTimingStrategy(
provider=provider, config=MomentumTimingConfig(max_pool=max_pool)),
"value_selection": lambda: ValueSelectionStrategy(
provider=provider, config=ValueSelectionConfig(max_pool=max_pool)),
"small_cap": lambda: SmallCapStrategy(
provider=provider, config=SmallCapConfig(max_pool=max_pool)),
"channel_test": lambda: ChannelTestStrategy(
provider=provider, config=ChannelTestConfig()),
}
if name not in factories:
raise ValueError(
f"未知 SANGUO_LIVE_STRATEGY: {name}"
f"(支持: {' / '.join(factories)})"
)
return factories[name]()
def initialize(context):
"""LiveEngine 启动时回调:挂策略 + 定时器 + 费用滑点。"""
from bullet_trade.core.api import ( # type: ignore
order_target_value as bt_otv,
order_value as bt_ov,
set_order_cost, set_slippage,
)
from bullet_trade.core.settings import ( # type: ignore
OrderCost, FixedSlippage, set_option as bt_set_option,
)
from bullet_trade.data.api import get_data_provider # type: ignore
from sanguo_portfolio.runner_backtest import _register_schedule
from sanguo_portfolio.strategies.all_weather import BrokerFacade
strategy = _build_live_strategy(get_data_provider())
_register_schedule(strategy)
# broker 注入(与回测同构):下单委托 bullet_trade 顶层 API,live 下路由 engine
strategy.broker = BrokerFacade(
order_target_value=lambda c, v: bt_otv(c, v),
order_value=lambda c, v: bt_ov(c, v),
set_option=lambda k, v: bt_set_option(k, v),
)
# A 股费用 + 滑点(与回测默认一致)
set_order_cost(
OrderCost(
open_tax=0.0, close_tax=0.001,
open_commission=0.0003, close_commission=0.0003,
min_commission=5.0,
),
type="stock",
)
set_slippage(FixedSlippage(value=0.001))
strategy.initialize(context)
logger.info("live strategy 已挂载: %s", type(strategy).__name__)