Nephyr Backtest
Prediction market strategy validation — weather signals and copy trading.
Extracts backtesting capability from Momentai and MoonMirror into a standalone package.
Install
pip install -e ".[dev]"
Quick start
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).
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_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:
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
{
"mcpServers": {
"nephyr-backtest": {
"command": "nephyr-backtest-mcp"
}
}
}
Tools: run_weather_backtest, run_copy_backtest, get_available_data
REST API
uvicorn api.app:app --reload
POST /v1/backtest/weather
POST /v1/backtest/copy
GET /v1/data/available
GET /v1/health
Tests
pytest tests/ -v
Pricing
| 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