[main] Starting Donchian breakout backtest.
[fetch_data] IBKR unreachable (No module named 'ib_insync'); generating synthetic GBM data.
[main] Train rows: 261 Test rows: 495 Split at 2024-05-25
[main] Wrote 27 trades. Total PnL $-4817.25
[main] Artifacts in /Users/shanpeiyuan/533-web-spy/.claude/worktrees/peaceful-sammet/data
Donchian Channel Breakout Strategy
Systematic trend-following on GLD (SPDR Gold Trust)
Donchian Channel Breakout on GLD
A transparent, rules-based trend-following system that enters on 20-bar price breakouts, sizes exits with ATR, and caps risk with a hard time-out.
Strategy Logic
The strategy watches a rolling 20-day high/low envelope — the classic Donchian channel — and waits for price to decisively pierce one of the boundaries. A close above the upper band signals that recent resistance has broken, the path of least resistance is up, and we go long the next morning; a close below the lower band does the symmetric thing on the short side. Every trade carries a pre-computed profit target of two ATRs and a stop-loss of one ATR from the entry, giving a 2:1 reward-to-risk geometry; if neither boundary is touched within twenty trading days the position is closed at the market so capital never sits idle in a range-bound trade. Only one position is open at a time, slippage and commission are charged on both legs, and no pyramiding is permitted.
Asset Selection
The candidate universe was an 8-ETF basket spanning equities, bonds, and commodities: SPY, QQQ, IWM, TLT, GLD, USO, XLE, and EEM. For each ETF we counted how many 20-bar Donchian breakouts occurred over a 3-year sample and divided by bar count to get a breakout frequency. GLD screened best: commodities in general showed stronger trending behaviour than equities over this window, and gold specifically produced the cleanest alternation of decisive trends and clear consolidations — exactly the regime that rewards channel breakouts. GLD is also highly liquid (tight spreads, large ADV) so the slippage assumption below is conservative.
Breakout Definition
A breakout is defined mechanically so there is zero discretion:
- Upper band = highest high of the prior 20 bars (
LOOKBACK_PERIOD = 20). - Lower band = lowest low of the prior 20 bars.
- Long signal fires when today’s close > upper band; the trade is filled at the next bar’s open.
- Short signal fires when today’s close < lower band; filled at the next bar’s open.
- ATR uses Wilder smoothing over 14 bars (
ATR_PERIOD = 14). - Profit target = entry ± 2.0 × ATR (
ATR_MULT = 2.0). - Stop-loss = entry ∓ 1.0 × ATR (
STOP_MULT = 1.0). - Time-out = force-close at the close of bar 20 after entry (
MAX_HOLDING_DAYS = 20). - Size = 100 shares per trade (
POSITION_SIZE = 100). - Costs = 0.1% slippage + 0.1% commission applied on both entry and exit sides.
- Risk-free rate = 5.3% annualised, used for Sharpe / Sortino (
RISK_FREE_RATE = 0.053).
All channel values are shifted by one bar so only prior-bar information is ever used — no peek-ahead.
Equity Curve
Donchian Channel Chart
Performance Metrics
| Metric | Value | What it means |
|---|---|---|
| Number of trades | 27 | Total completed round-trips in the test window. |
| Win rate | 22.22% | Share of trades with positive net return after costs. |
| Average return per trade | -1.06% | Mean of all trade returns, winners and losers combined. |
| Average winning trade | 2.88% | Mean return across trades that closed in profit. |
| Average losing trade | -2.18% | Mean return across trades that closed at a loss or flat. |
| Profit factor | 0.38 | Gross profit divided by gross loss — above 1 is profitable. |
| Sharpe ratio (annualised) | -2.25 | Risk-adjusted return using total equity-curve volatility. |
| Sortino ratio (annualised) | -6.10 | Like Sharpe but penalises only downside volatility. |
| Max drawdown | $-6063.51 | Largest peak-to-trough equity decline in the test window. |
| Total PnL | $-4817.25 | Net dollar profit/loss after slippage and commission. |
Trade Outcome Analysis
Every position is forced to close through one of three doors: the profit target (entry ± 2 × ATR), the stop-loss (entry ∓ 1 × ATR), or a time-out after 20 trading days. The stop-loss is tested each bar against the bar’s low (for longs) or high (for shorts); if the stop and the target are both reachable on the same bar, the stop is assumed to fill first — a conservative choice that avoids flattering the numbers.
Trade Blotter
Download
Assumptions
- Slippage: 0.1% of fill price applied on every entry and exit.
- Commission: 0.1% per side, in addition to slippage.
- No pyramiding: only one position is held at any time; new signals during an open trade are ignored.
- Data source: live GLD daily bars from Interactive Brokers TWS (
ib_insync); if TWS is unreachable the pipeline falls back to a synthetic GBM series with GLD-like parameters so the site always renders. - No dividends: GLD distributions are ignored; returns are price-only.
- Walk-forward: year 1 is used for indicator warm-up, years 2–3 are the out-of-sample test window reported above.
- Single-instrument: results do not account for portfolio-level diversification or correlation effects.