Kalshi Perps Direction Classifier
Purpose: predict whether a crypto perpetual future's ("perp") price on Kalshi will be higher or lower 1 minute from now. A binary classifier trained on papylove/kalshi-perps-data.
Part of an open-source, dry-run-by-default automated trading bot: papykabukanyi/bettor. The bot never relies on this model alone -- an entry always also requires an independent technical scalper signal (a local price dip/rally against a trend filter) to agree first.
The prediction horizon changed from 30 minutes to 1 minute. The strategy checks every open position every 20 seconds and exits within minutes via take-profit/quick-profit/stop-loss, so a model answering "up or down 30 minutes from now" was answering a materially different question than what the strategy actually needs moment to moment.
Model details
- Type: scikit-learn classifier, selected by comparing Logistic Regression, Random Forest, and Gradient Boosting on a chronological holdout split (never randomly shuffled -- this is time-series data, and a random split would leak future information into training).
- Retrained: daily, on the full accumulated history in the companion dataset -- both the live Kalshi archive and (when available) the deeper Coinbase-sourced pretraining rows, see the dataset card.
Features
Every timeframe from 1 minute up is derived directly from the 1-minute close series -- Kalshi's and Coinbase's candlestick APIs both cap out at 1-minute native resolution, so nothing finer (5s/15s/30s) exists to train on from any free source.
ret_1m, ret_3m, ret_5m, ret_10m, ret_15m, ret_30m, # 1-30 minute returns
trend_1h, trend_2h, trend_3h, trend_4h, # 1-4 hour returns
dist_to_ma_15, dist_to_ma_30, # distance from the 15/30-min moving average
volatility_5, volatility_15, volatility_30, # rolling volatility, 3 scales
trend_pct, # 6-hourly-candle trend
sentiment_score, # news sentiment for the underlying coin
ticker_code # which instrument (categorical, see meta)
ticker_code is a label-encoding over the instruments present at training
time -- see perps_model_meta.json's ticker_categories list for the exact
mapping (order matters: index = code).
Performance (most recent training run)
Chronological holdout, ~150k rows (capped for memory -- see
PERPS_MAX_TRAIN_ROWS in the GitHub repo), 13 instruments, 1-minute label
horizon:
| Model | Accuracy | ROC AUC |
|---|---|---|
| Logistic Regression | 0.517 | 0.529 |
| Random Forest | 0.536 | 0.548 |
| Gradient Boosting (selected) | 0.537 | 0.549 |
Read this honestly: an AUC of ~0.549 is a real but modest edge over
random (0.5) -- not a strong predictive signal on its own, comparable to
what the previous 30-minute-horizon version of this model showed. This is
exactly why the bot requires the technical filter to agree too, and why a
separate backtest (perps_backtest.py in the GitHub repo) validates the
combined strategy's trade frequency and win rate, not this model's
accuracy in isolation. See perps_model_meta.json's scores field on this
repo for the current numbers, updated on every retrain.
Usage
import joblib
from huggingface_hub import hf_hub_download
model_path = hf_hub_download("papylove/kalshi-perps-model", "perps_model.joblib")
model = joblib.load(model_path)
# x is one row, in the exact order of perps_model_meta.json's feature_columns
proba_up = model.predict_proba([x])[0][1]
Limitations
- No Kalshi trading fees or bid-ask slippage are modeled anywhere in this project's backtests -- treat any backtested return figures as optimistic.
- Kalshi's crypto perps are a new product (first listings 2026-06-04), so the LIVE (traded) training data covers at most ~7 weeks per instrument. The dataset's Coinbase-sourced rows extend this for pretraining, but that is the underlying coin's spot price, not Kalshi's own perp quote -- a reasonable proxy given a perp tracks its spot price closely, not a guarantee of identical behavior.
- Confirmed live: many of Kalshi's
immediate_or_cancelorders don't fully fill at the requested price -- this model (and any backtest built on top of it) has no way to account for real order-book liquidity/fill-rate, so actual trade frequency and returns should be expected to run below any backtested figure. - Not financial advice. Provided for research/educational purposes as part of an open-source project.