Learn › EAs and automated trading

Test Your Entry Against Random Entries: Does Your Signal Beat a Coin Flip?

Backtest profit can come from your exits and the market's trend, not your entry. How to compare with 1,000 random-entry runs, get a p-value, and build a fair placebo.

Advanced 12 min read 22 October 2026

What you will learn
  • The test keeps the same exits and the same number of trades, randomises the entry times 1,000 times, and asks where the real result falls in that spread
  • A do-it-yourself p-value = (random runs that did as well or better + 1) ÷ (number of runs + 1)
  • In a trending market, a buy-only system must be compared with random buys, not coin flips, or you will see a fake edge
  • In our simulation, coin-flip direction with a trailing stop looked just like a trend-following system, yet its expectancy was exactly minus the cost
  • A good control matches the real signal in everything (direction, time of day, distance, cost) except the part that is supposed to be the edge

Profit in a backtest doesn’t tell you that your entry is good. It is the sum of several things: the entry, the exit, the position size, the overall direction of the market during the test, and luck. A random entry benchmark isolates the entry by keeping everything else exactly the same and changing only the entry times to random ones. If random entries do about as well, your signal adds nothing. This article walks through the method step by step, with simulations that show where the traps are.

Profit has 5 sources, and the entry is only one

  1. Entry. What the signal claims to do: pick moments when price tends to move in the direction you open.
  2. Exit. A trailing stop that lets winners run, or a near TP with a far SL that wins often, can change the shape of results a lot without guessing direction at all.
  3. Position size. Adding size after losses, or compounding, changes how the equity curve looks even when the entry has no information.
  4. Market drift. If price rose over the whole test, almost any buy-only system looks good.
  5. Luck. A few hundred trades swing far more than most people expect. Read more in How many trades before you can trust a result.

Random entries that use the same exit, position size, direction and data period get sources 2–5 in full. They are missing only source 1. So the gap between the real result and the random results is what the entry actually does.

The method, step by step

  1. Record the real result. The number of trades N and the total in R (1R = the money risked per trade, so risking 50 dollars to make 100 dollars = +2R). Using R keeps position size out of the picture.
  2. Lock everything that isn’t the entry. Exit, SL, TP, maximum holding time, costs, direction (or the buy/sell mix), and the rule for overlapping trades.
  3. Pick N random entry times from the same data period, work out each trade’s result with the same exit, and add them up for that run.
  4. Repeat 1,000 times. You get 1,000 totals, a picture of how results spread when there is no signal.
  5. See where the real result falls. Count how many random runs did as well as or better than the real result.

p-value = (random runs ≥ real result + 1) ÷ (number of runs + 1)

The +1 on both sides counts the real result as one of the possibilities, and stops you getting p = 0, which a finite number of runs can’t prove. If 746 of 1,000 runs did as well or better, p = 747 ÷ 1,001 = 0.746: random entries do this well about three times in four. If no run gets there, p = 1 ÷ 1,001 ≈ 0.001. The usual threshold is 0.05, but if you have tried many signals you need to be much stricter. The reason is in Data snooping.

Simulated example: a breakout that made +143R, with no help from the entry

We built a price series in code (not a real market) of 10,000 bars. Each bar moves randomly with a standard deviation of 1 point, plus a small upward drift of 0.03 points per bar. Over the whole series price rises from 1,000 to 1,411, like a long bull market. The system:

  • Entry: the close makes a new 20-bar high (a breakout). Buy only, at least 20 bars between signals
  • Exit: a trailing stop 10 points below the highest close since entry (10 points = 1R), held for at most 500 bars
  • Cost: 0.05R per trade. Each trade is measured on its own

The real result is 267 trades, 51.3% winners, +142.9R in total. Looks great. Then we picked 267 random entry times on the same series, with the same exit, 1,000 times, in two versions: random buys (same direction as the system) and coin flips (buy or sell at random).

