Impulse Momentum blends 13-bar momentum with a 3-bar impulse score and buys when that signal tops 0.7 and its own 8-bar average. Volume must be 1.2 times normal, the bar must be 1.8 times the recent average range, and the 9 SMA must sit above the 21 SMA. It exits on a 1% stop, when the signal fades, or when price closes under the 9 SMA.
Best run of 10. Nasdaq 100, 1 hour, spread 3, from run pf:2026-09-24-NAS100-1h.tsv:2.
| Period | Up to 2026-09-25 |
| Instrument | Nasdaq 100, 1 hour |
| Spread | 3 points |
| Contracts | 1 |
| Starting capital | 1,000,000 |
| Costs | Spread only. Commissions and overnight financing are not included. |
| Bars | Up to 200,000 bars, fewer where the instrument has less history |
| Last tested | 2026-09-25 |
| positionSize Contracts per trade | 1 |
| momentumPeriod Price momentum length and normalising window | 13 |
| volumePeriod Average volume length | 21 |
| fastPeriod Fast SMA length | 9 |
| slowPeriod Slow SMA length | 21 |
| impulseBars Bars in the short impulse window | 3 |
| powerPeriod Average bar range length for impulse power | 5 |
| momentumWeight Weight of normalised momentum in the signal | 2 |
| impulseWeight Weight of normalised impulse in the signal | 3 |
| signalPeriod SMA length of the signal line | 8 |
| signalLevel Signal must be above this to buy | 0.7 |
| minVolumeRatio Volume must be this multiple of its 21-bar average | 1.2 |
| minImpulsePower Bar range must be this multiple of its 5-bar average | 1.8 |
| stopLossPct Protective stop, percent of entry price | 1 |
Every run
| Market | Timeframe | PF | Trades | Win % | Net | Max DD |
|---|---|---|---|---|---|---|
| Nasdaq 100Best run | 1 hour | 1.44 | 481 | 48.65 | 4,958 EUR | -1,182 |
| USD/JPY | 1 hour | n/a | 839 | 42.55 | 144,730 JPY | -56,450 |
| USD/JPY | 10 min | n/a | 975 | 40.21 | 46,450 JPY | -40,770 |
| Silver | 3 min | n/a | 773 | 36.74 | 3,975 USD | -2,757 |
| Nikkei 225 | Daily | n/a | 22 | 45.45 | 3,294 USD | -1,928 |
| Silver | 2 min | n/a | 812 | 33.25 | 2,654 USD | -2,639 |
| Nasdaq 100 | 4 hours | n/a | 282 | 53.19 | 2,145 EUR | -1,341 |
| DAX 40 | 4 hours | n/a | 215 | 49.30 | 1,078 EUR | -821 |
| Gold | 4 hours | n/a | 345 | 41.74 | 321 EUR | -185 |
| Gold | Daily | n/a | 43 | 39.53 | 164 EUR | -156 |
Charts
The code
Every file in the library uses the same header, the same section order and the same variable names. The numbers above were produced by the original version before the rewrite, and the rewrite has not yet been compiled in ProRealTime.
// ============================================================ // Impulse Momentum // ProRealAlgos Strategy Library | prorealalgos.com // Type: Momentum // Direction: Long only // Timeframe tested: 1 hour // ============================================================ // --- Settings --- DEFPARAM CumulateOrders = false // --- Parameters --- positionSize = 1 // contracts per trade momentumPeriod = 13 // price momentum length and normalising window volumePeriod = 21 // average volume length fastPeriod = 9 // fast SMA length slowPeriod = 21 // slow SMA length impulseBars = 3 // bars in the short impulse window powerPeriod = 5 // average bar range length for impulse power momentumWeight = 2 // weight of normalised momentum in the signal impulseWeight = 3 // weight of normalised impulse in the signal signalPeriod = 8 // SMA of the signal line signalLevel = 0.7 // signal must be above this to buy minVolumeRatio = 1.2 // volume must be this multiple of its average minImpulsePower = 1.8 // bar range must be this multiple of its average stopLossPct = 1 // protective stop, percent of entry price ONCE inTrade = 0 // --- Indicators --- fastMA = Average[fastPeriod](close) slowMA = Average[slowPeriod](close) priceMomentum = (close - close[momentumPeriod]) / close[momentumPeriod] * 100 // Directional movement: only count up moves that beat down moves. upMove = high - high[1] IF upMove <= 0 THEN upMove = 0 ENDIF downMove = low[1] - low IF downMove <= 0 THEN downMove = 0 ENDIF upMoveDominant = 0 IF upMove > downMove AND upMove > 0 THEN upMoveDominant = 1 ENDIF volumeRatio = Volume / Average[volumePeriod](Volume) impulseUp = (close - close[impulseBars]) / (Highest[impulseBars](high) - Lowest[impulseBars](low)) * 100 impulsePower = (high - low) / Average[powerPeriod](high - low) // Scale momentum and impulse to 0..1 over the recent window, then blend them. normMomentum = (priceMomentum - Lowest[momentumPeriod](priceMomentum)) / (Highest[momentumPeriod](priceMomentum) - Lowest[momentumPeriod](priceMomentum)) normImpulse = (impulseUp - Lowest[momentumPeriod](impulseUp)) / (Highest[momentumPeriod](impulseUp) - Lowest[momentumPeriod](impulseUp)) signalLine = (normMomentum * momentumWeight + normImpulse * impulseWeight) / (momentumWeight + impulseWeight) signalMA = Average[signalPeriod](signalLine)
19 more lines: the entry and exit rules.
Read this first
Questions
Yes. All five entry filters, the signal exit and the 1% stop are coded. The rewritten code has not been compile checked yet.
The headline Nasdaq 100 1 hour run made 4,958.30 EUR over 481 trades. All 9 other runs were positive, including USD/JPY 1 hour at 144,730 JPY and DAX 40 4 hours at 1,077.90 EUR.
At 1 contract with a 3 point spread, the Nasdaq 100 1 hour run had a max drawdown of 1,181.50 EUR. Each trade is protected by a 1% stop.
The volume and range filters need enough activity per bar to be meaningful. On Nasdaq 100 the 1 hour chart gave the best profit factor, 1.44.
Related
Copy trading on US indices is available to ProRealAlgos members as spots open.