|
| 1 | +# Kronos Integration Summary |
| 2 | + |
| 3 | +This document summarizes the Kronos financial forecasting integration added to the framework. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +**Kronos** is a foundation model for financial K-line (OHLCV) forecasting. The integration allows trading bots to leverage AI-driven price predictions from a state-of-the-art model trained on 12B+ candlestick records across 45+ exchanges. |
| 8 | + |
| 9 | +**Architecture**: The model runs on a Hugging Face Docker Space (CPU, free tier, 16GB RAM). K8s cronjobs call it via HTTP to stay within K8s memory limits (2Gi). |
| 10 | + |
| 11 | +## Files Created |
| 12 | + |
| 13 | +### Core Implementation |
| 14 | + |
| 15 | +1. **`kronos_space/Dockerfile`** — HF Space Docker image |
| 16 | + - Python 3.11, CPU-only PyTorch, FastAPI |
| 17 | + - Clones Kronos source at build time |
| 18 | + - Pre-bakes model weights (instant startup) |
| 19 | + - Ports 7860 (HF convention) |
| 20 | + |
| 21 | +2. **`kronos_space/app.py`** — FastAPI inference server |
| 22 | + - `GET /health` — check if Kronos-mini is loaded |
| 23 | + - `POST /predict` — accept OHLCV JSON, return forecast rows |
| 24 | + - Lifespan event loads model once at startup |
| 25 | + |
| 26 | +3. **`kronos_space/requirements.txt`** — Space dependencies |
| 27 | + - torch (CPU), transformers, fastapi, uvicorn, pandas, huggingface_hub |
| 28 | + |
| 29 | +4. **`tradingbot/utils/kronos_client.py`** — K8s HTTP client |
| 30 | + - `KronosClient.predict(symbol, horizon=5)` → DataFrame |
| 31 | + - Falls back gracefully (logs warning, returns None) if Space unavailable |
| 32 | + - `@tool kronos_forecast` for LangChain integration with `run_ai_with_tools()` |
| 33 | + |
| 34 | +5. **`tradingbot/kronosbot.py`** — Daily cronjob orchestrator |
| 35 | + - Restarts the Space via `HfApi.restart_space()` |
| 36 | + - Polls `/health` until Kronos loads (~60s) |
| 37 | + - Loops over active tickers, predicts next N days |
| 38 | + - Upserts `KronosPrediction` rows to Postgres |
| 39 | + - Pauses Space via `HfApi.pause_space()` to save quota |
| 40 | + |
| 41 | +### Database |
| 42 | + |
| 43 | +6. **`tradingbot/utils/db.py` — Added `KronosPrediction` model** |
| 44 | + - Stores forecasts per (symbol, target_date, model_name) |
| 45 | + - Auto-created by `init_db()` |
| 46 | + - Indexed on symbol + target_date for fast queries |
| 47 | + |
| 48 | +### Kubernetes Deployment |
| 49 | + |
| 50 | +7. **`helm/tradingbots/values.yaml` — Updated** |
| 51 | + - Added `kronosbot` cronjob entry: `"5 22 * * 1-5"` (10:05 PM UTC Mon-Fri) |
| 52 | + - Added `KRONOS_SPACE_URL` env var (plain, public URL) |
| 53 | + - Added `HF_TOKEN` secret reference (for Space lifecycle control) |
| 54 | + |
| 55 | +### Python Dependencies |
| 56 | + |
| 57 | +8. **`pyproject.toml` — Updated** |
| 58 | + - Added `huggingface_hub>=0.20.0` (API client for Space control) |
| 59 | + |
| 60 | +### Utilities Export |
| 61 | + |
| 62 | +9. **`tradingbot/utils/core/__init__.py` — Updated** |
| 63 | + - Exported `KronosClient` and `kronos_forecast` for easier imports |
| 64 | + |
| 65 | +## Files Modified |
| 66 | + |
| 67 | +- `tradingbot/utils/db.py` — added `KronosPrediction` class |
| 68 | +- `helm/tradingbots/values.yaml` — added kronosbot + env vars |
| 69 | +- `pyproject.toml` — added huggingface_hub dependency |
| 70 | +- `tradingbot/utils/core/__init__.py` — exported new classes |
| 71 | +- `mkdocs.yml` — added documentation references |
| 72 | + |
| 73 | +## Documentation |
| 74 | + |
| 75 | +1. **`docs/api/kronos-client.md`** — API reference |
| 76 | + - Full `KronosClient` documentation |
| 77 | + - Usage examples (direct, in bots, with AI tools) |
| 78 | + - Error handling, performance characteristics |
| 79 | + |
| 80 | +2. **`docs/guides/kronos-forecasting.md`** — Comprehensive guide |
| 81 | + - What is Kronos, architecture overview |
| 82 | + - Deployment (Space, cronjob, env vars) |
| 83 | + - Using predictions in bots (direct API, DB query, LangChain tool) |
| 84 | + - Monitoring, troubleshooting |
| 85 | + - Performance characteristics, cost analysis |
| 86 | + |
| 87 | +3. **`mkdocs.yml`** — Updated navigation |
| 88 | + - Added "Kronos Forecasting" to Guides section |
| 89 | + - Added "Kronos Client" to API Reference → Integrations |
| 90 | + |
| 91 | +## Deployment Status |
| 92 | + |
| 93 | +### ✅ Completed |
| 94 | + |
| 95 | +- HF Space created: `https://huggingface.co/spaces/guestros/kronos-trading-api` |
| 96 | +- Space files uploaded (Dockerfile, app.py, requirements.txt) |
| 97 | +- Docker build started (watch at Space page) |
| 98 | +- `HF_TOKEN` patched into K8s secret `tradingbot-secrets` |
| 99 | +- Helm values updated with kronosbot + env vars |
| 100 | + |
| 101 | +### ⏳ Next Steps |
| 102 | + |
| 103 | +1. **Wait for Space Docker build** (5-10 min) |
| 104 | + - Check status: https://huggingface.co/spaces/guestros/kronos-trading-api |
| 105 | + - Watch build logs; torch CPU download is the slow part |
| 106 | + |
| 107 | +2. **Deploy cronjob to K8s** |
| 108 | + ```bash |
| 109 | + helm upgrade --install tradingbots ./helm/tradingbots --namespace tradingbots-2025 |
| 110 | + ``` |
| 111 | + |
| 112 | +3. **Test manually** (after Space is ready) |
| 113 | + ```bash |
| 114 | + # Check Space health |
| 115 | + kubectl create job --from=cronjob/tradingbot-kronos test-run -n tradingbots-2025 |
| 116 | + kubectl logs -f job/test-run -n tradingbots-2025 |
| 117 | + |
| 118 | + # Or directly from your machine |
| 119 | + python -c " |
| 120 | + from tradingbot.utils.kronos_client import KronosClient |
| 121 | + client = KronosClient() |
| 122 | + pred = client.predict('SPY', horizon=5) |
| 123 | + print(pred) |
| 124 | + " |
| 125 | + ``` |
| 126 | + |
| 127 | +## Usage Examples |
| 128 | + |
| 129 | +### Direct Usage in a Bot |
| 130 | + |
| 131 | +```python |
| 132 | +from tradingbot.utils.core import Bot, KronosClient |
| 133 | + |
| 134 | +class MyBot(Bot): |
| 135 | + def decisionFunction(self, row): |
| 136 | + client = KronosClient() |
| 137 | + pred = client.predict(self.symbol, horizon=5) |
| 138 | + |
| 139 | + if pred is not None: |
| 140 | + next_close = pred.iloc[0]["close"] |
| 141 | + if next_close > row["close"] * 1.05: |
| 142 | + return 1 # Buy if predicted 5%+ upside |
| 143 | + return 0 |
| 144 | +``` |
| 145 | + |
| 146 | +### With AI Tools |
| 147 | + |
| 148 | +```python |
| 149 | +from tradingbot.utils.core import run_ai_with_tools, kronos_forecast |
| 150 | + |
| 151 | +decision = run_ai_with_tools( |
| 152 | + system_prompt="You are a trading analyst. Use Kronos forecasts to inform your decision.", |
| 153 | + user_message="Should we buy QQQ?", |
| 154 | + extra_tools=[kronos_forecast], # Kronos is now a callable tool |
| 155 | +) |
| 156 | +``` |
| 157 | + |
| 158 | +### Database Query |
| 159 | + |
| 160 | +```python |
| 161 | +from tradingbot.utils.core import get_db_session |
| 162 | +from tradingbot.utils.db import KronosPrediction |
| 163 | +from datetime import datetime, timedelta |
| 164 | + |
| 165 | +with get_db_session() as session: |
| 166 | + tomorrow = datetime.utcnow() + timedelta(days=1) |
| 167 | + pred = session.query(KronosPrediction).filter_by( |
| 168 | + symbol="SPY", |
| 169 | + target_date=tomorrow.replace(hour=0, minute=0, second=0) |
| 170 | + ).first() |
| 171 | + |
| 172 | + if pred: |
| 173 | + print(f"SPY predicted close: {pred.predicted_close}") |
| 174 | +``` |
| 175 | + |
| 176 | +## Environment Variables |
| 177 | + |
| 178 | +**Required:** |
| 179 | + |
| 180 | +- `KRONOS_SPACE_URL` — HF Space URL (e.g. `https://guestros-kronos-trading-api.hf.space`) |
| 181 | + |
| 182 | +**For Space control (optional but recommended):** |
| 183 | + |
| 184 | +- `HF_TOKEN` — HF write token (for restart/pause) |
| 185 | +- `HF_SPACE_REPO` — Space repo ID (default: `guestros/kronos-trading-api`) |
| 186 | + |
| 187 | +**Optional tuning:** |
| 188 | + |
| 189 | +- `KRONOS_HORIZON` — Days to forecast (default: 5) |
| 190 | +- `KRONOS_EXTRA_SYMBOLS` — Extra tickers to always predict (default: `SPY,QQQ,GLD`) |
| 191 | + |
| 192 | +## Key Design Decisions |
| 193 | + |
| 194 | +1. **HTTP client, not local inference** — keeps K8s image small (<700MB), avoids 2GB torch download |
| 195 | +2. **Free HF Space** — CPU-only, 16GB RAM, pauses when idle, saves costs |
| 196 | +3. **Daily cronjob** — runs once after market close, Space wakes/predicts/sleeps in 2-3 min |
| 197 | +4. **Graceful fallback** — KronosClient returns `None` if Space unavailable; bots continue with fallback signals |
| 198 | +5. **Async pause** — Space is paused immediately after predictions to save HF quota |
| 199 | +6. **LangChain integration** — `kronos_forecast` tool can be used alongside `run_ai_with_tools()` for AI reasoning |
| 200 | + |
| 201 | +## Performance |
| 202 | + |
| 203 | +| Operation | Time | |
| 204 | +|-----------|------| |
| 205 | +| Space cold start (after restart) | ~60s | |
| 206 | +| Kronos-mini model load | ~40s | |
| 207 | +| Warm inference per symbol | ~30-60s | |
| 208 | +| DataService fetch per symbol | ~2-5s | |
| 209 | +| Upsert 100 predictions to DB | ~1s | |
| 210 | +| **Total cronjob runtime** | ~2-3 min | |
| 211 | + |
| 212 | +## Cost |
| 213 | + |
| 214 | +- HF Space: Free tier (CPU-only, paused after 48h) |
| 215 | +- Cronjob frequency: 1x per day |
| 216 | +- Total monthly quota: ~2-3 min/day × 30 days ≈ 60-90 min |
| 217 | +- **Cost: $0** (within free tier limits) |
| 218 | + |
| 219 | +## References |
| 220 | + |
| 221 | +- **Kronos GitHub**: https://github.com/shiyu-coder/Kronos |
| 222 | +- **Kronos Paper**: https://arxiv.org/abs/2508.02739 |
| 223 | +- **HF Model Hub**: https://huggingface.co/NeoQuasar/Kronos-mini |
| 224 | +- **API Docs**: [docs/api/kronos-client.md](docs/api/kronos-client.md) |
| 225 | +- **Guide**: [docs/guides/kronos-forecasting.md](docs/guides/kronos-forecasting.md) |
0 commit comments