Random buys, same direction: mean +161R · p = 0.746 Coin flip buy/sell: mean +22R · p ≈ 0.001 Actual breakout +143R −50050100150200250 Total (R) of 267 trades per run
Simulated data, not a real market: a random price series of 10,000 bars with a slight upward drift. Each bar in the chart counts runs of 267 random entries using the system's exit (1,000 runs per version). The red line is the real breakout result.

Against coin flips, no run reaches +142.9R, so p ≈ 0.001 and it looks like a clear edge. Against random buys, 746 of 1,000 runs do as well or better, so p = 0.746. Random buys average +161.1R, more than the breakout. All the profit comes from holding buys in a rising market, not from choosing when to enter. And in this series the breakout truly has no information, because the price is pure randomness.

To avoid picking a flattering series, we built five of them. Against random buys, p was 0.24–0.86 every time, and the breakout result was within about one standard deviation of the random-buy average in each series. When the series rose a lot, the breakout made a lot. When it rose a little, the breakout made a little.

The trend trap: compare with the wrong thing and the p-value is wrong

The example above is the most common trap. A buy-only system on gold while gold rallies hard, or a buy-only system on Bitcoin in a bull run, always looks skilled against zero or against a coin flip. The rule: the control must have the same direction as the system. A buy-only system is compared with random buys. A system that is 60% buys and 40% sells is compared with random entries that are also 60% buys and 40% sells.

The beauty of random buys is that they get exactly the same market direction as the system, so whatever gap is left belongs to the entry alone. And if a system beats random buys only because the trend in that period was unusually strong, you still need to check whether it also wins in years without a trend. Read more about markets changing character in Market regime change.

What do coin flips with a trailing stop get you?

There is an old belief that “you can enter on a coin flip, as long as your exit is good.” We simulated it directly on random price with no drift at all: 1,000 separate series of 10,000 bars, one per “trader”, 1,000 traders taking 200 trades each, choosing buy or sell by coin flip and exiting with the same 1R trailing stop as above, minus 0.05R cost.

  • 35.0% winners, average win +1.12R, average loss −0.68R
  • Wins are 1.12 ÷ 0.68 = 1.65 times the size of losses, which looks like a typical trend-following system
  • The break-even win rate at that ratio is 1 ÷ (1 + 1.65) = 37.8%, but the win rate is only 35.0%, below break-even
  • Expectancy per trade is −0.052R, almost exactly the 0.05R cost we charged
713 traders lose 287 profit · best +86R Mean −10.4R −80−60−40−20020406080 Total (R) of 200 trades per trader
Simulated data, not a real market: 1,000 traders, each trading their own random price series with no drift, choosing direction by coin flip and exiting with a trailing stop, minus 0.05R cost per trade. Red is a loss, green is a profit.

A trailing stop really does change the shape of results: many small losses, a few large wins. But it doesn’t create expectancy by itself. On driftless price the result is break-even before costs and a loss equal to the costs after. The striking part: 287 of the 1,000 traders were still in profit after 200 trades, 103 made +20R or more, and the best made +86.4R. If those traders sold signals, their track records would look convincing.

Add drift, though (the same +0.03 points per bar as the first example), and coin flips with a trailing stop earn +0.03R per trade, with 54.1% of traders in profit. Buys get to ride the trend while sells are stopped out quickly. That is the exit and the trend working together, not the entry, and it disappears as soon as the trend does. To compare trailing stop styles, read Trailing stop methods compared.

More ways exits and sizing make random entries look good

  • Near TP, far SL. On driftless price, the chance of hitting TP first = SL distance ÷ (SL distance + TP distance). A TP of 1.3 with an SL of 26 wins about 95% with random entries. In our backtest, a breakout system on gold (2026, real tick data) won 92.8–95.8%, while random entries with the same distances won 95.3%. Details in Win rate vs break-even
  • Adding size after losses. Martingale makes almost every “cycle” end in profit whatever the entry, until one cycle runs longer than the account. See Grid and Martingale
  • Compounding and sizing by balance. These bend the equity curve upward in good periods, but don’t change whether the entry carries information

