Commit Graph

105 Commits

Author SHA1 Message Date
f1c1210724 research: beta-hedged momentum (STOP) and 24-market futures TSMOM quick checks
hedged_momentum: overnight_recovery_top10 hedged with QQQ futures at a
rolling 126d beta earns Sharpe 0.11; alpha vs QQQ on the Tiingo panel is
+5.3%/yr (t 1.10). futures_trend: Yahoo =F data is roughly usable (ES/NQ
corr 0.98, ZN/GC miss on settlement time), 24-market TSMOM Sharpe 0.44,
corr 0.22 with TrendRider: a crisis diversifier, not a core stream.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 22:45:21 -07:00
8845f31b3b research: risk-budgeted book of five return streams (REJECT)
Preregistered: inverse-vol shares of momentum, lowrisk, TrendRider V10
(synthetic 3x ETFs, lag fills), 8-ETF TSMOM and BTC trend, 2006-10..2026-09.
invvol5 1x: 12.6%/yr, Sharpe 1.07, MaxDD -18% (halves 0.82/1.38) beats the
three-sleeve book (0.97, -38%) but not TrendRider V10 in 2017-26 (1.65);
levered to 25% vol it drops to 0.98. Inverse vol over-weights the weakest
streams; the bottleneck is stream Sharpe, not weighting.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 21:17:12 -07:00
0f9554e77f research: S&P 600 replication of mid-cap quality sleeves (all REJECT)
Preregistered replication vs IJR, 2017-01..2026-09, 20bp decides:
quality composite +2.3%/yr (t 0.78; halves +8.0/-3.5), quality-filtered
momentum +2.2% (t 0.73); SUE and lottery-filtered momentum also REJECT,
all weaker at 40bp. Equal-weight members beat IJR (t 3.2) and every
sleeve. Decision: drop quality stock selection in mid/small caps.

Adds --universe small to fetch_us_fundamentals (IJR, name-checked CIKs),
a `which` argument to fundamentals.load_mid, and --universe small to
midcap_sleeve.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 18:46:45 -07:00
dc14a541b0 research: separate S&P 400 sleeve family vs IJH (all REJECT)
After S&P 400 names failed inside the large-cap momentum top 10, test them
as their own sleeve: top 30, monthly, buffer 1, 20 bp, judged by alpha vs
IJH and by whether 1/3 of the book in the sleeve beats 1/3 in IJH. Four
hypotheses and a control, definitions and rule written before the run.

Holdout 2017-01..2026-09: mid-cap momentum -1.0%/yr vs IJH (corr 0.83 with
the large-cap book), lottery-excluded momentum -1.7%, SUE earnings momentum
-1.7%, quality-screened momentum +3.5% (t 1.28), quality composite +3.4%
(t 1.23; book 0.91 vs 0.85 with IJH). Quality is positive in both halves
but underpowered; nothing is adopted.

fetch_us_fundamentals gains --universe mid: EDGAR facts for S&P 400
ever-members, CIKs accepted only when an SEC name matches the iShares
holding name. fundamentals.load_mid builds the same factors on that panel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 09:55:12 -07:00
92af4e5ac0 feat(research): Tiingo backfill of delisted names; honest PIT panels
Yahoo purges delisted members: the S&P research panel was missing 209
ever-members (AGN/CELG/ESRX/ATVI/TWTR/XLNX/...), the production store 89, and
the S&P 400/600 panels ~180 more. The gap inflated momentum-family factors
(overnight_mom holdout 16.9->14.8%/yr, rec_126 14.7->10.7 on the research
panel; factor_panel_check).

research/lab/fetch_tiingo.py pulls full EOD histories (free tier: 500 unique
symbols/month, 50/hour; paced, resume-safe, key never logged).
research/lab/tiingo_merge.py overlays the caches on the research S&P panel at
build time (>=50% PIT-coverage gate, median-overlap cross-check, stub-column
replacement, rename splices GPS<-GAP, DISCA<-WBD, WLTW<-WTW, ADS<-BFH,
CCE<-CCEP, ESV<-VAL, FBHS<-FBIN, HFC<-DINO) and can apply the same to the
production store (--production [--apply]; data/us*.csv, .bak-tiingo backups,
under the panel lock). load_us() rebuilds when the overlay changes
(_tiingo_sig); fetch_us_mid.load_bars falls back to converted CSVs.

