KB / ARTICLE

目标仓位与组合调仓

策略文档修订 R1发布于 2026-11-05

本文讲解“最终想持有多少”的目标仓位接口,以及多标的组合调仓方法。

目标仓位方法描述“最终想持有多少”,框架根据当前持仓计算需要买入或卖出的差额。特别适合选股、轮动和定期调仓。

共同规则:

  • 目标方法只对“当前持仓与目标的差额”下单,不会自动撤销已有活动订单。
  • 调仓前应检查 get_open_orders(),否则未成交订单和新差额订单可能叠加。
  • 数量差额会按 lot_size 向下取整;close_position() 为完整清仓,不受整手取整限制。
  • 返回订单编号表示已经提交请求,不表示订单已经成交。

order_target(symbol=None, target=None, price=None, **kwargs)

把标的持仓数量调整到 target。已达目标时不下单。

from qmfquant import  Strategy


class MyStrategy(Strategy):

    def on_bar(self, bar) -> None:
        self.order_target(bar.symbol, target=1000)
        self.order_target(bar.symbol, target=0)

order_target_value(symbol=None, target_value=None, price=None, **kwargs)

按目标市值调仓。框架使用 目标市值 ÷ 当前价格 计算目标数量,再按交易单位调整。

from qmfquant import  Strategy


class MyStrategy(Strategy):

    def on_bar(self, bar) -> None:
        self.order_target_value(bar.symbol, target_value=200_000)

order_target_percent(symbol=None, target_percent=None, price=None, **kwargs)

按账户权益比例设置目标仓位。0.25 表示目标市值为当前权益的 25%。普通无杠杆股票策略通常将比例控制在 0.0 到 1.0。

from qmfquant import  Strategy


class MyStrategy(Strategy):

    def on_bar(self, bar) -> None:
        self.order_target_percent(bar.symbol, target_percent=0.25)

rebalance_weights(...)

按多个标的的目标权重一次性调仓。可以等所有标的时间对齐后在on_bar中执行调仓,也可以在on_cross_section中执行统一调仓。

参数 默认值 说明
target_weights 无 标的到目标权重的映射,权重不能为负
liquidate_unmentioned False 是否清仓未出现在目标中的标的
allow_leverage False 是否允许总权重超过 1
rebalance_tolerance 0.0 小于该权重偏差时不调仓
from qmfquant import  Strategy


class MyStrategy(Strategy):

    def on_cross_section(self, trading_date, timestamp) -> None:
        self.rebalance_weights(
            target_weights={"510300.SH": 0.6, "510500.SH": 0.4},
            liquidate_unmentioned=True,
            rebalance_tolerance=0.01,
        )

同周期调仓为先减后加:先执行释放资金的腿,再执行加仓腿。默认权重和不超过 1.0。该接口更偏向只做多组合;如需正负目标仓位,使用 rebalance_positions(),并确认账户支持做空。

rebalance_positions(...)

按多个标的的目标数量调仓。相比 rebalance_weights 只做多、按权重工作,这个接口按目标持仓数量工作,支持同时表达多头与空头目标,适合反手切换、多空同时管理等高级调仓场景。

参数 默认值 说明
target_positions 无 dict[str, float]:标的到目标数量的映射。正值为多头,负值为空头,0 表示清仓
liquidate_unmentioned False 是否清仓未出现在目标字典中的现有持仓
allow_short 按执行环境自动推断 是否允许负目标仓位
strict_short_capability False 当 broker 未声明支持做空时是否严格拒绝负目标
missing_price_mode "fail" price_map 缺项时的处理:"ignore" 跳过、"skip" 记录后跳过、"fail" 直接报错
from qmfquant import  Strategy


class MyStrategy(Strategy):

    def on_cross_section(self, trading_date, timestamp) -> None:
        self.rebalance_positions(
            target_positions={"IF2406": -2, "510300": 1000},
            liquidate_unmentioned=True,
            allow_short=True,
            missing_price_mode="fail",
        )   

适用场景:

  • 一个调用里同时表达多头与空头目标
  • 从 +100 -> -50 这样的反手切换
  • broker_live 下需要结合 broker capability 提前校验做空能力

调仓计划查询:get_last_target_positions_plan()

执行完成后,可用这个 helper 查看最近一次调仓计划,用于排查“为什么某条腿被跳过、为什么负目标被拒绝、为什么这条腿先执行”等问题。

from qmfquant import  Strategy


class MyStrategy(Strategy):

    def on_bar(self, bar) -> None:
        plan = self.get_last_target_positions_plan()
        print(plan["status"])
        print(plan["reduce_legs"])
        print(plan["increase_legs"])
        print(plan["submitted_legs"])
        print(plan["skipped_legs"])

返回的 plan 字段:

字段 说明
status 本次调仓整体状态,例如 "submitted"、"partial"
reduce_legs 需要减仓(平多 / 平空)的腿
increase_legs 需要加仓(开多 / 开空)的腿
submitted_legs 已成功提交的腿
skipped_legs 因能力不匹配、价格缺失等被跳过的腿

默认 allow_short 按当前执行环境自动推断;在 cash 或 broker 未声明支持做空时,负目标会被明确拒绝。

rebalance_to_topn(...)

根据评分选择前 N 个标的并调仓。返回值是入选标的代码,不是订单编号。

from qmfquant import  Strategy


class MyStrategy(Strategy):

    def on_cross_section(self, trading_date, timestamp) -> None:
        selected = self.rebalance_to_topn(
            scores={"510300.SH": 0.8, "510500.SH": 0.6, "159915.SZ": 0.9},
            top_n=2,
            weight_mode="equal",
            long_only=True,
            liquidate_unmentioned=True,
        )
  • long_only=True 时只做多,这是证券策略的默认选择。
  • weight_mode="equal" 等权;"score" 按正评分分配。

相关阅读

已复制到剪贴板
策略文档修订 R1

返回策略文档板块

评论