Auf GitHub ansehen

Strategie RSI Value

Strategie, die auf dem Relative Strength Index (RSI) basiert, der einen mittleren Wert kreuzt.

Die Idee ist, darauf zu achten, wenn der RSI ein konfigurierbares Niveau (Standard 50) von unten oder oben kreuzt. Wenn der Indikator von unten nach oben über dieses Niveau steigt, wird eine Long-Position eröffnet. Wenn er wieder darunter kreuzt, wird eine Short-Position eröffnet. Bestehende Positionen werden beim entgegengesetzten Kreuz geschlossen. Optionaler Stop-Loss, Take-Profit und Trailing-Stop schützen den Trade.

Details

  • Einstiegskriterien: Kaufen, wenn RSI das Niveau nach oben kreuzt. Verkaufen, wenn RSI darunter kreuzt.
  • Long/Short: Beide Richtungen.
  • Ausstiegskriterien: Entgegengesetzte Kreuzung oder Trailing-Stop.
  • Stops: Optionaler fester Stop-Loss, Take-Profit und Trailing-Stop.
  • Standardwerte:
    • RsiPeriod = 14
    • RsiLevel = 50
    • StopLoss = 100
    • TakeProfit = 200
    • TrailingStop = 0
    • CandleType = TimeSpan.FromMinutes(5)
  • Filter:
    • Kategorie: Oszillator
    • Richtung: Beide
    • Indikatoren: RSI
    • Stops: Ja
    • Komplexität: Grundlegend
    • Zeitrahmen: Intraday (5m)
    • Saisonalität: Nein
    • Neuronale Netze: Nein
    • Divergenz: Nein
    • Risikolevel: Mittel
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 level crossing strategy.
/// </summary>
public class RsiValueStrategy : Strategy
{
	private readonly StrategyParam<int> _rsiPeriod;
	private readonly StrategyParam<decimal> _rsiLevel;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevRsi;
	private bool _hasPrev;

	public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
	public decimal RsiLevel { get => _rsiLevel.Value; set => _rsiLevel.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public RsiValueStrategy()
	{
		_rsiPeriod = Param(nameof(RsiPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("RSI Period", "RSI period", "Indicators");
		_rsiLevel = Param(nameof(RsiLevel), 50m)
			.SetDisplay("RSI Level", "RSI crossing level", "Indicators");
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Candle type", "General");
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
		=> [(Security, CandleType)];

	protected override void OnReseted()
	{
		base.OnReseted();
		_prevRsi = 0;
		_hasPrev = false;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		var rsi = new RelativeStrengthIndex { Length = RsiPeriod };

		SubscribeCandles(CandleType)
			.Bind(rsi, ProcessCandle)
			.Start();
	}

	private void ProcessCandle(ICandleMessage candle, decimal rsiVal)
	{
		if (candle.State != CandleStates.Finished) return;

		if (!_hasPrev)
		{
			_prevRsi = rsiVal;
			_hasPrev = true;
			return;
		}

		var crossUp = _prevRsi <= RsiLevel && rsiVal > RsiLevel;
		var crossDown = _prevRsi >= RsiLevel && rsiVal < RsiLevel;

		if (crossUp && Position <= 0)
		{
			if (Position < 0) BuyMarket();
			BuyMarket();
		}
		else if (crossDown && Position >= 0)
		{
			if (Position > 0) SellMarket();
			SellMarket();
		}

		_prevRsi = rsiVal;
	}
}