Märkte retracieren häufig einen Teil einer vorherigen Bewegung, bevor sie den Trend fortsetzen. Diese Strategie identifiziert jüngste Swing-Hochs und -Tiefs und beobachtet, wie der Kurs die Retracement-Niveaus von 61.8% oder 78.6% testet. Diese Bereiche markieren häufig Erschöpfungspunkte.
Tests zeigen eine durchschnittliche Jahresrendite von etwa 115%. Die Strategie eignet sich am besten für den Aktienmarkt.
Der Algorithmus verfolgt Swings über ein rollendes Fenster und berechnet Fibonacci-Niveaus zwischen ihnen. Wenn der Kurs sich einem wichtigen Retracement nähert und eine Kerze in Richtung des ursprünglichen Trends bildet, wird ein Trade mit einem in festem Prozentabstand platzierten Stop eröffnet. Ziele liegen um den 50%-Mittelpunkt des Swings.
Indem der Fokus auf tiefen Pullbacks innerhalb eines bestehenden Trends liegt, zielt die Methode darauf ab, die frühen Phasen einer Fortsetzungsbewegung zu erfassen, nachdem Verkäufer oder Käufer kurzzeitig die Kontrolle übernommen haben.
Details
Einstiegskriterien: Kurs testet 61.8%- oder 78.6%-Retracement und bildet eine bestätigende Kerze.
Long/Short: Beide abhängig vom Trend.
Ausstiegskriterien: Kurs erreicht das 50%-Niveau oder Stop-Loss.
Stops: Ja, prozentbasiert.
Standardwerte:
SwingLookbackPeriod = 20
FibLevelBuffer = 0.5
CandleType = 5 minute
StopLossPercent = 2
Filter:
Kategorie: Trendfolge
Richtung: Beide
Indikatoren: Fibonacci levels
Stops: Ja
Komplexität: Fortgeschritten
Zeitrahmen: Intraday
Saisonalität: Nein
Neuronale Netze: Nein
Divergenz: Nein
Risikolevel: Mittel
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Fibonacci Retracement Reversal strategy.
/// Identifies swing high/low over a lookback window and enters at key Fibonacci retracement levels.
/// Bullish reversal at 61.8% retracement from swing low.
/// Bearish reversal at 61.8% retracement from swing high.
/// Uses SMA for exit signals.
/// </summary>
public class FibonacciRetracementReversalStrategy : Strategy
{
private readonly StrategyParam<int> _swingLookback;
private readonly StrategyParam<int> _maPeriod;
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _cooldownBars;
private readonly List<decimal> _highs = new();
private readonly List<decimal> _lows = new();
private int _cooldown;
/// <summary>
/// Swing lookback period.
/// </summary>
public int SwingLookback
{
get => _swingLookback.Value;
set => _swingLookback.Value = value;
}
/// <summary>
/// MA Period.
/// </summary>
public int MAPeriod
{
get => _maPeriod.Value;
set => _maPeriod.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Cooldown bars.
/// </summary>
public int CooldownBars
{
get => _cooldownBars.Value;
set => _cooldownBars.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public FibonacciRetracementReversalStrategy()
{
_swingLookback = Param(nameof(SwingLookback), 20)
.SetGreaterThanZero()
.SetDisplay("Swing Lookback", "Lookback for swing high/low", "Indicators");
_maPeriod = Param(nameof(MAPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("MA Period", "Period for SMA", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(1).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
_cooldownBars = Param(nameof(CooldownBars), 500)
.SetRange(1, 1000)
.SetDisplay("Cooldown Bars", "Bars to wait between trades", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_highs.Clear();
_lows.Clear();
_cooldown = default;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_highs.Clear();
_lows.Clear();
_cooldown = 0;
var sma = new SimpleMovingAverage { Length = MAPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(sma, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, sma);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal smaValue)
{
if (candle.State != CandleStates.Finished)
return;
// Track highs and lows
_highs.Add(candle.HighPrice);
_lows.Add(candle.LowPrice);
if (_highs.Count > SwingLookback)
{
_highs.RemoveAt(0);
_lows.RemoveAt(0);
}
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (_highs.Count < SwingLookback)
return;
if (_cooldown > 0)
{
_cooldown--;
return;
}
// Find swing high and swing low from lookback
decimal swingHigh = decimal.MinValue;
decimal swingLow = decimal.MaxValue;
for (int i = 0; i < _highs.Count; i++)
{
if (_highs[i] > swingHigh) swingHigh = _highs[i];
if (_lows[i] < swingLow) swingLow = _lows[i];
}
var range = swingHigh - swingLow;
if (range <= 0)
return;
// Fibonacci 61.8% retracement levels
var fib618FromHigh = swingHigh - range * 0.618m;
var fib618FromLow = swingLow + range * 0.618m;
var buffer = range * 0.02m; // 2% buffer
var isBullish = candle.ClosePrice > candle.OpenPrice;
var isBearish = candle.ClosePrice < candle.OpenPrice;
// Buy at 61.8% retracement from high (near swing low area) with bullish candle
if (Position == 0 && Math.Abs(candle.ClosePrice - fib618FromHigh) < buffer && isBullish)
{
BuyMarket();
_cooldown = CooldownBars;
}
// Sell at 61.8% retracement from low (near swing high area) with bearish candle
else if (Position == 0 && Math.Abs(candle.ClosePrice - fib618FromLow) < buffer && isBearish)
{
SellMarket();
_cooldown = CooldownBars;
}
// Exit long above SMA
else if (Position > 0 && candle.ClosePrice < smaValue)
{
SellMarket();
_cooldown = CooldownBars;
}
// Exit short below SMA
else if (Position < 0 && candle.ClosePrice > smaValue)
{
BuyMarket();
_cooldown = CooldownBars;
}
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Math
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
class fibonacci_retracement_reversal_strategy(Strategy):
"""
Fibonacci Retracement Reversal strategy.
Identifies swing high/low over a lookback window and enters at key Fibonacci retracement levels.
Bullish reversal at 61.8% retracement from swing low.
Bearish reversal at 61.8% retracement from swing high.
Uses SMA for exit signals.
"""
def __init__(self):
super(fibonacci_retracement_reversal_strategy, self).__init__()
self._swing_lookback = self.Param("SwingLookback", 20).SetDisplay("Swing Lookback", "Lookback for swing high/low", "Indicators")
self._ma_period = self.Param("MAPeriod", 20).SetDisplay("MA Period", "Period for SMA", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(1))).SetDisplay("Candle Type", "Type of candles to use", "General")
self._cooldown_bars = self.Param("CooldownBars", 500).SetDisplay("Cooldown Bars", "Bars to wait between trades", "General")
self._highs = []
self._lows = []
self._cooldown = 0
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(fibonacci_retracement_reversal_strategy, self).OnReseted()
self._highs = []
self._lows = []
self._cooldown = 0
def OnStarted2(self, time):
super(fibonacci_retracement_reversal_strategy, self).OnStarted2(time)
self._highs = []
self._lows = []
self._cooldown = 0
sma = SimpleMovingAverage()
sma.Length = self._ma_period.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(sma, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, sma)
self.DrawOwnTrades(area)
def _process_candle(self, candle, sma_val):
if candle.State != CandleStates.Finished:
return
# Track highs and lows
self._highs.append(float(candle.HighPrice))
self._lows.append(float(candle.LowPrice))
lb = self._swing_lookback.Value
if len(self._highs) > lb:
self._highs.pop(0)
self._lows.pop(0)
if len(self._highs) < lb:
return
if self._cooldown > 0:
self._cooldown -= 1
return
# Find swing high and swing low from lookback
swing_high = max(self._highs)
swing_low = min(self._lows)
rng = swing_high - swing_low
if rng <= 0:
return
# Fibonacci 61.8% retracement levels
fib618_from_high = swing_high - rng * 0.618
fib618_from_low = swing_low + rng * 0.618
buffer = rng * 0.02 # 2% buffer
close = float(candle.ClosePrice)
sv = float(sma_val)
cd = self._cooldown_bars.Value
is_bullish = candle.ClosePrice > candle.OpenPrice
is_bearish = candle.ClosePrice < candle.OpenPrice
# Buy at 61.8% retracement from high (near swing low area) with bullish candle
if self.Position == 0 and abs(close - fib618_from_high) < buffer and is_bullish:
self.BuyMarket()
self._cooldown = cd
# Sell at 61.8% retracement from low (near swing high area) with bearish candle
elif self.Position == 0 and abs(close - fib618_from_low) < buffer and is_bearish:
self.SellMarket()
self._cooldown = cd
# Exit long below SMA
elif self.Position > 0 and close < sv:
self.SellMarket()
self._cooldown = cd
# Exit short above SMA
elif self.Position < 0 and close > sv:
self.BuyMarket()
self._cooldown = cd
def CreateClone(self):
return fibonacci_retracement_reversal_strategy()