Diese Strategie mittelt die letzten RSI-Werte, um Handelssignale zu erzeugen. Sie berechnet einen Standard-Relative Strength Index (RSI) über eine konfigurierbare Periode und wendet dann einen einfachen gleitenden Durchschnitt auf den RSI selbst an. Trades werden eröffnet, wenn der gemittelte RSI vordefinierte Schwellenwerte kreuzt, und geschlossen, wenn der entgegengesetzte Schwellenwert erreicht wird.
Handelslogik
RSI-Berechnung
Der Indikator verwendet RsiPeriod, um den RSI basierend auf Kerzenschlusskursen zu berechnen.
RSI-Mittelung
Die letzten AveragePeriod RSI-Werte werden durch einen einfachen gleitenden Durchschnitt geglättet.
Einstiegsregeln
Wenn BuyEnabledtrue ist und keine Position offen ist, wird eine Kauforder gesendet, wenn der gemittelte RSI BuyThreshold (Standard 55) überschreitet.
Wenn SellEnabledtrue ist und keine Position offen ist, wird eine Verkaufsorder gesendet, wenn der gemittelte RSI unter SellThreshold (Standard 45) fällt.
Ausstiegsregeln
Wenn CloseBySignaltrue ist, werden offene Positionen bei entgegengesetzten Signalen geschlossen:
Long-Positionen schließen, wenn der gemittelte RSI unter CloseBuyThreshold (Standard 47) fällt.
Short-Positionen schließen, wenn der gemittelte RSI über CloseSellThreshold (Standard 52) steigt.
Parameter
BuyEnabled – Long-Einstiege aktivieren oder deaktivieren.
SellEnabled – Short-Einstiege aktivieren oder deaktivieren.
CloseBySignal – Ausstiege bei entgegengesetzten RSI-Signalen erlauben.
RsiPeriod – RSI-Berechnungslänge.
AveragePeriod – Anzahl der RSI-Werte für die Mittelung.
BuyThreshold – gemittelter RSI-Wert, über dem eine Long-Position eröffnet wird.
SellThreshold – gemittelter RSI-Wert, unter dem eine Short-Position eröffnet wird.
CloseBuyThreshold – gemittelter RSI-Wert, unter dem eine Long-Position geschlossen wird.
CloseSellThreshold – gemittelter RSI-Wert, über dem eine Short-Position geschlossen wird.
CandleType – Kerzentyp für Abonnements.
Hinweise
Diese Strategie zeigt, wie Indikatorwerte durch Bindung in der StockSharp High-Level-API kombiniert werden können. Trailing-Stop- und Geldverwaltungsfunktionen aus der ursprünglichen MQL-Version werden der Einfachheit halber weggelassen.
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 that trades based on averaged RSI values.
/// Uses RSI smoothed by SMA to generate signals.
/// </summary>
public class AutoTradeWithRsiStrategy : Strategy
{
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<int> _averagePeriod;
private readonly StrategyParam<decimal> _buyThreshold;
private readonly StrategyParam<decimal> _sellThreshold;
private readonly StrategyParam<DataType> _candleType;
private ExponentialMovingAverage _rsiAvg;
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public int AveragePeriod { get => _averagePeriod.Value; set => _averagePeriod.Value = value; }
public decimal BuyThreshold { get => _buyThreshold.Value; set => _buyThreshold.Value = value; }
public decimal SellThreshold { get => _sellThreshold.Value; set => _sellThreshold.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public AutoTradeWithRsiStrategy()
{
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "RSI calculation period", "Indicator");
_averagePeriod = Param(nameof(AveragePeriod), 21)
.SetGreaterThanZero()
.SetDisplay("Average Period", "SMA period to smooth RSI", "Indicator");
_buyThreshold = Param(nameof(BuyThreshold), 55m)
.SetDisplay("Buy Threshold", "Averaged RSI above which to buy", "Rules");
_sellThreshold = Param(nameof(SellThreshold), 45m)
.SetDisplay("Sell Threshold", "Averaged RSI below which to sell", "Rules");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle data type", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_rsiAvg = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
_rsiAvg = new ExponentialMovingAverage { Length = AveragePeriod };
Indicators.Add(_rsiAvg);
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(rsi, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
var area2 = CreateChartArea();
if (area2 != null)
DrawIndicator(area2, rsi);
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue rsiValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!rsiValue.IsFormed)
return;
var avgResult = _rsiAvg.Process(rsiValue);
if (!avgResult.IsFormed)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var avgRsi = avgResult.GetValue<decimal>();
if (avgRsi > BuyThreshold && Position <= 0)
BuyMarket();
else if (avgRsi < SellThreshold && 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, ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class auto_trade_with_rsi_strategy(Strategy):
def __init__(self):
super(auto_trade_with_rsi_strategy, self).__init__()
self._rsi_period = self.Param("RsiPeriod", 14) \
.SetDisplay("RSI Period", "RSI calculation period", "Indicator")
self._average_period = self.Param("AveragePeriod", 21) \
.SetDisplay("Average Period", "SMA period to smooth RSI", "Indicator")
self._buy_threshold = self.Param("BuyThreshold", 55.0) \
.SetDisplay("Buy Threshold", "Averaged RSI above which to buy", "Rules")
self._sell_threshold = self.Param("SellThreshold", 45.0) \
.SetDisplay("Sell Threshold", "Averaged RSI below which to sell", "Rules")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candle data type", "General")
self._rsi_avg = None
@property
def rsi_period(self):
return self._rsi_period.Value
@property
def average_period(self):
return self._average_period.Value
@property
def buy_threshold(self):
return self._buy_threshold.Value
@property
def sell_threshold(self):
return self._sell_threshold.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(auto_trade_with_rsi_strategy, self).OnReseted()
self._rsi_avg = None
def OnStarted2(self, time):
super(auto_trade_with_rsi_strategy, self).OnStarted2(time)
rsi = RelativeStrengthIndex()
rsi.Length = self.rsi_period
self._rsi_avg = ExponentialMovingAverage()
self._rsi_avg.Length = self.average_period
self.Indicators.Add(self._rsi_avg)
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(rsi, self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def process_candle(self, candle, rsi_value):
if candle.State != CandleStates.Finished:
return
if not rsi_value.IsFormed:
return
avg_result = self._rsi_avg.Process(rsi_value)
if not avg_result.IsFormed:
return
avg_rsi = float(avg_result)
if avg_rsi > float(self.buy_threshold) and self.Position <= 0:
self.BuyMarket()
elif avg_rsi < float(self.sell_threshold) and self.Position >= 0:
self.SellMarket()
def CreateClone(self):
return auto_trade_with_rsi_strategy()