CrunchDAO challenge package for Vanta (Bittensor Subnet 8) — model interface, indicators, backtesting, and walk-forward validation.
Project description
🏔️ 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
- Scoring Guide — how scoring works, what the leaderboard metrics mean
- Strategy Guide — practical tips, common approaches, pitfalls
- Compare Notebook — run all strategies side by side
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}
"""
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file crunch_vanta-0.1.0.tar.gz.
File metadata
- Download URL: crunch_vanta-0.1.0.tar.gz
- Upload date:
- Size: 2.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
32397420dbb8f4f72369c43e6275c483334032fd094246b9abc986cae3eb3448
|
|
| MD5 |
2e16f2841762ed1c332ef49d84a861eb
|
|
| BLAKE2b-256 |
771ecc30e9dea024cd8d4ac20533c20d869f16cc3ebdbae3cf0d59fb78640e54
|
File details
Details for the file crunch_vanta-0.1.0-py3-none-any.whl.
File metadata
- Download URL: crunch_vanta-0.1.0-py3-none-any.whl
- Upload date:
- Size: 68.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c7479858fea7e1857cf3dfa3b926fb273087c67838b6bd9142ef0893e5e86735
|
|
| MD5 |
4eea643e106d32d1f85171e67a2a618a
|
|
| BLAKE2b-256 |
7e922783dbc4b6c5d9e38fb130c49147a81715e1dc274a2d690b97e126645a46
|