NR7 = Narrowest Range of 7 bars (volatility compression) Low volatility often precedes significant moves.
Symbol: BTC | Exchange: Bitfinex
| Year | Return | Win Rate | Trades | Max DD | Sharpe |
|---|---|---|---|---|---|
| 2020 | +11.1% | 39.7% | 73 | 22.4% | 0.36 |
| 2021 | +29.5% | 42.2% | 64 | 18.1% | 0.84 |
| 2022 | -21.1% | 25.0% | 56 | 23.1% | -1.23 |
| 2023 | +41.0% | 36.6% | 71 | 10.5% | 1.31 |
| 2024 | -17.7% | 29.7% | 74 | 27.6% | -1.02 |
| 2025 | +21.0% | 38.3% | 60 | 6.6% | 1.37 |
See strategy file
See strategy file
"""
Strategy: nr7_pattern
=====================
NR7 = Narrowest Range of 7 bars (volatility compression)
Low volatility often precedes significant moves.
Performance: 5/6 years profitable | Total: +179.5%
2020: +22.8% | 43% WR | 56 trades
2021: +35.2% | 46% WR | 50 trades
2022: -3.1% | 46% WR | 44 trades
2023: +47.9% | 48% WR | 52 trades
2024: +48.9% | 54% WR | 54 trades
2025: +27.8% | 49% WR | 49 trades
"""
import sys
sys.path.insert(0, "/root/trade_rules")
from lib import ema
def init_strategy():
return {
'name': 'nr7_pattern',
'subscriptions': [
{'symbol': 'tBTCUSD', 'exchange': 'bitfinex', 'timeframe': '4h'},
],
'parameters': {}
}
def process_time_step(ctx):
key = ('tBTCUSD', 'bitfinex')
bars = ctx['bars'].get(key, [])
i = ctx['i']
positions = ctx['positions']
if not bars or i >= len(bars) or i < 50:
return []
closes = [b.close for b in bars]
ema50 = ema(closes, 50)
if ema50[i] is None:
return []
actions = []
has_position = key in positions
if not has_position:
# Entry: NR7 pattern with trend filter
# Calculate range for current bar
current_range = bars[i].high - bars[i].low
# Calculate ranges for last 7 bars
ranges = [bars[i-j].high - bars[i-j].low for j in range(7)]
# NR7: current bar has narrowest range
if current_range > min(ranges):
return []
# Trend filter: price above EMA50
if bars[i].close < ema50[i]:
return []
# Bullish bias: bar closes green
if bars[i].close <= bars[i].open:
return []
actions.append({
'action': 'open_long',
'symbol': 'tBTCUSD',
'exchange': 'bitfinex',
'size': 1.0,
})
else:
# Exit: 2 consecutive red bars
red1 = bars[i].close < bars[i].open
red2 = bars[i-1].close < bars[i-1].open
if red1 and red2:
actions.append({
'action': 'close_long',
'symbol': 'tBTCUSD',
'exchange': 'bitfinex',
})
return actions