Skip to main content

🏔️ Vanta Crunch — Challenge Package

Predict short-term crypto returns. Beat the leaderboard.

Quickstart

pip install vanta-challenge matplotlib  # matplotlib optional, for plots

1. Write a model

from vanta.tracker import TrackerBase
from vanta.indicators import RSI, EMA, OrderBookImbalance, FundingSignal

class MyModel(TrackerBase):
    def __init__(self):
        super().__init__()
        self.rsi = RSI(period=14)
        self.ema_fast = EMA(period=5)
        self.ema_slow = EMA(period=20)
        self.obi = OrderBookImbalance(period=10)
        self.funding = FundingSignal(period=8)

    def tick(self, data: dict):
        super().tick(data)
        for candle in data.get("candles_1m", []):
            price = float(candle["close"])
            self.rsi.update(price)
            self.ema_fast.update(price)
            self.ema_slow.update(price)

        # Order book imbalance (if available)
        ob = data.get("orderbook")
        if ob:
            self.obi.update(ob["imbalance"])

        # Funding rate (if available)
        fund = data.get("funding")
        if fund:
            self.funding.update(fund["funding_rate"])

    def predict(self, symbol: str, horizon_seconds: int, step_seconds: int) -> dict:
        if not self.rsi.ready:
            return {"expected_return": 0.0}

        signal = 0.0

        # RSI + trend filter
        if self.rsi.value < 30 and self.ema_fast.value > self.ema_slow.value:
            signal += 0.003
        elif self.rsi.value > 70 and self.ema_fast.value < self.ema_slow.value:
            signal -= 0.003

        # Order book pressure boost
        if self.obi.ready:
            signal += self.obi.value * 0.002  # imbalance [-1,1] → ±0.002

        # Funding rate mean-reversion (negative = contrarian)
        if self.funding.ready:
            signal -= self.funding.value * 50  # e.g. 0.0001 × 50 = 0.005

        return {"expected_return": max(-0.01, min(0.01, signal))}

2. Backtest it

from vanta.backtest import BacktestRunner

result = BacktestRunner(model=MyModel()).run(
    subject="BTCUSDT",
    start="2025-06-01",
    end="2026-01-01",
)
result.summary()  # formatted metrics table
result.plot()     # equity curve, drawdown, hit rate, scatter

3. Compare with other strategies

from vanta.backtest import compare
from vanta.examples import MeanReversionTracker, TrendFollowingTracker

compare([
    ("Mean Reversion", MeanReversionTracker()),
    ("Trend Following", TrendFollowingTracker()),
    ("My Model", MyModel()),
], start="2025-06-01", end="2026-01-01")

4. Sweep parameters

from vanta.backtest import sweep

sweep(
    model_fn=lambda period: MyModel(period=period),
    params={"period": [7, 14, 21, 28]},
    start="2025-06-01", end="2026-01-01",
)

How It Works

  • Data: Multi-timeframe OHLCV candles (1m, 5m, 15m, 1h) + order book depth + funding rates from Binance
  • Prediction: Every 15 minutes, predict the 1-hour forward return
  • Scoring: score = expected_return × actual_return
  • History: ~1 year of data available for backtesting (Jan 2025 → present)

Scoring

score = expected_return × actual_return
Scenario Score Meaning
You predict +0.01, price goes up +0.005 ✅ +0.00005 Correct direction, good conviction
You predict +0.01, price goes down -0.005 ❌ -0.00005 Wrong direction, penalized
You predict 0.0 🤷 0.0 No opinion, no gain, no loss

Direction AND magnitude matter. See docs/scoring-guide.md for details.

Indicators

Built-in stateful indicators — no pandas/numpy required:

from vanta.indicators import SMA, EMA, RSI, MACD, BollingerBands, ATR, VWAP, Returns

