Home Live Ticker Fear & Greed
Sign in

Backtesting & Performance

How to Turn a Trading Idea Into Objective, Testable Rules

Spot the edge. Swoop in.

A backtest cannot simulate intuition. It can only execute deterministic instructions, and most amateur backtests fail not because the code is wrong, but because the rules behind it were never actually finished being written.

Can a Backtest Run Directly on a Trading Idea?

No. A backtest cannot simulate intuition — it needs deterministic instructions that leave no subjective judgment call implicit, no threshold to eyeball, nothing left for a person to decide by feel in the moment. Most amateur backtests do not fail because the code is wrong; they fail because the rules behind the code were never actually finished being written.

A rule set is not finished when it produces trades in a script. It is finished when a second person, given only the written specification, would generate the identical set of trades without asking a single clarifying question.

Why a Hypothesis Comes Before a Rule

"Buy when RSI falls below 30" is a rule, not a hypothesis. It specifies an action without explaining why an edge should exist behind it. Ask why 30 rather than 28 or 33, and a rule alone has no answer beyond the backtest that produced it — which is circular, since the threshold was likely chosen because it performed well in that same test. The RSI indicator can be a reasonable way to measure a condition a hypothesis describes; it is not a substitute for having one.

A hypothesis explains why an opportunity might exist. Examples:

"Momentum stocks go up" cannot be tested, because nothing in that sentence is measurable — not which stocks, not what horizon, not compared to what. A fully specified version names every one of those gaps: market (US-listed common stocks), universe (largest 1,000 by market capitalization with a minimum liquidity threshold), trend filter (only stocks trading above their 200-day moving average), ranking variable (twelve-month total return), lookback (twelve months), skip period (the most recent month excluded from the ranking), holding period (one month before re-ranking), comparison group (the bottom decile on the same ranking), and cost boundary (the conclusion must hold after commissions, spread, and a stated slippage assumption).

A hypothesis this specific can be wrong, which is what makes it worth testing. It also reduces the temptation to change the story after seeing the results. A vague hypothesis can be quietly reinterpreted to fit whatever the backtest produced; a falsifiable one either matches the outcome or it does not, and there is no room to argue about which.

The mechanism named in a hypothesis also implies its own expiration. A hypothesis built on forced institutional selling should weaken if forced selling becomes rarer, or if enough capital competes to absorb it. A hypothesis built on underreaction to new information should weaken as more participants specifically watch for that underreaction. Naming the mechanism gives a developer something concrete to monitor going forward, rather than only a return figure to watch for signs of decay after the fact.

The Six Components Every Rule Set Needs

Every complete stock trading rule set answers the same six questions, regardless of the strategy's style. Skipping any one of them does not remove the decision — it just moves the decision somewhere less visible, usually into the backtesting code itself.

Universe rules

The universe defines which stocks the strategy was even allowed to consider on a given date.

Hypothetical example — for education only.

Change any one of those lines and the strategy under test changes with it. A rule tested against micro-cap stocks under $2 and the same rule tested against this list are not variations of one strategy — they are two different strategies that happen to share an indicator.

Entry rules

An entry rule states the condition that must be true, computed without room for interpretation.

Hypothetical example — for education only.

Each condition resolves to true or false from data alone. None of them requires a person to look at a chart and decide whether it "qualifies."

Signal timing

A final daily close is not known until the session ends. A signal calculated from that close therefore cannot normally receive a fill at that same close — the price that triggered the decision did not exist while the market was still open to trade it. The exception is a strategy that specifically models a closing-auction process, where an order can be submitted before the close based on information available earlier in the session. Absent that, the conservative default is to execute at the next session's open.

This single timing issue invalidates a large share of amateur backtests. The signal value and the fill price often sit on the same row of the same table, and using both feels natural — which is exactly why the error survives so long unnoticed. The execution modeling guide covers fill assumptions once timing is settled.

Exit rules

An exit rule set can combine several structures at once:

Hypothetical example — for education only.

Exit when the close falls below the 20-day moving average. If no exit has fired after 30 sessions, exit regardless. Submit the order for a fill at the next session's open.

Stop-placement philosophy is covered in more depth in the stop-loss placement guide. It is written for crypto positions, but the underlying reasoning — placing a stop where the original thesis is invalidated rather than at an arbitrary distance from entry — transfers directly to stocks.

Position-sizing rules

Sizing is part of the strategy, not a reporting preference applied after the fact. Change the sizing method and the return, the drawdown, the portfolio's concentration, its turnover, and its risk of ruin all change too — from an identical set of entry and exit signals. Two backtests of the same entry and exit logic with different sizing are two different strategies wearing the same name.

