固定目标配置:多资产目标权重与可选开关
重要声明:策引是个人开发的投资策略分析工具和教育平台,通过模拟组合展示交易规则、仓位变化与历史表现。平台不提供投资建议,所有策略分析仅供研究参考。真实账户中的决策与风险由用户自行判断和承担。
普通的原语策略回答"何时买、何时卖";轮动策略回答"这一期在候选里选谁"。还有一种更直接的组合方式:你心里已经想好了一个固定的资产清单和各自的目标比例,只想再给它加一个可选的"开/关"条件。
这就是 TargetAllocation(固定目标配置)。
一句话区分三种组合方式:
- 纵向(普通策略):"QQQ 上穿 200 日线就买 QQQ。"
- 横向(轮动 / 横截面):"在我这 10 只里,每月持有 RSI 最强的 3 只。"
- 目标配置(TargetAllocation):"SPY 60% + TLT 40%,每季度调回这个比例;SPY 跌破 200 日线时把 SPY 归零。"
怎么工作的
TargetAllocation 由四部分组成:
| 环节 | 作用 | 举例 |
|---|---|---|
| 固定资产 | 你要持有哪些资产 | SPY、TLT |
| 目标权重 | 每个资产的最终目标比例 | SPY 0.60、TLT 0.40 |
| 可选开关 | 每个资产各自的启用条件(布尔信号) | SPY 是否站上 200 日线 |
| 再平衡节奏 | 多久把组合调回目标比例 | 每季度 / 每月 / 不自动再平衡 |
关键一点:weight 就是最终的、可直接执行的目标权重,不会再乘以其它 exposure 系数。SPY 0.60 + TLT 0.40 之和是 1.0,代表满仓;如果你写 SPY 0.50 + TLT 0.30(之和 0.80),剩余 0.20 就是现金,这是明确的一部分组合,不是"算错"。
因此 TargetAllocation 必须搭配 RebalancingCapitalStrategy,且其 gross_exposure 必须是 1.0——目标权重本身就是唯一的敞口来源,不能再叠加一个杠杆/敞口系数。
三个例子
1. 普通 60/40,季度再平衡
最经典的股债组合,没有开关,每个季度把漂移后的比例调回 60/40:
{
"strategy_definition": {
"trade_strategy": {
"indicators": [],
"signals": [],
"outputs": {}
},
"portfolio_construction": {
"type": "TargetAllocation",
"allocations": [
{ "symbol": "SPY", "weight": 0.60 },
{ "symbol": "TLT", "weight": 0.40 }
],
"rebalance": {
"frequency": "quarterly"
}
},
"capital_strategy": {
"name": "RebalancingCapitalStrategy",
"params": {
"initial_capital": 100000,
"gross_exposure": 1.0
}
}
}
}
2. 各自独立的开关
SPY 和 TLT 各自用自己资产的趋势作为开关,互不影响:
{
"strategy_definition": {
"market_indicators": {
"indicators": [
{ "code": "SPY" },
{ "code": "TLT" }
],
"transformers": [
{ "name": "spy_price", "type": "IdentityTransformer", "params": { "indicator": "SPY", "field": "Close" } },
{ "name": "tlt_price", "type": "IdentityTransformer", "params": { "indicator": "TLT", "field": "Close" } },
{ "name": "spy_ma200", "type": "MovingAverageTransformer", "params": { "indicator": "SPY", "window": 200 } },
{ "name": "tlt_ma200", "type": "MovingAverageTransformer", "params": { "indicator": "TLT", "window": 200 } }
]
},
"trade_strategy": {
"indicators": [],
"signals": [
{ "id": "spy_gate", "type": "GreaterThan", "inputs": [{ "market": "SPY", "transformer": "spy_price" }, { "market": "SPY", "transformer": "spy_ma200" }] },
{ "id": "tlt_gate", "type": "GreaterThan", "inputs": [{ "market": "TLT", "transformer": "tlt_price" }, { "market": "TLT", "transformer": "tlt_ma200" }] }
],
"outputs": {}
},
"portfolio_construction": {
"type": "TargetAllocation",
"allocations": [
{ "symbol": "SPY", "weight": 0.60, "enabled_by": "spy_gate" },
{ "symbol": "TLT", "weight": 0.40, "enabled_by": "tlt_gate" }
],
"rebalance": {
"frequency": "quarterly"
}
},
"capital_strategy": {
"name": "RebalancingCapitalStrategy",
"params": { "initial_capital": 100000, "gross_exposure": 1.0 }
}
}
}
开关为 true 时,该资产按目标权重配置;为 false 时,该资产的目标精确归 0,剩余部分进现金。
3. 多资产共享一个外部开关
开关信号可以引用 market_indicators 里的外部观察标的——它不必出现在组合的 traded symbols[] 里,也不占用交易标的数量上限,它只是"看"的信号来源:
{
"strategy_definition": {
"market_indicators": {
"indicators": [
{ "code": "QQQ" }
],
"transformers": [
{ "name": "qqq_price", "type": "IdentityTransformer", "params": { "indicator": "QQQ", "field": "Close" } },
{ "name": "qqq_ma200", "type": "MovingAverageTransformer", "params": { "indicator": "QQQ", "window": 200 } }
]
},
"trade_strategy": {
"indicators": [],
"signals": [
{ "id": "qqq_gate", "type": "GreaterThan", "inputs": [{ "market": "QQQ", "transformer": "qqq_price" }, { "market": "QQQ", "transformer": "qqq_ma200" }] }
],
"outputs": {}
},
"portfolio_construction": {
"type": "TargetAllocation",
"allocations": [
{ "symbol": "QQQM", "weight": 0.30, "enabled_by": "qqq_gate" },
{ "symbol": "TQQQ", "weight": 0.20, "enabled_by": "qqq_gate" }
],
"rebalance": {
"frequency": "monthly"
}
},
"capital_strategy": {
"name": "RebalancingCapitalStrategy",
"params": { "initial_capital": 100000, "gross_exposure": 1.0 }
}
}
}
这里 QQQM、TQQQ 是 traded 资产,QQQ 只是观察源。多个资产共用同一个 QQQ 趋势开关,是 TargetAllocation 的一等公民能力,不是某个策略的特例。
精确语义
| 语义 | 规则 |
|---|---|
weight | 最终的、可直接执行的目标权重,不再乘以 gross_exposure |
| 剩余权重 | 自动作为现金(residual cash) |
gross_exposure | TargetAllocation 必须为 1.0,否则校验拒绝 |
enabled_by 缺省 | 该资产始终启用 |
enabled_by = false | 该资产目标精确为 0 |
enabled_by 的布尔来源 | 必须解析为布尔信号,可引用 market_indicators 外部观察标的 |
| 外部观察标的 | 只作信号来源,不必是 traded 标的,不占 traded 数量上限 |
rebalance.frequency | 必填:none / monthly / quarterly,无隐藏默认值 |
| 开关翻转 | 立即重算整份目标向量(所有启用资产回到各自 authored weight,禁用资产归 0) |
none | 只在开关翻转时整体再平衡,其余时间 hold-and-drift |
monthly / quarterly | 在开关翻转之外,额外按周期整体再平衡 |
| 重复资产 / 负权重 / 权重和大于 1 | 校验拒绝 |
和轮动(Cross-sectional)的区别
两者都用"完整目标权重向量"执行,但选择权重的方式完全不同:
| TargetAllocation | Cross-sectional | |
|---|---|---|
| 资产清单 | 作者固定写明 | 候选池固定,但每一期由评估器选择/排名 |
| 权重来源 | 作者固定写明每个目标权重 | 评估器归一化后产出完整向量(如等权前 N) |
| 开关 | 每个资产可选的布尔 enabled_by | 资格条件决定谁参与排名 |
| 定位 | "我想长期 60/40,加个趋势开关" | "我想每期自动选最强的几只" |
两者不互相替代。想长期固定比例用 TargetAllocation;想定期在候选里择优用 Cross-sectional。
常见问题
为什么不用 trade_strategy.outputs 写买卖信号?
TargetAllocation 的目标权重完全由 portfolio_construction 产生,trade_strategy.outputs 必须留空({})。trade_strategy 仍然必填,用来承载 enabled_by 引用的 permission 信号(没有开关时可以是空的 indicators / signals 数组)。写成 outputs.buy_signal 反而会被校验拒绝。