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>
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>
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>
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>
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>
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>
- 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>
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>
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>
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>
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>
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>
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>
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>
- 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>
- 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>
- 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>
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>
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>
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>
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>
- 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>
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>
- 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>
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>
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>
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>
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>
Add .qoder/ (local tool settings) and SEC fundamental data
(sec_frames/, sec_company_tickers.json) to prevent large
downloaded datasets from being tracked.