Round 1 (2026-10-08): 165/209 S&P names and 183 mid/small PIT members
restored (2011-19 snapshots were 15-20% short of PIT members). prod_impact
A/B on registered replays: overnight_recovery_top10 23.8%/0.83/-38.3% vs
27.8%/0.88/-47.3% backfill-off; lowrisk_top20 6.1%/0.58 vs 8.6%/0.60 -
honest long returns with shallower drawdowns; trend_rider_v10 (ETF path)
unchanged at 55.0%/1.64. Official precompute refreshed (backup at
data/precomputed/backtest_results.json.pretiingo). midsmall_scan on the
corrected panel: no factor beats the EW benchmark (0.60 holdout Sharpe vs
0.51-0.52 best) - no mid/small sleeve.
2026-10-08 09:48:05 -07:00
2f754998a3 research: S&P 500 ∪ S&P 400 universe for overnight_recovery_top10 (FAIL)
LITE ranked #1-4 on the overnight_recovery score from 2025-07 while still an
S&P 400 member, and the book could only buy it after it joined the S&P 500
on 2026-03-23. research/lab/universe_midcap.py tests whether ranking S&P 400
members alongside the S&P 500 helps, on one merged panel with one engine and
20 bp a side for every arm; the decision rule is written before the run.

Primary window 2019-01..2026-09: union Sharpe 0.86 / CAGR 24.7% / MaxDD
-38.8% vs base 0.98 / 29.4% / -34.3%; 2019-24 alone 0.48 vs 0.70; without
PENN, LITE and SMCI the union's alpha vs base is -6.7%/yr (t -2.1). Mid-cap
momentum adds a few large winners and many small losers. Not adopted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 08:43:50 -07:00
7bd0aa355d chore: add skill for codex too 2026-10-02 19:26:16 -07:00
722cade974 fix: unify backtest execution and add forward validation candidates
Share point-in-time signals and a cash-funded order ledger across backtests and trading. Correct eligibility, missing-price fills, quality factors, regime inputs, warmup windows, and cash-injection accounting. Add reproducible registered-strategy comparisons and paired forward candidates with a 20% resize band.

Validation: 125 Python tests, 23 web tests, TypeScript/Vite build, 87 strategy causality checks, and real-data target/order/equity parity for 10 strategies.
2026-10-01 02:24:01 -07:00
761725d2c8 feat: agent-reviewed overnight_recovery_agent_top10; guard monitor hot-reload
overnight_recovery_agent_top10 (strategies/agent_review.py) re-ranks the
overnight_recovery top 50 with an LLM agent's daily scores:
final = quant percentile + 0.25 x score (-2..+2), vetoes for five event types,
top 10 on the base strategy's rebalance rows and hysteresis. Score files are
stamped by `agent_review.py submit` and steer a session only if stamped before
its 16:00 New York close; without one the strategy holds exactly what
overnight_recovery_top10 holds (checked on the live panel 2016-2026).
- agent_review.py: candidates / submit / evaluate; skill
  .claude/skills/agent-stock-review drives the daily research.
