Engineering notes
How we measure things, including when we got it wrong.
No performance claims and no predictions — just the arithmetic behind how a strategy gets measured before it trades money. Every post shows its working.
Linear in documents is a bug: computing each indicator once for many strategies on the same pair
How a multi-tenant strategy engine stops paying per loaded document — demand-driven streams, bar-close cadence, and a per-pass indicator cache — with the arithmetic and the measured compute timings behind each.
· 19 min read
A per-trade Sharpe treats your trades as independent samples. Ten open positions are not.
Our Sharpe scales mean-over-stdev by the square root of the trade count, which is the right scaling only if the trades are independent draws — here is the effective-sample-size arithmetic for ten concurrent positions, and the fix we have documented but not shipped.
· 9 min read
Read the exit-reason histogram before you read the headline number
How to read a backtest's exit-reason breakdown — including the end_of_data bucket for positions still open when the sample ran out — and the six ratios worth demanding beside any summary card.
· 11 min read
An indicator that rewrites its own history every time a candle arrives
A port of the Đỉnh 1 / Đáy 1 peak-and-trough definition, and the two ways its original changed the value at bar 449 without ever reading bar 450 — including a trough loop whose guard was false on the first check.
· 12 min read
Why your RSI changes when you give it more history
A rolling mean over 14 bars forgets bar 15 and a Wilder average never does, which is why the same RSI on the same candles differs when the series behind it starts earlier — and why an indicator cache key has to carry the depth of history it was computed over.
· 9 min read
Running a stranger's strategy without a sandbox
How to evaluate a user-supplied expression in Python without eval, exec, or a container per customer — the AST allowlist, the three attacks it refuses, and the three things it does not cover.
· 10 min read
The ampersand that silently rewrites your entry rule
In Python and pandas, `&` binds tighter than every comparison, so `a > 1 & b > 2` parses as a chained comparison against a bitwise mask — here are the parse trees, the arithmetic, and the two ways it hides.
· 10 min read
Your strategy version hash does not pin the code that runs it
A content hash of a strategy document makes a backtest reproducible only against the document; pinning the result also needs a second hash over the indicator implementations that document reaches.
· 13 min read
Your stop is a fraction of your stake, not of the price — and leverage is the conversion
In a strategy document the stop, the timed profit-target ladder and the trailing offset are all fractions of stake, but every comparison inside the bar loop is against price — here is the division that converts them, and what our backtester measured while it was missing.
· 7 min read
Two Bollinger bands, same window, same standard deviations, different trades
Two widely-copied Bollinger helpers with identical parameters disagree for the whole warm-up because of one min_periods argument, and one popular entry rule is secretly a test of that disagreement.
· 10 min read
Your stop width decides what share of your risk goes to the exchange
Fees and slippage are a fixed toll per round trip, so the narrower the stop, the larger the share of your own risk budget that goes to the venue instead of the market — worked out at the 0.07% fee and 0.05% slippage this engine charges.
· 7 min read

Three ways our own backtester was flattering us
Sharpe annualised as if the strategy never left the market, returns compounded across trades that overlapped, drawdown measured in the wrong order. Here is the arithmetic, and what each one is now.
· 6 min read