Stalin-Indikator-Strategie
Diese Strategie repliziert die Logik des „Stalin"-Indikators aus MQL5.
Sie verwendet ein Paar exponentieller gleitender Durchschnitte (EMAs) und einen optionalen RSI-Filter.
Ein Long-Signal erscheint, wenn die schnelle EMA die langsame EMA von unten nach oben kreuzt und der RSI über 50 liegt.
Ein Short-Signal erscheint, wenn die schnelle EMA die langsame EMA von oben nach unten kreuzt und der RSI unter 50 liegt.
Signale können durch eine erforderliche Preisbewegung bestätigt und durch den Abstand zum letzten Signal gefiltert werden.
Positionen werden mit Marktaufträgen eröffnet und bei entgegengesetzten Signalen umgekehrt.
Details
- Einstiegskriterien:
- Long:
FastEMA(t-1) < SlowEMA(t-1) && FastEMA(t) > SlowEMA(t) && RSI(t) > 50.
- Short:
FastEMA(t-1) > SlowEMA(t-1) && FastEMA(t) < SlowEMA(t) && RSI(t) < 50.
- Bestätigen: Der Handel wird verzögert, bis sich der Preis um
Confirm Punkte vom Ausbruchsniveau bewegt.
- Flat-Filter: Neue Signale werden ignoriert, wenn sie näher als
Flat Punkte am Preis des vorherigen Signals liegen.
- Long/Short: Beide.
- Ausstiegskriterien: Entgegengesetztes Signal.
- Stops: Keine.
- Standardwerte:
FastLength = 14.
SlowLength = 21.
RsiLength = 17.
Confirm = 0 Punkte (deaktiviert).
Flat = 0 Punkte (deaktiviert).
CandleType = 1-Stunden-Kerzen.
- Filter:
- Kategorie: Trendfolge.
- Richtung: Beide.
- Indikatoren: Mehrere.
- Stops: Nein.
- Komplexität: Moderat.
- Zeitrahmen: Mittelfristig.
- Saisonalität: Nein.
- Neuronale Netze: Nein.
- Divergenz: Nein.
- Risikolevel: Mittel.
using System;
using System.Linq;
using System.Collections.Generic;
using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Strategy based on "Stalin" indicator.
/// Uses fast and slow EMAs with optional RSI filter.
/// </summary>
public class StalinStrategy : Strategy
{
private readonly StrategyParam<int> _fastLength;
private readonly StrategyParam<int> _slowLength;
private readonly StrategyParam<int> _rsiLength;
private readonly StrategyParam<DataType> _candleType;
private ExponentialMovingAverage _fastMa;
private ExponentialMovingAverage _slowMa;
private RelativeStrengthIndex _rsi;
private decimal _prevFast;
private decimal _prevSlow;
private bool _initialized;
public int FastLength { get => _fastLength.Value; set => _fastLength.Value = value; }
public int SlowLength { get => _slowLength.Value; set => _slowLength.Value = value; }
public int RsiLength { get => _rsiLength.Value; set => _rsiLength.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public StalinStrategy()
{
_fastLength = Param(nameof(FastLength), 14)
.SetGreaterThanZero()
.SetDisplay("Fast EMA", "Fast EMA period", "Indicator")
.SetOptimize(5, 30, 1);
_slowLength = Param(nameof(SlowLength), 21)
.SetGreaterThanZero()
.SetDisplay("Slow EMA", "Slow EMA period", "Indicator")
.SetOptimize(20, 50, 1);
_rsiLength = Param(nameof(RsiLength), 17)
.SetGreaterThanZero()
.SetDisplay("RSI Length", "RSI period", "Indicator")
.SetOptimize(10, 30, 5);
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_fastMa = null;
_slowMa = null;
_rsi = null;
_prevFast = 0;
_prevSlow = 0;
_initialized = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_fastMa = new ExponentialMovingAverage { Length = FastLength };
_slowMa = new ExponentialMovingAverage { Length = SlowLength };
_rsi = new RelativeStrengthIndex { Length = RsiLength };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(_fastMa, _slowMa, _rsi, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, _fastMa);
DrawIndicator(area, _slowMa);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow, decimal rsiValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!_initialized)
{
_prevFast = fast;
_prevSlow = slow;
_initialized = true;
return;
}
var buySignal = _prevFast <= _prevSlow && fast > slow && rsiValue > 50m;
var sellSignal = _prevFast >= _prevSlow && fast < slow && rsiValue < 50m;
if (IsFormedAndOnlineAndAllowTrading())
{
if (buySignal && Position <= 0)
BuyMarket();
else if (sellSignal && Position >= 0)
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 ExponentialMovingAverage, RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class stalin_strategy(Strategy):
def __init__(self):
super(stalin_strategy, self).__init__()
self._fast_length = self.Param("FastLength", 14) \
.SetDisplay("Fast EMA", "Fast EMA period", "Indicator")
self._slow_length = self.Param("SlowLength", 21) \
.SetDisplay("Slow EMA", "Slow EMA period", "Indicator")
self._rsi_length = self.Param("RsiLength", 17) \
.SetDisplay("RSI Length", "RSI period", "Indicator")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._prev_fast = 0.0
self._prev_slow = 0.0
self._initialized = False
@property
def fast_length(self):
return self._fast_length.Value
@property
def slow_length(self):
return self._slow_length.Value
@property
def rsi_length(self):
return self._rsi_length.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(stalin_strategy, self).OnReseted()
self._prev_fast = 0.0
self._prev_slow = 0.0
self._initialized = False
def OnStarted2(self, time):
super(stalin_strategy, self).OnStarted2(time)
fast_ma = ExponentialMovingAverage()
fast_ma.Length = self.fast_length
slow_ma = ExponentialMovingAverage()
slow_ma.Length = self.slow_length
rsi = RelativeStrengthIndex()
rsi.Length = self.rsi_length
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(fast_ma, slow_ma, rsi, self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, fast_ma)
self.DrawIndicator(area, slow_ma)
self.DrawOwnTrades(area)
def process_candle(self, candle, fast, slow, rsi_value):
if candle.State != CandleStates.Finished:
return
fast = float(fast)
slow = float(slow)
rsi_value = float(rsi_value)
if not self._initialized:
self._prev_fast = fast
self._prev_slow = slow
self._initialized = True
return
buy_signal = self._prev_fast <= self._prev_slow and fast > slow and rsi_value > 50.0
sell_signal = self._prev_fast >= self._prev_slow and fast < slow and rsi_value < 50.0
if buy_signal and self.Position <= 0:
self.BuyMarket()
elif sell_signal and self.Position >= 0:
self.SellMarket()
self._prev_fast = fast
self._prev_slow = slow
def CreateClone(self):
return stalin_strategy()