- US only, skipped by precompute (no history before its first score file);
  runs in the original book and in selected_2026_09 (from the book's start).
- .gitignore tracks .claude/skills/ and ignores data/agent/.

Monitor fix: hot-reload re-imports trader.py but not strategies/*. After the
2026-09-29 strategy commits the stale modules made every phase's panel refresh
fail ("Unknown signal 'low_risk'") and US books skipped 09-29 until a restart.
_reload_strategies now builds every factory and keeps the old registry when
any fails; CLAUDE.md says to restart the monitor after changing strategy code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 20:25:20 +08:00
ab3acfe4cb feat(research): supply-chain links, theme propagation, cycles, attention, small caps
Tests of the "rank and buy top N misses the chain / cycle / sentiment" question
(report: https://claude.ai/artifact/HUnPtcy7D7Zp1yNQsDLRHY):
- review_live_us: Apr-Sep 2026 replay; book return vs AI-chain weight corr 0.71,
  overnight_recovery_top10 excess almost all allocation (memory stage +28pp).
- fetch_supply_links: 10-K mentions of S&P 1500 companies by role, PIT by filing
  date (12,117 S&P 500 10-Ks; --universe mid for 14,382 S&P 400/600 10-Ks).
- lead_lag: corr-peer and 10-K link momentum worked 2006-16 (FM t 3.3-4.3) and
  vanished 2017-26 (t -2.1..-0.6); Granger lead-lag network and earnings
  spillover drift null after 2016.
- theme_propagation: linked laggards of each era's hot industry underperform
  2017-26 (-2% to -12%/yr).
- lead_lag_small: the same signals on S&P 400/600, 2019-26, all |t| <= 1.8.
- sector_cycle: 21 cycle/rotation variants, none with holdout |t| > 2.
- fetch_wiki_attention + attention: Wikipedia pageview attention, |IC| <= 0.013.
- concentration: industry caps on momentum top 10 cut alpha, not drawdown.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 20:25:08 +08:00
db1ce69702 chore: untrack data/csi300_history.json
The CSI 300 snapshot history is local data like the S&P 500 history. It is
not rebuilt automatically (seeded from baostock), so a new machine needs a
copy; CLAUDE.md says so.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 15:15:31 +08:00
5e0ab6eb3b chore: untrack generated data; add momentum + fundamentals experiment
- Stop tracking data/sp500_history.json (rebuilt daily from Wikipedia by
  universe_history.load_sp500_history) and ignore data/books/ (per-machine
  live book state, like data/trader_*.json).
- research/lab/momentum_fundamentals.py: financial-statement vetoes and
  confirmations on overnight_recovery_top10 (2011-16 design, 2017-26
  holdout). No return gain; re-sorting the momentum top 30 by fundamental
  momentum lowers MaxDD at equal return.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 14:42:49 +08:00
ad569f1cea feat: us_momentum_qqq_trend; alpha-vs-QQQ research across new data sources
Register us_momentum_qqq_trend: half overnight_recovery_top10, half a QQQ
trend sleeve (strategies/qqq_trend.py: 200-day switch times a 30% vol target,
held as TQQQ + SHY). Mixed stock+ETF, US only (extra tickers QQQ, SHY, TQQQ).

Research (research/lab/): alpha against QQQ with a 2006-16 design / 2017-26
holdout split (alpha.py, qqq_scan.py, beat_qqq.py); leverage and drawdown
frontier (levered_book.py, us_target50.py); synthetic 3x ETFs from 1990 and
TrendRider/QQQ-trend stress tests (fetch_long_history.py, letf_history.py,
vol_trend.py); short-horizon sleeves, diversifiers, industry momentum,
earnings-announcement returns; new point-in-time data sources: SEC Form 4
insider trades (fetch_insider.py, insider.py), 10-K/10-Q text similarity,
8-K earnings dates and SIC codes (fetch_lazy_prices.py, lazy_prices.py), and
an S&P 400/600 universe from iShares holdings (fetch_us_mid.py, panel_mid.py).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 13:40:15 +08:00
2c19e5efe5 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>
2026-09-29 01:03:50 +08:00
38a55e7882 feat(books): drop trend_rider_v3_vt24 and v4 from selected_2026_09
v3_vt24 held the same position as v7_vt24. 29 strategies remain.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 22:26:42 +08:00
465189ba9a feat(books): selected_2026_09 adds trend_rider, $2/¥10 per order, CN ¥100k
Adds five trend_rider ETF strategies (best 10-year Sharpe of each version,
plus v7_vt36): 31 strategies in all. Fees per order are $2 and ¥10, and CN
accounts start with ¥100,000. No trade has been executed yet (US accounts
hold only this morning's orders; CN starts 2026-09-28).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 22:13:49 +08:00
5dbabc3e08 feat: named live books; start selected_2026_09 (26 strategies)
A live book is a cohort of strategies, each with its own account, started
on one date with one capital and a flat fee per order (trader.LIVE_BOOKS).
The original book keeps its state in data/; a named book in
data/books/<book>/. The monitor runs every book; auto/status/log/compare/
replay take --book. A fresh account opens on the book's first session.

selected_2026_09: US $10,000 and $1 per order from 2026-09-25, CN ¥50,000
and ¥5 per order from 2026-09-28 (the first CN session after the choice).
Strategies beat their benchmark in the Apr-Sep 2026 point-in-time replay
and passed a 10-year PIT backtest (US Sharpe >= 0.6, MaxDD > -50%; CN
Sharpe >= 0.2, CAGR > 0), no daily variants, at most two frequencies per
factor signal, plus the three 2026-09 research strategies.

bridge.py live --book and bridge.py books feed a book selector on the
live page (/api/strategies/live?book=, /api/strategies/live/books).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 20:46:09 +08:00
905ca4fe05 fix(trader): replay and catch-up trade each day's point-in-time index members
Replaying live books over past sessions used today's constituent list for
every day, so US books bought names (BE, MRVL, ILMN, FLEX, P) before they
joined the S&P 500. session_universes/session_signals now compute each past
session on that day's members (S&P change log, CSI 300 snapshots); the
latest session keeps the live list. Used by auto/monitor catch-up, replay
and simulate. _run_session takes precomputed targets only.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 20:29:39 +08:00
cc1366b2dc feat: robust-momentum strategies live; fix live universe, lots and UI backtests
Strategies
- BarStrategy protocol (close/open/high/low/volume bars; row d uses bars
  through d-1) and RobustMomentumStrategy: overnight_recovery_top10 (US),
  lowrisk_momentum_top15 and lowbeta_sharpe_mom_top20 (CN), top-N with
  rank hysteresis, 10-day rebalance, weights drift between rebalances.
- trader: strategy_fields/strategy_bars/bar_session_weights; one signal
  path (_signals_for_sessions) replaces generate_target_weights.

Live fixes
- CSI 300 constituents come from China Securities Index's file; the
  Wikipedia table was 122 names off the real index.
- S&P 500 change log moved to "Historical components of the S&P 500".
- data_manager: tickers missing from a partial Yahoo batch are retried
  alone before being marked unavailable (CEG, GEV, SNDK ... were dropped).
  update() takes fields=[...] and stores high/low/volume panels.
- Whole-lot orders go to the nearest lot within cash (CN books held ~62%
  cash); held names are resized only beyond RESIZE_BAND (10%), so books no
  longer pay a ticket fee to trade daily drift.

Web backtests
- backtest_runner.py replaces the duplicated bridge/precompute code: PIT
  membership in both markets (data/csi300_history.json), stock universe
  limited to index members (ETFs and benchmarks in the shared panel were
  pickable), and the book kept like the live trader (simulate_live_book:
  signal timing, drift, order floor, resize band, fees on orders placed).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 19:12:02 +08:00
0e378efa67 research: point-in-time factor research harness (research/lab)
Event-driven long-only simulator with next-open fills, CN tradability
(halts, limit-up/down, stamp duty), PIT S&P 500 / CSI 300 membership,
rebalance-phase averaging, factor IC scans, maximin stepwise composite
search across 5-year blocks, walk-forward LightGBM/ridge combiners,
overlays, and deflated Sharpe. Fetchers pull 20y US OHLCV from Yahoo and
CSI 300/500 ever-members (membership snapshot from baostock, bars from
Yahoo). Research data lives in data/research/ (ignored).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 19:11:59 +08:00
83495bcd23 chore(deploy): keep start scripts and systemd units in deploy/
The three services become quant-trading-monitor, quant-trading-api and
quant-trading-vite, run from /home/gahow/projects/quant-trading. Their
units were previously untracked files in ~/.config/systemd/user.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 11:42:40 +08:00
96a845ebcd refactor: wire web to the in-repo engine and shared data dir
- web/src/server/paths.ts resolves the repo root from its own location,
  loads the single repo-root .env, and defines data/web/ (watchlist,
  stock cache, backtest cache) and data/precomputed/.
- The API spawns bridge.py at the repo root instead of ../quant.
- precompute_backtest.py writes to data/precomputed/ instead of
  ../stock-agent/data/precomputed.
- Rename the project to quant-trading (web package quant-trading-web).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 11:42:35 +08:00
0eb5b95efa Merge stock-agent history into web/
stock-agent (the web UI and API that shell out to bridge.py) now lives in
this repository under web/, with its full commit history rewritten into
that prefix.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 11:39:31 +08:00
f6b46d4d68 chore: track precompute and ops scripts; move monitor proxy into .env
The monitor start script used to embed the proxy URL with credentials,
which kept scripts/ out of git. It now reads QUANT_MARKET_PROXY from the
untracked repo-root .env.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 11:35:59 +08:00
6dc623b4a1 fix(backtest): give mixed stock+ETF strategies their ETFs; derive markets from trader
trend_rider_v6 backtests failed ('SPY' not in data) because only the stock
universe was passed. Strategy markets in 'list' now follow the trader's
eligibility rule, so v6 is no longer offered for CN.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 02:16:48 +08:00
69636c3fae perf(monitor): refresh each price panel once per phase
Every strategy used to re-download its whole universe each phase (~75
downloads of 500+ tickers for the US book), which tripped Yahoo's rate
limit. The monitor now refreshes each panel once for the union of tickers
and runs strategies offline, like replay.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 02:09:02 +08:00
10a74ea4f7 fix(trader): record trade and snapshot prices at full precision
Rounding to cents made trade logs irreproducible for low-priced lines
(HK ETFs in USD, A-shares): replaying a log drifted up to $200 from the
recorded cash.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 02:05:15 +08:00
592de02e27 perf(replay): refresh panels once and compute signals in one pass
Replay refreshes each price panel once for the union of tickers and then
replays offline; target weights for all sessions come from one causal
signal pass instead of re-running the strategy per day (verified identical
daily equity for v7_vt36, recovery_mom_top10 and fc monthly).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 01:56:32 +08:00
0d3642435b fix(data): judge late newest rows as sparse; require SPY print only in the ETF panel
Tickers count as alive for 10 rows after their last bar, so a newest row
printed by a few early tickers is dropped until the rest arrive. The
benchmark-print session rule now applies only to the mixed US/HK ETF panel:
Yahoo's 510300.SS lags CN stocks by days and would stall the CN book.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 01:51:02 +08:00
eefd879a93 fix(strategy-ui): correct rankings, currency, injection view and staleness
- MaxDD ranks shallower drawdowns first (values are negative); ruined
  results are badged and never ranked as best.
- Metrics render '—' for null/non-finite values instead of crashing.
- Amounts use the market's currency (CNY for CN) instead of hard-coded USD.
- Injection scenarios show invested / final value / profit / return on
  invested from capitalFlows and label return metrics as time-weighted.
- Precomputed results show their data end date and warn when older than 7
  days; live strategies warn when not updated for 4 days, show start date,
  price as-of, stale holdings, and same-window benchmark with excess return.
- Unknown precomputed scenario returns 400 instead of silently serving the
  first scenario; the client uses the scenarioId it receives.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 01:22:07 +08:00
1697bc1641 fix(report): correct periodic returns, injection metrics and live view
- Monthly/yearly returns chain from the previous period's close (the first
  trading day of every period was dropped; up to ~9pp/yr error).
- With cash injections, metrics/drawdowns/periodic returns are time-weighted
  on the no-injection curve; capitalFlows reports invested/profit separately.
- Benchmarks cover exactly the strategies' dates.
- CAGR uses calendar time, so gaps in live records do not inflate it.
- Backtests skip the per-trade fee for rebalances below the live minimum
  order and keep a ruined portfolio at zero.
- live: exact strategy match, ineligible strategies hidden, currency,
  startDate, same-window benchmark, stale-price fallback, equity anchored at
  the initial capital.
- PIT membership falls back to the cached history when the Wikipedia change
  log cannot be parsed (the table is no longer on the page).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 01:16:33 +08:00
11f4dd95dd fix(trader): make live sessions complete, final-close based and executable
- Process every completed session since the last recorded one, so monitor
  downtime and late data are caught up; today's bar only counts after the
  exchange closes. The monitor's evening phase always goes through auto and
  catches up at startup.
- Tickers without a real closing print are valued at the last price but not
  traded; held tickers missing from the panel keep their last recorded price
  instead of being valued at zero.
- Use registry parameters (live momentum strategies ran top_n=len//10=49
  instead of the backtested 20).
- A-share orders use 100-share board lots; per-market default capital
  (US $10k, CN ¥70k); HK tickers are converted to USD (HKD=X, peg fallback)
  and exempt from the US per-share fee.
- ETF strategies only run in the US book; buy_and_hold is excluded from live
  because its ~$20 slices never reach the minimum order size.
- CN benchmark switches to 510300.SS (Yahoo's 000300.SS is truncated).
- New 'replay' command rebuilds live state files from each start date.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 01:16:14 +08:00
838749d8b2 fix(data): store raw price panels and refresh a trailing window on every update
The append-only updater only fetched when last_date+1 < local date, never
revisited appended rows and forward-filled before saving. First-seen values
(partial intraday bars, late or missing prints) were frozen permanently: vs
Yahoo, 22% (US), 58% (CN) and 27% (ETF) of recent days had >0.5% daily-return
errors, CN never received same-day data, and HK tickers created US-holiday rows.

Panels are now stored raw (NaN = no print) and forward-filled on read; every
update re-downloads the last 30 days for the requested tickers, rescales older
history when Yahoo's split/dividend adjustment moves, drops rows printed by a
minority of tickers, and writes atomically under a per-market file lock.
Tickers Yahoo has no data for are retried weekly instead of every run.
rebuild() repairs panels written by the old updater.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 01:16:10 +08:00
c2882ae4cf fix(live): remount strategy detail when switching focused strategy
Keying LiveStrategyDetail by strategy name resets its child state (trade-log
pagination), so switching strategies no longer keeps the previous page index.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 00:17:09 +08:00
f0739185d4 chore(deploy): bind vite to localhost behind nginx and enable env proxy for node fetch
Vite is now only an upstream for the nginx :5443 HTTPS entrypoint, and the
API server opts into NODE_USE_ENV_PROXY so Nasdaq/Yahoo requests go through
the host proxy. Ignore the .qoder/ IDE session directory.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 00:16:34 +08:00
0d983edfc0 research: individual stock swing, new frameworks, literature alpha, DCA
Four research directions beyond V7+VT36:

1. single_stock_swing: 20 famous stocks (Mag 7 + others), per-stock
   optimized swing trading. High-vol growth stocks (AMD Sharpe 1.55,
   TSLA 1.54) work best, but overfitting risk is extreme — universal
   params only TSLA is viable. Not competitive with V7.

2. v7_literature_alpha: 9 academic directions (VIX overlay, Kelly
   sizing, multi-MA, cross-asset, momentum acceleration, VIX mean-
   reversion, vol-adaptive PT, combined). V3's regime engine already
   implicitly captures most literature signals. MA130 marginally
   better than MA150 (+0.02 Sharpe, within noise).

3. new_frameworks_eval: volatility trading (SVXY risk-off) and
   calendar effects (turn-of-month). SVXY and V7 regime structurally
   conflict — SVXY crashes exactly when V7 goes risk-off.
   Turn-of-month has decent Sharpe (1.30) but only 28% annual.
   Nothing beats V7.

4. smart_dca_eval: fixed/VIX-scaled/MA-deviation/value-averaging/RSI
   DCA into SPY/QQQ/TQQQ/UPRO + V7 hybrids. Smart DCA barely beats
   fixed DCA. Any DCA hybrid dilutes V7's alpha. DCA only useful for
   new monthly contributions that can't lump-sum into V7.

Conclusion: V7+VT36 remains SOTA across all tested frameworks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-23 00:45:44 +08:00
149a00c458 chore: backtest engine fee model, metrics, and strategy fixes
- main.py: add IBKR-style tiered fee schedule (fee_base + fee_per_share),
  PIT universe support, and open-to-close execution improvements
- metrics.py: add raw_summary helper for JSON-safe metric export
- Misc strategy fixes: deprecation warnings, NaN handling

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-21 20:57:56 +08:00
1f50253d13 research: extensive V7 optimization and V8 (TMF) evaluation
Research scripts exploring paths beyond V7+VT36:
- regime_stock_picker_eval: V3 regime + S&P 500 stock picking
- v7_parameter_sweep: VT range (20-48%) + adaptive PT variants
- v7_synthetic_leverage_eval: synthetic 2x/3x leveraged individual stocks
- v7_breakthrough_eval/fixed: ensemble, cross-market, alt regime engines
- v7_three_ideas_eval: TMF risk-off, PT entry reset, fast exit
- v7_trade_audit: full 10y trade log and alpha attribution
- sota_ranking: comprehensive cross-strategy ranking

Key findings:
- VT36 is optimal risk-return tradeoff (+7% vs VT28, Sharpe ~flat)
- PT30 is structural optimum for 3x ETFs (all adaptive variants worse)
- V8 (TMF risk-off) debunked: +5% was 1-day lookahead bias artifact
- V3 regime engine irreplaceable (all simplified alternatives fail)
- PT mechanism is dominant alpha source (+15.6pp ann, +0.58 Sharpe)

V8 strategy file kept for reference (not registered).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-21 20:57:34 +08:00
b8bac26b8f feat: register V7+VT36 as SOTA and add monitor hot-reload
- Register trend_rider_v7_vt36 (target_vol=0.36, min_lev=0.75) in
  strategy registry, ETF universe map, and bridge metadata.
  10y backtest: Ann 60.5%, Sharpe 1.87, MaxDD -29.2%.

- Add hot-reload to monitor: each phase re-imports trader module to
  pick up newly registered strategies without restart. New strategies
  are logged on detection.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-21 20:57:16 +08:00
c4ae944345 fix(v7): ensure SHY column exists for profit-take park allocation
V3's output only includes {SPY, TQQQ, UPRO, GLD, DBC}. When PT
triggered, park_col resolved to "" (cash at 0%) instead of SHY.
Now injects SHY column before the PT loop if present in data.

Impact: ~0 in 2016-2026 (rising rates made SHY slightly negative),
but fixes ~0.6%/yr drag in normal rate environments (SHY ~4%/yr,
14.3% of days in PT-park).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-21 20:57:06 +08:00
e147890066 feat: include ETF strategies in monitor and register V7 in bridge
- DEFAULT_MONITOR_STRATEGIES now includes ALL strategies (stock + ETF)
  instead of excluding ETF strategies. The cmd_morning/evening/auto
  already route ETF strategies to the correct data pipeline via
  strategy_universe() and strategy_data_market().

- Register trend_rider_v7, v7_vt24, v7_vt32 in bridge.py STRATEGY_META
  so they appear in the stock-agent frontend via /api/strategies.

- Monitor now runs as a background daemon with logs written to
  logs/monitor.log (PYTHONUNBUFFERED=1, no tmux dependency).
  PID saved to logs/monitor.pid.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-21 00:46:48 +08:00
df0a051403 feat(strategy): add TrendRider V7 — V3 + vol-target + profit-take
Three-layer strategy for leveraged ETF portfolios:

  Layer 1: V3 regime engine (MA150) — SPY technicals for risk-on/off
  Layer 2: Vol-target overlay (28%, clip 0.6-1.0) — scale by realized vol
  Layer 3: Profit-take with hysteresis (+30% → clear to SHY, restore <20%)

The profit-take exploits a structural property of 3x leveraged ETFs:
after large gains, volatility drag on the inflated base erodes compound
returns. Clearing the position locks in geometric gains before the drag
takes effect — this is rebalancing alpha, not prediction alpha.

10y backtest (2016-2026, 10bps one-way cost):
  Ann 54.7%, Sharpe(rf=5%) 1.72, MaxDD -25.7%, Sortino 2.23

Also registers trend_rider_v7, trend_rider_v7_vt24, trend_rider_v7_vt32
in the trader strategy registry and ETF_STRATEGY_UNIVERSES.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-21 00:39:17 +08:00
5716267309 feat(ui): split client into Live and Strategy pages and wire new routes
Rebuilds the client into Live (watchlist with charts, fundamentals, news,
quant analysis) and Strategy (backtest runner / precomputed results) pages,
adds the corresponding /api/stocks/:symbol/chart|fundamentals|related|quant
and /api/strategies endpoints, and updates project tooling.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 23:21:03 +08:00
f54041646f feat(strategy): add backtest strategy module
Introduces strategyTypes shared schema and a server-side strategyService
that lists strategies, runs backtests, and caches results.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 23:20:50 +08:00
a4a2cb2ccf feat(data): extend market data provider with charts, fundamentals, and quant analysis
Adds a stock data cache layer and indicator helpers (MA/RSI/MACD), expands
the MarketDataProvider interface with candles, fundamentals, related-data,
and quant analysis, and threads tags + source attribution through the
shared types. Updates affected agent tests.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 23:20:42 +08:00
30f6cd84a8 chore: add dev start scripts for server and vite
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 22:59:32 +08:00
b9a2a6a57b feat: add yearly sweep script for parameter optimization 2026-05-14 12:54:13 +08:00
24663ebd35 test: add strategy and integration tests
Add tests for trend rider (integration, robustness, v4),
US combo sweep, and US fundamentals modules.
2026-05-14 12:54:10 +08:00
541f7bcf5b research: add strategy evaluation and exploration scripts
Add 28 research scripts covering DCA simulation, momentum evaluation,
Sharpe optimization, trend rider analysis, and US fundamentals exploration.
2026-05-14 12:54:08 +08:00
d086930ab3 feat: add new trading strategies
Add 12 strategy modules including adaptive blend, composite alpha,
cross-asset momentum, ensemble alpha, trend rider v5/v6, and more.
2026-05-14 12:54:05 +08:00