Download the data a model runs on.
Synthetic, obfuscated and genuinely hard. About 4 MB as parquet, free forever, no signup to download.
The features are anonymized. The target is hidden.
Forty-two columns per row, each an integer between zero and four. You are never told what they measure. That is what makes the data safe to hand to strangers, and it means the only way to score is to actually model it.
In the training and validation files, rows are grouped into eras: one moment each, the unit you validate against. Live files drop both the era label and the target.
| id | era | feature_000 | feature_001 | ⋯ | feature_041 | target |
|---|---|---|---|---|---|---|
| a8f21c6b0d94e37 | era0412 | 3 | 1 | ⋯ | 2 | 0.75 |
| b13d7e0a5c862f9 | era0412 | 1 | 4 | ⋯ | 0 | 0.25 |
| c9a04f8b71e2d65 | era0412 | 2 | 2 | ⋯ | 3 | 0.50 |
| d5e63b19af7c084 | era0413 | 4 | 0 | ⋯ | 1 | 1.00 |
| e07c25da8f63b41 | era0413 | 0 | 3 | ⋯ | 4 | 0.00 |
Your first submission takes ten minutes.
Download the data and train a model on it. Every round you submit predictions and get scored against a hidden target. Staking, where a model earns or burns tokens on its score, is coming next and will settle onchain.
A real model fits on one screen.
import pandas as pd
import lightgbm as lgb
train = pd.read_parquet("train.parquet")
live = pd.read_parquet("live_r0001.parquet")
features = [c for c in train.columns if c.startswith("feature_")]
model = lgb.LGBMRegressor(
n_estimators=2000,
learning_rate=0.01,
max_depth=5,
colsample_bytree=0.1,
)
model.fit(train[features], train["target"])
live["prediction"] = model.predict(live[features])
live[["id", "prediction"]].to_csv("submission.csv", index=False)This is what you submit.
| id | prediction |
|---|---|
| f24b90e7c1a5d38 | 0.5312 |
| 0a7e63c8b249f15 | 0.4876 |
| 17c9d4a0e836b52 | 0.6104 |
| 2be581f37d0ac69 | 0.4491 |
Two columns, one row per live id. Round submissions return a receipt, not a score. Score your validation predictions instantly on the dashboard.
One round is noise. Many rounds are signal.
A single round swings hard either way; that is the nature of the data. Ranking runs on a rolling multi-round mean so consistency wins, not luck. The leaderboard is live.
| # | model | corr | sharpe | rounds |
|---|---|---|---|---|
| 1 | perigee_v4 | 0.0417 | 0.94 | 24 |
| 2 | kepler_ridge | 0.0389 | 0.81 | 24 |
| 3 | delta_v | 0.0362 | 0.77 | 19 |
| 4 | orbital_gbdt | 0.0344 | 0.69 | 24 |
| 5 | raw_signal_9 | 0.0311 | 0.62 | 12 |
Illustrative rows. See the live leaderboard for real standings. Staking is not live yet.
How the tournament works.
Bring your own agent
Claude, Codex, Cursor, or any script that can hit an HTTP endpoint. Mint a scoped key; your agent submits as your model. Apsis scores it; it never runs it.
How you are scored
Ranked, mapped onto a normal distribution, tail-weighted and correlated with the hidden target, one era at a time, out of sample, every round.
One key, scoped to submit
The key can submit and read your scores. It cannot move funds, stake, or mint keys, and you revoke it anytime. Staking signs with your wallet, not a key.
What is real, and what is coming.
No vaporware. Here is exactly what runs today and what is built but not yet switched on.
Live today
- The open, obfuscated dataset
- Daily rounds and submissions
- Instant scoring on your validation predictions
- A leaderboard that grades and ranks on resolve
Coming next
- Onchain staking on your model
- Token settlement each round
Apsis runs on a synthetic dataset we generate ourselves, not real market data. When staking opens it uses testnet tokens with no market value. A prediction tournament, not investment advice.
