Blog

Notes from the lab

Systematic trading research, execution modeling, and backtesting realism — written as we go.

Execution Modeling6

Why Execution Modeling Matters

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-17

Modeling Bid/Ask Correctly

A 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-17

How Limit Orders Really Behave

A 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-17

Stop Orders, Gaps, and Reality

A 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-17

Bracket Orders Done Correctly

A 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-17

Why OHLCV Execution Is Harder Than It Looks

Open, 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
Trust & Correctness4
Validation & Robustness2
Practical Research Workflows11

Testing Earnings Strategies with Exogenous Data

An 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-19

Adding Macro Events to Strategy Research

A 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-19

Multi-Asset Portfolio Research

Running 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-19

Researching Cross-Asset Relationships

The 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-19

Parameter Sweeps Without Overfitting

There'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-19

Building a Research Workflow in Python

The 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-19

Forex and CFD Realism: Spread, Swap, and Rollover

Forex 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-19

Rolling a Continuous Futures Contract Without a Fake Gap

Splicing 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-19

Per-Ticker Execution Costs in a Multi-Asset Portfolio

A 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-19

Order Lifetime: IOC, GTD, and Why It Matters

An 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-19

Scaling In and Reversing a Position Correctly

Real 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-19
Engineering10

Designing a Deterministic Simulation Engine

A 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-19

Why Synthetic Ticks Instead of Stored Ticks

An 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-19

Why the Hot Loop Is Compiled, Not Interpreted

reamer_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-19

What a Rolling Window Actually Costs

A 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-19

Scaling Multi-Asset Backtests

Running 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-19

One Compiled Module, Every Asset Class

reamer_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

Publishing an Execution Specification

\"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-19

Testing a Trading Engine

Most 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-19

Cross-Platform Python Packaging

pybind11 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-19

The .reamer File: Making a Backtest Result Portable

A 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