Retired Experiments

Swing Trader and Astro Lite are retired, in full — full logs, frozen final state, and an honest retirement note. Nothing here is deleted.

Astro Heavy

May 2026 – Oct 2026 · retired: the site moved from trading signals to scenario analysis

Swing Trader

late May 2026 (exact start unrecorded) – Jun 19, 2026 · died in the June outage

Astro Lite

late May 2026 (exact start unrecorded) – Jul 6, 2026 · retired: ablation superseded by pillar scoring
# Experiment Archive — Retirement Notes PredictMyGold originally ran a three-bot ablation (Swing Trader, Astro Lite, Astro Heavy) to test whether Vedic astrology signals add anything over pure technical/regime trading. The owner has retired that ablation in favor of a weighted, Brier-scored, four-pillar intelligence Ledger: every pillar (including astrology) now files pre-registered, dated calls that are scored against actual price outcomes, and its "earned weight" is published at `/api/weights`. That per-call scoring is a more direct and continuously-updated answer to "does astrology add anything?" than comparing three separate paper accounts ever was. Swing Trader and Astro Lite were retired in July 2026. **Astro Heavy was retired in October 2026**, when PredictMyGold moved from trading signals to scenario analysis (the gold price simulator is now the home page). Nothing here is deleted; wrong or unflattering results are kept, not hidden. ## Astro Heavy (`bot_astro_heavy.py`) — retired October 2026 - **What stopped:** position sizing, rebalancing, stops and P&L tracking. - **What did not stop:** everything analytical. Price, the weekly/daily regime, RSI, MACD and ADX, the astro calendar, and the registration and grading of astrology calls moved unchanged to `market_signals.py` (indicators copied verbatim into `indicators.py`, with a test proving the outputs are identical). The astrology pillar's track record continues without a gap. - **Final state:** the frozen `state_heavy.json` and `trades_astro_heavy.csv` stay in the production data volume; the /experiments page reads its final NAV and trade count from them directly. --- ## Swing Trader (`bot_swing.py`) - **Strategy:** weekly-regime-gated swing trades (15-min check cycle), daily regime + astro bias as an entry filter, technical trailing/hard stops. - **Start:** operational since late May 2026. The exact first-cycle timestamp was not preserved in any surviving log (no dated CSV row or state snapshot from before June 1 survives in this repo). - **End:** June 19, 2026 — `run_bots.py` had no restart logic; when the Swing process died it was never restarted (see `README_UPGRADE.md`, "Silent death, June 19"). Nothing detected or alerted on the outage. - **Last recorded state:** cycle 58, updated 2026-06-01T18:11:37Z — see `swing_final_state.json`. At that point: `balance_usdt=$50.00`, `balance_paxg=0`, `portfolio_val=$50.00`, `pnl=$0.00` per the bot's own state write. - **Trade log:** `trades_swing.csv` does not exist anywhere in this repo — no trade was ever appended to it, and `swing_trades.csv` is intentionally **not** included here since there is nothing real to freeze. The state file's `balance_usdt` ($50) does not match its own starting `CAPITAL` ($100) despite zero logged trades and zero PAXG held — that inconsistency predates this retirement, was not introduced by it, and is not resolved by this document. It is presented as-recorded, not corrected or explained away. - **Trades executed:** 0 (per the missing CSV and `position_pct: 0` / `balance_paxg: 0` in the last state). - **Reason for retirement:** superseded by per-call Brier scoring of the astrology pillar; one bot (Astro Heavy) remains for the live track record. Swing's silent death on June 19 — and the fact that its own state hadn't been refreshed since June 1, well before that death — was itself a symptom of the monitoring gaps this rework closes (loud staleness badges, a supervisor that actually restarts crashed bots, ops alerts to Telegram). ## Astro Lite (`bot_astro_lite.py`) - **Strategy:** the same regime/astro framework as Swing but on an hourly cycle, with a simplified position-sizing rule and Claude-authored planetary briefs. - **Start:** operational since late May 2026 (same caveat as above — exact first cycle not preserved). - **End:** July 6, 2026 (today) — retired as part of this rework, not a crash. - **Last recorded state:** cycle 15, updated 2026-06-01T17:47:48Z — see `lite_final_state.json`. `balance_usdt=$50.00`, `balance_paxg=0`, `portfolio_val=$50.00`, `pnl=$0.00`. Like Swing, state hadn't refreshed since June 1 even though the bot was nominally "live" until today — the same silent-staleness pattern, undetected until this audit. - **Trade log:** **Correction, 2026-07-07 (Phase 9 v2 audit):** this was wrong. `trades_astro_lite.csv` did not exist *in this repo* at the time this was written, but it existed on the real production DigitalOcean volume this repo never had access to until the Azure migration. Real log, now copied here as `lite_trades.csv`: a BUY at $4,309.72 (25%, 2026-06-07 16:43 UTC) and a SELL at $4,116.52 (back to 0%, 2026-06-23 11:53 UTC) — a real ~4.5% loss on the 25%-sized position, roughly -1% of total capital. This does not reconcile with the ~$50 `portfolio_val` in `lite_final_state.json` (see below); that figure is presented as-recorded, not corrected, consistent with this document's own rule. - **Trades executed:** 2 (see `lite_trades.csv`) — not 0 as originally stated here. - **Reason for retirement:** the three-bot ablation is superseded by per-call Brier scoring of the astrology pillar; one bot remains for the live track record. --- ## What's in this folder | File | Contents | |---|---| | `swing_final_state.json` | Frozen copy of Swing's last `state_swing.json` (cycle 58, 2026-06-01). | | `lite_final_state.json` | Frozen copy of Lite's last `state_lite.json` (cycle 15, 2026-06-01). | | `lite_trades.csv` | **Added 2026-07-07** — Lite's real 2-trade log, recovered from the production DigitalOcean volume during the Azure migration (this repo never had it before). See the correction under Astro Lite above. | | `code/bot_swing.py` | The exact code that produced Swing's trade history. No longer imported anywhere live. | | `code/bot_astro_lite.py` | The exact code that produced Lite's trade history. No longer imported anywhere live. | No `swing_trades.csv` is included — Swing genuinely logged zero trades (confirmed against the real production volume too, not just this repo). `lite_trades.csv` **is** now included (see above) — the "zero trades for both bots" claim below is kept struck through rather than deleted, per this document's own "nothing here is deleted" rule. ~~No `swing_trades.csv` / `lite_trades.csv` are included — both bots logged zero trades before retirement, so there is no trade log to freeze.~~ If this changes (e.g. an older trade CSV turns up elsewhere), it should be added here rather than reconstructed — which is exactly what happened for Lite.
# Honest Backtest Re-Run (2026-07-06) `backtest_macro_v2.py` re-runs the same three-pass macro/astro backtest as the archived `backtest_macro.py` (see `archive/experiments/code/`), over the same 730-day PAXG/USDT window (2024-07-07 → 2026-07-06), with the two bugs the audit found actually fixed: 1. **Weekly-candle look-ahead.** The old backtest's weekly slice was `ww = [c for c in weekly if c["time"] <= wd[-1]["time"]]` — this includes the *current, still-forming* weekly bar as soon as its **open** time is on or before today, which leaks that week's not-yet-known final close into mid-week decisions. `backtest_macro_v2.py` requires a full 7 days to have elapsed since the bar opened (`c["time"] + timedelta(days=7) <= wd[-1]["time"]`) before that bar is visible — the same `closed()` discipline now used live in `bot_astro_heavy.py` via `signal_policy.py`. 2. **Zero trading costs.** The old backtest had no fee variable at all — every rebalance was free. `backtest_macro_v2.py` applies `FEE = 0.0012` (12bps per side) on every fill, the same `COST_BPS` used live. ## Old claim vs honest re-run `bot_astro_heavy.py`'s docstring (and the dashboard's `backtest_pnl` / `backtest_dd` fields) claimed **Pass C — Dynamic sizing + Vedic astro** achieved: | | Old claim (look-ahead, no fees) | Honest re-run (closed candles, 12bps fees) | |---|---|---| | Net P&L | +62.88% | **+38.42%** | | Max drawdown | 14.40% | **17.42%** | | Win rate | 69.1% | **57.4%** | The gap is not noise — it's the two bugs. Removing the look-ahead alone lets the strategy react to real, already-closed information instead of a sneak preview of the current week's close; adding realistic fees on top of 102–113 rebalances per pass (vs. free trading before) compounds directly into the P&L. **The honest number is meaningfully worse than advertised on every metric**, and the archived `bot_astro_lite.py`'s own claimed +57.94% is presumed to carry the same bugs (it was backtested with the same pre-fix harness) — that file is left untouched as the frozen, inspectable historical record of what the retired bot's authors believed at the time (see `archive/experiments/RETIREMENT.md`); it is not re-run or re-published as a current claim anywhere live. ## Full honest re-run — all three passes Period: **2024-07-07 → 2026-07-06** (730 days) · Capital: $50 · Fee: 12bps/side | Metric | A: Buy & Hold | B: Dynamic, no astro | C: Dynamic + astro | |---|---|---|---| | Net P&L % | **+65.67%** | +37.73% | +38.42% | | Final value | $82.83 | $68.87 | $69.21 | | Alpha vs Buy & Hold | +0.00% | **−27.94%** | **−27.25%** | | Max drawdown | 27.74% | 15.48% | 17.42% | | Win rate | n/a (0 trades) | 52.2% | 57.4% | | Rebalances | 0 | 192 (102 buy / 90 sell) | 207 (113 buy / 94 sell) | **The uncomfortable headline: over this exact 2-year window, simply buying and holding PAXG beat both managed passes by roughly 27 points**, even after the managed passes' real drawdown-reduction benefit (27.74% → 15.48%, a genuine ~12-point improvement) is accounted for. Astro adds a modest +0.7pp of P&L and +5.2pp of win rate over the no-astro pass in this window, at the cost of ~1.9pp more drawdown and 15 more rebalances (more fee drag) — a wash at best, not the standalone edge the old docstring implied. This is exactly the question `compare_baselines.py` (below) is built to keep asking on a rolling basis, not just as a one-time backtest: **did the live bot beat just holding gold?** Publish the answer every week — including when it's no. ## Single source of truth Every published performance number now traces to `backtest_claims.py`, populated directly from this re-run. Nothing else in the codebase should hardcode a backtest number — import from `backtest_claims.py` instead.

Frozen files — read-only

lite_final_state.json lite_trades.csv swing_final_state.json