Die Exp RSIOMA-Strategie verwendet den RSI des gleitenden Durchschnitts (RSIOMA)-Indikator, um Trendumkehrungen und Ausbrüche zu handeln. RSI-Werte werden durch einen zusätzlichen gleitenden Durchschnitt geglättet, um eine Signallinie und ein Histogramm zu bilden. Die Strategie unterstützt vier Modi:
Breakdown – handelt, wenn RSI konfigurierte Hoch-/Niedrig-Niveaus kreuzt.
HistTwist – handelt, wenn das Histogramm die Richtung wechselt.
SignalTwist – handelt, wenn die Signallinie die Richtung wechselt.
HistDisposition – handelt, wenn das Histogramm die Signallinie kreuzt.
Positionen können für Long- und Short-Seiten unabhängig geöffnet oder geschlossen werden.
Details
Einstiegskriterien: abhängig vom Mode
Long/Short: beide
Ausstiegskriterien: Gegensignal
Stops: keine
Standardwerte:
CandleType = 4 hour
RsiPeriod = 14
SignalPeriod = 21
HighLevel = 20
LowLevel = -20
Filter:
Kategorie: Trend
Richtung: Beide
Indikatoren: RSI
Stops: Nein
Komplexität: Mittel
Zeitrahmen: Intraday
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 the RSI crossover with an EMA of RSI (RSIOMA style).
/// Buys when RSI crosses above its EMA and sells when RSI crosses below.
/// </summary>
public class ExpRsiomaStrategy : Strategy
{
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevRsi;
private decimal _prevEma;
private bool _hasPrev;
/// <summary>RSI calculation length.</summary>
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
/// <summary>EMA smoothing period.</summary>
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
/// <summary>Candle type.</summary>
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public ExpRsiomaStrategy()
{
_rsiPeriod = Param(nameof(RsiPeriod), 21)
.SetDisplay("RSI Period", "RSI calculation length", "Parameters")
.SetGreaterThanZero();
_emaPeriod = Param(nameof(EmaPeriod), 14)
.SetDisplay("EMA Period", "EMA smoothing period", "Parameters")
.SetGreaterThanZero();
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Timeframe for candles", "General");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevRsi = 0m;
_prevEma = 0m;
_hasPrev = false;
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var rsiEma = new ExponentialMovingAverage { Length = EmaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(rsi, (candle, rsiValue) =>
{
if (candle.State != CandleStates.Finished)
return;
var emaResult = rsiEma.Process(new DecimalIndicatorValue(rsiEma, rsiValue, candle.ServerTime) { IsFinal = true });
if (!rsiEma.IsFormed)
return;
var emaValue = emaResult.ToDecimal();
if (_hasPrev)
{
var crossUp = _prevRsi <= _prevEma && rsiValue > emaValue;
var crossDown = _prevRsi >= _prevEma && rsiValue < emaValue;
if (crossUp && Position == 0)
BuyMarket();
else if (crossDown && Position == 0)
SellMarket();
}
_prevRsi = rsiValue;
_prevEma = emaValue;
_hasPrev = true;
})
.Start();
StartProtection(
takeProfit: new Unit(2, UnitTypes.Percent),
stopLoss: new Unit(1, UnitTypes.Percent)
);
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, rsi);
DrawOwnTrades(area);
}
}
}