Conventions
Units and input rules. Read these before you hit them, because each one raises rather than guesses.
Nothing is silently clamped. A simulator that repairs your inputs gives you a market you did not specify, so a malformed scenario raises ValidationError and a rejected order raises OrderError.
The rules
Rates are fractional
0.052 means 5.2 percent. Passing 5.2 raises, with an error that says so.
Absence differs from zero
corporate_bond_yield=None falls through to the policy rate. 0.0 is a real observation and is used as given. In a columnar read, where a column can not carry None, absence is NaN and never zero, because zero is a real maker inventory, a real mispricing and a real return.
Negative EPS is legal
Loss-makers are valued off book value, and a universe without them is not realistic. It also never exercises that valuation path, so a study on such a roster covers half the model.
Short interest is a share count
The squeeze rule divides it by the float. A value strictly between 0 and 1 raises for a company with a real share count.
Roster order is contractual
A re-sorted universe is a different market. The fingerprint covers order as well as content.
Coefficients ship as a preset
They are named and versioned rather than passed as constructor keywords, so two published results can be compared. pt-v14 is the default as of the 2026-08-28 era boundary, pt-v12 was the default before it, and every earlier name from pt-v1 on still reproduces bit for bit.
Every numeric column is f64
No integer columns, no downcasting. A join that produces a different dtype is a sign the read went wrong.
Short interest, in detail
This is the convention that bites hardest, because the mistake would otherwise be silent. The squeeze rule divides short interest by the float, so 3% of a hundred million shares is 3,000,000.
Why 0.03 raises
Three hundredths of one share against a real float is a squeeze ratio of 3e-10, and a squeeze that can never fire. So a value strictly between 0 and 1 raises for a company with a real share count.
Zero is legal. It means no short interest, which is a real observation.
What the generator draws
Log-uniform between 0.4% and 30% of shares outstanding, so the median is the geometric mean of those bounds.
A hundred names is a small sample of a draw whose top and bottom differ by a factor of seventy-five, so a roster the size these docs use runs lower and noisier.
What a preset does and does not carry
In the dictionary
The mispricing and crowd model: the half-life, mispricing_phi, momentum_theta, the mispricing and daily-shock caps, and the three crowd terms. Eight numbers, and every one of them live.
Live, and absent from it
The GARCH parameters, the market and sector factor sigmas, and the order-flow coefficient. None of them appear, and nothing forces a preset name to change when one of them moves.
So the preset name is necessary and not sufficient. A fully specified run also names the package version, which pins the implementation.