How prices are made
Every price is a fair value, set by the company's earnings and the economy, times a mispricing that wanders and reverts, traded through an order book. The two layers meet in one number, the model price, and the book turns it into the prints an agent trades against. This page describes the default model, pt-v20. The full specification, every equation with the line of code that implements it, is docs/MODEL.md in the library repository.
The two layers
the economy, daily at the close
business cycle
-> growth, unemployment, inflation
-> central bank -> policy rate
-> 2-year, 10-year, corporate yields
-> nominal output, earnings cycle
-> the VIX
every tick
fair value V = sector P/E x earnings
x rate term
x the company's own level
mispricing s = mean reversion + herding
+ crowd + news
+ order flow + noise
model price = V x exp(s)
printed price = model price traded
through the maker's book
daily at the close
volatility = per-name GJR-GARCH,
market and sector
variance, all scaled
by the VIXA session is 390 one-minute ticks. At the open the day's company news is drawn. Each tick draws the market, sector and company shocks, updates every name's mispricing and fair value, and settles the print through the book. At the close the variance processes update, jumps land, and the economy steps: the VIX, the yield curve, the business cycle, the earnings cycle and the central bank. The next session reads the new rates and volatility.
Fair value
A profitable company is worth its sector's anchor P/E times its earnings, times a rate term that shrinks the multiple when the corporate bond yield is above its neutral level, more for fast-growing companies. A loss-making company is valued at 1.2 times book. Earnings grow with nominal output and an aggregate earnings cycle that falls in a contraction, plus buybacks.
So rates reach prices the way they do in a real market. At the neutral rate, 100 basis points on the corporate yield moves a profitable company's fair value by 3% to 5.4%, depending on its growth. Rows R6 and E1 of the registered checks compare the market P/E's response to the 2022 rate path and the fall in earnings around a contraction with real data.
Part of every shock is permanent. A company's own news and its sector's shocks move its fair value for good, and so do the market's plain shocks up to a volatility ceiling. What a fear regime adds above that ceiling sits in the mispricing and reverts as the fear passes. This matches evidence that mean reversion in index returns concentrates in turbulent periods (Poterba and Summers 1988; Kim, Nelson and Startz 1991). Above a VIX of 40, fear also marks fair value down until it calms, after French, Schwert and Stambaugh (1987).
Mispricing
The mispricing is the log gap between the model price and fair value. Each tick it moves by:
| Term | What it does |
|---|---|
| Mean reversion | pulls the gap back toward zero, with an effective half-life of about 40 sessions |
| Herding | a share of yesterday's re-rating carries on today, set by momentum_theta, 0.0186 on pt-v20 |
| The crowd | buys what trades below fair value and chases yesterday's move a little, up to a cap |
| News | company, sector and market news as it is priced in |
| Order flow | the permanent part of order imbalance, including your own fills |
| Squeezes and cascades | forced buying when a rising price meets high short interest, and stop-loss cascades either way |
| Noise | the market, sector and company random draws, scaled by beta and the variance state |
Summed over a session the gap follows a stationary daily AR(2), so it neither trends away nor sits still. Herding is low enough that the lag-one autocorrelation of returns stays inside the real band, so a rule that reads only past prices finds no edge a real market would not give it.
Volatility and the VIX
Each company's variance is a GJR-GARCH process, so a fall raises volatility more than a rise of the same size. The market factor and each sector have their own variance. All three read the VIX, so a high VIX is a violent market and there is no separate crisis switch.
Each day the VIX is computed from the index's own variance. It moves toward the volatility that variance implies, plus a fear response to the day's return, and every variance process reads it back. When it crosses the crisis threshold a crisis episode starts, and with probability 0.6 it starts in financial services, as 2008 did. Rows A1 to A3 of the registered checks replay 2008 and 2020 with the real VIX imposed.
The economy
The business cycle moves through expansion, peak, contraction, trough and recovery. Growth, unemployment and inflation follow it, and a central bank sets the policy rate at its meetings. The 2-year and 10-year Treasury yields and the corporate yield follow the policy rate, with daily moves of their own.
An agent sees the economy as it is published. The business-cycle phase and GDP growth arrive late, as the statistical agencies publish them, and a rate decision is priced at the moment it is announced.
The order book
A market maker quotes around a blend of the last print and the model price, and the market's own flow trades against it, so the print follows the model price with the noise a real tape has.
An agent's order meets three kinds of liquidity: the maker's ladder, other agents' resting orders at their limits, and latent depth behind them priced so that cost grows with the square root of the order's size, as Tóth and colleagues measured in 2011 (row C9 of the registered checks). A limit order waits behind the shares already at its price and fills in parts. Depth an order takes refills with a half-life of 27 ticks, and each agent's net fill leaves a permanent impact on the mispricing on the next tick.
The eleven factors
engine.truth() books every tick's change in mispricing to eleven named factors that add up to it, with a residual of about 1e-16 from rounding.
| Factor | What it books |
|---|---|
reversion | the pull back toward fair value |
momentum | herding: yesterday's re-rating carrying on |
crowd_lean | the crowd's net flow |
company_news | news as it is priced in |
order_flow_impact | the permanent part of order imbalance, your orders included |
short_squeeze_effect | squeezes and stop-loss cascades |
random_noise | the market, sector and company random draws |
circuit_breaker | the correction when the price leaves the session's band |
jump | the daily jump, recorded on the tick it is first seen |
overnight | the close-to-open move, zero on every shipped preset |
fair_value_shift | the part of a shock that moved fair value instead, with a minus sign |
An agent's explain(day) answers with one of the first ten, and Agents and evaluation says how the answer is scored.
Seeds and streams
Each process draws from its own random stream derived from the run's seed: the market, the economy, news, jumps, volume and the crisis epicenter. The market stream's schedule depends only on the roster, never on a price or a preset, so two presets run on the same seed see the same market shocks and differ only in how they respond. A seed can be any 64-bit integer. Every coefficient is listed, with its value on each preset, under Model parameters.