feat: US 3-sleeve portfolio and lowrisk_top20; US portfolio research harness

Register two live strategies from the 2026-09-29 US research:
- lowrisk_top20: idiosyncratic vol + low beta, top 20, monthly, buffer 2
  (new `low_risk` signal in strategies/robust_momentum.py)
- us_three_sleeve: 1/3 each of overnight_recovery_top10, lowrisk_top20 and
  trend_rider_v7_vt24 in one account (strategies/sleeve_portfolio.py, a
  mixed stock+ETF strategy). Sleeve shares drift with their returns and reset
  at a month start once any is >25% off its share.

Research (research/lab, S&P 500 PIT, next-open fills):
- rotation.py / persistence.py: walk-forward factor weighting (factor
  momentum, rolling IC, market state) and last-year's-winner selection do not
  beat a fixed composite
- us_sweep.py: holdings count, z/vol weights, dynamic N, tranching and market
  overlays (Faber SMA, de-risk vol target, statistical jump model,
  momentum state); engine.py gains zvol weighting and dyn_n
- fetch_us_fundamentals.py / fundamentals.py / fund_eval.py: SEC EDGAR
  point-in-time fundamentals (first-filed values) and factor tests
- trend_rider_long.py / us_final.py: 2010-2026 TrendRider curves and the
  3-sleeve check (2011-2026 Sharpe 1.21, CAGR 21.9%, MaxDD -23%)

Web-UI engine, 2017-09..2026-09, $2/order: us_three_sleeve CAGR 28.9%,
Sharpe 1.49, MaxDD -24.8%.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-29 01:03:50 +08:00
parent 38a55e7882
commit 2c19e5efe5
16 changed files with 1857 additions and 7 deletions

View File

@@ -58,6 +58,7 @@ from strategies.permanent import (
)
from strategies.recovery_momentum import RecoveryMomentumStrategy
from strategies.robust_momentum import RobustMomentumStrategy
from strategies.sleeve_portfolio import us_three_sleeve
from strategies.trend_following import TrendFollowingStrategy
from strategies.trend_rider_v5 import TrendRiderV5
from strategies.trend_rider_voltgt import (
@@ -290,6 +291,13 @@ STRATEGY_REGISTRY = {
"lowbeta_sharpe_mom_top20": lambda **kw: RobustMomentumStrategy(
"lowbeta_sharpe_mom", top_n=20, rebal_freq=10, buffer=1.0,
),
# --- US portfolio research (2026-09-29): defensive sleeve and the 3-sleeve book ---
"lowrisk_top20": lambda **kw: RobustMomentumStrategy(
"low_risk", top_n=20, rebal_freq=21, buffer=2.0,
),
# 1/3 each of overnight_recovery_top10, lowrisk_top20 and trend_rider_v7_vt24
# in one account (strategies/sleeve_portfolio.py)
"us_three_sleeve": lambda **kw: us_three_sleeve(),
# --- TrendRiderV6: stock-picking + V5 regime engine ---
"trend_rider_v6": lambda **kw: TrendRiderV6(),
"trend_rider_v6_top10": lambda **kw: TrendRiderV6(top_n=10),
@@ -319,6 +327,7 @@ ETF_STRATEGY_UNIVERSES = {
MIXED_STRATEGY_EXTRA_TICKERS = {
"trend_rider_v6": sorted(set(ETF_UNIVERSE)),
"trend_rider_v6_top10": sorted(set(ETF_UNIVERSE)),
"us_three_sleeve": sorted(set(ETF_UNIVERSE)),
}
# Registered strategies the live monitor does not run, with the reason.