Diese Strategie konvertiert den ursprünglichen iRSISign Expert Advisor aus MQL5 in die StockSharp High-Level-API. Sie kombiniert den Relative Strength Index (RSI) mit dem Average True Range (ATR), um Einstiegs- und Ausstiegssignale zu generieren.
Das System wartet auf abgeschlossene Kerzen eines benutzerdefinierten Zeitrahmens. Wenn der RSI die untere Schwelle von unten nach oben kreuzt, signalisiert dies eine potenzielle bullische Umkehr und eröffnet eine Long-Position oder schließt eine bestehende Short-Position. Umgekehrt, wenn der RSI unter die obere Schwelle fällt, wird eine Short-Position eingegangen oder eine aktive Long-Position geschlossen. Der ATR wird berechnet, aber nur für zusätzlichen Kontext verwendet, analog zum Originalindikator, der Signalpfeile mit ATR-Versatz anzeigte.
Details
Einstiegskriterien:
Long: Vorheriger RSI-Wert war unter DownLevel und aktueller RSI kreuzt darüber.
Short: Vorheriger RSI-Wert war über UpLevel und aktueller RSI kreuzt darunter.
Long/Short: Beide Richtungen sind erlaubt und können unabhängig aktiviert werden.
Ausstiegskriterien:
Ein entgegengesetztes Signal schließt die aktuelle Position, wenn das entsprechende Schließ-Flag aktiviert ist.
Stops: Nicht implementiert. Risikomanagement kann bei Bedarf extern hinzugefügt werden.
Standardwerte:
RsiPeriod = 14
AtrPeriod = 14
UpLevel = 70
DownLevel = 30
CandleType = 1-Stunden-Kerzen
Filter:
Kategorie: Momentum
Richtung: Beide
Indikatoren: RSI, ATR
Stops: Nein
Komplexität: Grundlegend
Zeitrahmen: Flexibel
Saisonalität: Nein
Neuronale Netze: Nein
Divergenz: Nein
Risikolevel: Mittel
Parameter
Name
Beschreibung
RsiPeriod
RSI-Länge.
AtrPeriod
ATR-Länge.
UpLevel
RSI-Oberschwelle, die Verkaufssignale generiert.
DownLevel
RSI-Unterschwelle, die Kaufsignale generiert.
CandleType
Für Berechnungen verwendeter Kerzen-Zeitrahmen.
BuyOpen
Öffnen von Long-Positionen aktivieren.
SellOpen
Öffnen von Short-Positionen aktivieren.
BuyClose
Schließen bestehender Longs bei entgegengesetztem Signal erlauben.
SellClose
Schließen bestehender Shorts bei entgegengesetztem Signal erlauben.
Die Strategie ist als Lehrbeispiel gedacht, das demonstriert, wie man einfache MQL5-Logik in das High-Level-Strategie-Framework von StockSharp übersetzt.
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>
/// RSI based signal strategy.
/// Opens long when RSI crosses above the down level.
/// Opens short when RSI crosses below the up level.
/// </summary>
public class RsiSignStrategy : Strategy
{
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<decimal> _upLevel;
private readonly StrategyParam<decimal> _downLevel;
private readonly StrategyParam<DataType> _candleType;
private decimal? _previousRsi;
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public decimal UpLevel { get => _upLevel.Value; set => _upLevel.Value = value; }
public decimal DownLevel { get => _downLevel.Value; set => _downLevel.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public RsiSignStrategy()
{
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "Length of RSI indicator", "Indicator");
_upLevel = Param(nameof(UpLevel), 70m)
.SetDisplay("RSI Upper Level", "Sell when RSI falls below this value", "Indicator");
_downLevel = Param(nameof(DownLevel), 30m)
.SetDisplay("RSI Lower Level", "Buy when RSI rises above this value", "Indicator");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Timeframe used for indicator calculations", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_previousRsi = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_previousRsi = null;
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(rsi, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, rsi);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal rsiValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var prevRsi = _previousRsi;
_previousRsi = rsiValue;
if (prevRsi is null)
return;
// RSI crosses above lower level -> buy signal
if (prevRsi <= DownLevel && rsiValue > DownLevel && Position <= 0)
BuyMarket();
// RSI crosses below upper level -> sell signal
else if (prevRsi >= UpLevel && rsiValue < UpLevel && Position >= 0)
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 RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class rsi_sign_strategy(Strategy):
def __init__(self):
super(rsi_sign_strategy, self).__init__()
self._rsi_period = self.Param("RsiPeriod", 14) \
.SetDisplay("RSI Period", "Length of RSI indicator", "Indicator")
self._up_level = self.Param("UpLevel", 70.0) \
.SetDisplay("RSI Upper Level", "Sell when RSI falls below this value", "Indicator")
self._down_level = self.Param("DownLevel", 30.0) \
.SetDisplay("RSI Lower Level", "Buy when RSI rises above this value", "Indicator")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Timeframe used for indicator calculations", "General")
self._previous_rsi = None
@property
def rsi_period(self):
return self._rsi_period.Value
@property
def up_level(self):
return self._up_level.Value
@property
def down_level(self):
return self._down_level.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(rsi_sign_strategy, self).OnReseted()
self._previous_rsi = None
def OnStarted2(self, time):
super(rsi_sign_strategy, self).OnStarted2(time)
self._previous_rsi = None
rsi = RelativeStrengthIndex()
rsi.Length = self.rsi_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(rsi, self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, rsi)
self.DrawOwnTrades(area)
def process_candle(self, candle, rsi_value):
if candle.State != CandleStates.Finished:
return
rsi_value = float(rsi_value)
prev_rsi = self._previous_rsi
self._previous_rsi = rsi_value
if prev_rsi is None:
return
down_lvl = float(self.down_level)
up_lvl = float(self.up_level)
if prev_rsi <= down_lvl and rsi_value > down_lvl and self.Position <= 0:
self.BuyMarket()
elif prev_rsi >= up_lvl and rsi_value < up_lvl and self.Position >= 0:
self.SellMarket()
def CreateClone(self):
return rsi_sign_strategy()