Default market model
A market runs on the preset pt-v20 when no model is given, in tradefloor 0.8.8. pt-v20 passes all 40 of its pre-registered validation criteria on holdout seeds that were not used during tuning, graded over 90 simulated histories of 21 years, and the 19 statistics of the one-year table fall inside their acceptance ranges. In the preset table at the end, 15/15 means 15 of the 15 fixed-roster statistics a record measured fall inside their ranges. How it is measured lists every criterion with its observed result.
What it gets right
Crash rates inside the registered band
Over 90 simulated histories of 21 years, the index has 1.96 bear markets of 20% a decade against a real 1.12, 4.52 corrections of 10% against 3.65, and 9.6 sessions a decade down more than 5% against 6.2, all within the half-to-twice band the rows allow. Replaying 2008 and 2020 with the real VIX imposed, the maximum drawdown reads 45% and 37% against a real 57% and 34%.
How often and how long the VIX stays high
The VIX is above 30 on 5.9% of sessions against a real 8.2%, and a spell above 30 lasts 27 sessions on average against 22.
Rates and bonds that move prices
Driven through the real 2022 rate path, the market P/E moves -4.26% per 100 bp of the corporate yield, against the S&P 500's -5.2%. The simulated 10-year Treasury moves 4.96 bp a day against a real 5.41, and the correlation of stock and bond returns has the sign measured in real data.
Earnings that fall in recessions
Around a contraction, aggregate earnings move -17.2% against -17% in Shiller's data, and after the packaged recession's low the index rises 55% within a year, against 69% after March 2009.
Costs that grow with size
The cost of an order grows with the square root of its size: the fitted exponent is 0.48, against the empirical 0.5.
Leak checks
A market that is easy to game makes a bad strategy look good and teaches a learning agent an edge real markets do not have, so some checks are strategies built to find leaks. Reading a headline 5 ticks late earns 15.8 bp, under the 20 bp limit. No price-only rule on the published suite of 20 markets beats buy-and-hold by more than 5 points, value and momentum screens stay inside bands set from real data, and timing the market on published economic data earns at most a point a year. pt-v19 fails both price-only checks.
Long-run return and volatility
The long-run index return is 6.4% a year against a target of 6.25%, with annual volatility of 19.1% against 18.1%.
What a simulated market adds
Fork a market at day 100, raise rates in one copy, and the difference between the copies is the effect of the rate rise on your strategy, with the luck held fixed. Run the same agent on 30 seeds and you have 30 versions of the same economy to test it on, each with crashes and recoveries of its own. A result says how a strategy behaves in this model. It does not forecast returns in a real market.
What changed from pt-v19
- The tape follows the model price.
- A company's own news moves its fair value for good.
- Plain market shocks are permanent up to a volatility ceiling, so the index no longer reverts on the mispricing's half-life.
- Fear marks fair value down while the VIX is above 40.
- Agents trade in a book with depth and a queue.
- The business cycle and GDP are published late, as the agencies publish them. Published at once, they would let an agent that went to cash on a contraction beat holding in every history.
On the same pooled histories pt-v19 fails 16 of the 40 rows. It still runs, and replays exactly, with model="pt-v19".
Limits
The model still falls short in places. The named gaps lists each measured shortfall with the uses it rules out, and tf.envelope.check() refuses a question that depends on one.
Every preset
A shipped preset never changes, so a result names the preset it ran on and replays on it in every later release. Select one with model="pt-v19" or similar. The numbering skips 17. The counts are each record's fixed-roster panel of shape statistics, at one and two years.
| Preset | Standing | In band, one year | In band, two years |
|---|---|---|---|
pt-v20 | Default from 0.8.5 | 15/15 | 14/14 |
pt-v19 | Default from 0.8.0, replaced in 0.8.5 | 15/15 | 14/14 |
pt-v18 | Default from 0.7.0, replaced in 0.8.0 | 14/14 | 13/13 |
pt-v16 | Default from 0.6.0, replaced in 0.7.0 | 14/14 | 13/13 |
pt-v15 | Never the default | 14/14 | 13/13 |
pt-v14 | Default from 0.4.0, replaced in 0.6.0 | 14/14 | 13/13 |
pt-v13 | Never the default | 14/14 | 13/13 |
pt-v12 | Default from 0.3.0, replaced in 0.4.0 | 14/14 | 12/13 |
pt-v11 | Never the default | 13/14 | 11/13 |
pt-v10 | Default from 0.2.0, replaced in 0.3.0 | 13/14 | 12/13 |
pt-v9 | Never the default | 13/14 | 11/13 |
pt-v8 | Never the default | 13/14 | 12/13 |
pt-v7 | Never the default | 13/14 | 12/13 |
pt-v6 | Never the default | 12/14 | 9/13 |
pt-v5 | Never the default | 12/14 | 8/13 |
pt-v4 | Never the default | 11/14 | 8/13 |
pt-v3 | Default from 0.1.0, replaced in 0.2.0 | 12/14 | 7/13 |
pt-v2 | Never the default | 11/14 | 8/13 |
pt-v1 | Never the default | 9/14 | 7/13 |