The position sizing and risk-per-trade guide works through the arithmetic behind each of these.

Conflict rules

Signals compete, and the specification has to resolve what happens when they do:

If the answer to any of these is not coded, the backtesting engine will still make a decision. It just makes it through an accidental implementation detail — alphabetical ticker order, whatever row order the data happens to sit in, or whichever branch of an if-statement runs first — and that detail becomes part of the strategy's historical results without anyone having chosen it.

A Worked Example: From Vague Idea to Frozen Rule Set

The idea "buy stocks breaking out to new highs" sounds specific. It is not yet a rule set. Watch it tighten across several passes.

Hypothetical example — for education only.

Iteration 1 — the vague idea. "Buy stocks breaking out to new highs."

Iteration 2 — add a measurable trigger. "Buy when a stock's close is the highest close of the last 20 sessions." This still hides a self-reference problem: does "the last 20 sessions" include the session being tested? If today's close is one of the 20 values being compared against itself, every qualifying day trivially satisfies the rule. The window has to be defined as the 20 sessions preceding today, compared against today's close, with today excluded from inside the window.

Iteration 3 — add a universe and a liquidity floor. Restrict candidates to US-listed common stocks, primary listing, closing price of at least $5, 20-day median dollar volume of at least $10 million, at least 252 trading days of history, with ETFs, preferred shares, warrants, units, and over-the-counter listings excluded.

Iteration 4 — freeze the remaining components. Entry: today's close is the highest close of the prior 20 sessions, excluding today's close from that window, with 20-day average volume above 500,000 shares, no existing position, and fewer than 10 positions currently open. Signal timing: fill at the next session's open. Exit: close falls below the 20-day moving average, or 30 sessions elapse with no earlier exit, filled at the next open. Sizing: 5% of equity per position, whole shares only. Conflict resolution: rank qualifying stocks by how far the close sits above the 20-day high, take openings for the top-ranked names down the list until either the portfolio limit or available cash is reached, and skip a candidate rather than take a partial position if cash cannot cover the full target size.

Four iterations turned a slogan into a specification another person could code without asking a single question about what "breaking out" or "new highs" was supposed to mean.

Rules That Look Objective but Aren't

Some rules read as precise and are not. The words sound like measurements, but no measurement is actually defined.

The pattern in every rewrite is the same: replace a word that sounds like a measurement with the actual number, window, and comparison it was standing in for.

Common Mistakes

Limitations

An objective rule set removes hindsight and ambiguity. It does not, by itself, prove that the underlying hypothesis is real. A fully specified bad idea is still a bad idea — it is simply a testable one now, and testing it honestly is what a completed rule set makes possible.

Strategy Rules FAQs

What is the difference between a trading hypothesis and a trading rule?

A hypothesis explains why an edge might exist — a market mechanism, a behavioral pattern, or a structural constraint that could plausibly leave money on the table. A rule is the exact, computable instruction derived from that hypothesis: what to buy, when, how much, and when to exit. A rule without a hypothesis behind it can still be backtested, but there is no particular reason to expect the result to generalize beyond the sample it was found in.

Why do backtests fail even with correct code?

Because the code can only execute what the rules actually specify, and rules are often left implicitly subjective — a volume filter with no stated comparison window, a conflict between two signals with no stated resolution, an exit condition described in words rather than as a formula. The code runs without error and produces a number, but that number reflects whatever the engine did by default when the rule was silent, not what the strategy was intended to do.

What is signal timing and why does it matter?

Signal timing is the question of when an input became knowable versus when an order based on that input could first be filled. A signal calculated from a session's closing price is not knowable until that session has ended, so it normally cannot be filled at that same close. Getting this wrong is one of the most common ways a backtest quietly assumes information the strategy would not have had in real time.

How specific should an entry rule be?

Specific enough that two people, working independently from only the written rule, would flag the identical set of qualifying stocks on the identical set of dates. If two implementations could reasonably disagree about whether a condition is met, the rule still contains a subjective judgment call that needs to be replaced with a measurable threshold.

What happens if a rule doesn't cover every situation?

The backtesting engine still makes a decision — it just makes it through whatever default behavior the code happens to fall back on, such as processing tickers in alphabetical order or skipping a trade when cash runs short in a particular way. That default becomes part of the historical result without anyone having deliberately chosen it, and it may not behave the same way in a different implementation or in live trading.

Related Guides