The fix is to measure both the real system and the control in R at a fixed risk per trade, and deal with position sizing afterwards.

Building a fair control

A control, or placebo, is a fake that matches the real signal in every way except the part that is supposed to be the edge. If the control differs in other ways too, any gap you see comes from those differences instead.

  1. Same direction, or the same buy/sell mix
  2. Same number of trades and the same overlap rule. If the system holds one trade at a time, so does the control
  3. Same time of day. If the system only enters between 14:00 and 17:00 Thai time (UTC+7), draw random times only from that window, because volatility and spread vary a lot by hour. See Forex market hours
  4. Same distance and depth. If you test whether price bounces at the 61.8 level of a Fibonacci retracement, don’t compare it with a flat 50%. Compare it with fake levels nearby at a similar depth, because in our backtests the deeper the pullback, the more often price bounced, whether or not the level was a Fibonacci one
  5. Same costs. Use the spread at the actual entry time, not the daily average

A control that doesn’t match can produce a very strong fake result. In one of our backtests (gold, M1 bars, 06:00–09:00 Thai time, July 2022 to September 2026, 192,728 bars) we measured whether price sat at Fibonacci levels more often than chance. The first control used Fibonacci levels from a time-shifted window that had nothing to do with current price. Against it, the real levels looked 1.8–2.0 times “better”. When we switched the control to the depth distribution from the same data, the ratio dropped to 0.95–1.00, no different from chance.

If a system beats its control by a mile, suspect the control first: does it differ from the real thing in some other way?

In our backtests

Our research on gold (XAUUSD) uses a control almost every time. Examples confirmed in the original files:

① Level 261.8 of 10 older swings: bounced first ② Level 78.6 of a Fibonacci drawn across 2 swings: bounced first ③ Morning box closes at its top, breaks up first (control: afternoon box) ④ N-bar box breaks out and keeps going (control: random) SignalControl SignalControl SignalControl SignalControl 41%42% 50%50% 79%76% 56%50%
Backtest results on gold, which do not predict future results. ①–③ are not meaningfully different from their controls. ④ is the only pair that clearly beats its control (2026 data only), and it has not yet been shown to make money after spread.
  1. Fibonacci levels of older swings. We once saw price reverse exactly at the 261.8 level of the previous swing, so we measured every touch of the levels of the 10 previous large swings, about 241,000 touches (1-minute bars, roughly 2022–2026), against fake levels placed every 10% nearby. Level 261.8 bounced 41%, the fake levels 42%. No Fibonacci level bounced meaningfully more often than the fakes
  2. Fibonacci drawn across 2 swings. At 78.6 it bounced 50%, against 50% for neighbouring levels, and 46–51% in every single year (1-minute bars, January 2022 to August 2026)
  3. Morning box, 06:30–08:30 Thai time. If price closes the box at its top edge, it breaks up first 79% of the time. Sounds precise, but the same box shape from 13:30–15:30 gets 76%. Most of it comes from price already sitting near the top edge, not from anything special about the morning (about 1,000 days, 2022–2026). This is a “same shape, different time” control
  4. Box breakouts that keep going. Boxes of 20, 40 and 89 M1 bars kept going after a breakout 56% of the time against 50% for random, at every box size, with 7,800–25,000 cases each (2026). This pair clearly beats its control, but “different in the statistics” is not the same as “makes money”. It still needs testing as a full system with real spread

