|
7 | 7 | <a id="english"></a> |
8 | 8 | ## English |
9 | 9 |
|
10 | | -Standalone us_equity strategy repository for QuantStrategyLab platforms. |
| 10 | +Standalone `us_equity` strategy repository for QuantStrategyLab platforms. |
11 | 11 |
|
12 | | -Current strategy implementations: |
| 12 | +This repository is the strategy layer: it owns pure signal, allocation, and target-computation logic plus strategy metadata. Downstream platform repositories still own broker adapters, order routing, schedule, secrets, and notifications. |
13 | 13 |
|
14 | | -- `global_etf_rotation` |
15 | | -- `hybrid_growth_income` |
16 | | -- `semiconductor_rotation_income` |
| 14 | +### Strategy index |
| 15 | + |
| 16 | +| Profile | Downstream runtime today | Core idea | |
| 17 | +| --- | --- | --- | |
| 18 | +| `global_etf_rotation` | `InteractiveBrokersPlatform` | Quarterly top-2 global ETF rotation with a daily canary defense | |
| 19 | +| `hybrid_growth_income` | `CharlesSchwabPlatform` | QQQ-driven TQQQ attack layer plus SPYI / QQQI income layer and BOXX defense | |
| 20 | +| `semiconductor_rotation_income` | `LongBridgePlatform` | SOXL / SOXX trend switch with BOXX parking and an additive income sleeve | |
17 | 21 |
|
18 | 22 | These strategies are consumed by platform repositories through `QuantPlatformKit` strategy contracts and component loaders. |
19 | 23 |
|
| 24 | +### global_etf_rotation |
| 25 | + |
| 26 | +**Objective** |
| 27 | +- Keep a broad, lower-beta rotation framework for US equity accounts. |
| 28 | +- Stay open to leadership from tech and semiconductors without concentrating only in high-beta products. |
| 29 | +- Fall back to a short-duration safe haven when the cross-asset risk picture is weak. |
| 30 | + |
| 31 | +**Universe** |
| 32 | +- 22 rotation ETFs: `EWY`, `EWT`, `INDA`, `FXI`, `EWJ`, `VGK`, `VOO`, `XLK`, `SMH`, `GLD`, `SLV`, `USO`, `DBA`, `XLE`, `XLF`, `ITA`, `XLP`, `XLU`, `XLV`, `IHI`, `VNQ`, `KRE` |
| 33 | +- Canary basket: `SPY`, `EFA`, `EEM`, `AGG` |
| 34 | +- Safe haven: `BIL` |
| 35 | + |
| 36 | +**Indicators and rules** |
| 37 | +- Momentum uses Keller-style `13612W` monthly momentum: `(12×R1M + 4×R3M + 2×R6M + R12M) / 19`. |
| 38 | +- Trend filter: candidate ETF must be above its 200-day SMA. |
| 39 | +- Hold bonus: an existing holding receives `+2%` score bonus to reduce turnover. |
| 40 | +- Daily canary check: if all 4 canary assets have negative or missing momentum, the strategy goes `100% BIL` immediately. |
| 41 | + |
| 42 | +**Rebalance behavior** |
| 43 | +- Normal rotation only happens on the last NYSE trading day of March, June, September, and December. |
| 44 | +- On a rebalance day, the strategy ranks the eligible universe and selects the top 2 ETFs. |
| 45 | +- Selected ETFs are equally weighted (`50 / 50`). |
| 46 | +- If fewer than 2 names survive, the unused slot is parked in `BIL`. |
| 47 | +- On non-rebalance days, the strategy returns no target change unless the canary emergency path is triggered. |
| 48 | + |
| 49 | +**Why it exists** |
| 50 | +- Compared with a pure tech or leveraged-Nasdaq approach, this profile is meant to be steadier. |
| 51 | +- It still allows `VOO`, `XLK`, and `SMH` to win their way into the rotation instead of hard-coding them out. |
| 52 | + |
| 53 | +### hybrid_growth_income |
| 54 | + |
| 55 | +**Objective** |
| 56 | +- Combine growth exposure, income production, and idle-cash defense in one profile. |
| 57 | +- Let the attack sleeve react to QQQ trend conditions while keeping a separate income sleeve for larger accounts. |
| 58 | + |
| 59 | +**Portfolio layers** |
| 60 | +- Attack layer: `TQQQ` |
| 61 | +- Income layer: `SPYI`, `QQQI` |
| 62 | +- Defense / cash-like layer: `BOXX` plus a cash reserve |
| 63 | + |
| 64 | +**Signals and indicators** |
| 65 | +- Uses daily `QQQ` history as the signal source. |
| 66 | +- Core indicators are `MA200` and `ATR14%`. |
| 67 | +- The strategy derives two ATR-adjusted lines around `MA200`: |
| 68 | + - `entry_line = MA200 × clamp(1 + ATR% × atr_entry_scale)` |
| 69 | + - `exit_line = MA200 × clamp(1 - ATR% × atr_exit_scale)` |
| 70 | +- The exact clamp floors/caps are injected by the downstream runtime. |
| 71 | + |
| 72 | +**Attack-layer rules (`TQQQ`)** |
| 73 | +- Position size comes from `get_hybrid_allocation(strategy_equity, qqq_p, exit_line)`. |
| 74 | +- That sizing is applied only to strategy-layer equity, which is total equity after subtracting the income layer. |
| 75 | +- If already holding `TQQQ`: |
| 76 | + - `QQQ < exit_line` → target `TQQQ = 0` |
| 77 | + - `exit_line <= QQQ < MA200` → target `TQQQ = agg_ratio × 0.33` |
| 78 | + - `QQQ >= MA200` → target `TQQQ = agg_ratio` |
| 79 | +- If flat and `QQQ > entry_line` → open `TQQQ` at `agg_ratio`. |
| 80 | + |
| 81 | +**Income-layer rules (`SPYI` / `QQQI`)** |
| 82 | +- `get_income_ratio(total_equity)` stays at `0` below the configured threshold. |
| 83 | +- From `1x` to `2x` the threshold, the income sleeve ramps linearly to `40%`. |
| 84 | +- Above `2x` the threshold, the income sleeve caps at `60%`. |
| 85 | +- `QQQI_INCOME_RATIO` decides the split between `QQQI` and `SPYI`. |
| 86 | + |
| 87 | +**Defense behavior (`BOXX` and cash)** |
| 88 | +- A cash reserve is kept at the strategy layer. |
| 89 | +- After reserving cash and sizing `TQQQ`, the remaining strategy-layer capital is assigned to `BOXX`. |
| 90 | +- Downstream execution decides whether the gap to target is large enough to trade via a rebalance threshold. |
| 91 | + |
| 92 | +**Current live Charles Schwab profile defaults** |
| 93 | +- `INCOME_THRESHOLD_USD = 100000` |
| 94 | +- `QQQI_INCOME_RATIO = 0.5` |
| 95 | +- `CASH_RESERVE_RATIO = 0.05` |
| 96 | +- `REBALANCE_THRESHOLD_RATIO = 0.01` |
| 97 | +- `RISK_LEVERAGE_FACTOR = 3.0`, `RISK_NUMERATOR = 0.30`, `RISK_AGG_CAP = 0.50` |
| 98 | +- `ATR_EXIT_SCALE = 2.0`, `ATR_ENTRY_SCALE = 2.5` |
| 99 | +- `EXIT_LINE_FLOOR / CAP = 0.92 / 0.98`, `ENTRY_LINE_FLOOR / CAP = 1.02 / 1.08` |
| 100 | + |
| 101 | +### semiconductor_rotation_income |
| 102 | + |
| 103 | +**Objective** |
| 104 | +- Use a simpler semiconductor trend switch than the Schwab profile. |
| 105 | +- Keep a dedicated income sleeve for larger accounts without forcing that sleeve to shrink during normal trading-layer changes. |
| 106 | + |
| 107 | +**Portfolio layers** |
| 108 | +- Trading layer: `SOXL`, `SOXX`, `BOXX` |
| 109 | +- Income layer: `QQQI`, `SPYI` |
| 110 | + |
| 111 | +**Trading-layer rules** |
| 112 | +- The core signal compares `SOXL` to a configurable trend moving average window. |
| 113 | +- If `SOXL > trend MA`, the active risk asset is `SOXL`. |
| 114 | +- If `SOXL <= trend MA`, the strategy delevers into `SOXX`. |
| 115 | +- Unused trading-layer capital is parked in `BOXX`. |
| 116 | + |
| 117 | +**Sizing behavior** |
| 118 | +- The deploy ratio is dynamic and depends on account size. |
| 119 | +- Small, mid, and large accounts use different base deploy ratios. |
| 120 | +- Above the large-account breakpoint, the trading-layer deploy ratio decays logarithmically so very large accounts do not keep scaling risk linearly. |
| 121 | +- The downstream runtime also keeps a cash reserve and only trades when the rebalance gap is large enough. |
| 122 | + |
| 123 | +**Income-layer rules** |
| 124 | +- The income layer starts only after total strategy equity crosses `income_layer_start_usd`. |
| 125 | +- It ramps linearly to `income_layer_max_ratio` by `2x` that threshold. |
| 126 | +- Existing income holdings are locked with `max(current_income_layer_value, desired_income_layer_value)`, so the layer only adds capital instead of force-selling down. |
| 127 | +- New income allocation is split by configurable `QQQI` / `SPYI` weights. |
| 128 | + |
| 129 | +**Current live LongBridge profile defaults** |
| 130 | +- `TREND_MA_WINDOW = 150` |
| 131 | +- `CASH_RESERVE_RATIO = 0.03` |
| 132 | +- `MIN_TRADE_RATIO = 0.01`, `MIN_TRADE_FLOOR = 100 USD` |
| 133 | +- `REBALANCE_THRESHOLD_RATIO = 0.01` |
| 134 | +- Deploy ratios: `0.60 / 0.57 / 0.50` for small / mid / large accounts |
| 135 | +- `TRADE_LAYER_DECAY_COEFF = 0.04` above `180000 USD` |
| 136 | +- Income layer starts at `150000 USD`, caps at `15%` |
| 137 | +- Income split: `QQQI 70%`, `SPYI 30%` |
| 138 | + |
20 | 139 | --- |
21 | 140 |
|
22 | 141 | <a id="中文"></a> |
23 | 142 | ## 中文 |
24 | 143 |
|
25 | 144 | 这是 `QuantStrategyLab` 的独立美股策略仓。 |
26 | 145 |
|
27 | | -当前已收录的策略实现: |
| 146 | +这个仓库负责**纯策略层**:信号、仓位、目标权重计算,以及策略元数据。下游平台仓库继续负责券商适配、下单方式、调度、密钥和通知。 |
28 | 147 |
|
29 | | -- `global_etf_rotation` |
30 | | -- `hybrid_growth_income` |
31 | | -- `semiconductor_rotation_income` |
| 148 | +### 策略索引 |
| 149 | + |
| 150 | +| 策略档位 | 当前下游运行仓库 | 核心思路 | |
| 151 | +| --- | --- | --- | |
| 152 | +| `global_etf_rotation` | `InteractiveBrokersPlatform` | 22 只全球 ETF 的季度 Top 2 轮动,带每日 canary 防守 | |
| 153 | +| `hybrid_growth_income` | `CharlesSchwabPlatform` | 由 QQQ 驱动的 TQQQ 攻击层,加上 SPYI / QQQI 收入层和 BOXX 防守层 | |
| 154 | +| `semiconductor_rotation_income` | `LongBridgePlatform` | SOXL / SOXX 趋势切换,剩余资金停在 BOXX,并叠加收入层 | |
32 | 155 |
|
33 | 156 | 这些策略通过 `QuantPlatformKit` 提供的策略契约和组件加载接口,被各个平台仓库引用。 |
| 157 | + |
| 158 | +### global_etf_rotation |
| 159 | + |
| 160 | +**策略目标** |
| 161 | +- 给美股账户提供一个更分散、波动更低的轮动框架。 |
| 162 | +- 不把科技和半导体硬排除在外,但也不把风险全部集中到高弹性品种上。 |
| 163 | +- 当跨资产风险明显转弱时,退回短久期避险仓位。 |
| 164 | + |
| 165 | +**标的池** |
| 166 | +- 22 只轮动 ETF:`EWY`、`EWT`、`INDA`、`FXI`、`EWJ`、`VGK`、`VOO`、`XLK`、`SMH`、`GLD`、`SLV`、`USO`、`DBA`、`XLE`、`XLF`、`ITA`、`XLP`、`XLU`、`XLV`、`IHI`、`VNQ`、`KRE` |
| 167 | +- Canary 篮子:`SPY`、`EFA`、`EEM`、`AGG` |
| 168 | +- 避险资产:`BIL` |
| 169 | + |
| 170 | +**指标和规则** |
| 171 | +- 动量使用 Keller 风格的 `13612W` 月频动量:`(12×R1M + 4×R3M + 2×R6M + R12M) / 19`。 |
| 172 | +- 趋势过滤:候选 ETF 必须站上 `200 日均线`。 |
| 173 | +- 持有加分:当前持仓会获得 `+2%` 分数加成,用来降低换手。 |
| 174 | +- 每日 canary 检查:如果 `SPY / EFA / EEM / AGG` 这 4 个资产的动量全部为负,或缺失到全部失效,就立刻切到 `100% BIL`。 |
| 175 | + |
| 176 | +**调仓行为** |
| 177 | +- 正常轮动只在 `3 / 6 / 9 / 12` 月最后一个 NYSE 交易日触发。 |
| 178 | +- 到调仓日后,对合格标的打分,选出前 2 名。 |
| 179 | +- 前 2 名等权配置,默认 `50 / 50`。 |
| 180 | +- 如果合格标的不满 2 个,空出来的部分停到 `BIL`。 |
| 181 | +- 非调仓日默认不改目标仓位,除非触发 canary 应急防守。 |
| 182 | + |
| 183 | +**这套策略的定位** |
| 184 | +- 相比纯科技或者杠杆纳指路线,这个档位更稳。 |
| 185 | +- 但它仍然允许 `VOO`、`XLK`、`SMH` 靠表现进入组合,而不是事先把它们排除。 |
| 186 | + |
| 187 | +### hybrid_growth_income |
| 188 | + |
| 189 | +**策略目标** |
| 190 | +- 把增长、分红收入、闲置现金防守放进同一个档位里。 |
| 191 | +- 攻击层根据 `QQQ` 趋势动态调节,收入层则服务于更大的账户规模。 |
| 192 | + |
| 193 | +**资产层级** |
| 194 | +- 攻击层:`TQQQ` |
| 195 | +- 收入层:`SPYI`、`QQQI` |
| 196 | +- 防守 / 现金类:`BOXX` 加现金储备 |
| 197 | + |
| 198 | +**信号和指标** |
| 199 | +- 以 `QQQ` 的日线数据作为主信号源。 |
| 200 | +- 核心指标是 `MA200` 和 `ATR14%`。 |
| 201 | +- 策略会围绕 `MA200` 生成两条 ATR 调整后的线: |
| 202 | + - `entry_line = MA200 × clamp(1 + ATR% × atr_entry_scale)` |
| 203 | + - `exit_line = MA200 × clamp(1 - ATR% × atr_exit_scale)` |
| 204 | +- 具体的 clamp 上下界由下游运行仓库注入。 |
| 205 | + |
| 206 | +**攻击层规则(`TQQQ`)** |
| 207 | +- 仓位大小来自 `get_hybrid_allocation(strategy_equity, qqq_p, exit_line)`。 |
| 208 | +- 这个仓位只作用在**策略层资产**上,也就是总资产扣掉收入层之后的部分。 |
| 209 | +- 如果当前已经持有 `TQQQ`: |
| 210 | + - `QQQ < exit_line` → `TQQQ` 目标仓位归零 |
| 211 | + - `exit_line <= QQQ < MA200` → `TQQQ` 目标仓位降到 `agg_ratio × 0.33` |
| 212 | + - `QQQ >= MA200` → `TQQQ` 维持 `agg_ratio` |
| 213 | +- 如果当前空仓且 `QQQ > entry_line` → 按 `agg_ratio` 开仓。 |
| 214 | + |
| 215 | +**收入层规则(`SPYI` / `QQQI`)** |
| 216 | +- `get_income_ratio(total_equity)` 在阈值以下为 `0`。 |
| 217 | +- 从 `1 倍阈值` 到 `2 倍阈值` 之间,收入层线性抬升到 `40%`。 |
| 218 | +- 超过 `2 倍阈值` 后,收入层上限为 `60%`。 |
| 219 | +- `QQQI_INCOME_RATIO` 决定 `QQQI` 和 `SPYI` 的拆分比例。 |
| 220 | + |
| 221 | +**防守行为(`BOXX` 与现金)** |
| 222 | +- 策略层先保留一部分现金储备。 |
| 223 | +- 扣掉现金储备并算出 `TQQQ` 目标后,剩余策略层资金进入 `BOXX`。 |
| 224 | +- 是否真的下单,由下游执行层再结合再平衡阈值判断。 |
| 225 | + |
| 226 | +**当前 Charles Schwab live profile 默认值** |
| 227 | +- `INCOME_THRESHOLD_USD = 100000` |
| 228 | +- `QQQI_INCOME_RATIO = 0.5` |
| 229 | +- `CASH_RESERVE_RATIO = 0.05` |
| 230 | +- `REBALANCE_THRESHOLD_RATIO = 0.01` |
| 231 | +- `RISK_LEVERAGE_FACTOR = 3.0`,`RISK_NUMERATOR = 0.30`,`RISK_AGG_CAP = 0.50` |
| 232 | +- `ATR_EXIT_SCALE = 2.0`,`ATR_ENTRY_SCALE = 2.5` |
| 233 | +- `EXIT_LINE_FLOOR / CAP = 0.92 / 0.98`,`ENTRY_LINE_FLOOR / CAP = 1.02 / 1.08` |
| 234 | + |
| 235 | +### semiconductor_rotation_income |
| 236 | + |
| 237 | +**策略目标** |
| 238 | +- 用一套比 Schwab 档位更直接的半导体趋势切换逻辑。 |
| 239 | +- 给大账户保留收入层,但不因为交易层切换就强制把收入层减回来。 |
| 240 | + |
| 241 | +**资产层级** |
| 242 | +- 交易层:`SOXL`、`SOXX`、`BOXX` |
| 243 | +- 收入层:`QQQI`、`SPYI` |
| 244 | + |
| 245 | +**交易层规则** |
| 246 | +- 核心信号是比较 `SOXL` 与一条可配置的趋势均线。 |
| 247 | +- 如果 `SOXL > trend MA`,风险资产使用 `SOXL`。 |
| 248 | +- 如果 `SOXL <= trend MA`,策略降杠杆切到 `SOXX`。 |
| 249 | +- 交易层没有部署出去的资金停在 `BOXX`。 |
| 250 | + |
| 251 | +**仓位规则** |
| 252 | +- 交易层 deploy ratio 会随账户规模变化。 |
| 253 | +- 小账户、中账户、大账户各有一档基础 deploy ratio。 |
| 254 | +- 超过大账户断点后,交易层 deploy ratio 会按对数方式继续衰减,避免超大账户风险线性放大。 |
| 255 | +- 下游运行层另外还会保留现金储备,并且只有偏离目标足够大时才触发调仓。 |
| 256 | + |
| 257 | +**收入层规则** |
| 258 | +- 总策略权益超过 `income_layer_start_usd` 才启动收入层。 |
| 259 | +- 到 `2 倍阈值` 时,收入层线性抬升到 `income_layer_max_ratio`。 |
| 260 | +- 收入层采用 `max(current_income_layer_value, desired_income_layer_value)` 锁定已有收入资产,所以默认只增配,不主动减配。 |
| 261 | +- 新增收入资金按可配置的 `QQQI / SPYI` 比例拆分。 |
| 262 | + |
| 263 | +**当前 LongBridge live profile 默认值** |
| 264 | +- `TREND_MA_WINDOW = 150` |
| 265 | +- `CASH_RESERVE_RATIO = 0.03` |
| 266 | +- `MIN_TRADE_RATIO = 0.01`,`MIN_TRADE_FLOOR = 100 USD` |
| 267 | +- `REBALANCE_THRESHOLD_RATIO = 0.01` |
| 268 | +- 小 / 中 / 大账户 deploy ratio:`0.60 / 0.57 / 0.50` |
| 269 | +- `TRADE_LAYER_DECAY_COEFF = 0.04`,在 `180000 USD` 以上继续衰减 |
| 270 | +- 收入层起点 `150000 USD`,上限 `15%` |
| 271 | +- 收入层配比:`QQQI 70%`,`SPYI 30%` |
0 commit comments