Skip to main content
Glama
FETKlOkAn2

crypto-quant-platform MCP server

by FETKlOkAn2
README.md
# Crypto Quant Platform

Backtesting, walk-forward validation and paper trading for crypto strategies —
self-hosted, and drivable by an AI agent through MCP.

**It is built to tell you when a strategy does not work.** Take 200 strategies
with provably zero edge and keep the luckiest one:

| | |
|---|---|
| Conventional significance test | **99.5%** — accepted |
| Deflated Sharpe *(this platform)* | **43.7%** — rejected |

Same data. One of those answers is wrong, and it is the one most backtesting
tools give you.

[**See a real report**](docs/examples/walk-forward-report.html) —
RSI on BTC-USD, 18 windows, one self-contained HTML file
([download and open it](https://raw.githubusercontent.com/FETKlOkAn2/crypto-quant-platform/main/docs/examples/walk-forward-report.html)).

```bash
git clone <repo> && cd backend
make setup        # deps, generated secrets, real market data
make demo         # health → strategies → backtest → walk-forward → paper trading
```

No API keys. No cloud account. The demo runs against real BTC-USD and ETH-USD
candles committed to the repository, so it works offline on a clean clone.

---

## What this is

Infrastructure for testing whether a trading strategy actually works, and for
running it once you believe it does.

- **Backtesting** — vectorbt engine with transaction costs and slippage taken
  from your risk configuration, not hardcoded
- **Walk-forward validation** — parameters chosen per training window with a
  purge gap, scored once on unseen data, reported with in-sample/out-of-sample
  degradation, parameter stability and a deflated-Sharpe correction for
  the size of the parameter search
- **Paper trading** — order book, fills, fees and slippage simulation
- **Live execution** — Kraken (verified) and Coinbase Advanced (implemented,
  not yet exercised against the live venue), with risk-based position sizing
  and stop-loss enforcement
- **Position reconciliation** — compares what the platform thinks it holds
  against what the exchange reports, and halts on a material mismatch
- **Strategy plug-ins** — 18 reference implementations; add your own by
  subclassing `Strategy`
- **REST + WebSocket API** — Flask, with a local auth provider that needs no
  cloud account
- **MCP server** — drive all of the above from Claude Desktop or Cursor in
  plain English

## What this is not

- **Not a source of alpha.** The included strategies are reference
  implementations. Run the walk-forward before believing any of them; it is
  built to tell you when a strategy does not work, and it usually does.
- **Not high-frequency.** Intraday to multi-day holding periods.
- **Not a managed service.** You run it.

---

## Ask an agent to do the work

The MCP server exposes the research surface as tools, so an agent can run the
analysis and interpret it:

> *"List the strategies, run a 90-day RSI backtest on BTC-USD, then a
> walk-forward with rsi_window between 10 and 30, and tell me whether it's
> overfitted."*

```bash
make mcp     # stdio server; see core/mcp/README.md for Claude Desktop wiring
```

Tools: `list_strategies`, `run_backtest`, `run_walk_forward`,
`run_combined_backtest`, `start_paper_trading`, `stop_paper_trading`,
`get_trading_status`, `get_risk_state`, `get_reconciliation`.

The MCP server is paper-only by design. There is no tool that can place a real
order.

---

## Walk-forward: the part that matters

A backtest tells you what a strategy would have returned on data you fitted it
to. That number is nearly always good and nearly always meaningless.

```bash
curl -X POST localhost:5000/api/backtest/walk-forward \
  -H 'Content-Type: application/json' \
  -d '{"strategy":"RSI","symbol":"BTC-USD","granularity":"ONE_HOUR",
       "num_days":365,"param_ranges":{"rsi_window":[10,14,20,30]}}'
```

Returns per-window in-sample and out-of-sample metrics, a buy-and-hold
benchmark for each window, the degradation between in and out of sample,
how much the selected parameters moved between windows, and a verdict:

```json
{
  "summary": {
    "mean_oos_return": -1.52,
    "mean_benchmark_return": -3.32,
    "mean_excess_return": 1.80,
    "windows_beating_benchmark": 13,
    "degradation": 0.31
  },
  "verdict": {
    "rating": "inconclusive",
    "summary": "No disqualifying signal, but the evidence is not strong
                enough to call this an edge."
  }
}
```

Or as a self-contained HTML report you can send to someone:

```bash
make report STRATEGY=RSI SYMBOL=BTC-USD
```

One file, no network, no scripts — per-window in-sample against
out-of-sample, a benchmark bar per window, parameter stability, and the
verdict. It opens from disk and survives an email attachment.

It also answers the question a good backtest number cannot: **how much of
this is just the best of N tries?**

```
combinations tried   16
best-by-chance SR    0.0527      <- what 16 zero-edge attempts produce
deflated Sharpe      0.0%        <- probability this reflects skill
```

Search a parameter grid, report the best result, and that result is biased
upward whether or not the strategy has an edge. The deflated Sharpe (Bailey &
López de Prado) corrects for how many combinations were tried and for the skew
and fat tails of the actual returns. Below 95%, the result does not survive.

Methodology: parameters are selected in memory from each training window and
never read back from a shared table; a purge gap separates train from test;
out-of-sample windows do not overlap; selection defaults to Sharpe rather than
total return, because selecting on raw return reliably picks the most
over-fitted corner of the grid.

---

## Configuration

`make setup` writes a `.env` with generated secrets. Only two values are
required:

| Variable | Purpose |
|----------|---------|
| `SECRET_KEY` | Signs session tokens |
| `ENCRYPTION_KEY` | Encrypts stored exchange API keys. **Back this up** — losing it makes stored credentials unreadable |

Everything else has a working default. The ones worth knowing:

| Variable | Default | Notes |
|----------|---------|-------|
| `TRADING_MODE` | `paper` | `paper`, `backtest` or `live` |
| `AUTH_PROVIDER` | `local` | `local` (no cloud account), `cognito`, or `none` |
| `DATABASE_PATH` | `database` | Where SQLite files live |
| `EXCHANGE` | `kraken` | Live venue: `kraken` or `coinbase` |

`AUTH_PROVIDER=none` disables authentication and refuses to start unless
`TRADING_MODE` is explicitly `paper` or `backtest`, so an unauthenticated API
can never front a live-money deployment.

Check any deployment with:

```bash
curl -s localhost:5000/api/health | jq .data.checks
```

Every check reports `ok`, `warn` or `error` plus what to do about it.

---

## Market data

```bash
python -m scripts.seed_data                    # fetch from Coinbase's public API
python -m scripts.seed_data --offline          # committed fixtures only
python -m scripts.seed_data --symbols ETH-USD --granularities ONE_HOUR --days 730
```

Fixtures under `scripts/fixtures/` are gzipped CSV — text, so they diff and
review like code rather than sitting in the repository as opaque binaries.

---

## Adding a strategy

```python
from core.strategies.strategy import Strategy, MarketCondition, register_strategy

@register_strategy
class MyStrategy(Strategy):
    market_condition = MarketCondition.TRENDING
    strategy_name = "My Strategy"

    def custom_indicator(self, close=None, window=14):
        ...
        return self.generate_signals(buy_signal, sell_signal)
```

Drop it in `core/strategies/`. It is discovered automatically and becomes
available to backtesting, walk-forward, the API and the MCP server with no
registration step.

## Adding an exchange

Implement [`ExchangeClient`](core/wrappers/base.py) — nine methods — and pass
it in:

```python
LiveTrader(socketio, client=MyVenueClient())
```

The contract states the units explicitly, because the trading path does not
convert between them: volume is base-asset units, never dollars. An
incomplete client is rejected at construction with a list of what is missing,
rather than failing part-way through a trading cycle. `core/paper_trading/
client.py` is a complete reference implementation, and the conformance tests
in `tests/test_exchange_clients.py` run against every registered venue.

---

## Development

```bash
make test        # 730 tests with coverage
make lint        # ruff
make check       # both, as CI runs them
```

CI runs lint, the suite, an end-to-end smoke test that boots the API and
drives it, and a Docker build that fails if the container does not report
healthy.

## Tech stack

Python 3.10 · Flask + Socket.IO · pandas / NumPy / TA-Lib · vectorbt ·
Optuna · SQLite (PostgreSQL optional) · Docker

The numeric stack is pinned to Python 3.10 by vectorbt 0.26.2's numba
requirement. See [docs/ROADMAP.md](docs/ROADMAP.md).

## Documentation

- **[docs/OVERVIEW.md](docs/OVERVIEW.md) — start here: what this solves, in plain language**
- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) — how it fits together
- [docs/DEMO.md](docs/DEMO.md) — annotated walkthrough
- [docs/SECURITY.md](docs/SECURITY.md) — threat model and key handling
- [docs/ROADMAP.md](docs/ROADMAP.md) — known limitations and what's next
- [core/mcp/README.md](core/mcp/README.md) — MCP client wiring
- [docs/COMMERCIAL.md](docs/COMMERCIAL.md) — what is free, what is paid

## License

[Apache-2.0](LICENSE). Use it commercially, modify it, fork it — no fee and
no per-seat licence. See [NOTICE](NOTICE) for the trading-risk disclaimer and
third-party components.

Paid work (audits, integrations, retainers) is described in
[docs/COMMERCIAL.md](docs/COMMERCIAL.md). The software itself is not for
sale — expertise is.

---

*Cryptocurrency trading involves substantial risk of loss. Nothing here is
financial advice.*