Skip to content
All strategies

Strategies

Chartist-minus-Fundamentalist Signal (Bouchaud et al. 2017, 'Black was right'): 6-Month Vol-Normalised Trend Minus 5-Year Log-Price Deviation, Long/Flat, Per-Asset on a 10-ETF Asset-Class Panel (USEQ DAILY)

Outcome: Abandoned

ChartistMinusFundamentalistEtfPanelLongFlat

Outcome Summary

The strategy was built to test whether Bouchaud et al.'s 'fundamentalist' 5-year mean-reversion term adds anything to a 6-month trend signal, trading a 10-ETF asset-class panel long/flat on USEQ daily bars with a k=0 control. The hypothesis's own pre-study already suggested it would not (Sharpe 0.32 vs 0.33 without the value term). The code used incremental O(1) indicators and weekly batched decisions. Even so, all 3 iterations timed out in the Layer 3 sandbox backtest (over 300s on ~2400 days of SPY data), and the run was abandoned before any engine backtest, optimization or analyst verdict.

Hypothesis

This takes the one testable rule in the abstract: markets trend over months and mean-revert over several years toward a value that is within about a factor of 2 of price. For each asset the signal is S = T - k*V. T is the chartist term: the EMA (span 126 sessions) of daily log returns, divided by 63-session realized vol and scaled by sqrt(126). V is the fundamentalist term: log(close / SMA(close, 1260 sessions)), the log distance from the 5-year average. A factor of 2 corresponds to |V| of about 0.69. k = 1.0 is……Show moreShow less

This takes the one testable rule in the abstract: markets trend over months and mean-revert over several years toward a value that is within about a factor of 2 of price. For each asset the signal is S = T - k*V. T is the chartist term: the EMA (span 126 sessions) of daily log returns, divided by 63-session realized vol and scaled by sqrt(126). V is the fundamentalist term: log(close / SMA(close, 1260 sessions)), the log distance from the 5-year average. A factor of 2 corresponds to |V| of about 0.69. k = 1.0 is fixed in advance and not optimised, because the paper says the reversion is weak. Each asset is traded on its own, LONG/FLAT only. Dividends are not in PnL, borrow costs are not modelled, and in the pre-study short legs on drifting equity ETFs lost money. The rule: go long when S > +0.25, go flat when S < -0.25, otherwise keep the current state. Decisions are made only every 5th session. The universe is chosen by ASSET CLASS, not by backtest result, and is capped at 10 names (L173): SPY (US equity), EFA (developed ex-US), EEM (emerging), EWJ (Japan), TLT (long Treasuries), IEF (7-10y Treasuries), GLD (gold), SLV (silver), DBC (broad commodities), USO (crude). Each leg is an INDEPENDENT long/flat position, not part of a neutral book. Each leg targets 10% annualised vol (weight = 0.10/(sqrt(252)*vol63)), capped at 1.0x its sleeve of 10% of equity, so gross exposure stays at or below 100% of equity and Reg-T 2x is not needed. The flat state is explicit: in the in-sample pre-study each asset was flat about 30-45% of sessions. A control variant with k = 0 (pure trend) must run on the same code and be scored separately, so the analyst can measure what the fundamentalist term ADDS. That increment is the paper's actual claim. HONEST PRE-STUDY (point-in-time, 3bp per side cost, 2006-2026, pooled equal-weight sleeves): k=1 long/flat Sharpe 0.32 (15 of 21 years positive); k=0 long/flat 0.33; k=2 0.21; long-short versions 0.09-0.28. On our data the value term adds nothing, and at k=2 it hurts on drifting equity indices. It helped only on DBC, EEM and XLE. This is therefore submitted as a falsification test of the paper's claim on tradable 1993-2026 ETF history, at low priority with modest pre-registered numbers. Expect it to fail the 0.5 OOS floor unless the engine's full-sample result differs from the pre-study.

Iteration 3 preserves the prior passing signal and sizing logic while batching position and order-cache lookups once per weekly panel decision. This removes repeated per-asset cache scans from the decision loop and keeps bar processing constant-time.

verification_loop: sandbox_timeout: Verification failed (Layer 3 — sandbox backtest): smoke test exceeded the 300s wall-clock limit on a ~20000-bar window (2400 days of SPY.USEQ-1-DAY-LAST-EXTERNAL). This almost always means per-bar work that scales with history — e.g. rescanning the full funding/supplementary series, or rebuilding a list and calling min()/sorted() inside calculate_signal()/on_bar() on every bar. Precompute sorted timestamp arrays ONCE in __init__ and use bisect, or cache lookups keyed by timestamp, so per-bar cost is O(log n) not O(n).

Implementation

Independent long/flat ETF sleeves using a six-month volatility-normalized trend minus five-year log-price deviation signal, evaluated weekly with incremental indicator state.

Verification Results

sandbox_timeout: Verification failed (Layer 3 — sandbox backtest): smoke test exceeded the 300s wall-clock limit on a ~20000-bar window (2400 days of SPY.USEQ-1-DAY-LAST-EXTERNAL). This almost always means per-bar work that scales with history — e.g. rescanning the full funding/supplementary series, or rebuilding a list and calling min()/sorted() inside calculate_signal()/on_bar() on every bar. Precompute sorted timestamp arrays ONCE in __init__ and use bisect, or cache lookups keyed by timestamp, so per-bar cost is O(log n) not O(n).

Outcome Summary

A multi-instrument panel strategy with a 1260-session warm-up has to fit inside the sandbox's 300s smoke-test budget before its research claim can be tested at all, so profile the runtime with every extra instrument feed attached, not just the per-bar indicator math.

After 3 iterations it was abandoned in the verification loop. The Layer 3 sandbox backtest went over the 300s wall-clock limit on a ~20,000-bar window (2400 days of SPY.USEQ daily bars), so it never reached backtest review, optimization, analyst or risk review.

A falsification test of Bouchaud et al. (2017): trade each of 10 asset-class ETFs (SPY, EFA, EEM, EWJ, TLT, IEF, GLD, SLV, DBC, USO) long/flat on USEQ daily bars. The signal was S = T - k*V, where T is a vol-normalised 126-session EMA trend and V is the log deviation from the 1260-session SMA, with k=1 fixed in advance, weekly decisions, and a k=0 control.

No engine backtest or optimization was produced (empty backtest report, no optimization report). The hypothesis's own point-in-time pre-study gave a pooled Sharpe of 0.32 for k=1 and 0.33 for k=0 (2006-2026, 15 of 21 years positive), so the value term added nothing, and the pre-study expected the strategy to fail the 0.5 OOS floor.

Analysis

Black was right: Price is within a factor 2 of Value

Backtest and paper results are hypothetical. Trading involves risk of loss.