And a real example of the trend trap. We tested one trade a day at 06:30 Thai time with 7 ways of choosing direction (SL 5 dollars, TP 30 dollars, 0.10 lot, 10,000-dollar balance) against two controls: “buy every day” and “sell every day”. The best rules made roughly +5,700 to +5,900 dollars over 5 years, close to what “buy every day” made when entering at 07:00 (+5,408). No rule beat both controls in more than 2 of the 5 years. The standard error of a 5-year total was about ±4,500 dollars, and every total was within twice that, so none can be told apart from luck. Gold rose strongly over that period, so the best rules earned about what buying every day earned, not anything from choosing direction.

Data conditions: in the multi-year results above, 2022–2025 come from 1-minute bars or ticks generated from 1-minute bars. Only 2026 uses real tick data. These are all backtest results. Past results do not predict future results.

What passing and failing mean

  • It tests only the entry, under this exit, on this price history. To check whether the exit is any good, do the reverse: keep the entries and compare with random exits or a fixed-time exit
  • You need enough trades. In the breakout example with 267 trades, the top 5% of random buys starts at +204.1R, 43.8R above the median (+160.3R). The entry would need to add about 43.8 ÷ 267 = 0.16R per trade to pass at 0.05. A smaller edge can be real but invisible
  • Trying many signals and keeping the one that passes breaks the p-value of the winner. The threshold has to rise with the number of things you tried
  • It is not Monte Carlo. Monte Carlo reshuffles your existing trades to look at risk, while this test replaces the entries to look for an edge. Do both

Try it on your own system

If you can code, the core is short. The hard parts are the function that applies your exact exit, and drawing random bars only from the times your system is allowed to enter.

// entries = bars where the system really entered, resultR(i, dir) = R result of entering at bar i with the same exit
const real = entries.reduce((s, i) => s + resultR(i, +1), 0);
let atLeast = 0;
for (let k = 0; k < 1000; k++) {
  let sum = 0;
  for (let t = 0; t < entries.length; t++) {
    const i = randomAllowedBar(); // same hours, same data period
    sum += resultR(i, +1);        // same direction as the system
  }
  if (sum >= real) atLeast++;
}
const p = (atLeast + 1) / 1001;

If you don’t code, a rough manual version works: record the real entry price and time of every trade, then draw 20–30 sets of random entry times from the same window and work them out with the same exit. It is crude, but if the real result sits in the middle of the random pile, you already have your answer.

Common mistakes

  • Comparing a buy-only system with zero or a coin flip. In a rising market, nearly every buy system beats a coin flip. Compare with random buys
  • Giving the control a different exit or cost. For example, a control with no trailing stop, or a daily-average spread. The gap then comes from the exit or the cost
  • Drawing random times from the whole day when the system trades only certain hours. Hours with different volatility give different results by themselves. Draw from the same hours
  • Running one random set and drawing a conclusion. A single random run swings a lot. You need the spread of hundreds to a thousand runs
  • Pointing at a chart example that worked instead of counting every case. With enough lines on screen, one will always line up with a reversal. Count every touch and compare with fake levels. Read more in Hindsight bias

Frequently asked questions

How is this different from a Monte Carlo reshuffle?

Monte Carlo takes your existing trades and reshuffles or resamples them to see the range of drawdowns and risk, assuming those trades are real. The random-entry test replaces every entry with a random time to ask whether your entry carries any information at all. They answer different questions, so do both.

How many random runs are enough?

1,000 runs is enough to see whether the real result sits in the middle or the tail of the spread. The smallest p-value you can measure is about 1 ÷ 1,001. To separate very small values such as 0.001 from 0.0001 you need tens of thousands of runs, but the real problem is rarely the number of runs. It is usually a control that doesn't match the signal.

My system failed this test. Should I throw it away?

It means the entry adds nothing you can measure on this data. If the system still makes money, that money comes from the exit, the market's trend, or luck, and you should know which. If it comes from the trend, the result ends when the trend ends. And if the entry doesn't help, a simpler buying rule may do just as well with less complexity.

This is general education, not investment advice. Trading is risky and you may lose all of your capital.

Tools Chat on LINE