rsi = RSI(period=14)
rsi.update(price)     # feed one value
rsi.value             # current reading (or None if not ready)
rsi.ready             # True once enough data accumulated
Indicator .update() .value
SMA(period) (price) Moving average
EMA(period) (price) Exponential average
RSI(period) (price) 0–100 scale
MACD(fast, slow, signal) (price) (macd, signal, histogram)
BollingerBands(period, num_std) (price) (upper, middle, lower, width, percent_b)
ATR(period) (high, low, close) Average true range
VWAP() (price, volume) Volume-weighted price
Returns(period) (price) % return over N periods
OrderBookImbalance(period) (imbalance) Smoothed bid/ask imbalance
SpreadTracker(period) (best_bid, best_ask) Spread in basis points
FundingSignal(period) (funding_rate) Smoothed funding rate
BasisTracker(period) (basis) Smoothed futures basis

Examples

Seven starter strategies in vanta/examples/:

Strategy Approach
Mean Reversion Fades deviation from SMA
Trend Following EMA crossover momentum
RSI Contrarian at RSI extremes
Bollinger Breakout Mean-reversion at band edges
Volatility Regime Switches strategy based on ATR
Dual Timeframe RSI filtered by trend direction
Volume Profile Volume-weighted momentum

Docs

Model Interface

class TrackerBase:
    def tick(self, data: dict) -> None:
        """Called with each new data batch.
        data = {
            "symbol": "BTCUSDT",
            "asof_ts": 1234567890,

            # Multi-timeframe OHLCV candles
            "candles_1m":  [{"ts": ..., "open": ..., "high": ..., "low": ..., "close": ..., "volume": ...}, ...],
            "candles_5m":  [...],   # last 60 bars (5h)
            "candles_15m": [...],   # last 40 bars (10h)
            "candles_1h":  [...],   # last 24 bars (1 day)

            # Order book snapshot (or None if unavailable)
            "orderbook": {
                "best_bid": 50000.0, "best_ask": 50001.0,
                "spread": 1.0, "mid_price": 50000.5,
                "bid_depth": 123.4, "ask_depth": 98.7,
                "imbalance": 0.11,  # (bid-ask)/(bid+ask), range [-1, 1]
                "bids_top": [[50000.0, 1.5], ...],
                "asks_top": [[50001.0, 1.2], ...],
            },

            # Funding rate / basis (or None if unavailable)
            "funding": {
                "funding_rate": 0.0001,   # current 8h funding rate
                "mark_price": 50000.5,
                "index_price": 50000.0,
                "basis": 0.00001,          # (mark-index)/index
                "next_funding_ts": 1234571490,
            },
        }
        """

    def predict(self, symbol: str, horizon_seconds: int, step_seconds: int) -> dict:
        """Return your prediction.
        Returns: {"expected_return": float}
        """

Metadata

Release files for crunch-vanta 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for crunch-vanta 0.1.0
File Size Uploaded
crunch_vanta-0.1.0.tar.gz 2.2 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for crunch-vanta 0.1.0
File Interpreter ABI Platform
crunch_vanta-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 2.2 MB

Release files / crunch_vanta-0.1.0.tar.gz

Download URL crunch_vanta-0.1.0.tar.gz
Size 2.2 MB
Tags Source
SHA-256 checksum
How to use checksums
32397420dbb8f4f72369c43e6275c483334032fd094246b9abc986cae3eb3448
BLAKE2b-256 checksum
How to use checksums
771ecc30e9dea024cd8d4ac20533c20d869f16cc3ebdbae3cf0d59fb78640e54
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / crunch_vanta-0.1.0-py3-none-any.whl

Download URL crunch_vanta-0.1.0-py3-none-any.whl
Size 68.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c7479858fea7e1857cf3dfa3b926fb273087c67838b6bd9142ef0893e5e86735
BLAKE2b-256 checksum
How to use checksums
7e922783dbc4b6c5d9e38fb130c49147a81715e1dc274a2d690b97e126645a46
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page