# Horizon SDK

Prediction market trading SDK. Rust core (PyO3) + Python interface.

## Build

```bash
maturin develop --features skip-auth   # build + install
cargo check                            # Rust compilation check
pytest tests/                          # Python test suite (~960+ tests)
```

## Architecture

- **Rust core** (`src/`): types, risk pipeline, orders, positions, paper exchange, Polymarket/Kalshi/Limitless/Alpaca/Coinbase/Robinhood/IBKR clients, feed system
- **Python SDK** (`python/horizon/`): `hz.run()`, pipeline composition, TUI dashboard, CLI, MCP server
- **No IPC**: direct PyO3 function calls between Python and Rust

### Key Files

| File | Purpose |
|------|---------|
| `src/types.rs` | Core types: Side, OrderSide, Market, Quote, OrderRequest, Order, Position, Fill, RiskConfig |
| `src/risk.rs` | 8-point risk pipeline |
| `src/engine.rs` | Engine orchestrator, owns risk + orders + positions + exchange + feed manager |
| `src/exchanges/paper.rs` | Paper exchange with tick-based matching |
| `src/exchanges/polymarket.rs` | Polymarket CLOB client |
| `src/exchanges/kalshi.rs` | Kalshi REST client |
| `src/exchanges/alpaca.rs` | Alpaca Markets REST client |
| `src/exchanges/coinbase.rs` | Coinbase Advanced Trade REST client |
| `src/exchanges/robinhood.rs` | Robinhood Crypto REST client |
| `src/exchanges/limitless.rs` | Limitless REST client (Base chain prediction market) |
| `src/exchanges/ibkr.rs` | Interactive Brokers REST client (stocks, options, ForecastEx) |
| `src/feeds/mod.rs` | FeedSnapshot, FeedConfig enum, FeedManager |
| `src/feeds/chainlink.rs` | Chainlink on-chain price oracle via JSON-RPC eth_call |
| `src/feeds/binance.rs` | Binance WebSocket trade stream |
| `src/feeds/polymarket_book.rs` | Polymarket orderbook WebSocket |
| `src/feeds/kalshi_book.rs` | Kalshi orderbook polling |
| `src/feeds/rest_json_path.rs` | Enhanced REST feed with JSON path extraction |
| `python/horizon/strategy.py` | `hz.run()`, pipeline composition, feed wiring |
| `python/horizon/feeds.py` | Feed dataclasses (BinanceWS, ChainlinkFeed, etc.) |
| `python/horizon/mcp_server.py` | MCP server (181 tools, 2 resources) |
| `python/horizon/tools.py` | Shared tool functions for MCP server and CLI |
| `python/horizon/cli/__init__.py` | CLI entry point, 23 top-level commands |
| `python/horizon/cli/engine.py` | CLI: status, submit, cancel, positions, orders, fills |
| `python/horizon/cli/discovery.py` | CLI: discover, events, top-markets, market |
| `python/horizon/cli/feeds.py` | CLI: feed group (snapshot, list, health, metrics, start) |
| `python/horizon/cli/wallet.py` | CLI: wallet group (trades, positions, value, profile, score, flow) |
| `python/horizon/cli/analytics.py` | CLI: kelly, parity, simulate |
| `python/horizon/cli/fund.py` | CLI: fund group (status, report, deploy, stop, pause, resume, etc.) |
| `python/horizon/cli/account.py` | CLI: setup, login, key-status |
| `python/horizon/cli/db.py` | CLI: db group (fills, positions, orders from SQLite) |
| `python/horizon/__init__.py` | Public API re-exports |
| `python/horizon/fund/__init__.py` | FundManager orchestrator, oversight loop |
| `python/horizon/fund/_types.py` | FundConfig, StrategyConfig, enums |
| `python/horizon/fund/_regime.py` | RegimeDetector: 3-state HMM + trend/MR classification |
| `python/horizon/fund/_alpha_model.py` | AlphaModel: 7-factor IC-weighted edge estimation |
| `python/horizon/fund/_alpha_decay.py` | AlphaDecayTracker: exponential decay fitting |
| `python/horizon/fund/_hypothesis.py` | HypothesisManager: SQLite lifecycle with Bayesian updating |
| `python/horizon/fund/_signal_ensemble.py` | SignalEnsemble: IC-weighted combination with redundancy |
| `python/horizon/fund/_research_intel.py` | ResearchIntelligence: event-driven triggers |
| `python/horizon/fund/_portfolio_optimizer.py` | PortfolioOptimizer: Kelly + Ledoit-Wolf + constraints |
| `python/horizon/fund/_risk_analytics.py` | RiskAnalytics: regime-conditional VaR, portfolio Greeks |
| `python/horizon/fund/_performance_attribution.py` | PerformanceAttribution: alpha/beta decomposition |
| `python/horizon/fund/_execution_intelligence.py` | ExecutionIntelligence: VPIN toxicity, inventory risk |
| `python/horizon/fund/_alerts.py` | AlertManager: webhook/callback notifications, rate limiting |
| `python/horizon/fund/_ledger.py` | FundLedger: double-entry SQLite accounting |
| `python/horizon/fund/_promotion.py` | PromotionManager: paper-to-shadow-to-live lifecycle |
| `python/horizon/fund/_recovery.py` | RecoveryManager: self-healing, circuit breaker |
| `python/horizon/fund/_adaptive_thresholds.py` | ThresholdTuner: self-tuning confidence from outcomes |
| `python/horizon/fund/_backtest_runner.py` | BacktestRunner: built-in backtester for Autopilot |
| `python/horizon/fund/_explainability.py` | Explainer: structured fund/strategy/risk explanations |
| `python/horizon/fund/_multi_fund.py` | FundCluster: multi-fund orchestration |
| `python/horizon/mcp_fund.py` | MCP fund server (32 tools) |

## Conventions

- **f64 at PyO3 boundary** (not rust_decimal)
- **Enums**: `#[pyclass(eq, eq_int, frozen, hash)]`
- **Feed pattern**: async function following `manifold.rs` pattern (loop + tokio::select! + metrics)
- **New feeds** use `config_json` kwarg: `engine.start_feed(name, feed_type, config_json='...')`
- **FeedConfig enum**: 17 variants (BinanceWS, PolymarketBook, KalshiBook, REST, PredictIt, Manifold, ESPN, NWS, RESTJsonPath, Chainlink, Mempool, Alpaca, Coinbase, Robinhood, IBKR, Calendar, Treasury)
- **Paper order IDs**: `p1`, `p2`... (AtomicU64)
- **Position has no `#[new]`** — tests build positions via `engine.process_fill()`

## Adding a New Feed

1. Create `src/feeds/<name>.rs` with `run_<name>_feed()` async function
2. Add `pub mod <name>;` to `src/feeds/mod.rs`
3. Add variant to `FeedConfig` enum in `src/feeds/mod.rs`
4. Add dispatch arm in `FeedManager::start_feed()` in `src/feeds/mod.rs`
5. Add `"<name>"` match arm in `Engine::start_feed()` in `src/engine.rs`
6. Add dataclass to `python/horizon/feeds.py`
7. Add `elif isinstance(feed_config, <Name>Feed)` to `_start_feeds()` in `python/horizon/strategy.py`
8. Add to imports/`__all__` in `python/horizon/__init__.py`
9. Add tests to `tests/test_new_feeds.py`
10. Add docs section to `docs/feeds.mdx`

## Testing

```bash
cargo check --tests          # Rust type-check (can't link PyO3 cdylib directly)
maturin develop              # build + install
pytest tests/ -v             # full suite
pytest tests/test_new_feeds.py -v  # feed tests only
```
