Since 2026-07-16 (current live system): Account +3.32% vs SPY +1.90% (outperforming SPY by 1.42pp) All-time, net of all deposits/withdrawals: +1.67%
Last updated: 2026-08-19 20:30 UTC — percentage returns only, position size/equity not disclosed.
SerenityAlphaTrader Pro (short name: AlphaTrader) — an autonomous AI trading platform whose stock-selection brain reasons through the Serenity supply-chain chokepoint lens.
SerenityAlphaTrader Pro is a fully automated AI quantitative trading system powered by a Python/FastAPI backend and a pure HTML/JS frontend. It runs a hybrid LLM stack (local Qwen3.5 35B MoE + optional DeepSeek-Cloud API) with the Kronos K-line prediction model, and executes real trades across US (Alpaca) and Hong Kong (Moomoo OpenD) markets.
The trade-selection brain applies the analytical methodology of Serenity (@aleabitoreddit) — a public X trader and AI/semiconductor supply-chain analyst who traces hyperscaler capex into the overlooked upstream bottlenecks (optical/CPO, InP substrates, memory/HBM, AI power/grid). His lens is packaged as two installable agent skills under .claude/skills/: serenity-aleabitoreddit (per-ticker theses + track record, distilled from 5,857 tweets) and serenity-chokepoint-analysis (the six-step chokepoint framework). Both are also published standalone at 14H034160212/serenity-skills — install with npx skills add 14H034160212/serenity-skills.
Attribution. The
serenity-aleabitoredditskill is redistributed from the upstream research artifactyan-labs/serenity-aleabitoreddit(skills.sh), which independently distilled the public work of Serenity (@aleabitoreddit). All credit for the underlying research and tweet corpus belongs to them; this project is an independent, unaffiliated redistribution.serenity-chokepoint-analysisis original work by @14H034160212.
⚠️ Decision-support only — not financial advice. The Serenity lens shapes which questions the brain asks; it never auto-trades on copied signals. Serenity's self-reported returns are unverified and carry survivorship/selection bias; his names are volatile micro/small-caps. See the skill's risk framing.
🔴🔴 What's new (2026-07-03) — Plan D management mandate + hybrid 4-master/Serenity cross-validation + rogue-engine kill-switch
Plan D ratified as the standing management mandate. The user formally delegated full ongoing stewardship ("以后你就是我的管家"). Target allocation: 70% SPY / 15% QQQ / 12% BRK.B / 3% cash as the core (95%+ of the portfolio), plus a Serenity satellite for opportunistic active picks, capped at 20% of total portfolio value ($12,333) with a 20%-of-satellite per-name guardrail ($2,467). This cap is non-negotiable by design — see ~/serenity-trader-stack/PLAN_D.md for the full escalating-authorization history and the backtest evidence (0/15 strategies tested achieve simultaneous up-capture>100%/down-capture<100%) behind why the cap exists.
New: crossvalidate_satellite.py — automated hybrid cross-validation, every 4 hours. Runs entirely on-demand-free local compute + a small paid tail:
- For each live satellite position (pulled fresh from Alpaca, core SPY/QQQ/BRK.B excluded), runs two independent local Ollama (
gemma4:31b) lenses at zero marginal cost: a condensed 4-master value check (Buffett/Munger/段永平/李录 — approximatesai-berkshire's/investment-team, which needs a live Claude Code session and can't itself be cron-triggered) and a Serenity chokepoint re-check (is the original thesis still intact, not a fresh screen). - Escalates to a paid
claude -pdeep-dive (~$0.05–0.15/call) only when the two lenses disagree, either flags a break, price has moved >15% from cost basis, or 7+ days have passed since the last paid check-in. - Logs every cycle to
~/serenity-trader-stack/reports/<TICKER>/updates.md(git-committed); emails only on escalation — routine "still fine" cycles stay silent. - Installed via cron:
0 */4 * * * ... crossvalidate_satellite.py.
This is the "hybrid" approach because the full ai-berkshire 4-master framework and Serenity's own six-step chokepoint analysis are each too expensive/interactive to run unattended every 4 hours — this script approximates both cheaply and only pays for a real Claude read when the local checks actually disagree or something looks wrong.
🔴 Rogue legacy-engine incident — recurred twice, root-caused and structurally fixed. The old always-on auto_trade_enabled=true engine sold live satellite positions twice without authorization (CRDO on 2026-07-01, VST on 2026-07-03), each time believed already stopped. Root causes, all now fixed:
stop.shgrepped for the uvicorn process on port 8000, but the server has always run on port 8888 — the pattern never matched anything, sostop.shprinted "successfully stopped" while the engine kept running the whole time. This is the most likely reason the same incident happened twice. (Fixed: pattern corrected to 8888; the health-check curl example above had the same stale port and is also fixed.)backend/main.pyhas its own standaloneif __name__ == "__main__"entrypoint that never checked the kill-switch — onlystart.shdid. (Fixed: same kill-switch check added there.)- A structural kill-switch file (
/data/qbao775/AlphaTrader/.DISABLE_AUTOSTART) was added at the top of both entrypoints: while it exists, the engine refuses to start no matter how it's invoked (bash start.sh,python main.py, or systemd). It exits 0, not 1 —alphatrader.serviceruns withRestart=on-failure, so a non-zero exit would have made systemd tight-loop-restartstart.shevery 5 seconds for as long as the switch was active. - Lesson recorded in the standing mandate: killing a process is not sufficient for a self-healing supervisor (
start.sh's ownwhile trueloop, plus systemd, plus a shared server where anyone could re-runbash start.sh) — the fix has to be structural (a checked flag file), not just operational (killing PIDs).
news_watch.py fixes — a silent bug had it firing zero alerts for months: mcporter/node live in the base miniconda /bin, not on PATH inside the alphatrader conda env, so every Exa search silently failed with rc=127. Fixed by explicitly prepending the base conda bin/ to the subprocess PATH. Also added: keyword coverage for layoffs/tariffs/export-controls/M&A/model-releases (per the user's "track official announcements, not just headline sentiment" preference), and a local Ollama pre-screen (quick_chokepoint_take()) that scores each fresh headline as a real bottleneck / noise / too-early before it reaches an email alert.
After 6 months of live autonomous operation, the daily-driver model has been retired in favor of a passive-index core (70–80% SPY/VOO + HK 2800) + on-demand AI research via Claude Code skills.
Why the pivot:
- A live single-name SMIC bet (~$1,300 unrealized loss at the worst point) showed conviction-based satellite picks need stronger pre-trade discipline than the 24/7 auto-trade loop provided.
- For a personal portfolio of this size (~US$60k after a fresh NZ$100k deposit), keeping a fleet of background processes (Ollama GPU runner, IB Gateway, Moomoo OpenD, 21-task asyncio loop, cron jobs) running on a shared lab server is not a sustainable footprint. All AlphaTrader daemons have been shut down; the SQLite DB and code remain.
- Net of the SMIC drag, the existing Alpaca SPY/VOO core has tracked S&P 500 cleanly. The conclusion: index it, then be selective about the satellite ~20-30% rather than running a continuous decision engine.
The new path — serenity-trader-stack: a lightweight, on-demand stack that runs entirely inside Claude Code (Opus 4.8), with one install script and zero background processes.
~/.claude/{commands,skills}/ ← 18 ai-berkshire slash commands + 3 anthropic equity-research skills
~/serenity-trader-stack/
├── scripts/refresh-today.sh # Anchor today's date (UTC/NZT/EDT/HKT) + market hours
├── scripts/snapshot-portfolio.sh # Pull Alpaca + IBKR + Moomoo holdings → markdown snapshot
├── scripts/quote.sh <TICKER> # Current price (US + HK) via market_data.get_stock_quote()
├── scripts/check-allocation.sh # Actual vs target 70/20/8/2 allocation; warn if >5pp off
├── scripts/place-order.sh # One-shot order placement (US auto via Alpaca, HK manual via App)
├── reports/ # Git-versioned per-ticker thesis state (init'd by installer)
└── CLAUDE.md # 8 operating rules — sizing buckets, sourcing, falsifiable thesis
One-command install (idempotent, safe to re-run):
bash install-trader-stack.shThis clones three external repos — xbtlin/ai-berkshire (Buffett/Munger/段永平/李录 multi-master value framework), muxuuu/serenity-skill (chokepoint scorecard JSON; the existing serenity-chokepoint-analysis Chinese skill is preserved), and anthropics/financial-services (idea-generation + thesis-tracker + market-researcher skills) — installs the markdown skills into ~/.claude/, writes the 5 helper scripts, sets up the git-versioned reports/ folder, and writes a project CLAUDE.md with the operating rules.
Daily use (no background daemons; everything is on-demand):
# Before any session — refresh date + portfolio snapshot
~/serenity-trader-stack/scripts/refresh-today.sh
~/serenity-trader-stack/scripts/snapshot-portfolio.sh # IB Gateway / OpenD start on demand
# In Claude Code (Opus 4.8)
/portfolio-review # Re-evaluate current holdings against stored theses
/investment-team <ticker> # 4-master adversarial value research (Buffett/Munger/段/李)
/dyp-ask "<question>" # 段永平 persona
"用 Serenity 卡点分析 <theme>" # Supply-chain chokepoint analysis (existing CN skill)
"Run an idea-generation screen for ..." # Anthropic equity-research skillWhat carries forward from the old system:
- All broker integration in
backend/futu_broker.py,backend/trading_engine.py, etc., is intact —scripts/place-order.shwraps it for one-shot execution. - The bug-fix session that preceded the pivot landed:
price_refresh20-symbol starvation cap → 250; silentauto_tradefailure logging at the call-site; dust-position filter for held-symbol scan front-loading; DCF poison-data gate tightened for non-US tickers (0.5×–2× sanity band);priority_symbolsinitialized before the try block so the gap-filter bypass never NameErrors. - The autonomous trading loop, dynamic watchlist, online RL pipeline, LLM shootout, regime-aware exposure engine, and cron-driven monitoring described below remain operational if re-started, but are not the recommended daily path.
The full Serenity supply-chain skill (serenity-chokepoint-analysis), the live tweet pipeline (fetch_serenity_tweets.sh), and the daily email reporting still work standalone if invoked manually.
- 🛡️ No-margin lockdown (living-money safety): a critical bug had
get_cash_balance()return Alpacabuying_power(4× margin) instead of realcash, letting the engine silently buy on margin. Fixed: real-cash only + a hard cash-reserve-floor guard at the singleexecute_buy()chokepoint (so deposit/rebalance paths can't bypass it) + the broker account is locked tomax_margin_multiplier=1+no_shorting=true— borrowing is now impossible at both the software and broker layer. - 📈 Adaptive exposure engine (
market_regime.py): scores SPY trend / momentum / volatility / drawdown into RISK_ON / NEUTRAL / RISK_OFF and writes a dynamiccash_reserve_pct(20 / 40 / 65 %). "Earn more in good markets, lose less in bad" — the engine deploys more when healthy, defends when stressed. Daily pre-open cron, no restart needed. - 🐦 LIVE Serenity tweets via Agent Reach: the yan-labs archive froze at 2026-06-08;
fetch_serenity_tweets.shnow pulls @aleabitoreddit's live timeline (burner account, never the main one) and merges it into the lens recency scoring, so his freshest picks (SIVE/AAOI/COHR …) drive the watchlist. - 🐳 Smart-money + influencer tracking (
fetch_smart_money.sh): Buffett/Berkshire & Ackman 13F, Congressional/STOCK-Act trades (Pelosi, Trump), and Musk/Trump market-relevant X posts — a LAGGED cross-check only (never overrides Serenity, never auto-buys), surfaced in the daily email. - 📰 Proactive news alerts (
news_watch.py): Exa-searches holdings + sectors (memory/HBM, CPO/optics) for material-risk headlines (plunge/downgrade/glut/halt …) and emails an alert — closes the "breaking-news blind spot". - 💰 Deposit auto-detect (
deposit_watch.py): detects new cash deposits and lets the engine deploy them into Serenity names within the guardrails; emails on arrival. - 📧 Daily email upgrade: status banner shows leverage state, market regime + cash floor, and real cumulative return NET OF DEPOSITS broken down into unrealized + realized + today (deposits are never miscounted as gains).
- 🔌 Real-time internet access (Agent Reach): Exa semantic search, RSS, web, GitHub, X — installed in an isolated
agentreachconda env; powers the catalyst/news pipeline above. - 🧱 Cron-robustness: absolute SQLite DB path (was a relative
./path that broke cron-run scripts) +rsync --deleteexcludes for locally-generated data files.
- Hong Kong live trading via Moomoo NZ OpenD (FUTUAU entity). HK + US in one platform; separate daily emails.
- P0 fix — Qwen3.5 reasoning-model JSON parser: previous extractor failed on Qwen3's free-text reasoning prefix, causing 73.9% of signals to come back as zero-conf HOLDs. Now < 1% parse-error rate via a robust extractor that handles
<think>tags, "Thinking Process:" prefixes, multi-block JSON output, reasoning loops, and partial truncation. - Cross-stock catalyst engine: macro events (e.g. Trump's 2026 China visit with CEO delegation) automatically light up every materially-exposed ticker without hand-curating keyword lists per stock. Geopolitical RSS feeds (cached) feed directly into per-symbol catalyst detection.
backend/.envsecret loading: SECRET_KEY no longer has a hardcoded fallback — must be supplied via gitignored.envfile.- Scenario mute (DB column): user-flagged themes (e.g. Middle East/Iran in this account) are blocked from showing in reports AND from being regenerated by the AI Layer 4 scenario auto-generator.
- Real-time Market Data: Global market data via Yahoo Finance, auto-refreshing every 2 minutes with staggered requests to avoid rate limits.
- K-Line Prediction: The Kronos foundation model (trained on data from 45+ exchanges) predicts the next 5 candles based on historical data.
- AI Decision Making: Hybrid LLM (Qwen3.5-35B-A3B MoE for local, optional DeepSeek-Cloud API) synthesizes K-line predictions, technical indicators, news, catalysts, and social sentiment. Reasoning-model output is parsed via a robust extractor that handles
<think>tags, free-text reasoning prefixes, and partial truncation. - Multi-Broker Automated Trading:
- US equities via Alpaca Live API (notional/dollar orders, fractional shares).
- Hong Kong equities via Moomoo OpenD (Moomoo NZ / FUTUAU entity, REAL or SIMULATE mode; supports odd-lot HK trading).
- A-shares / Futu HK also supported via the same OpenD layer.
- Cross-Stock Catalyst Engine:
TRUMP_CHINA_BENEFICIARIES-style macro events automatically propagate to all materially-exposed tickers without per-symbol keyword duplication. Geopolitical RSS feeds (cached for 5 min) feed directly into per-symbol catalyst detection. - Linked Symbols: BABA → 9988.HK, BIDU → 9888.HK etc — earnings news on one listing surfaces as a catalyst alert on the cross-listed sibling.
- Geopolitical Monitoring: Real-time tracking of 27 RSS feeds (White House, Reuters, BBC, Al Jazeera, CN financial, etc.) to auto-detect CRITICAL events.
- Macro Scenario Lifecycle: DB-backed scenarios with ACTIVE/DECLINING/RESOLVED/EXPIRED states. AI Layer 4 auto-generates new scenarios from news. Per-scenario
muted_by_userflag respects user preferences across restarts. - Two-Path RL Feedback Loop:
- Path 1 (XGBoost) — short, fast: every 6 hours, train a candidate from
rl_training_data.jsonl, A/B against current production by directional accuracy + RMSE, promote/shadow/reject. - Path 2 (Online LoRA fine-tune) — daily incremental: every day, rebuild
training/rl_sft_datasetfrom the latest labeled signals and warm-start continue-training a QLoRA adapter ongoogle/gemma-4-31B-it(the live brain — see "Model selection & online RL" below), validate vs holdout, and auto-promote into vLLM serving when it beats production.
- Path 1 (XGBoost) — short, fast: every 6 hours, train a candidate from
- Daily Email Reports: Separate emails for US (Alpaca, kitchen-sink) and HK (Moomoo, glance-friendly). Each summarizes account, positions, today's trades, top BUY/SELL signals.
- Reply-to-Email AI: User can reply to the daily report; LLM parses and applies setting changes (auto-trade toggle, watchlist add/remove, confidence threshold).
- JWT Multi-User: Secure authentication with isolated positions, settings, and trade records per user. SECRET_KEY MUST be supplied via
backend/.env— no hardcoded fallback.
The live trading brain is not hand-picked — it wins an automated, backtested
competition. backend/rl_llm_shootout.py:
- Discovers candidate local models across both Ollama daemons (system
:11434and the user-space:11435), e.g.gemma4:31b,deepseek-r1:32b,llama3:70b. - Runs the exact production
analyze_stockprompt for each candidate over a rolling 7-day holdout of already-reward-labeled signals. - Scores each on directional accuracy + mean realised reward.
- If the winner beats the incumbent
ollama_modelby ≥ 5 percentage points, it auto-promotes (updates theollama_modelsetting). A shootout report is written torl_models/llm_shootout/.
Why gemma-4-31B-it (gemma4:31b) is live (promoted 2026-05-27): it won the
shootout on rolling-holdout directional accuracy, beating deepseek-r1:32b (now the
fallback) — while returning clean JSON on the production prompt and making sound
calls (e.g. correctly holding parabolic names instead of chasing). It runs locally
on Ollama :11435 (Q4 for fast inference) with full-precision HF weights available
for fine-tuning.
Earlier the LoRA pipeline fine-tuned Qwen3.5-35B while the live brain was
gemma-4-31B — so RL never improved the model that actually traded. That mismatch
is now closed: online RL targets google/gemma-4-31B-it, the live brain.
brain logs a signal on every watchlist name ──► reward_1d/3d/7d labeled after the fact
(independent of whether a trade filled — paper forward-return reward)
│
daily cron rebuilds training/rl_sft_dataset from the latest labeled records
│
warm-start continue-train gemma-4-31B QLoRA adapter (attention-targeted, reward-weighted SFT)
│
validate vs holdout ──► decide_lora_promotion (≥5pp dir-acc AND reward↑)
│ pass
serve gemma-4-31B + adapter via vLLM (--enable-lora) ──► set `lora_inference_url`
│
deepseek_ai._call_ollama auto-routes live decisions to the vLLM adapter (no code change)
- Daily incremental, not per-step. True per-step online RL on a 31B LLM is
unstable; the practical form here is a daily warm-start continue-train on the
newest labeled batch, mixed with historical replay (full
rl_sft_dataset). - Validation gate prevents catastrophic forgetting. A new adapter only goes
live if it beats the current production model on the holdout (
rl_lora_validator.py→decide_lora_promotion). Otherwise it is shadowed/rejected. - Reward is forward price-return on signals, not realised account P&L (the account is small and trades rarely), so RL learns "which calls predicted good moves," not direct P&L. It is a drift-tracking refinement, not a profit switch.
SerenityAlphaTrader Pro utilizes multi-modal data inputs, continuously fetched in the background by automated daemon tasks:
- Market Data & Historical K-Lines
- Channel: Yahoo Finance (
yfinancePython library). - Content: Real-time global stock prices, historical OHLCV data (for Kronos model input), and dozens of auto-calculated technical indicators (MACD, RSI, etc.).
- Mechanism: Auto-polled every 2 minutes with staggered requests to prevent API rate limiting.
- Channel: Yahoo Finance (
- Stock-Specific News & Company Updates
- Channel: Yahoo Finance News API and official AI company blog RSS feeds.
- Content: Selected watchlist news summaries, major earnings releases, and industry trends.
- Mechanism: Scanned automatically every 15 minutes.
- Retail Social Sentiment
- Channel: StockTwits and Reddit (e.g., r/wallstreetbets, r/stocks).
- Content: Extraction of retail discussion volume and bullish/bearish emotion tags.
- Mechanism: Polled via API or specific web scraping every 30 minutes.
- Geopolitical & Macroeconomic Events (Core Feature)
- Channel: 15 integrated top-tier global RSS feeds (White House, Reuters, BBC, Financial Times, etc.).
- Content: Real-time capture of "CRITICAL" global macro events such as sudden wars, major sanctions, tariffs, or rate cuts.
- Mechanism: High-frequency concurrent scanning every 10 minutes to trigger specific scenario playbooks and auto-execute trades on beneficiary assets.
- Real-World Trading Execution
- Channel: Alpaca Live API.
- Content: A commission-free, API-native broker acting as the system's "execution arm".
- Mechanism: Executes millisecond-level live/paper trades, strictly using Notional (dollar-amount) orders for maximum reliability.
- Daily Trading Experience & Feedback Loop
- Channel: Internal System Logs & Reinforcement Learning (RL) Data Collector.
- Content: Extracted insights from daily profitable and losing trades, assessing why signals succeeded or failed.
- Mechanism: Systematically archives execution records into
rl_training_data.jsonlto form an ongoing feedback loop, fine-tuning future LLM trading logic.
graph TB
subgraph DATA["📡 Information Layer"]
YF["Yahoo Finance<br/>Quotes / K-lines / News"]
RSS["15 RSS Feeds<br/>Reuters / BBC / White House"]
SS["StockTwits / Reddit<br/>Retail Sentiment"]
KRONOS["Kronos GPU Model<br/>K-line Prediction (next 5)"]
QUANT["DCF / DDM Valuation<br/>Intrinsic Value"]
GC["Global Context<br/>VIX / Indices / FX"]
COT["CFTC COT<br/>Futures Positioning"]
end
subgraph SCENARIO["🌍 Macro Scenario Engine"]
SCAN["Keyword Scanner<br/>Every 10 min"]
AIREV["AI Review<br/>Every 6 hours"]
DB_S[("scenario_states<br/>SQLite")]
LIFE["ACTIVE → DECLINING → RESOLVED"]
end
subgraph AI["🧠 AI Brain Layer"]
PROMPT["Super-Prompt Builder<br/>Quote + Technicals + Valuation + News<br/>+ Scenarios + Sentiment + Predictions + Lessons"]
LLM["Ollama DRL70B<br/>/ DeepSeek-R1 API"]
SIGNAL["JSON Signal Output<br/>BUY / SELL / HOLD<br/>confidence + target + stop_loss"]
end
subgraph FILTER["🛡️ Risk Control Layer"]
F1["Gap Filter<br/>Skip BUY if +3% today"]
F2["Bear Filter<br/>Skip BUY if SPY < MA20"]
F3["Cooldown Filter<br/>No re-buy within 3d of stop-loss"]
F4["Market Hours<br/>Skip if market closed"]
F5["Kelly Sizing<br/>Half-Kelly × VIX scaling"]
end
subgraph EXEC["⚡ Execution Layer"]
ENGINE["TradingEngine<br/>Auto broker routing"]
ALP["Alpaca<br/>US Stocks"]
FUTU["Futu<br/>CN / HK"]
IBKR["IBKR<br/>Global"]
PAPER["Paper<br/>Simulated"]
end
subgraph FB["🔄 Feedback Loop"]
RL["RL Training Data<br/>232MB+ JSONL"]
EMAIL["Daily Email Report<br/>P&L / Win Rate"]
ARCHIVE["Signal Archive<br/>90-day compression"]
end
YF --> PROMPT
RSS --> PROMPT
RSS --> SCAN
SS --> PROMPT
KRONOS --> PROMPT
QUANT --> PROMPT
GC --> PROMPT
COT --> PROMPT
SCAN --> DB_S
AIREV --> DB_S
DB_S --> LIFE
DB_S --> PROMPT
PROMPT --> LLM
LLM --> SIGNAL
SIGNAL --> F1 --> F2 --> F3 --> F4 --> F5
F5 --> ENGINE
ENGINE --> ALP
ENGINE --> FUTU
ENGINE --> IBKR
ENGINE --> PAPER
ENGINE --> RL
ENGINE --> EMAIL
ENGINE --> ARCHIVE
RL -.->|"Historical lessons<br/>fed back into prompt"| PROMPT
sequenceDiagram
participant Trader as ⏱️ auto_trade_loop
participant MD as market_data.py
participant NI as news_intelligence.py
participant KR as Kronos (A100 GPU)
participant AI as LLM (Qwen3.5 35B)
participant FLT as Risk Filters
participant ENG as TradingEngine
participant DB as SQLite
Trader->>Trader: Triggered every ~15-30 min
loop For each symbol in watchlist
par Gather data in parallel
Trader->>MD: get_stock_quote + history + indicators + news
Trader->>NI: scan_all_threats + detect_catalysts
Trader->>KR: predict_next_candles (5 candles)
end
Trader->>Trader: Build super-prompt (all data merged)
Trader->>AI: analyze_stock(prompt) with /no_think
AI-->>Trader: signal / confidence / target / stop
Trader->>DB: Store AI signal
Trader->>FLT: Apply 5 filters
alt All filters passed & confidence ≥ 75%
FLT->>ENG: Execute trade
ENG->>DB: Record trade + update position
ENG-->>Trader: Broadcast via WebSocket
else Filtered out
FLT-->>Trader: Skip (log reason)
end
end
stateDiagram-v2
[*] --> ACTIVE: Trigger keywords matched / AI creates new scenario
ACTIVE --> ACTIVE: Evidence found (evidence_count + 1)
ACTIVE --> DECLINING: 3h with no evidence OR resolution keywords ≥ 2
DECLINING --> ACTIVE: New evidence appears (after 20 min cooldown)
DECLINING --> RESOLVED: Resolution keywords ≥ 4 OR AI review confirms resolved
DECLINING --> EXPIRED: 12h with zero evidence
ACTIVE --> RESOLVED: Resolution keywords ≥ 4 OR AI review (every 6h)
RESOLVED --> [*]
EXPIRED --> [*]
graph LR
subgraph CORE["Core trading & risk"]
L1["🔴 auto_trade_loop<br/>⏱ ~15-30 min<br/>watchlist scan → AI → trade"]
L2["🔴 stop_loss_monitor<br/>⏱ 15 sec<br/>Protect positions"]
L3["🌍 global_market_scan<br/>⏱ 5 min<br/>VIX / cross-asset"]
end
subgraph INTEL["News & intelligence"]
N1["📰 news_scan<br/>⏱ 10 min<br/>Breaking + scenarios"]
N2["📅 event_scan<br/>⏱ 10 min<br/>Earnings / M&A"]
N3["💬 social_sentiment<br/>⏱ 30 min<br/>StockTwits / Reddit"]
N4["📝 blog_monitor<br/>⏱ 30 min<br/>AI lab blogs"]
N5["🇭🇰 hk_ipo_scan<br/>⏱ 12 h<br/>New HK IPO watchlist add"]
end
subgraph EXEC["Execution & ops"]
E1["⏳ pending_executor<br/>⏱ 5 min<br/>Deferred orders"]
E2["🔁 dca_core_etf<br/>⏱ 1 h<br/>Re-buy SPY/QQQ to target"]
E3["⚖ one_shot_rebalance<br/>⏱ Daily<br/>Drift control"]
E4["💵 deposit_handler<br/>⏱ 5 min<br/>Detect & re-deploy fresh cash"]
end
subgraph RL["RL pipeline"]
R1["🧠 rl_policy_trainer<br/>⏱ 6 h<br/>XGBoost retrain → A/B → promote"]
R2["📊 kronos_gpu<br/>⏱ On-demand<br/>K-line prediction (A100)"]
end
subgraph COMM["Communication"]
C1["📧 email_reporter<br/>⏱ 21:10 UTC<br/>2 emails: US + HK"]
C2["📨 email_reply_checker<br/>⏱ IMAP IDLE<br/>Apply user commands via LLM"]
C3["💼 annual_tax_report<br/>⏱ 31 Mar yearly<br/>NZ tax-year P&L"]
end
graph LR
subgraph Backend
FastAPI --> SQLAlchemy --> SQLite
end
subgraph AI_Models["AI Models"]
Ollama["Ollama (DRL70B 70B)"]
DeepSeek["DeepSeek-R1 API"]
Kronos["Kronos (A100 GPU)"]
end
subgraph Brokers
Alpaca
Futu
IBKR
end
subgraph Frontend
direction TB
SPA["HTML / JS / CSS"] --> WS["WebSocket"]
WS --> TV["TradingView Charts"]
end
subgraph Infra["Infrastructure"]
systemd --> HPC["University HPC Server"]
end
| Component | Version | Description |
|---|---|---|
| Python | 3.10 (conda) | alphatrader conda environment |
| CUDA | 12.4+ | A100 GPU for running Kronos |
| Ollama | Any | To run the DRL70B model |
| GPU | A100 80GB × 1 | Recommend GPU-7 (most idle) |
| SQLite | Built-in | No separate installation required |
git clone https://github.com/14H034160212/AlphaTrader.git
cd /data/qbao775/AlphaTraderconda create -n alphatrader python=3.10 -y
# Install PyTorch (CUDA 12.4)
/data/qbao775/miniconda3/envs/alphatrader/bin/pip install \
torch==2.6.0 --index-url https://download.pytorch.org/whl/cu124
# Install all project dependencies
/data/qbao775/miniconda3/envs/alphatrader/bin/pip install \
numpy pandas \
fastapi "uvicorn[standard]" \
sqlalchemy \
pydantic \
"python-jose[cryptography]" \
bcrypt \
python-multipart \
requests \
yfinance \
ta \
feedparser \
"alpaca-trade-api" \
"alpha_vantage==2.3.1" \
transformers \
huggingface_hub \
accelerate \
sentencepiece \
einops \
safetensors \
tqdmPowers live Serenity tweets, Exa news search, and the smart-money / news / deposit watchers. Installed in its OWN isolated conda env (needs Python ≥ 3.10) so it never touches the trading env:
conda create -n agentreach python=3.11 -y
/data/qbao775/miniconda3/envs/agentreach/bin/pip install \
"https://github.com/Panniantong/agent-reach/archive/main.zip"
/data/qbao775/miniconda3/envs/agentreach/bin/agent-reach install --env=auto # zero-config channels
/data/qbao775/miniconda3/envs/agentreach/bin/agent-reach install --channels=twitter # X channel tooling
# Exa global semantic search (needs node + mcporter, npm-global into miniconda)
npm install -g mcporter
mcporter config add exa https://mcp.exa.ai/mcp # writes ./config/mcporter.json
# X / Twitter auth — use a BURNER account, never your main one (datacenter-IP
# scraping can get an account rate-limited/locked). Export cookies with the
# Cookie-Editor extension on x.com (Export → Header String), then:
# agent-reach configure twitter-cookies "PASTED_STRING"
# and store the auth for cron (chmod 600), read by fetch_serenity_tweets.sh:
cat > ~/.agent-reach/twitter.env <<'EOF'
export TWITTER_AUTH_TOKEN="..." # from the burner account's cookies
export TWITTER_CT0="..."
EOF
chmod 600 ~/.agent-reach/twitter.envCron jobs that drive the intelligence pipeline (all use absolute paths so they survive cron's minimal env):
*/30 * * * * refresh_serenity_data.sh # yan-labs archive sync
23 */6 * * * fetch_serenity_tweets.sh 25 # LIVE Serenity tweets
17 6 * * * backend/refresh_serenity_intel.py # semiconstocks focus
0 13 * * 1-5 backend/market_regime.py # adaptive cash floor (pre-open)
13 7 * * 1,4 fetch_smart_money.sh # 13F + congress + Musk/Trump
47 13,15,17,19 * * 1-5 backend/news_watch.py # breaking-news alerts (market hours)
*/30 * * * * backend/deposit_watch.py # deposit auto-detect
33 21 * * 1-5 send_market_reports.sh # daily email (after US close)cd /data/qbao775/AlphaTrader/kronos_lib
git clone https://github.com/shiyu-coder/Kronos.git ./data/qbao775/miniconda3/envs/alphatrader/bin/python3 -c "
from huggingface_hub import snapshot_download
snapshot_download(
repo_id='NeoQuasar/Kronos-base',
local_dir='/data/qbao775/AlphaTrader/kronos_lib/weights/Kronos-base',
ignore_patterns=['*.bin']
)
snapshot_download(
repo_id='NeoQuasar/Kronos-Tokenizer-base',
local_dir='/data/qbao775/AlphaTrader/kronos_lib/weights/Kronos-Tokenizer-base'
)
print('Done')
"# Install Ollama (if not installed)
curl -fsSL https://ollama.com/install.sh | sh
# Pull DeepSeek-R1 70B (~42GB)
ollama pull DRL70B:latest
# Verify
ollama list
# Should display: DRL70B:latest 42.5GBThe backend now refuses to start without SECRET_KEY. Generate a fresh 64-char hex
and store it in backend/.env (gitignored). start.sh loads it automatically.
# Generate a random key (run on your local machine, NOT in chat):
python3 -c "import secrets; print(f'SECRET_KEY={secrets.token_hex(32)}')" > backend/.env
chmod 600 backend/.env # important — file contains a credentialstart.sh sources this file via set -a / set +a before launching uvicorn. If
the file is missing or unreadable, the supervisor exits immediately with a fatal
log line (don't run a JWT system with no signing key).
Other secrets (Alpaca API key/secret, DeepSeek API key, Gmail app password,
Moomoo password MD5) live in the DB settings table, not in .env.
mkdir -p ~/.config/systemd/user
cat > ~/.config/systemd/user/alphatrader.service << 'EOF'
[Unit]
Description=SerenityAlphaTrader Backend Service
After=network.target
[Service]
Type=simple
WorkingDirectory=/data/qbao775/AlphaTrader
ExecStart=/bin/bash /data/qbao775/AlphaTrader/start.sh
Restart=on-failure
RestartSec=5
StandardOutput=append:/tmp/alphatrader.log
StandardError=append:/tmp/alphatrader.log
[Install]
WantedBy=default.target
EOF
chmod 600 ~/.config/systemd/user/alphatrader.service
systemctl --user daemon-reload
systemctl --user enable alphatraderNote: On shared servers where
user@.serviceis in failed state (some NeSI-style HPC nodes), systemctl --user won't work. In that case run start.sh viasetsid nohup bash start.sh </dev/null >>/tmp/alphatrader.log 2>&1 &from a login shell — start.sh'swhile trueloop auto-restarts uvicorn on crash.
For HK / A-share / multi-region trading, install Moomoo OpenD on the same host as the backend (or on any host SerenityAlphaTrader can reach on port 11111).
# Download OpenD Linux tarball from Moomoo's official site
# (region-gated, must use a logged-in Moomoo account)
mkdir -p ~/moomoo-opend && cd ~/moomoo-opend
# extract the tarball: tar -xzf moomoo_OpenD_*.tar.gz --strip-components=2
# Edit OpenD.xml — fill in your Moomoo UserID + 32-char MD5 of password
# (generate MD5 locally: printf '你的密码' | md5sum | cut -d' ' -f1)
# Enable telnet (line ~40 of OpenD.xml) for first-time 2FA setup:
# <telnet_ip>127.0.0.1</telnet_ip>
# <telnet_port>22222</telnet_port>
chmod 600 OpenD.xml
# First launch will trigger SMS 2FA. Pipe code in via telnet:
nohup ./OpenD > opend.console.log 2>&1 &
# Then in another shell (or via Python socket), send to 127.0.0.1:22222:
# input_phone_verify_code -code=NNNNNN
# Wire SerenityAlphaTrader to OpenD via the DB settings table:
# futu_enabled=true
# futu_host=127.0.0.1
# futu_port=11111
# futu_security_firm=FUTUAU # for Moomoo NZ/AU. Use FUTUSECURITIES for Futu HK
# futu_trade_env=REAL # or SIMULATE for paper
# futu_hk_acc_id=<your HK acc_id> # required when futu_trade_env=REALOpenD must complete a one-time "API Questionnaire" inside the Moomoo phone app before it accepts any login. Without this, OpenD logs in successfully then exits with "regulatory requirements" error.
The Hong Kong daily P&L is sent as a separate email from the main US report (triggered at the same 21:10 UTC cadence).
systemctl --user start alphatradersystemctl --user stop alphatradersystemctl --user restart alphatradersystemctl --user status alphatradertail -f /tmp/alphatrader.logcurl http://localhost:8888/api/health
# Returns: {"status":"ok","timestamp":"..."}If /data/qbao775/AlphaTrader/.DISABLE_AUTOSTART exists, both start.sh and backend/main.py's standalone entrypoint refuse to start (see "What's new (2026-07-03)" further down for why this exists). Delete it to restore normal operation:
rm /data/qbao775/AlphaTrader/.DISABLE_AUTOSTART
systemctl --user restart alphatraderVisit http://<Server IP>:8000 and go to the settings page:
| Setting | Recommended Value | Description |
|---|---|---|
| AI Provider | Local Ollama |
Use DRL70B (DeepSeek-R1 70B) |
| Alpaca API Key | Your Key | Live for real trades, Paper for testing |
| Alpaca Secret Key | Your Secret | Same as above |
| Alpaca Mode | live / paper |
paper = simulated, live = real |
| Auto-Trading | Enabled |
Auto-order when confidence ≥ 70% |
| Min Confidence | 0.70 |
Minimum confidence threshold |
| Risk Per Trade | 2.0% |
Max risk exposure per trade |
# Get token
TOKEN=$(curl -s http://localhost:8000/api/auth/auto-login | \
python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")
# Configure Alpaca for Live trading
curl -s -X POST http://localhost:8000/api/settings \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"key":"alpaca_api_key","value":"YOUR_KEY"}'
curl -s -X POST http://localhost:8000/api/settings \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"key":"alpaca_secret_key","value":"YOUR_SECRET"}'
curl -s -X POST http://localhost:8000/api/settings \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"key":"alpaca_paper_mode","value":"false"}'
# Enable auto-trading
curl -s -X POST http://localhost:8000/api/settings \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"key":"auto_trade_enabled","value":"true"}'
curl -s -X POST http://localhost:8000/api/settings \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"key":"ai_provider","value":"ollama"}'SerenityAlphaTrader/
├── start.sh # Startup script (includes auto-restart daemon)
├── stop.sh # Stop script
├── rl_training_data.jsonl # RL training data (appended per trade)
├── intelligence_attribution_report.json # Signal attribution analysis report
│
├── backend/
│ ├── main.py # FastAPI app + background tasks
│ ├── auth.py # JWT authentication (bcrypt)
│ ├── database.py # SQLAlchemy models + SQLite (incl. SignalArchive)
│ ├── trading_engine.py # Trading engine (Alpaca Notional orders + short protection)
│ ├── market_data.py # Market data + technical indicators
│ ├── deepseek_ai.py # DeepSeek-R1 / Ollama AI analysis
│ ├── kronos_analysis.py # Kronos K-line prediction (A100 GPU)
│ ├── news_intelligence.py # News + macro scenario detection + geopolitical RSS
│ ├── social_sentiment.py # StockTwits + Reddit sentiment scanning
│ ├── blog_monitor.py # AI company blog RSS monitoring
│ ├── event_monitor.py # Earnings / macro event calendar
│ ├── intelligence_feedback.py # RL signal feedback & reward calculation
│ ├── rl_data_collector.py # RL training data collector
│ ├── quant_models.py # Quantitative models (DCF/DDM/VPA)
│ ├── notifier.py # Notifications
│ ├── trading_platform.db # SQLite runtime database
│ └── requirements.txt # Python dependencies (for reference, use conda env)
│
├── frontend/
│ ├── index.html # SPA main page
│ ├── app.js # Frontend logic (market/trading/AI analysis)
│ └── styles.css # Dark theme styles
│
└── kronos_lib/ # Kronos model (cloned from git)
├── model/ # Kronos code
│ ├── __init__.py
│ └── kronos.py # KronosTokenizer, Kronos, KronosPredictor
├── prediction_results/ # Kronos prediction results (JSON, auto-gzipped >90 days)
└── weights/
├── Kronos-base/ # Model weights (HuggingFace)
└── Kronos-Tokenizer-base/ # Tokenizer weights
| Data | Location | Description |
|---|---|---|
| Users/Positions/Trades/Signals | backend/trading_platform.db |
SQLite, auto-created |
| Weekly Signal Archives | signal_archives (Same DB) |
>90 days signals compressed into weekly summaries |
| Price Cache | Memory | Rebuilt ~2 mins after restart |
| Kronos Predictions | kronos_lib/prediction_results/ |
JSON; compressed to gzip if >90 days old |
| RL Training Data | rl_training_data.jsonl |
JSONL format, appended continuously |
| Signal Attribution Report | intelligence_attribution_report.json |
Periodically updated |
| Service Logs | /tmp/alphatrader.log |
Auto-rotated/gzipped if >200MB |
Data Retention Policy (90 Days): Automated maintenance task runs daily at UTC 00:00:
- AI Signals > 90 days → Aggregated into
signal_archivesby (user, stock, week) and deleted from original table. - Kronos JSON > 90 days → Gzipped, and JSON deleted.
- Logs > 200MB → Keep last 500 lines as summary, gzip old logs, and truncate current file.
The following background loops run automatically once the service starts:
| Task | Frequency | Description |
|---|---|---|
background_price_refresh |
Every 2 mins | Refreshes price cache; staggers requests to prevent rate limiting |
background_auto_trade_loop |
Continuous | Scans watchlist, triggers AI analysis, and auto-trades |
background_news_scan |
Every 15 mins | yfinance news + macro scenario detection |
background_news_scan (Geopolitical Sub-task) |
Every 10 mins | 15-feed RSS geopolitical scanning; auto-triggers AI for beneficiary stocks on CRITICAL events |
background_event_scan |
Every 15 mins | Competitive threats + catalyst identification |
background_social_sentiment_scan |
Every 30 mins | StockTwits/Reddit sentiment |
background_blog_scan |
Every 15 mins | AI company blog RSS |
background_daily_summary |
Daily | Generates daily summary reports |
background_pending_trade_executor |
Every 1 min | Executes pending limit/stop orders |
_run_daily_maintenance |
Daily at UTC 00:00 | Signal archival + Kronos gzip + log rotation |
The system monitors these 15 sources to detect CRITICAL macro events such as wars, sanctions, or tariffs in real-time:
| Source | Description |
|---|---|
| US White House | whitehouse.gov official RSS |
| US Dept of State | state.gov press releases |
| US Treasury | treasury.gov announcements |
| Reuters | Top news + World news |
| BBC | BBC World news |
| Al Jazeera | English RSS |
| The Guardian | World edition |
| NPR | International news |
| Financial Times | World news |
| Associated Press | Top headlines |
| Times of Israel | Israel news |
| Jerusalem Post | Israel news |
| OilPrice.com | Oil market news |
| Scenario | Severity Level | Beneficiary Assets | Assets to Avoid |
|---|---|---|---|
middle_east_war_2026 |
CRITICAL | GLD, IAU, SLV, XOM, LMT, RTX, NOC | TSLA, AMZN, AAPL, QQQ, TQQQ, SOXL |
fed_rate_cut |
HIGH | QQQ, ARKK, TSLA, NVDA, AMZN | GLD (Partially) |
tariff_war |
HIGH | Domestic mfg, Agriculture | Import/Export dependent stocks |
recession_fears |
HIGH | GLD, TLT | Cyclical stocks |
When a CRITICAL/HIGH scenario is detected, the system automatically triggers an AI analysis for the beneficiary stocks, and issues a buy order if the confidence is ≥ 70%.
The system uses Notional (Dollar-Amount) Orders instead of quantity (qty) orders for the following reasons:
- Alpaca limits the minimum fraction for qty orders, often causing small orders to be canceled.
- Notional orders (e.g.,
notional=18.00) specify exact dollar amounts spent, providing much higher reliability. - Minimum order amount: $1.00
Short Protection Mechanism: Before selling, the system automatically verifies your position via the Alpaca API. If Alpaca shows no holding, the sell action is skipped, preventing accidental naked shorting leading to order rejections.
# View detailed error logs
tail -50 /tmp/alphatrader.log
# Check port usage
ss -tlnp | grep 8000
# Manual startup test
cd /data/qbao775/AlphaTrader/backend
/data/qbao775/miniconda3/envs/alphatrader/bin/python3 -c "
import uvicorn
uvicorn.run('main:app', host='0.0.0.0', port=8000)
"# Check GPU memory usage
nvidia-smi --query-gpu=index,memory.used,memory.free --format=csv
# Modify start.sh to select a more idle GPU
# E.g., Change CUDA_VISIBLE_DEVICES=7 to another free GPU indexThe price refresh already operates with a 1.5s delay and 2-minute loop interval, usually avoiding throttling.
If you still hit limits, temporarily increase the refresh interval in start.sh.
The system includes short protection that auto-verifies your Alpaca holding before selling. If the error persists:
# Check if local portfolio syncs with Alpaca actual holding
curl -s http://localhost:8000/api/positions -H "Authorization: Bearer $TOKEN"
# Query actual position using Alpaca API
curl -s https://api.alpaca.markets/v2/positions \
-H "APCA-API-KEY-ID: YOUR_KEY" \
-H "APCA-API-SECRET-KEY: YOUR_SECRET"The system uses notional orders, so normal purchases shouldn't be cancelled. If they are:
- Ensure the account balance has enough cash (minimum $1).
- Ensure the stock supports fractional trading (some OTC stocks might not).
# Check Ollama processes
ps aux | grep ollama
# Verify model availability
curl http://localhost:11434/api/tags
# Restart Ollama
pkill ollama && ollama serve &This project is for educational and experimental purposes only. AI trading signals do NOT constitute investment advice, and the developers hold no liability for any trading losses. Please ensure you fully understand the associated risks and validate strategies in Paper Mode before performing live trading.