Konvertiert aus dem ursprünglichen MQL-Expert Advisor PINBAR.mq4 (Ordner MQL/22269). Die Strategie erkennt Pin-Bar-Umkehrungen auf dem primären Zeitrahmen und bestätigt diese mit höherzeitigen Momentum- und MACD-Filtern. Sie reproduziert den Geist des Quellsystems unter Verwendung der StockSharp High-Level-API-Features.
Handelslogik
Primärer Zeitrahmen – konfigurierbarer Kerzentyp zur Identifizierung von Kursaktions-Mustern.
Höherer Zeitrahmen – konfigurierbarer Kerzentyp zur Bestätigung von Momentum und MACD-Trendbias.
Pin-Bar-Erkennung – eine Bar wird akzeptiert, wenn der echte Kerzenkörper klein relativ zum Gesamtbereich ist und ein Docht die Kerze dominiert (konfigurierbare Körper- und Dochtverhältnisse).
Trendfilter – der schnelle EMA muss über (oder unter) dem langsamen EMA für Long- (oder Short-)Setups liegen und spiegelt die LWMA-Filter aus dem Originalcode wider.
Momentum-Bestätigung – das Momentum auf dem höheren Zeitrahmen muss für mindestens einen der letzten drei höherzeitigen Bars über (Long) oder unter (Short) einem konfigurierbaren Schwellenwert liegen.
MACD-Bestätigung – der MACD-Wert muss für Long-Trades über seiner Signallinie und für Shorts unter der Signallinie liegen, entsprechend der monatlichen MACD-Bestätigung im MQL-Expert.
Fraktal-Bestätigung – die Strategie pflegt ein rollendes Fünf-Bar-Fenster und erfordert das Vorhandensein des neuesten bullischen/bärischen Fraktals vor dem Annehmen eines neuen Trades, ähnlich dem FindFractals()-Gate in der Quelle.
Risikomanagement – konfigurierbarer Stop-Loss, Take-Profit, Break-Even-Trigger/Offset und Trailing-Stop-Logik verfolgen die offene Position. Der Trade wird geschlossen, wenn ein Niveau berührt wird oder das Trailing-Niveau verletzt wird.
Einstiegsregeln
Long-Setup
Letzte Kerze auf dem primären Zeitrahmen bildet einen bullischen Pin Bar (langer unterer Docht, kleiner Körper).
Schneller EMA > langsamer EMA.
Letztes Momentum des höheren Zeitrahmens (oder einer der zwei vorherigen Werte) liegt über dem Schwellenwert.
Höherzeitiger MACD liegt über seiner Signallinie.
Ein bullisches Fraktal wurde kürzlich erkannt und der Preis hat es nicht ungültig gemacht.
Strategie ist flat oder short (Shorts werden umgekehrt).
Short-Setup
Letzte Kerze auf dem primären Zeitrahmen bildet einen bärischen Pin Bar (langer oberer Docht, kleiner Körper).
Schneller EMA < langsamer EMA.
Letztes Momentum des höheren Zeitrahmens (oder einer der zwei vorherigen Werte) liegt unter dem negativen Schwellenwert.
Höherzeitiger MACD liegt unter seiner Signallinie.
Ein bärisches Fraktal wurde kürzlich erkannt und der Preis hat es nicht ungültig gemacht.
Strategie ist flat oder long (Longs werden umgekehrt).
Ausstiegsregeln
Stop-Loss und Take-Profit werden in Prozent relativ zum Einstiegspreis ausgedrückt.
Break-Even aktiviert sich, sobald sich der Preis um den Trigger-Prozentsatz bewegt; der Stop wird zu Einstieg plus/minus einem Offset verschoben.
Trailing-Stop aktiviert sich nach Erreichen des Aktivierungsprozentsatzes und folgt dem Preis bei der konfigurierten Distanz.
Entgegengesetzte Signale kehren ebenfalls die Position um.
Parameter
Name
Standard
Beschreibung
CandleType
15-Minuten-Kerzen
Primärer Zeitrahmen für die Mustererkennung.
TrendCandleType
1-Stunden-Kerzen
Höherer Zeitrahmen für Momentum/MACD-Filter.
FastMaLength
6
Schnelle EMA-Länge (ersetzt schnellen LWMA).
SlowMaLength
85
Langsame EMA-Länge (ersetzt langsamen LWMA).
MomentumLength
14
Momentum-Indikatorlänge auf höherem Zeitrahmen.
MomentumThreshold
0.1
Minimaler absoluter Momentum-Wert zur Bestätigung.
MacdFastLength
12
MACD schnelle EMA-Länge.
MacdSlowLength
26
MACD langsame EMA-Länge.
MacdSignalLength
9
MACD Signal-EMA-Länge.
BodyToRangeRatio
0.3
Maximale Körpergröße relativ zum Kerzenbereich.
WickRatio
0.6
Minimales dominantes Dochtverhältnis zur Pin-Bar-Definition.
StopLossPercent
2
Schutz-Stop-Größe in Prozent.
TakeProfitPercent
4
Gewinnzielgröße in Prozent.
BreakEvenTriggerPercent
1.5
Erforderlicher Gewinn zum Verschieben des Stops auf Break-Even.
BreakEvenOffsetPercent
0.2
Zusätzlicher Offset für den Break-Even-Stop.
TrailingActivationPercent
2.5
Gewinnschwelle zur Aktivierung des Trailing Stops.
TrailingDistancePercent
1
Trailing-Stop-Distanz nach Aktivierung.
Hinweise
Das Volumen ist standardmäßig auf 1 Kontrakt fixiert; passen Sie das Strategie-Volumen für unterschiedliche Positionsgrößen an.
Die Fraktals-Erkennung setzt sich zurück, wenn der Preis das aufgezeichnete Fraktal-Niveau verletzt, was ein neues Muster vor einem neuen Trade erfordert.
Optimierungsbereiche sind für wichtige Parameter enthalten, um das Backtesting und die Abstimmung in StockSharp Designer zu erleichtern.
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class PinbarReversal2Strategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private decimal? _prevFast, _prevSlow;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public PinbarReversal2Strategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame()).SetDisplay("Candle Type", "Timeframe", "General");
_fastPeriod = Param(nameof(FastPeriod), 6).SetGreaterThanZero().SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 25).SetGreaterThanZero().SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevFast = null;
_prevSlow = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevFast = null; _prevSlow = null;
var fast = new ExponentialMovingAverage { Length = FastPeriod };
var slow = new ExponentialMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(fast, slow, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null) { DrawCandles(area, subscription); DrawIndicator(area, fast); DrawIndicator(area, slow); DrawOwnTrades(area); }
}
private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
{
if (candle.State != CandleStates.Finished) return;
if (!IsFormedAndOnlineAndAllowTrading()) { _prevFast = fast; _prevSlow = slow; return; }
if (_prevFast == null || _prevSlow == null) { _prevFast = fast; _prevSlow = slow; return; }
var prevAbove = _prevFast.Value > _prevSlow.Value;
var currAbove = fast > slow;
_prevFast = fast; _prevSlow = slow;
if (!prevAbove && currAbove && Position <= 0) { if (Position < 0) BuyMarket(); BuyMarket(); }
else if (prevAbove && !currAbove && Position >= 0) { if (Position > 0) SellMarket(); SellMarket(); }
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class pinbar_reversal2_strategy(Strategy):
def __init__(self):
super(pinbar_reversal2_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Timeframe", "General")
self._fast_period = self.Param("FastPeriod", 6) \
.SetDisplay("Fast EMA", "Fast EMA period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 25) \
.SetDisplay("Slow EMA", "Slow EMA period", "Indicators")
self._prev_fast = None
self._prev_slow = None
@property
def CandleType(self):
return self._candle_type.Value
@property
def FastPeriod(self):
return self._fast_period.Value
@property
def SlowPeriod(self):
return self._slow_period.Value
def OnReseted(self):
super(pinbar_reversal2_strategy, self).OnReseted()
self._prev_fast = None
self._prev_slow = None
def OnStarted2(self, time):
super(pinbar_reversal2_strategy, self).OnStarted2(time)
self._prev_fast = None
self._prev_slow = None
fast = ExponentialMovingAverage()
fast.Length = self.FastPeriod
slow = ExponentialMovingAverage()
slow.Length = self.SlowPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(fast, slow, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, fast)
self.DrawIndicator(area, slow)
self.DrawOwnTrades(area)
def _on_process(self, candle, fast_value, slow_value):
if candle.State != CandleStates.Finished:
return
fv = float(fast_value)
sv = float(slow_value)
if self._prev_fast is None or self._prev_slow is None:
self._prev_fast = fv
self._prev_slow = sv
return
prev_above = self._prev_fast > self._prev_slow
curr_above = fv > sv
self._prev_fast = fv
self._prev_slow = sv
if not prev_above and curr_above and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif prev_above and not curr_above and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
def CreateClone(self):
return pinbar_reversal2_strategy()