Fairness and calibration
What happened when strikeabox's real pricing and settlement code was run over real recorded Strike mainnet prices: the same public prices the hosted app's board and practice mode use. Every number on this page is the output of a script you can run yourself (how to reproduce it). calibration
A measurement, not a guarantee
These results describe about five hours of Strike mainnet prices recorded on one afternoon. They are not a promise about any future price, and they say nothing about trading real money. Practice credits have no cash value.
The short version
Suppose you had staked 1 credit on every box the app offered, every 5 seconds, over the recorded period. Per credit staked, you would have got back:
| Market | Return to player (production quotes) |
|---|---|
| BTC-USD | 0.758 |
| ETH-USD | 0.794 |
| SOL-USD | 0.840 |
- The nominal figure, with a 10 % house edge, is 0.900. Every market came out below it. Over this data the effective house edge was larger than 10 %.
- No group of boxes paid back more than was staked. Grouped by quoted probability, the production quotes returned between 0.688 and 0.907 per credit. The best group on each market: BTC-USD 0.839 (boxes quoted at 10–20 %), ETH-USD 0.843 (70–80 %), SOL-USD 0.907 (10–20 %, the one group slightly above the nominal 0.900).
- In 20 of the 21 groups, boxes were touched less often than quoted. In the other, SOL-USD at 10–20 %, they were touched about as often as quoted: 14.7 % against 14.5 %.
- The random-walk model on its own was too generous on long shots. On SOL-USD boxes quoted at 10–20 %, it would have returned 1.222 per credit staked: a player who only tapped those boxes would have come out ahead. That is why every quote takes the higher of the model and an empirical replay of the last 30 minutes of prices. See the comparison below and Multipliers and the model.
What was measured
The data
The strikeabox collector recorded Strike mainnet's public markprice@1s mark prices for BTC-USD, ETH-USD and SOL-USD, about one tick per second, on 22 October 2026 from 13:00 to 19:52 UTC. That covers most of the US trading session, including the stock market open at 13:30 UTC.
The recorder was down from 13:53 to 15:16 UTC. That stretch is a gap in the data, not a quiet market: a box whose window ran into it without being touched first settled void, exactly as it would in the app. Void boxes are counted separately and left out of the return to player.
The recorder kept running while the script ran, so the markets read slightly different amounts of data: 19,129 to 19,486 ticks, about 5.3 hours of prices per market. "Quote times scheduled" counts every 5-second step after the volatility warm-up, including the steps that priced nothing because 30 minutes of history were not yet available (see the method).
| Market | Ticks read | Quote times scheduled | Boxes settled | Touched | Not touched | Void |
|---|---|---|---|---|---|---|
| BTC-USD | 19,129 | 3,640 | 151,077 | 34,954 | 116,123 | 1,059 |
| ETH-USD | 19,326 | 3,676 | 142,431 | 35,807 | 106,624 | 1,029 |
| SOL-USD | 19,486 | 3,707 | 82,982 | 26,636 | 56,346 | 780 |
The method
- Going through the recorded ticks in order, every 5 seconds the script takes a quote time (once volatility has warmed up). It assumes the server receives each tick about 100 ms after Strike stamped it.
- At each quote time it prices every visible box, exactly as the server would, with the production pricing code: 6 columns by 11 rows around the current price. Boxes the app would not offer are skipped.
- The empirical part of each quote uses only ticks from the 30 minutes before the quote, never the future. It needs a full 30 minutes of history, so nothing was quoted in the first half hour of the recording, or in the first half hour after the outage.
- It then settles every offered box with the production outcome code on the recorded ticks: touched, not touched, or void. Straight lines between ticks, closed box, gaps respected: the rules from Outcomes and settlement.
- It groups the boxes by quoted probability and compares the mean quoted probability with the share that were actually touched.
- Return to player is the credits paid out divided by the credits staked, with a 1-credit stake on every offered box and the payout rounded down to the hundredth as in the app.
The same box is quoted again at every 5-second step while it is on the grid, many boxes share the same stretch of price path, and neighbouring boxes move together: the samples are correlated. The z (approx.) column says how far the realised touch rate is from the quoted probability in standard errors; negative means fewer touches than quoted. It is deliberately conservative (the script inflates the variance tenfold to allow for the overlap). Treat it as a rough guide only.
The pricing parameters (30 minutes of history, 20 pseudo-observations, the higher of the two estimates) were set that morning on testnet data, before the mainnet recording began, and were not changed for it.
Results: production quotes
These are the quotes the app actually shows. The top group, labelled 0.70–0.81, runs from 0.70 to the 0.80 offer limit; its upper bound leaves room for rounding.
BTC-USD
| Quoted probability | Boxes | Mean quoted p | Realised touch rate | z (approx.) | Return to player |
|---|---|---|---|---|---|
| 0.10–0.20 | 47,499 | 0.150 | 0.139 | −2.18 | 0.839 |
| 0.20–0.30 | 42,935 | 0.250 | 0.208 | −6.25 | 0.750 |
| 0.30–0.40 | 36,013 | 0.345 | 0.264 | −10.22 | 0.688 |
| 0.40–0.50 | 14,895 | 0.442 | 0.343 | −7.66 | 0.697 |
| 0.50–0.60 | 5,917 | 0.543 | 0.435 | −5.28 | 0.717 |
| 0.60–0.70 | 2,716 | 0.643 | 0.554 | −3.05 | 0.773 |
| 0.70–0.81 | 1,102 | 0.740 | 0.665 | −1.80 | 0.805 |
| All | 151,077 | 0.758 |
ETH-USD
| Quoted probability | Boxes | Mean quoted p | Realised touch rate | z (approx.) | Return to player |
|---|---|---|---|---|---|
| 0.10–0.20 | 44,019 | 0.149 | 0.138 | −2.06 | 0.836 |
| 0.20–0.30 | 37,679 | 0.249 | 0.218 | −4.50 | 0.785 |
| 0.30–0.40 | 34,781 | 0.346 | 0.295 | −6.30 | 0.766 |
| 0.40–0.50 | 15,454 | 0.442 | 0.372 | −5.54 | 0.756 |
| 0.50–0.60 | 6,361 | 0.543 | 0.470 | −3.70 | 0.776 |
| 0.60–0.70 | 2,843 | 0.643 | 0.577 | −2.35 | 0.804 |
| 0.70–0.81 | 1,294 | 0.743 | 0.698 | −1.17 | 0.843 |
| All | 142,431 | 0.794 |
SOL-USD
| Quoted probability | Boxes | Mean quoted p | Realised touch rate | z (approx.) | Return to player |
|---|---|---|---|---|---|
| 0.10–0.20 | 21,384 | 0.145 | 0.147 | 0.17 | 0.907 |
| 0.20–0.30 | 15,234 | 0.248 | 0.232 | −1.46 | 0.839 |
| 0.30–0.40 | 13,310 | 0.350 | 0.330 | −1.52 | 0.850 |
| 0.40–0.50 | 14,779 | 0.450 | 0.411 | −3.01 | 0.821 |
| 0.50–0.60 | 10,350 | 0.545 | 0.467 | −5.08 | 0.768 |
| 0.60–0.70 | 5,131 | 0.645 | 0.552 | −4.38 | 0.768 |
| 0.70–0.81 | 2,794 | 0.743 | 0.658 | −3.26 | 0.793 |
| All | 82,982 | 0.840 |
Compared with the model alone
The same replay with each box priced by the random-walk model only, without the empirical replay. The app does not quote like this.
| Market | All boxes: production quotes | All boxes: model alone | 10–20 % boxes: production quotes | 10–20 % boxes: model alone |
|---|---|---|---|---|
| BTC-USD | 0.758 | 0.801 | 0.839 | 0.987 |
| ETH-USD | 0.794 | 0.847 | 0.836 | 0.996 |
| SOL-USD | 0.840 | 0.934 | 0.907 | 1.222 |
The model under-prices long shots, because a single jump of the mark price can carry it across several rows. SOL-USD boxes it quoted at 10–20 % (14.6 % on average) were touched in 19.7 % of cases, and BTC-USD and ETH-USD came close to paying back the stake. Taking the higher of the model and the empirical replay is what brings those boxes down to 0.84–0.91.
The model-alone run started later and has no history to wait for, so it also quotes in the first half hour of the recording and after the outage. It read 19,720 to 19,752 ticks per market and settled more boxes: compare the two as rough context, not as a controlled experiment.
Earlier measurement on Strike testnet
An earlier run of the same script used Strike testnet's mark prices, recorded the same morning from 07:08:47 UTC: about 2.5 hours per market, with no gaps and no void boxes.
| Market | Production quotes | Model alone |
|---|---|---|
| BTC-USD | 0.732 | 0.742 |
| ETH-USD | 0.730 | 0.768 |
| SOL-USD | 0.800 | 0.900 |
The pattern was the same: every market below 0.900, and the model alone over-paid SOL-USD long shots (1.166 per credit at 10–20 %, against 0.816 for the production quotes). The pricing parameters were chosen on the first 97 minutes of that recording, so the testnet result is not an out-of-sample test. Testnet prices can behave differently from mainnet's.
Limits of this measurement
- One afternoon, about five hours. Strike mainnet prices from 13:00 to 19:52 UTC on 22 October 2026, less an 83-minute outage. Nights, weekends and other days will look different, and the ratios could move either way.
- The samples are correlated. Windows overlap and neighbouring boxes move together, so the 80,000 to 150,000 boxes per market are not that many independent observations. The effective sample is much smaller, and the precision lower than the counts suggest.
- Volatility regimes change. The empirical estimate learns from the last 30 minutes only. If the market changes character, for example a calm half hour followed by a violent move, the quotes lag behind it.
- Return to player is a measurement, not a guarantee. It is the result of staking 1 credit on every offered box. Real players pick particular boxes, stakes and moments. Nobody should read 0.76 as "you will get back 76 %".
- The runs are not on identical data. The production run and the model-alone run started at different moments, read different amounts of data, and quote over different stretches.
- One price source. The ticks are Strike mainnet's mark price, whose behaviour follows Strike's own method. Testnet's prices, and any other source, behave differently.
- Practice credits have no cash value. None of this is a statement about real-money trading.
Reproduce it
You need a PostgreSQL database with a ticks table filled by the strikeabox collector (run the server's worker with STRIKE_DATA_NETWORK=mainnet for a while and let it record Strike's public mark prices), and the repository checked out with its dependencies installed.
# the production quotes (model and empirical estimate, higher of the two)
STRIKE_DATA_NETWORK=mainnet DATABASE_URL=postgres://sbx:sbx@127.0.0.1:5432/<your db> npx tsx apps/server/scripts/calibrate.ts 5 robust 1800
# the random-walk model alone
STRIKE_DATA_NETWORK=mainnet DATABASE_URL=postgres://sbx:sbx@127.0.0.1:5432/<your db> npx tsx apps/server/scripts/calibrate.ts 5 model 1800The three arguments are the seconds between quote times (5), the mode (robust or model) and the length of history in seconds that the empirical estimate uses (1800, i.e. 30 minutes). The script prints one table per market in the same layout as above, under a header that names the network the ticks came from: set STRIKE_DATA_NETWORK to the network you recorded (it defaults to testnet). Your numbers will differ with your data and your recording window.