Metadata-Version: 2.4
Name: nephyr-backtest
Version: 0.1.0
Summary: Prediction market strategy validation — weather signals and copy trading backtesting
Author-email: CLM Studios <citlali.lopmonster.studios@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/clm-studios/nephyr-backtest
Project-URL: Repository, https://github.com/clm-studios/nephyr-backtest
Project-URL: Issues, https://github.com/clm-studios/nephyr-backtest/issues
Keywords: prediction-markets,backtesting,polymarket,kalshi,weather-signals,copy-trading,kelly-criterion,trading,mcp
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial
Classifier: Topic :: Scientific/Engineering :: Mathematics
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.27
Requires-Dist: aiohttp>=3.9
Provides-Extra: mcp
Requires-Dist: mcp>=1.0; extra == "mcp"
Provides-Extra: api
Requires-Dist: fastapi>=0.110; extra == "api"
Requires-Dist: uvicorn[standard]>=0.29; extra == "api"
Requires-Dist: pydantic>=2.0; extra == "api"
Requires-Dist: slowapi>=0.1.9; extra == "api"
Provides-Extra: risk
Requires-Dist: nephyr-risk>=0.1.0; extra == "risk"
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Requires-Dist: httpx>=0.27; extra == "dev"
Requires-Dist: aiohttp>=3.9; extra == "dev"
Requires-Dist: ruff>=0.4; extra == "dev"
Requires-Dist: fastapi>=0.110; extra == "dev"
Requires-Dist: pydantic>=2.0; extra == "dev"
Requires-Dist: httpx[test]>=0.27; extra == "dev"
Requires-Dist: slowapi>=0.1.9; extra == "dev"
Provides-Extra: all
Requires-Dist: mcp>=1.0; extra == "all"
Requires-Dist: fastapi>=0.110; extra == "all"
Requires-Dist: uvicorn[standard]>=0.29; extra == "all"
Requires-Dist: pydantic>=2.0; extra == "all"
Requires-Dist: slowapi>=0.1.9; extra == "all"
Requires-Dist: nephyr-risk>=0.1.0; extra == "all"
Dynamic: license-file

# Nephyr Backtest

Prediction market strategy validation — weather signals and copy trading.

Extracts backtesting capability from Momentai and MoonMirror into a standalone package.

## Install

```bash
pip install -e ".[dev]"
```

## Quick start

```python
import asyncio
from nephyr_backtest import run_backtest, BacktestConfig, generate_report

config = BacktestConfig(
    start_date="2025-10-01",
    end_date="2026-03-29",
    starting_bankroll=1000.0,
    platform="polymarket",
    strategy="weather_signals",
)

result = asyncio.run(run_backtest(config))
outputs = generate_report(result, output_format="terminal")
print(outputs["terminal"])
```

## Strategies

### weather_signals
Replay the Momentai signal pipeline against historical data.
Uses GFS ensemble forecasts vs real Polymarket CLOB prices.

### copy_trading
Replay historical on-chain trades from top Polymarket wallets.
Strategies: `baseline`, `top3`, `consensus`, `category-filtered`.

### custom (Python package only)

Plug in any signal function and backtest it against real Polymarket market data.
Your function receives a `market_data` dict and returns a signal dict (or `None` to skip).

```python
import asyncio
from nephyr_backtest import run_backtest, BacktestConfig

def mean_reversion_signal(market_data: dict) -> dict | None:
    """Buy when price drops significantly from yesterday."""
    if market_data.get("price_24h_ago") is None:
        return None

    price_change = market_data["market_price"] - market_data["price_24h_ago"]

    # If price dropped >10%, bet it rebounds
    if price_change < -0.10:
        return {"probability": 0.65}

    return None

result = asyncio.run(run_backtest(BacktestConfig(
    start_date="2026-01-01",
    end_date="2026-03-28",
    starting_bankroll=1000.0,
    platform="polymarket",
    strategy="custom",
    signal_fn=mean_reversion_signal,
)))

print(f"Trades: {result.total_trades} | Return: {result.total_return:+.1f}%")
```

#### Signal function contract

Your function receives a `market_data` dict with these keys:

| Key | Type | Description |
|-----|------|-------------|
| `market_id` | str | Unique market identifier |
| `platform` | str | `"polymarket"` or `"kalshi"` |
| `category` | str | `"weather"`, `"crypto"`, `"politics"`, `"sports"`, `"other"` |
| `market_price` | float | Current YES price in [0, 1] |
| `volume` | float | Total USDC volume traded |
| `date` | str | ISO date `"YYYY-MM-DD"` |
| `city` | str \| None | City name for weather markets (e.g. `"NYC"`) |
| `threshold_f` | float \| None | Temperature threshold for weather markets |
| `direction` | str \| None | `"above"` or `"below"` for weather markets |
| `price_1h_ago` | float \| None | YES price 1 hour ago |
| `price_24h_ago` | float \| None | YES price 24 hours ago |

Return a dict `{"probability": float}` to place a trade, or `None` to skip.
Optional return keys: `"direction"` (`"YES"` / `"NO"`, default `"YES"`), `"confidence"` (float, for logging).

The probability must be in (0, 1). Kelly sizing, risk management, and settlement
are handled automatically by the engine — identical to the built-in strategies.

#### MCP server and REST API

Custom strategies require passing a Python callable, which cannot be serialized
over MCP or HTTP. The MCP server (`nephyr-backtest-mcp`) and REST API support
`weather_signals` and `copy_trading` only. Use the Python package directly for
custom strategies.

## MCP Server

```json
{
  "mcpServers": {
    "nephyr-backtest": {
      "command": "nephyr-backtest-mcp"
    }
  }
}
```

Tools: `run_weather_backtest`, `run_copy_backtest`, `get_available_data`

## REST API

```bash
uvicorn api.app:app --reload
```

- `POST /v1/backtest/weather`
- `POST /v1/backtest/copy`
- `GET /v1/data/available`
- `GET /v1/health`

## Tests

```bash
pytest tests/ -v
```

## Pricing

| Tier | Details |
|------|---------|
| **Free** | 1 backtest/month (1 month of data, 1 city) |
| **Paid** | $49/month — unlimited backtests, all data, all cities, CSV export |
| **Per-run** | $5/backtest for one-off users |
| **Agent-to-agent** | $0.05/backtest |

## License

MIT
