Die Suffic369-Strategie ist ein trendfolgendes Breakout-System, das zwei kurze gleitende Durchschnitte mit breiten Bollinger-Bändern kombiniert. Der Fachberater geht Long-Positionen ein, wenn der schnelle einfache gleitende Durchschnitt (SMA) der Schlusskurse die SMA der jüngsten Höchststände überschreitet, während der Markt nahe dem unteren Bollinger-Band handelt. Short-Positionen werden eröffnet, wenn der schnelle SMA den SMA der jüngsten Tiefststände unterschreitet, während der Preis gegen das obere Band drückt. Die konvertierte StockSharp-Version behält die ursprüngliche MQL-Logik bei, drückt sie jedoch mit Kerzenabonnements und Indikatorbindungen auf hoher Ebene aus.
Indikatoren
Fast SMA (Close, Länge = 3) – misst die kurzfristige Richtung des Schlusskurses.
Hoch SMA (Hoch, Länge = 5) – bildet den Durchschnitt der jüngsten Höchststände und dient als bullische Widerstandsreferenz.
Tief SMA (Tief, Länge = 5) – bildet den Durchschnitt der jüngsten Tiefststände und liefert die bärische Unterstützungsreferenz.
Bollinger Bänder (Länge = 156, Abweichung = 1) – identifiziert Preisextreme im Verhältnis zur Volatilität.
Alle Indikatoren werden bei abgeschlossenen Kerzen aktualisiert. Vorherige Werte werden zwischengespeichert, um die im ursprünglichen MetaTrader-Programm verwendete Verschiebung um einen Takt zu reproduzieren.
Handelsregeln
Langer Eintrag
Der vorherige schnelle SMA (Schlusskurs) liegt unter dem vorherigen Höchstwert SMA.
Der aktuelle Höchstkurs SMA (Schlusskurs) überschreitet das aktuelle Hoch SMA.
Der Schlusskurs der Kerze liegt unter dem unteren Bollinger-Band.
Kurzer Eintrag
Der vorherige schnelle SMA (Schlusskurs) liegt über dem vorherigen Tief SMA.
Das aktuelle Hoch SMA (Schlusskurs) kreuzt das aktuelle Tief SMA.
Der Schlusskurs der Kerze liegt über dem oberen Bollinger-Band.
Exit-Logik
Gegenteiliges Signal: Eine Long-Position wird geschlossen, wenn ein neues Short-Einstiegssignal auftritt, und umgekehrt.
Stop-Loss: Optionaler, auf Preisschritten basierender Stop, der die Position schützt, sobald er aktiviert ist.
Take-Profit: Optionales preisschrittbasiertes Ziel, das den ursprünglichen TakeProfit-Parameter widerspiegelt.
Trailing Stop: Optionaler Trailing Stop, der hinter profitablen Trades genau wie die MQL-Logik enger wird (verwendet den aktuellen Schlusskurs, um den Stop nur zu verschieben, wenn der Gewinn die konfigurierte Distanz überschreitet).
Die Strategie hält jeweils höchstens eine Position. Nachdem ein Stopp-, Ziel- oder Gegensignal den Handel schließt, wird bis zur nächsten abgeschlossenen Kerze kein neuer Eintrag ausgewertet.
Parameter
Name
Standard
Beschreibung
FastMaLength
3
Dauer des Fastens SMA basierend auf den Schlusskursen.
HighMaLength
5
Länge des SMA, berechnet auf Basis der Kerzenhöchststände.
LowMaLength
5
Länge des SMA, berechnet auf Basis der Kerzentiefs.
BollingerLength
156
Fenstergröße der Bollinger-Bänder.
BollingerDeviation
1
Standardabweichungsmultiplikator für die Bänder.
UseStopLoss
wahr
Aktiviert den Stop-Loss-Block.
StopLossPoints
30
Stoppdistanz in Instrumentenpreisschritten.
UseTakeProfit
wahr
Aktiviert den Take-Profit-Block.
TakeProfitPoints
60
Gewinnzielentfernung in Preisschritten.
UseTrailingStop
wahr
Aktiviert die Trailing-Stop-Verwaltung.
TrailingStopPoints
30
Nachlaufender Offset in Preisschritten.
CandleType
15-minütiger Zeitrahmen
Für Berechnungen verwendeter Kerzentyp.
Alle numerischen Parameter werden als StrategyParam<T>-Instanzen bereitgestellt, sodass sie direkt in StockSharp optimiert werden können.
Risikomanagement
Stop-Loss, Take-Profit und Trailing-Stops nutzen den Instrumentpreisschritt (Security.PriceStep), um Punktabstände in absolute Preise umzuwandeln.
Trailing-Stops folgen profitablen Bewegungen nur dann, wenn der Preis um mehr als die konfigurierte Distanz gestiegen ist, und reproduzieren so die ursprüngliche Orderänderungslogik.
StartProtection() wird beim Start aufgerufen, um die integrierten Schutzfunktionen von StockSharp zu aktivieren.
Nutzungshinweise
Abonnieren Sie die Strategie für ein Instrument, das den ausgewählten Kerzentyp unterstützt.
Stellen Sie sicher, dass die Eigenschaft Volume auf die gewünschte Handelsgröße eingestellt ist, bevor Sie mit der Strategie beginnen.
Die Strategie wartet auf vollständig gebildete Indikatorwerte, bevor sie Aufträge erteilt. Anfangskerzen werden verwendet, um den Verlauf des Indikators zu ermitteln.
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Suffic369 breakout strategy based on fast/slow SMA crossover.
/// Buy when fast SMA crosses above slow SMA, sell when fast crosses below slow.
/// </summary>
public class Suffic369Strategy : Strategy
{
private readonly StrategyParam<int> _fastMaLength;
private readonly StrategyParam<int> _slowMaLength;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevFast;
private decimal _prevSlow;
private bool _hasPrev;
/// <summary>
/// Fast SMA length.
/// </summary>
public int FastMaLength
{
get => _fastMaLength.Value;
set => _fastMaLength.Value = value;
}
/// <summary>
/// Slow SMA length.
/// </summary>
public int SlowMaLength
{
get => _slowMaLength.Value;
set => _slowMaLength.Value = value;
}
/// <summary>
/// Candle type used for calculations.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Initializes a new instance of the <see cref="Suffic369Strategy"/> class.
/// </summary>
public Suffic369Strategy()
{
_fastMaLength = Param(nameof(FastMaLength), 3)
.SetDisplay("Fast SMA Length", "Fast moving average period", "Indicators");
_slowMaLength = Param(nameof(SlowMaLength), 6)
.SetDisplay("Slow SMA Length", "Slow moving average period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Primary candle source", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevFast = 0m;
_prevSlow = 0m;
_hasPrev = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var fastSma = new SimpleMovingAverage { Length = FastMaLength };
var slowSma = new SimpleMovingAverage { Length = SlowMaLength };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(fastSma, slowSma, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
{
if (candle.State != CandleStates.Finished)
return;
if (!_hasPrev)
{
_prevFast = fast;
_prevSlow = slow;
_hasPrev = true;
return;
}
// Buy signal: fast SMA crosses above slow SMA
var longSignal = _prevFast <= _prevSlow && fast > slow;
// Sell signal: fast SMA crosses below slow SMA
var shortSignal = _prevFast >= _prevSlow && fast < slow;
if (Position > 0 && shortSignal)
{
SellMarket();
}
else if (Position < 0 && longSignal)
{
BuyMarket();
}
else if (Position == 0)
{
if (longSignal)
BuyMarket();
else if (shortSignal)
SellMarket();
}
_prevFast = fast;
_prevSlow = slow;
}
}
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 SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
from datatype_extensions import *
from indicator_extensions import *
class suffic369_strategy(Strategy):
"""Fast/slow SMA crossover (3/6)."""
def __init__(self):
super(suffic369_strategy, self).__init__()
self._fast_ma_length = self.Param("FastMaLength", 3).SetDisplay("Fast SMA Length", "Fast moving average period", "Indicators")
self._slow_ma_length = self.Param("SlowMaLength", 6).SetDisplay("Slow SMA Length", "Slow moving average period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))).SetDisplay("Candle Type", "Primary candle source", "General")
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, value): self._candle_type.Value = value
def OnReseted(self):
super(suffic369_strategy, self).OnReseted()
self._prev_fast = 0
self._prev_slow = 0
self._has_prev = False
def OnStarted2(self, time):
super(suffic369_strategy, self).OnStarted2(time)
self._prev_fast = 0
self._prev_slow = 0
self._has_prev = False
fast_sma = SimpleMovingAverage()
fast_sma.Length = self._fast_ma_length.Value
slow_sma = SimpleMovingAverage()
slow_sma.Length = self._slow_ma_length.Value
sub = self.SubscribeCandles(self.CandleType)
sub.Bind(fast_sma, slow_sma, self.OnProcess).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, sub)
self.DrawIndicator(area, fast_sma)
self.DrawIndicator(area, slow_sma)
self.DrawOwnTrades(area)
def OnProcess(self, candle, fast, slow):
if candle.State != CandleStates.Finished:
return
if not self._has_prev:
self._prev_fast = fast
self._prev_slow = slow
self._has_prev = True
return
long_signal = self._prev_fast <= self._prev_slow and fast > slow
short_signal = self._prev_fast >= self._prev_slow and fast < slow
if self.Position > 0 and short_signal:
self.SellMarket()
elif self.Position < 0 and long_signal:
self.BuyMarket()
elif self.Position == 0:
if long_signal:
self.BuyMarket()
elif short_signal:
self.SellMarket()
self._prev_fast = fast
self._prev_slow = slow
def CreateClone(self):
return suffic369_strategy()