Reality Check: Is the Golden Cross Worth Anything?
The claim
Section titled “The claim”When the 50-day moving average crosses above the 200-day moving average, a major uptrend has begun. This is the golden cross. The death cross — the same lines crossing the other way — marks the start of a downtrend.
It is the most widely reported technical signal in existence. It gets its own headlines in the financial press. It is also, as stated, untestable: “a major uptrend has begun” is not a claim with a truth value.
You now have every tool needed to fix that.
Step 1: make it objective
Section titled “Step 1: make it objective”From a headline to something a backtest can answer
- The claim as stated"A major uptrend has begun." No universe, no holding period, no comparison, no costs. Nothing to test.
- Make the rule mechanicalBuy when MA(Close,50) crosses above MA(Close,200). Sell when it crosses back. Long only. No stops, no filters, no discretion.
- Fix the universe and periodA stated watch list, a liquidity floor, a stated date range. Write all three down before running anything.
- Choose a fair benchmarkPassive ownership of the SAME names over the SAME period paying the SAME costs. Not an index.
- Decide what would count as an answerBefore you look: what difference in Risk Adjusted Return, over what period, would change your mind?
The rule is easy to make mechanical, which is part of why it is so popular:
Fragment — not a complete formula
Buy = Cross( MA( Close, 50 ), MA( Close, 200 ) );Sell = Cross( MA( Close, 200 ), MA( Close, 50 ) );Note what this specification excludes, deliberately: no stops, no profit targets, no regime filter, no position-sizing cleverness. If we add those, we are testing “the golden cross plus four other ideas” and we will not know which part did the work.
Step 2: the benchmark question, which is where most tests go wrong
Section titled “Step 2: the benchmark question, which is where most tests go wrong”A strategy result on its own is uninterpretable. It has to be compared with something. The question is what.
The obvious answer — compare against a major index — is wrong, and wrong in a way that is easy to miss. If your strategy trades thirty mid-cap shares and your benchmark is a large-cap index, then the difference between them measures the difference between two universes at least as much as it measures the strategy. Beat the index and you may have discovered nothing more than that mid-caps outperformed over your period.
The benchmark that isolates the rule is passive ownership of the very same names, over the very same period, paying the very same frictions.
Complete runnable AFL
// equal-weight-benchmark.afl// Part 28 - Reality Check: Is the Golden Cross Worth Anything?//// The benchmark the golden-cross test has to beat: buy every eligible member of// the SAME universe as early as it becomes eligible, in equal weight, pay the// SAME costs, and hold to the end of the SAME range.//// WHY NOT JUST USE AN INDEX. Comparing a strategy that trades thirty mid-cap// stocks against a large-cap index measures the difference between two// universes at least as much as it measures the strategy. The only benchmark// that isolates the RULE is passive ownership of the very same names over the// very same period with the very same frictions.//// ============================ ASSUMPTIONS ==================================// Universe Must be the identical watch list, range, periodicity and// liquidity floor as golden-cross-portfolio.afl.// Entry The first bar on which a symbol passes the liquidity floor// and is inside the analysis range; filled at the next bar's// open, with the same slippage.// Exit None. The portfolio backtester closes any position still open// at the end of the range, at the closing price.// Weighting 100 / NamesHeld percent of portfolio equity per position.// Symbols that become eligible later are bought at that same// percentage of a LATER equity figure, so the weights are equal// at purchase, not equal forever. There is no rebalancing.// Costs Same commission and slippage as the strategy. Buy-and-hold// pays them once each way; that asymmetry is the whole// economic argument against trading, so do not remove it.// Financing No interest, no dividends. Excluding dividends understates a// buy-and-hold benchmark's return, and it understates the// strategy's too whenever the strategy was holding. Say so// whenever you quote either number.// ===========================================================================
// --------------------------------------------------------- 1. the parametersNamesHeld = 10; // set to the number of positions you want heldStartingEquity = 100000;SlippagePercent = 0.05;CommissionPercent = 0.10;
MinTurnover = 2000000;MinPriceLevel = 2;
// ----------------------------------------------------------- 2. the accountSetOption( "InitialEquity", StartingEquity );SetOption( "MaxOpenPositions", NamesHeld );SetOption( "AllowPositionShrinking", True );SetOption( "MinPosValue", 1000 );SetOption( "AccountMargin", 100 );SetOption( "InterestRate", 0 );SetOption( "CommissionMode", 1 );SetOption( "CommissionAmount", CommissionPercent );
RoundLotSize = 1;SetBacktestMode( backtestRegular );SetPositionSize( 100 / NamesHeld, spsPercentOfEquity );SetTradeDelays( 1, 1, 1, 1 );
BuyPrice = Open * ( 1 + SlippagePercent / 100 );SellPrice = Open * ( 1 - SlippagePercent / 100 );ShortPrice = Open * ( 1 - SlippagePercent / 100 );CoverPrice = Open * ( 1 + SlippagePercent / 100 );
// ----------------------------------------------------------- 3. the universeTurnover = MA( Close * Volume, 50 );Tradeable = Turnover >= MinTurnover AND Close >= MinPriceLevel AND Volume > 0;
// -------------------------------------------------------- 4. buy once, hold// Eligible bars are those inside the analysis range that also pass the floor.// The first of them, and only the first, produces a signal.Eligible = Tradeable AND Status( "barinrange" );BarsSoFar = Cum( Eligible );
Buy = Eligible AND Nz( Ref( BarsSoFar, -1 ), 0 ) == 0;Sell = 0; // held to the end; the backtester closes it at the final close
// -------------------------------------------------------------- 5. the rank// Identical to the strategy's rank, so that if the universe is larger than// NamesHeld the same names are chosen by the same criterion.PositionScore = Turnover;
// -------------------------------------------------------- 6. what to record// The same list as the strategy: number of trades, Exposure %, Annual Return %,// Risk Adjusted Return %, Max. system % drawdown, CAR/MaxDD, Avg. Bars Held.// Exposure % here will be close to 100, and that is the point of recording it:// a strategy that is in the market half the time is not directly comparable on// return alone, which is exactly what Risk Adjusted Return % is for.Buy each eligible member of the same universe as soon as it becomes eligible, in equal weight, and hold to the end of the range. The portfolio backtester closes anything still open at the final close.
Step 3: the strategy formula
Section titled “Step 3: the strategy formula”Complete runnable AFL
// golden-cross-portfolio.afl// Part 28 - Reality Check: Is the Golden Cross Worth Anything?//// The claim under test, made objective: buy when a symbol's FastPeriod-bar// simple moving average of closing prices crosses above its SlowPeriod-bar// simple moving average; sell when it crosses back below. Long only. No stops,// no targets, no filters, no discretion, nothing else.//// Run it as a portfolio BACKTEST at the default 50/200 first. Then run it as an// OPTIMIZATION over both periods to see the whole surface, because a claim that// only survives at one pair of numbers is a claim about those numbers.//// ============================ ASSUMPTIONS ==================================// Universe The watch list you point the Analysis window at. Write down// how it was built. If it is today's index membership, the test// is contaminated by survivorship and cannot be repaired here.// Period The Range you set. Quote it every time you quote a result.// Averages Simple, on closing prices, on daily bars. Neither average is// defined until it has its full look-back, so no signal can// occur in the first SlowPeriod bars of a symbol's history.// Fill price Next bar's open, moved against us by SlippagePercent.// Commission CommissionPercent of trade value, entry and exit.// Sizing Equal weight across PosQty slots, from portfolio equity.// Selection When candidates outnumber slots, the most liquid wins. This// must match the benchmark formula exactly or the comparison is// between two different universes.// Financing No interest, no borrow, no dividends.// ===========================================================================//// This produces one number from one history. It is not an expected return, it// does not establish that the rule works, and it does not establish that it// fails. It is one observation, and the lesson explains how much weight one// observation can carry.
// --------------------------------------------------------- 1. the parameters// Defaults are the popular specification. The ranges exist so that the same// formula answers the far more interesting question: does anything special// happen AT 50 and 200, or is the surface flat?FastPeriod = Optimize( "Fast MA period", 50, 20, 90, 10 );SlowPeriod = Optimize( "Slow MA period", 200, 100, 250, 25 );
PosQty = 10;StartingEquity = 100000;SlippagePercent = 0.05;CommissionPercent = 0.10;
MinTurnover = 2000000;MinPriceLevel = 2;
// ----------------------------------------------------------- 2. the accountSetOption( "InitialEquity", StartingEquity );SetOption( "MaxOpenPositions", PosQty );SetOption( "AllowPositionShrinking", True );SetOption( "MinPosValue", 1000 );SetOption( "AccountMargin", 100 );SetOption( "InterestRate", 0 );SetOption( "CommissionMode", 1 );SetOption( "CommissionAmount", CommissionPercent );
RoundLotSize = 1;SetBacktestMode( backtestRegular );SetPositionSize( 100 / PosQty, spsPercentOfEquity );SetTradeDelays( 1, 1, 1, 1 );
BuyPrice = Open * ( 1 + SlippagePercent / 100 );SellPrice = Open * ( 1 - SlippagePercent / 100 );ShortPrice = Open * ( 1 - SlippagePercent / 100 );CoverPrice = Open * ( 1 + SlippagePercent / 100 );
// ----------------------------------------------------------- 3. the universe// Identical to the benchmark formula, deliberately. A benchmark measured over a// different set of symbols is not a benchmark.Turnover = MA( Close * Volume, 50 );Tradeable = Turnover >= MinTurnover AND Close >= MinPriceLevel AND Volume > 0;
// -------------------------------------------------------------- 4. the ruleFastMa = MA( Close, FastPeriod );SlowMa = MA( Close, SlowPeriod );
Buy = Cross( FastMa, SlowMa ) AND Tradeable;Sell = Cross( SlowMa, FastMa );
// A fast average that is not faster than the slow one describes nothing. Rather// than let such combinations produce a meaningless row in the optimization// table, silence them: they will appear with no trades at all.if( SlowPeriod <= FastPeriod ){ Buy = 0; Sell = 0;}
// -------------------------------------------------------------- 5. the rankPositionScore = Turnover;
// -------------------------------------------------------- 6. what to record// For the 50/200 run write down, from the report: number of trades, Exposure %,// Annual Return %, Risk Adjusted Return %, Max. system % drawdown, CAR/MaxDD,// Avg. Bars Held and Winners percentage. Then record the SAME list from the// benchmark formula, over the same universe, range and costs. A single one of// those numbers on its own settles nothing.The periods are wrapped in Optimize() for step 5. At the defaults it is exactly the popular
specification: 50 and 200.
One small piece of hygiene worth copying:
Fragment — not a complete formula
if( SlowPeriod <= FastPeriod ){ Buy = 0; Sell = 0;}A “fast” average that is not faster than the slow one describes nothing. Silencing those combinations keeps meaningless rows out of the optimization table rather than leaving you to spot them.
Step 4: run the pair and record everything
Section titled “Step 4: run the pair and record everything”Run both formulas over the identical watch list, range, periodicity, costs and slot count. Record this list from each report:
| Golden cross | Equal-weight buy and hold | |
|---|---|---|
| Number of trades | ||
| Exposure % | ||
| Annual Return % | ||
| Risk Adjusted Return % | ||
| Max. system % drawdown | ||
| CAR/MaxDD | ||
| Avg. Bars Held | ||
| Winners % | ||
| Total commissions paid |
Step 5: sensitivity to the period choice
Section titled “Step 5: sensitivity to the period choice”Here is the question that the headlines never ask: is there anything special about 50 and 200?
Run the strategy as an Optimization over both period ranges and look at the whole surface, not the best cell.
You are looking for one of three shapes:
A broad plateau. Neighbouring parameter pairs give similar results, and 50/200 sits somewhere inside a wide region that all behaves alike. This is the encouraging shape — it suggests you are looking at a property of trend-following in general rather than at an artefact of two numbers.
A single spike. 50/200 looks good and 40/180 and 60/220 do not. This is the discouraging shape, and it is what curve fitting looks like from the outside. A result that exists only at one parameter pair is a result about that pair.
A flat, uninteresting surface. Everything looks about the same, and about the same as the benchmark. This is the most common shape, and it is a perfectly good answer.
Step 6: read the evidence without wishful thinking
Section titled “Step 6: read the evidence without wishful thinking”Four questions, in this order. Answer each in writing before moving to the next.
Did the strategy beat the matched benchmark on Risk Adjusted Return, after identical costs? Not on annual return. Not against an index. Against the same names with the same frictions.
By how much, relative to how noisy the comparison is? You have one number from one history. If the gap is a fraction of the year-to-year variation in either series, you cannot distinguish it from luck by looking at it.
Is the drawdown behaviour different? This one is often more interesting than the return. A trend rule that is out of the market during declines may deliver a similar return with a materially smaller maximum drawdown — and if so, the return comparison was the wrong question all along.
Would the conclusion survive doubling the costs? Run the sensitivity sweep from the costs lesson. A conclusion that flips inside your own cost uncertainty is not a conclusion.
Step 7: what this result does and does not license
Section titled “Step 7: what this result does and does not license”It does not establish that the golden cross “works”. One period, one universe, one specification, one parameter pair, no dividends, survivorship in the universe, and a benchmark that is itself a choice.
It does not establish that it fails, either. A rule that matches a benchmark’s return with lower exposure and a smaller drawdown has done something, even if it did not beat the headline number.
It does say something about the popular version of the claim. The claim as reported — “a major uptrend has begun” — implies the signal identifies something exceptional. If your test shows the rule performing much like passive ownership of the same names, then whatever the crossing identifies, it is not exceptional enough to separate itself from simply owning the things.
And it says something about how the claim is normally presented. Every published golden-cross statistic you will read specifies the universe imprecisely, the costs not at all, and the benchmark rarely. You now know that all three change the answer.
The golden cross becomes testable the moment you replace “a major uptrend has begun” with a mechanical rule, a stated universe, a stated period, stated costs and a matched benchmark. The benchmark is the part most tests get wrong: comparing against an index measures the difference between universes, so the benchmark must be passive ownership of the same names paying the same frictions. Exposure is read before return, and Risk Adjusted Return is the figure built for comparing two systems that are in the market for different fractions of the time. The parameter surface tells you whether you have found a property or a coincidence. And after all of that you have one observation, which is exactly as much as one observation is worth.
Check your understanding
Sources for this lesson
5 verified · checked 2026-08-31
- 01AmiBroker User's Guide — Portfolio-level backtestingamibroker.com/guide/h_portfolio.html2026-08-31
- 02AmiBroker User's Guide — Backtest report§ Risk Adjusted Return, Exposureamibroker.com/guide/w_report.html2026-08-31
- 03AFL Function Reference — Optimizeamibroker.com/guide/afl/optimize.html2026-08-31
- 04AFL Function Reference — MAamibroker.com/guide/afl/ma.html2026-08-31
- 05AFL Function Reference — Crossamibroker.com/guide/afl/cross.html2026-08-31
Every technical claim on this page was checked against the official AmiBroker documentation on the date shown. Where the course disagrees with folklore, the source is how you can tell which one to trust.