Hypotheses
SPY Bull-Market Pullback Countertrend (faithful port of pinkfish 'ac-countertrend' by Farrell Aultman) — Long-Only All-In, DAILY bars, SPY.USEQ
A line-by-line port of the MIT-licensed pinkfish example strategy 'ac-countertrend' by Farrell Aultman…
Strategies
- SpyAcCountertrendPullback Abandoned
Hypothesis
A line-by-line port of the MIT-licensed pinkfish example strategy 'ac-countertrend' by Farrell Aultman (https://github.com/fja05680/pinkfish/blob/18a0d557ead25e0e82de3ece86bcab6c325a59ed/examples/strategies/ac-countertrend/strategy.py). Credit: the strategy is by Farrell Aultman. The source trades SPY on daily bars. Our platform carries that instrument as SPY.USEQ, with decades of split-adjusted daily history, zero commissions and about 0.02-0.05% round-trip spread plus impact. So no venue or fee adaptation is……Show moreShow less
A line-by-line port of the MIT-licensed pinkfish example strategy 'ac-countertrend' by Farrell Aultman (https://github.com/fja05680/pinkfish/blob/18a0d557ead25e0e82de3ece86bcab6c325a59ed/examples/strategies/ac-countertrend/strategy.py). Credit: the strategy is by Farrell Aultman. The source trades SPY on daily bars. Our platform carries that instrument as SPY.USEQ, with decades of split-adjusted daily history, zero commissions and about 0.02-0.05% round-trip spread plus impact. So no venue or fee adaptation is needed. This is not the fee-regime mismatch that killed the FMZ ports (lesson 167). Mechanism: in an uptrend (40-day EMA above 80-day EMA), buy a dip below the 20-day highest close. Exit on the snap-back above the 20-day SMA, a stop, a regime flip or a 20-bar time limit. Long-only, one position, flat most of the time. All indicators use the daily CLOSE and are computed exactly as in the source: ema_fast = EMA(close, 40); ema_slow = EMA(close, 80) (pinkfish.EMA is the TA-Lib EMA, seeded with the SMA of the first N closes); bull = ema_fast > ema_slow; daily_std = rolling 40-bar sample std (ddof=1, the pandas default) of close.pct_change(); high_close = rolling 20-bar max of close INCLUDING the current bar; pullback = (high_close - close) / daily_std; exit_ma = SMA(close, 20). Warm-up: no trading until every indicator is non-NaN (the source drops NaN rows, about 81 bars). DEFAULT PARAMETERS EXACTLY AS WRITTEN: std_period=40, high_period=20, ema_fast=40, ema_slow=80, hold_period=20, min_pullback=3.0, exit_ma=20, stop_loss_pct=0.15, exit_on_bear=True, margin=1 (no leverage), use_adj=False. SOURCE QUIRK THE DEVELOPER MUST KEEP (do not 'fix' it): pullback divides a DOLLAR distance (high_close - close) by a unitless return std (about 0.01 for SPY), so it is NOT a true z-score. With SPY near $500 and daily_std near 1%, pullback >= 3.0 only needs the close to be about $0.03-0.15 below the 20-day high close. In practice the entry fires on almost any close below the 20-day high while the market is in a bull regime. The port keeps this formula as written. A unit-correct variant (dividing by close*daily_std) would be a SEPARATE hypothesis, not this one. Position sizing: all-in, meaning 100% of account equity (pinkfish margin=1 → leverage 1.0), in whole shares: floor(equity / price). Fees: USEQ has zero commission; our engine models spread and impact. Expected flat fraction is about 55-70% of days, because the strategy exits at the first close above SMA20.
Analysis
ac-countertrend
Backtest and paper results are hypothetical. Trading involves risk of loss.