Systematic trading research, execution modeling, and backtesting realism — written as we go.
A backtest can be deterministic and well-validated and still be measuring the wrong thing, if the fill price underneath it doesn't reflect how an order actually gets filled. Execution modeling is the layer everything else depends on.
2026-07-17A buy pays the ask and a sell receives the bid — spread is a directional cost paid on every round trip, not symmetric noise. Getting the data's own bid/ask/midpoint convention wrong silently biases every fill the same way.
2026-07-17A limit order isn't a market order with a nicer price attached. It waits for a specific level to be crossed, might never fill at all, and modeling it any other way changes what a strategy's results actually mean.
2026-07-17A limit order guarantees a price. A stop order only guarantees a trigger — once crossed, it fills at whatever the market gives, which can be meaningfully worse than the stop level itself when price gaps through it.
2026-07-17A take-profit exit is easy to assume fills at exactly the target price, like a limit order. It doesn't — it uses the same slippage-inclusive formula as a stop-loss exit, and when both are close together, which one actually triggers first is a real question with a real answer.
2026-07-17Open, high, low, and close describe four points from a bar — not the path price actually took between them. Deciding which order filled first, or whether a level was touched at all, requires a real answer to a question OHLCV alone can't settle.
2026-07-17"Run it again, get the same answer" sounds like a low bar. Most ad-hoc research setups don't actually clear it — and without it, none of the other checks that make research trustworthy are even possible to run.
2026-07-17"The code does whatever the code does" isn't a definition of behavior — it's an admission that behavior hasn't actually been defined. A written execution specification is the difference between a claim that can be checked and a black box that has to be trusted.
2026-07-17Most software testing asks whether code runs without crashing. Behavioral testing for an execution engine asks something stricter — does this specific scenario produce the exact fill the specification says it should, not just a plausible-looking one.
2026-07-17A finished backtest result is a final-stage view — trades, fills, a summary. When something in that result looks wrong, a few outsized losses, an order that seemingly should have filled and didn't, replay is what finds the exact moment and diagnoses why.
2026-07-17A backtest happened with one specific set of trades. Monte Carlo asks a different question — if the strategy's real edge produced a slightly different draw of similar trades, how much would the result actually change?
2026-07-17Monte Carlo resamples what already happened under the same assumptions. Stress testing asks a different question — what happens if the assumptions themselves get worse, not just the specific sequence of trades drawn from them.
2026-07-17An earnings backtest is only honest if the data becomes visible on the date it was actually announced, not the date it happened to land in a spreadsheet. Exogenous data's point-in-time resolution is what makes that distinction real instead of assumed.
2026-07-19A CPI print or a rate decision doesn't belong to one ticker the way an earnings surprise does — but the exogenous data mechanism is keyed per-ticker. Deciding which instruments a macro event actually reaches is a research question, not a technical detail to skip past.
2026-07-19Running the same independent logic across many tickers isn't the same as running many separate single-asset backtests — they share one equity curve and one leverage pool, and that constraint only shows up once they're actually run together.
2026-07-19The moment a decision compares tickers to each other — ranking, correlation, a spread — a per-ticker loop stops being merely slower and becomes structurally the wrong shape for the question being asked.
2026-07-19There's no dedicated sweep engine in reamer_py — a sweep is just a loop over configs — and that absence of built-in guardrails means the discipline against overfitting to the sweep itself has to come from whoever's running it, not from the tool.
2026-07-19The parts of a research setup that should stay fixed across every idea — data loading, cost assumptions, evaluation — and the one part that should actually change between ideas. Most one-off research scripts blur that line without meaning to.
2026-07-19Forex and CFD cost structure maps onto reamer_py's execution model as-is, not as an approximation — but one silent unit mistake is enough to mis-price every fill by five orders of magnitude without ever throwing an error.
2026-07-19Splicing front-month futures contracts together at expiry creates a price jump that has nothing to do with the market. reamer_py rebases execution bookkeeping around that jump automatically — with one real limit worth knowing before relying on it.
2026-07-19A multi-asset backtest sharing one execution config across every ticker is itself an assumption of uniform costs — and real portfolios never actually have that.
2026-07-19An order doesn't just either fill or not — it stops being eligible to fill at some point too. Treating every order as though it waits indefinitely quietly tests a more patient strategy than the one that was actually written.
2026-07-19Real position management isn't strictly flat, full-open, or full-close. A framework that only knows those three states forces a strategy's logic to work around the tool instead of expressing the actual idea.
2026-07-19A backtest that gives a different answer on a different run, or a different machine, isn't measuring a strategy — it's measuring noise. Determinism was a hard constraint from the first line of the engine, not a property added once something else broke.
2026-07-19An OHLCV bar gives four prices, not the path between them. reamer_py answers the question of what happened inside a bar with a deterministic, seeded synthetic tick path — not with stored tick data most researchers can't afford or don't need.
2026-07-19reamer_py isn't Python that happens to be fast. The hot path — order matching, fill resolution, tick generation — runs as compiled machine code with no GIL, and on_bar hands a strategy zero-copy numpy views instead of objects the interpreter has to build one at a time.
2026-07-19A lookback window isn't free just because the syntax to request one is a single number. What a rolling window of OHLCV history actually costs in memory and compute, as that number grows, shapes how large a lookback a research loop can actually afford to run.
2026-07-19Running a strategy across fifty instruments isn't fifty single-asset backtests glued together — it's one aligned timeline, one shared equity curve, and a per-step cost that scales with ticker count regardless of how deep any single ticker's lookback is.
2026-07-19reamer_py briefly shipped a separate compiled Python module per asset class, each hiding the fields the others didn't need. It was removed the same cycle it was built, once splitting modules turned out to cost more than it protected.
2026-07-19\"The code does whatever the code does\" is not a definition of behavior — it's an admission that behavior was never actually decided. Writing the execution model down as a testable specification, before writing the tests, is a different discipline than testing code after the fact.
2026-07-19Most software testing asks whether code runs without crashing. Testing an execution engine against a published specification asks something stricter — does this exact scenario produce the exact fill the spec says it should, not just a plausible-looking one.
2026-07-19pybind11 has no stable-ABI support, on any version. Shipping one compiled extension that works across four Python minor versions and three operating systems means building the same unmodified C++ many times over and bundling every result into a single wheel, not one clever binary.
2026-07-19A result someone else can't independently reproduce isn't evidence — it's a claim asking to be trusted. A self-contained result file, carrying its own config, seed, and fills, is what turns "trust me" into "check it yourself."
2026-07-19