Thales
← research journal
May 29, 2026raw markdown ↗

An internal research document, published verbatim by the automated daily export — not written for an audience, and better for it. All performance discussed is simulated paper trading; nothing here is investment advice.

Execution-Fidelity Fix Spec — unify backtest & live construction

Authored 2026-05-29 (II) AFK. Operationalizes the session's #1 finding (RESEARCH.md top banner): the live execution path (execution/daily.py) and the backtest (backtest/engine.py) have diverged into two different strategies. This spec is the concrete plan to unify them. It is the #1 priority before any real-money deployment.

The problem (verified this session)

The two paths share only signal + selection (252/5 momentum + smoothness, top-50 by rank + hysteresis). Everything else diverges:

componentbacktest (validated)live (daily.py, active)
WeightingHRP (keystone)equal-weight 1/N
Sizinghalf-Kelly (keystone)none
Vol controlsymmetric vol-target (12%)one-sided vol-delever only
Drawdown control20% kill-switch (keystone)none
Sector cap35% (binds ~20% of rebals)none
Cadencemonthly (first-of-month)weekly (every Tuesday)
Emergency exitsnonerank>200 / zero-vol

Root cause: the construction/risk overlays are implemented twice — inlined in engine.py (backtest) and partially in portfolio/constructor.py:construct_portfolio (used only by the inactive pipeline.compute_targets) — and the active live path (daily.py:compute_diff) reimplements a third, stripped version (equal-weight). Three implementations → guaranteed drift.

The fix (recommended)

Extract ONE shared construction function and route BOTH the backtest engine and the live executor through it.

# portfolio/construct.py (new or extend constructor.py)
def build_target_weights(
    selected: list[str],          # the top-N names (post-selection/hysteresis)
    returns_window: ndarray,      # per-name returns for HRP + Kelly + vol-target
    equity_history: list[float],  # for the kill-switch
    sector_map, config,
) -> dict[str, float]:
    # 1. kill-switch (drawdown) -> {} (cash) if triggered
    # 2. HRP weights on selected (compute_hrp_weights)
    # 3. half-Kelly portfolio scalar (compute_kelly_weights -> scale HRP)
    # 4. position + sector limits
    # 5. symmetric vol-target (vol_target_scalar, max_leverage)
    # return final target weights
  • engine.py: replace its inlined block (lines ~590–680: Kelly scalar, limits, vol-target) with a call to build_target_weights. Verify the backtest is byte-identical after (final equity 3,419,610.237847) — the inlined logic and the function must match exactly. This is the safe first step (refactor, no behavior change).
  • daily.py: replace compute_diff's equal-weight target_weights with build_target_weights(selected_names, ...). The selection/hysteresis stays; only the sizing changes. Add the kill-switch + sector-cap (now inside the shared fn). Decide cadence: monthly stock-selection (gate the alpha rebalance to the monthly turn) to match validation, keeping the daily vol-delever as an additional intra-month safety overlay.
  • Lock it with a test: build_target_weights output for a fixed input must equal the engine's pre-refactor weights AND be what daily.py applies (one source of truth, no drift).

Sequencing / caveats

  1. Refactor engine first (byte-identical), THEN route daily.py through it — so the live change is "adopt the already-validated construction", not new code.
  2. The equal-vs-HRP and weekly-vs-monthly are DELIBERATE tradeoffs (RESEARCH entries): equal-weight outperformed HRP in 2017+ (1.24 vs 0.995) but is CPCV-REJECTED/crisis-fragile; weekly is benign-now but whipsaw-prone in crises. Unifying to the validated (HRP, monthly) gives up recent return for crisis robustness — make the call on purpose.
  3. Re-baseline after: once live = validated, the backtest numbers finally describe the live strategy; quote net walk-forward ~0.80.
  4. Then the 30-day live paper-trade A/B (the only true OOS test) is meaningful — currently it's testing a strategy the backtest never validated.

Why this is #1

Every CPCV/walk-forward/keystone result in this repo describes the HRP+Kelly+vol-target+kill-switch+monthly strategy. The live trades a bare equal-weight top-N book with NO crisis controls. Recent paper-trading success is not evidence of safety — the crisis protections are all absent. Unify before real money.