Study
Study 01: the 9/20 EMA crossover on daily EUR/USD, with a registered protocol and a trial log
Answer first
We registered the protocol on October 12, 2026, before downloading the price series, then ran the four configurations it declared (EMA 9/20, 9/21, 12/26 and 50/200) on 5,958 daily EUR/USD fixings, from 2002-12-24 to 2026-09-30, with spread and swap. The 9/20 rule finished with an annualized Sharpe of 0.136; discounted for the four trials, its Deflated Sharpe Ratio (DSR) came in at 0.619, below the 0.95 set in advance, so the study's hypothesis is discarded. As a secondary reading that decides nothing, the probability of backtest overfitting (PBO) across the four configurations came in at 0.787.
Registered protocol
The protocol sets the hypothesis, rules, data, costs, metrics and discard criterion before anything runs. Its sha256 fingerprint was posted on X on 2026-10-12 at 15:00 UTC (registration post):
ed02a661f8083632137b667f17e3bc4d92121bad356fe413fde356cbb12e22e1
The file is published in full with this study, byte for byte (protocolo-v0_4.md). The registered text is in Spanish; change a single character and the fingerprint changes. The protocol also states what was looked at before registration: the sources' terms-of-use and description pages; the ECB's and the Federal Reserve's public rate tables; a few rows of the H.10 historical euro page (January 2000 and October–November 2002, the latter inside the warm-up) while checking its format; a broker's charges page and help article; and two public scripts of the rule on a charting platform. The series had not been downloaded and no average, signal or metric had been computed.
| Item | What the protocol sets |
|---|---|
| Hypothesis (H1) | The canonical 9/20 EMA crossover produces, under the base cost scenario, a Sharpe whose DSR is 0.95 or higher |
| Instrument and data | Daily EUR/USD: the New York noon fixing published by the Federal Reserve (H.10 release), 1999-01-04 to 2026-09-30 |
| Rules | Long and short; a signal detected on bar t executes on bar t + 1; each signal closes the open position and opens the opposite one; no filters, stops or targets; 1× exposure rebalanced every bar |
| Warm-up | Bars 1 to 1,000 only compute the averages; evaluation starts on bar 1,001, the same for all four variants |
| Base costs | 2 pips of spread per side; swap from the ECB deposit rate and the Fed target, minus a 1.0% annual margin against the position; zero commission; taxes not modeled |
| Sensitivity | Low scenario (1 pip; 0.5%) and high (4 pips; 2.0%): reported, decide nothing |
| Discard criterion | H1 is discarded if variant 1's DSR under the base scenario is below 0.95, evaluated at full precision |
| Publication | The result is published whatever it is |
Data
The five files were downloaded once, on 2026-10-22, and are kept unmodified: the euro series from the Federal Reserve's Data Download Program, the H.10 historical euro page (as a cross-check only), the two FOMC decision pages and the deposit-rate series from the ECB Data Portal. A dated data annex records each file's URL, download time, size and sha256, plus the counts and anomalies. Its fingerprint was posted on X on 2026-10-23 at 17:47 UTC, in the same thread as the registration (data seal), before the study's first run (2026-10-29):
debb30d7ae5960c6d0859d25309e058c253c72e3fed2d90aee29c0b447528a0f
The annex also has an OpenTimestamps receipt (anexo-datos-2026-10-22.md.ots), verifiable with ots verify.
| Item | Value |
|---|---|
| Bars (numeric fixings through 2026-09-30) | 6,958 |
| "ND" days (no data), left out of every calculation | 280 |
| Bar 1,001 (evaluation start) | 2002-12-24 |
| Last bar | 2026-09-30 |
| Returns evaluated (T) | 5,958 |
| Cross-check against the historical page | 0 differences across 6,706 dates |
Two anomalies were written into the annex before the run: the FOMC archive page doesn't name the rate in its column (it is identified through the link and header of the current page), and from 2008-12-16 the target is a range, from which the code takes the midpoint. The FOMC table also carries a date corrected by the source itself ("March 4*": March 4, 2020, previously listed as March 3); the code uses the corrected date. Reviewing the result, we found that several dates in that table are the day after the meeting (for example, 2015-12-17 for the December 16 decision), while the protocol assumes the decision date; under its rule ("date before t"), those rates take effect one fixing later. The registered rule was applied. Under an "on or before" rule, variant 1's annualized Sharpe would move from 0.1357 to 0.1358 (log, row 5).
Federal Reserve data are in the public domain, and ECB statistics may be reused with attribution. That is why all five files are published as they are.
Trial log
The log uses the five columns from How to count your trials: number, date, what changed, what in the previous result led to the change, and which result was looked at. All four variants were declared in the protocol before running, and nothing else was run.
| No. | Date | What changed | Why | Result looked at (base scenario) |
|---|---|---|---|---|
| 0 | 2026-10-08 | The instrument moved from the BTCUSDT perpetual (drafts v0.1–v0.3) to EUR/USD | None of the BTC price sources reviewed had terms expressly allowing a commercial firm to publish derived results without a written license | None: nothing was downloaded or run. Not counted as a trial |
| 1 | 2026-10-29 | EMA 9/20 (H1) | Declared in the protocol before running | Sharpe 0.136 · kept |
| 2 | 2026-10-29 | EMA 9/21 | Declared in the protocol before running | Sharpe 0.133 · kept |
| 3 | 2026-10-29 | EMA 12/26 | Declared in the protocol before running | Sharpe 0.078 · kept |
| 4 | 2026-10-29 | EMA 50/200 | Declared in the protocol before running | Sharpe −0.013 · kept |
| 5 | 2026-10-29 | FOMC dating convention: "on or before" instead of "before", as a check only | The FOMC table lists dates the day after the meeting | Variant 1: Sharpe 0.1358 vs 0.1357 · discarded; not a configuration of the rule, not counted in n_trials |
n_trials = 4. Rows 1 to 4: the configurations of the rule with a result looked at. Row 5, cost scenarios, attribution runs and the reference are not trials. No configuration was rerun because of a code error.
Result
The four variants under the base scenario, on the same 5,958 returns:
| Variant | Annualized Sharpe | Total return | Max drawdown | Executions |
|---|---|---|---|---|
| 1 · EMA 9/20 | 0.136 | 21.2% | 32.5% | 251 |
| 2 · EMA 9/21 | 0.133 | 20.5% | 28.6% | 249 |
| 3 · EMA 12/26 | 0.078 | 7.2% | 30.9% | 193 |
| 4 · EMA 50/200 | −0.013 | −11.5% | 36.8% | 37 |
Chart. Equity curve of the four variants, base scenario, from 2002-12-23 (bar 1,000, capital = 1) to 2026-09-30.
The discount for four trials (DSR). Variant 1's per-bar Sharpe is 0.00855 (0.136 annualized). The SR₀ threshold, the highest Sharpe you would expect among four configurations whose true Sharpe is zero, given how spread out they are, is 0.00462 per bar (0.073 annualized). Returns show skewness of 0.103 and kurtosis of 6.01 (a normal distribution would give 3): fat tails. The DSR formula accounts for them, but at such a small per-bar Sharpe their effect is negligible. Variant 1 was designated before running; it is still discounted as if it had been picked among the four (the protocol's conservative criterion). With T = 5,958, the DSR is 0.619. The criterion asked for 0.95: H1 is discarded.
The PSR against zero, the same formula without the trial discount, is 0.745. So the rule doesn't reach 0.95 even before the discount: at this Sharpe level, 23.8 years of daily data aren't enough to tell it apart from statistical noise.
Probability of backtest overfitting (PBO). The 5,952 most recent returns are split into 16 contiguous blocks of 372 returns (about 18 months each), and the study walks through all 12,870 ways to pick 8 blocks as the fitting sample and keep 8 as the test. In each one, the configuration with the best Sharpe in the fitting sample gets its rank in the test:
| Rank of the in-sample winner in the test | Combinations | Share |
|---|---|---|
| 4th (worst) | 5,870 | 45.6% |
| 3rd | 4,264 | 33.1% |
| 2nd | 2,516 | 19.5% |
| 1st (best) | 220 | 1.7% |
In 78.7% of the combinations, the configuration that won the fitting sample landed in the bottom half outside it: PBO = 0.787. Only in 1.7% was the in-sample winner also the best in the test.
Costs. For variant 1, the same run without spread ends at 31.7% and without swap at 55.4%, against 21.2% with both. Swap weighs more than spread: with the position open almost the whole window, the 1.0% annual margin is paid for every day the position stays open, long or short.
| Scenario | Sharpe 9/20 | Sharpe 9/21 | Sharpe 12/26 | Sharpe 50/200 | Variant 1 DSR |
|---|---|---|---|---|---|
| Low (1 pip; 0.5%) | 0.213 | 0.210 | 0.150 | 0.047 | 0.738 |
| Base (2 pips; 1.0%) | 0.136 | 0.133 | 0.078 | −0.013 | 0.619 |
| High (4 pips; 2.0%) | −0.018 | −0.020 | −0.067 | −0.133 | 0.358 |
Even with low costs the DSR doesn't reach 0.95. With high costs, all four variants end with a negative Sharpe.
When it was earned. Variant 1's curve peaked on 2011-05-03, with capital 55.2% above the start. From there it fell 32.5% to 2020-05-22 and closed the window 21.9% below that peak. The 21.2% total return is what was left of the gains made up to May 2011; in the following 15.4 years the curve never returned to that level.
Final stretch. The last 24 months (2024-10-01 to 2026-09-30, 500 bars) are reported separately, without reopening the position. They decide nothing. Variant 1: return 2.6%, annualized Sharpe 0.221, max drawdown 9.0%, 22 executions.
Context reference, not a merit comparison. Holding EUR/USD long at 1× for the whole window, with the same spread and swap, ends at −31.6%, with a max drawdown of 52.5% (final stretch: −3.7%).
What it says and what it doesn't
It says that, with these rules, this data and these costs, the 9/20 result can't be told apart from statistical noise at the level of evidence set before the run. It also says that, among these four configurations, the one that looked best on the fitting sample (8 of the 16 blocks) landed in the bottom half on the other 8 in 78.7% of the splits.
It says nothing beyond this case. Its limits, as declared in the protocol:
- One instrument, one source, one timeframe. Daily EUR/USD from the H.10. Another asset, another fixing time or another price source is another study.
- Four variants, three of them very close. With N = 4, the spread between Sharpes is estimated with three degrees of freedom and the deflation is weak; that is why SR₀ and the PSR against zero are reported too. The PBO can only take four ranks and can be dominated by near-identical configurations; besides, the 50/200, the worst over the full window, won the fitting sample in 2,720 of the 12,870 splits. A high PBO here describes these four configurations, not the 9/20 rule alone.
- Approximate costs. The base spread (2 pips per side) is about 6.7 times the minimum half-spread a large retail broker published on 2026-10-08 (protocol §4); we found no verifiable public source for retail spreads in the early years. The swap uses policy rates as a proxy, and the margin m is a convention.
- Execution assumptions. The noon fixing is treated as a mid price; daily rebalancing pays no spread; the triple Wednesday charge is not modeled; taxes are not modeled.
- One period. 23.8 years span several stretches of the market, but not every possible one.
Discarding H1 is not a verdict on the rule outside this series, this period, these rules and these costs. None of this guarantees results.
Reproduce
Everything is published alongside this study at travidence.com/recursos/estudios/cruce-ema-9-20-eurusd/archivos/: the protocol, the five data files with SHA256SUMS, the annex and its receipt, the code, the synthetic-data tests, requirements.lock, the outputs and the log. The study code (run_study.py and estudio01/) uses the Python standard library and numpy, uses no component of the TRAVIDENCE platform and makes no network connection; the only download was made by download.py, once, on 2026-10-22. requirements.lock also pins pandas because the protocol (§8) provided for it; the code does not import it.
Verify the data:
cd data && shasum -a 256 -c SHA256SUMS
Run the study from a copy of the folder without outputs/, with Python 3.11.15 and the versions in requirements.lock:
python -B run_study.py --run-utc 2026-10-29T15:39:49Z
The command checks the six fingerprints (five files and the annex) and stops without writing anything if one doesn't match. With that timestamp, the 21 files it writes come out byte-identical to the published ones; this was checked on 2026-10-29 on two systems, macOS and Linux x86_64. bitacora.md is written by hand and is not part of the comparison.
| File | sha256 |
|---|---|
protocolo-v0_4.md |
ed02a661f8083632137b667f17e3bc4d92121bad356fe413fde356cbb12e22e1 |
data/anexo-datos-2026-10-22.md |
debb30d7ae5960c6d0859d25309e058c253c72e3fed2d90aee29c0b447528a0f |
run_study.py |
98901fad65c2e8fb49d62aa47db34b732d4c38ed7585768bc1c9173cd417f0d6 |
requirements.lock |
b883865636ee3268395c9669ad793410eae6dc3ce29260dba2f3979e0a66fcfa |
outputs/run-log.json |
3adb49bcc5917f79b54d34eaaca9ff7c1235b4df0158cecc006370e7f64de694 |
outputs/bitacora.md |
59a6e8b96b0b682605dc729b18c54465667abf4da51dceeb84b5802d20ed1192 |
The fingerprints of the five data files are in data/SHA256SUMS; those of the estudio01/ modules and of each output are in the folder's README.md; those of the outputs are also in outputs/run-log.json.
Sources: "Source: Board of Governors of the Federal Reserve System, H.10 Foreign Exchange Rates" · "Source: Board of Governors of the Federal Reserve System, Open Market Operations" · "Source: ECB statistics".
References
Bailey, D. H., & López de Prado, M. (2014). The Deflated Sharpe Ratio: Correcting for Selection Bias, Backtest Overfitting, and Non-Normality. The Journal of Portfolio Management, 40(5), 94–107.
Bailey, D. H., Borwein, J. M., López de Prado, M., & Zhu, Q. J. (2017). The Probability of Backtest Overfitting. Journal of Computational Finance, 20(4), 39–69. https://doi.org/10.21314/JCF.2016.322