# TR-Keltner — Results (vectorbtpro)

Article claim: ~100 manual 30m trades at fixed 1.5R, win rate ~49%.
Measurement (base, pooled): 1,928 trades, 762 TP / 1,164 SL / 2 END, win rate 39.56%.

## Measurement

- Period: Dukascopy H1 Bid, 2017-01-02 to 2026-06-26 (59,132 / 59,131 bars).
- Split (predeclared): IS = exit before 2024-01-01, OOS = exit on/after it.
- Engine: vectorbtpro 2026.9.5 Portfolio.from_signals, closed-bar signals,
  next-bar entry at open, one position per symbol, stop-first on ambiguous bars.
  (Run used interpreter Python 3.13.9; canonical command is `py -3.11 test.py`.)
- Base: EMA20 +/- 2.0 x ATR20 channel, fully-closed-candle breakout, opposite-band
  stop capped at 1.0 x ATR beyond 5.0 x ATR, 1.5R.

| Scope | Trades | TP | SL | END | Win rate | IS (n/rate) | OOS (n/rate) |
| EURUSD | 981 | 390 | 590 | 1 | 39.80% | 712 / 40.3% | 268 / 38.4% |
| EURJPY | 947 | 372 | 574 | 1 | 39.32% | 713 / 39.6% | 233 / 38.6% |
| POOLED | 1,928 | 762 | 1,164 | 2 | 39.56% | 1,425 / 39.9% | 501 / 38.5% |

## Costs (fixed assumptions, bid-only data)

- Spread EURUSD 1.0 pip / EURJPY 1.2 pip, half-spread adverse on every fill.
- Commission $7/lot round trip ($0.07 at 0.01 lot); EURJPY converted to
  price at a fixed USDJPY 140 (simplification, recorded in summary.csv).
- Pooled base: breakeven win rate with costs 42.13%, effective R 1.37,
  R-denominated max drawdown 132.6R (trade-sequence units, no profit claim).

## Variants (one dimension each, both symbols)

- k15 (1.5 x ATR channel, same stop rule): pooled 2,196 trades, 40.34%.
- Range across variants: 39.6-40.3%, both below the claimed ~49%.

## Limits

- H1 bid bars: intrabar paths unknown; a bar touching both TP and SL exits
  at SL (8 pooled base trades affected); fills are modeled, not observed.
- Spread, commission and USDJPY are fixed assumptions, not measured costs.
- Mechanical variant only: the article's manual 30m sample and undefined
  channel/stop parameters cannot be reconstructed; no exact replication is
  claimed and no parity with the ~49% manual figure is asserted.
- No profitability claim is made.
- Audit trail: results/summary.csv + results/trades.csv (no raw bars).
- Engine receipt: test.py requires vectorbtpro and replays every ledger trade
  in the engine at exact fills (same-bar trades as single-trade receipts);
  see vbt_reconciled in summary.csv.
