Spaces:
Runtime error
Runtime error
Upload README.md
Browse files
README.md
CHANGED
|
@@ -3,11 +3,157 @@ title: Chan Compass · US
|
|
| 3 |
emoji: 🧭
|
| 4 |
colorFrom: blue
|
| 5 |
colorTo: purple
|
| 6 |
-
sdk:
|
| 7 |
-
|
| 8 |
-
python_version: "3.11"
|
| 9 |
-
app_file: server.py
|
| 10 |
pinned: false
|
|
|
|
|
|
|
| 11 |
---
|
| 12 |
|
| 13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
emoji: 🧭
|
| 4 |
colorFrom: blue
|
| 5 |
colorTo: purple
|
| 6 |
+
sdk: docker
|
| 7 |
+
app_port: 7860
|
|
|
|
|
|
|
| 8 |
pinned: false
|
| 9 |
+
license: mit
|
| 10 |
+
short_description: Local Chan-theory US stock signals, fine-tuned 1.7B
|
| 11 |
---
|
| 12 |
|
| 13 |
+
# 🧭 Chan Compass — US Edition
|
| 14 |
+
|
| 15 |
+
Multi-timeframe **缠论 (Chan theory)** signal engine for US stocks — monthly → weekly →
|
| 16 |
+
daily → 60m → 30m → 15m → 5m → 1m **nested-interval (区间套) confirmation** — plus a
|
| 17 |
+
**sector capital-rotation monitor**, a **today-only watchlist news desk**, a
|
| 18 |
+
**multi-agent research desk**, and a **fully local llama.cpp brain** (Qwen3 GGUF +
|
| 19 |
+
a **published fine-tune**, all ≤ 32B parameters, no cloud APIs).
|
| 20 |
+
|
| 21 |
+
UI design language: **Adobe Spectrum 2** (pill buttons, Spectrum blue `#0265DC`,
|
| 22 |
+
Source Sans 3 — Adobe's open font), served from `ui_kits/chan-compass/` by
|
| 23 |
+
`gradio.Server`.
|
| 24 |
+
|
| 25 |
+
> **Backyard AI** — this solves a real problem for real people: my family trades
|
| 26 |
+
> US stocks with a Chan-theory engine whose reasoning is dense Chinese jargon and
|
| 27 |
+
> which had to be run by hand every night. Chan Compass runs it automatically and
|
| 28 |
+
> turns each verdict into a plain-English summary they actually read.
|
| 29 |
+
|
| 30 |
+
## The local sub-agent pool
|
| 31 |
+
|
| 32 |
+
All language work runs on a pool of small local models through llama.cpp — each
|
| 33 |
+
sub-agent has its own lock, so features never block one another:
|
| 34 |
+
|
| 35 |
+
| Sub-agent | Model | Used by |
|
| 36 |
+
|---|---|---|
|
| 37 |
+
| **Interpreter** | **Chan-Tuned Qwen3-1.7B** (my published fine-tune) | Signals → AI Interpret |
|
| 38 |
+
| **Narrator** | Qwen3-1.7B | Sector Rotation narrative |
|
| 39 |
+
| **Reporter** | Qwen3-1.7B | Watchlist News briefs + research support |
|
| 40 |
+
| **Analyst** | Qwen3-4B | Auto Research report writing |
|
| 41 |
+
|
| 42 |
+
The Interpreter sub-agent uses a **fine-tuned** Qwen3-1.7B
|
| 43 |
+
(`ranranrunforit/chan-compass-qwen3-1.7b-gguf`, Q8_0), LoRA-trained on
|
| 44 |
+
(raw read → English summary) pairs captured from the app's own usage — a small
|
| 45 |
+
model doing one focused job well.
|
| 46 |
+
|
| 47 |
+
## Tabs
|
| 48 |
+
|
| 49 |
+
| Tab | What it does |
|
| 50 |
+
|---|---|
|
| 51 |
+
| 📈 Signals | Runs the unchanged Chan engine over your ticker pool (pure rule engine, no LLM on this path): next-session BUY / SELL / HOLD / WAIT with an explicit **buy point**, entry zone, invalidation price, confidence and suggested weight. Pick a ticker for a plain-English raw read, then **AI Interpret** — the Interpreter sub-agent references the multi-timeframe ruling chain (kept backstage) and writes an English-only interpretation. |
|
| 52 |
+
| 🔄 Sector Rotation | Where capital is flowing: 11 SPDR sector ETFs (full S&P 500), flow proxy = change% × dollar volume + relative strength vs SPY, over 1/5/20 days, tables instant + an on-demand AI narrative. |
|
| 53 |
+
| 📰 Watchlist News | For each holding, checks **today's** news only, streaming each ticker / headline / AI brief as it arrives; quiet tickers are grouped. |
|
| 54 |
+
| 🧪 Auto Research | Multi-agent: PLAN → 6 evidence tools in parallel (fundamentals, quarterly financials, price action, the Chan engine itself, money-flow proxy, news) → Analyst (4B) streams valuation · tech moat · supply-chain map (with tickers) · bull/bear while the Reporter (1.7B) writes money-flow · Chan timing · risks in parallel. Every run saves a JSON **agent trace**; new pool tickers get a report **auto-generated** by the daily pipeline. |
|
| 55 |
+
| ⏰ Automation | Daily pipeline at **18:10 America/New_York**, with a live Pipeline Log and auto-refreshing trace list. Manual "Run now" too, plus a one-click **Publish traces as a Hub dataset** button (uses your `HF_TOKEN`, no command line). |
|
| 56 |
+
| 🧠 Model | Live sub-agent status (auto-refresh), one-click self-test, model picker, and a **fine-tuning dataset export** (download the JSONL the app captured). |
|
| 57 |
+
|
| 58 |
+
## Email any result
|
| 59 |
+
|
| 60 |
+
Each of the four result tabs has an **email box + ✉ Send Email** button — send the
|
| 61 |
+
current AI result to any address. Delivery uses the **Resend HTTPS API** (works on
|
| 62 |
+
HF Spaces, which block outbound SMTP), with SMTP as an off-HF fallback. Set a Space
|
| 63 |
+
secret `RESEND_API_KEY` to enable it. Both HTML and clean plain-text are rendered
|
| 64 |
+
from the markdown, so reports arrive properly formatted.
|
| 65 |
+
|
| 66 |
+
## Data
|
| 67 |
+
|
| 68 |
+
Yahoo Finance via `yfinance`: 10y daily (weekly/monthly resampled), 60m (730d),
|
| 69 |
+
30m/15m/5m (60d), 1m (7d). Downloads are parallel with a time budget; whatever
|
| 70 |
+
isn't fetched in time is skipped and picked up next run. Cached to parquet.
|
| 71 |
+
|
| 72 |
+
## Persistent storage (`/data` bucket)
|
| 73 |
+
|
| 74 |
+
With a storage bucket attached, the app keeps everything across restarts:
|
| 75 |
+
`/data/cache_us` market data · `/data/output` signals + holdings + **the last
|
| 76 |
+
pipeline results** (`last_results.json`) and **last-run time** (`last_run.txt`) ·
|
| 77 |
+
`/data/reports` research reports · `/data/traces` agent traces · `/data/dataset`
|
| 78 |
+
captured fine-tuning pairs · `/data/hf_cache` GGUF models · `/data/pylibs` the
|
| 79 |
+
llama.cpp runtime (installed once, persisted).
|
| 80 |
+
|
| 81 |
+
**Results survive restarts and page reloads.** When the daily pipeline runs (or
|
| 82 |
+
you press Run now), the signals table, sector-rotation tables, and watchlist-news
|
| 83 |
+
briefs are written to `/data`. Open the app later — even after a restart — and it
|
| 84 |
+
loads those last results immediately, no recompute. So if the 18:10 ET schedule
|
| 85 |
+
ran at 6 pm, opening the page at 7 pm shows the finished results right away.
|
| 86 |
+
(Re-running with a different ticker pool in Signals / News / Auto Research
|
| 87 |
+
recomputes just that view.)
|
| 88 |
+
|
| 89 |
+
## Fine-tuning kit (🎯 Well-Tuned)
|
| 90 |
+
|
| 91 |
+
`finetune/` contains a ready-to-run Colab notebook and guide: export the captured
|
| 92 |
+
(raw read → summary) pairs from the Model tab, LoRA-tune Qwen3-1.7B on a free T4,
|
| 93 |
+
convert to GGUF, push to the Hub, and point `MODEL_ZOO` at it. The published
|
| 94 |
+
result is already wired in as the **Interpreter sub-agent**.
|
| 95 |
+
|
| 96 |
+
## Hackathon badge checklist
|
| 97 |
+
|
| 98 |
+
🔌 **Off the Grid** — all inference local, zero cloud APIs · 🦙 **Llama Champion** —
|
| 99 |
+
Qwen3 GGUF through the llama.cpp runtime (installed at first run into `/data/pylibs`
|
| 100 |
+
to dodge the build-container OOM) · 🐜 **Tiny Titan** — the everyday language work
|
| 101 |
+
(Signals summary, rotation narrative, news briefs) all runs on **1.7B** models, and
|
| 102 |
+
the Interpreter sub-agent is a **fine-tuned 1.7B** · 🤖 **Best Agent** — the multi-agent
|
| 103 |
+
Auto Research desk (parallel evidence tools + Analyst/Reporter writing in parallel,
|
| 104 |
+
every step logged) · 📡 **Sharing is Caring** — each research run writes a full JSON
|
| 105 |
+
agent trace (PLAN -> each tool call + result -> each sub-agent request/response),
|
| 106 |
+
**published as a Hub dataset**:
|
| 107 |
+
[`ranranrunforit/chan-compass-agent-traces`](https://huggingface.co/datasets/ranranrunforit/chan-compass-agent-traces)
|
| 108 |
+
(one click from the Automation tab) · 🎨 **Off-Brand** — a hand-built **React + Spectrum 2** frontend served by `gradio.Server` (the app's own HTML/CSS/JS, not the default Gradio component render)
|
| 109 |
+
served by `gradio.Server`, with custom React/CSS instead of the stock Gradio look · 🎯
|
| 110 |
+
**Well-Tuned** — a published fine-tuned model
|
| 111 |
+
(`ranranrunforit/chan-compass-qwen3-1.7b-gguf`) the app actually uses.
|
| 112 |
+
|
| 113 |
+
> Submission to-do (not in this repo): the short demo video, the social post, and
|
| 114 |
+
> a screenshot/quote showing the person actually using it.
|
| 115 |
+
|
| 116 |
+
## Architecture (🎨 Off-Brand)
|
| 117 |
+
|
| 118 |
+
This is not the default Gradio component UI. `server.py` builds a
|
| 119 |
+
**`gradio.Server`** (Gradio's FastAPI-based server) that:
|
| 120 |
+
|
| 121 |
+
- serves the hand-built **React + Spectrum 2 frontend** (`ui_kits/chan-compass/`)
|
| 122 |
+
as static files at `/`, and
|
| 123 |
+
- exposes the unchanged Python backend as JSON + Server-Sent-Events endpoints
|
| 124 |
+
under `/api/*` (signals, rotation, news, research, automation, model, email).
|
| 125 |
+
|
| 126 |
+
So the whole look-and-feel is the app's own HTML/CSS/JS — a real custom frontend —
|
| 127 |
+
while still being a Gradio app (`gradio.Server`) running through llama.cpp.
|
| 128 |
+
|
| 129 |
+
## Deploy on Hugging Face Spaces
|
| 130 |
+
|
| 131 |
+
1. Create a Space → SDK **Docker**, hardware **CPU upgrade** (8 vCPU/32GB recommended).
|
| 132 |
+
The included `Dockerfile` runs `uvicorn server:app` on port 7860.
|
| 133 |
+
2. Upload every file in this folder (keep names + the `ui_kits/chan-compass/`
|
| 134 |
+
folder structure unchanged); overwrite-upload as a full set each time.
|
| 135 |
+
3. First launch installs the llama.cpp runtime once (prebuilt CPU wheel, with a
|
| 136 |
+
compile fallback) into `/data/pylibs`.
|
| 137 |
+
4. **Model** tab — sub-agents auto-load; watch the live status until each shows ✅.
|
| 138 |
+
5. Optional secrets: `RESEND_API_KEY` (email), `HF_TOKEN` (faster model downloads
|
| 139 |
+
+ the one-click trace publisher, silences the unauthenticated-Hub warning).
|
| 140 |
+
6. ⚠️ Free Spaces sleep when idle, so the 18:10 ET timer can't fire unattended —
|
| 141 |
+
use "Run now", or pick always-on hardware. Last-run time is persisted to
|
| 142 |
+
`/data`, so it survives restarts.
|
| 143 |
+
|
| 144 |
+
## Design system
|
| 145 |
+
|
| 146 |
+
UI follows the **Chan Compass · Spectrum 2** design system. The live frontend is
|
| 147 |
+
served from `ui_kits/chan-compass/` by `gradio.Server`; the source
|
| 148 |
+
tokens/components are under `design_system/` for reference.
|
| 149 |
+
|
| 150 |
+
## Files
|
| 151 |
+
|
| 152 |
+
`chan_engine.py` / `chan_multilevel.py` / `chan_enhance.py` — the original Chan
|
| 153 |
+
analysis engine, **verbatim, logic untouched** · `chan_glue.py` — runtime wiring +
|
| 154 |
+
analyzer cache · `data_us.py` — yfinance loader · `signal_runner.py` · `rotation.py` ·
|
| 155 |
+
`news_watch.py` · `research.py` · `research_agent.py` · `automation.py` ·
|
| 156 |
+
`llm_local.py` · `emailer.py` · `finetune_data.py` · `trace_publish.py` · `server.py` (the gr.Server entry) · `ui_kits/chan-compass/` (the React frontend) ·
|
| 157 |
+
`finetune/` — the fine-tuning notebook + guide.
|
| 158 |
+
|
| 159 |
+
*Educational tool — not investment advice.*
|