Auf GitHub ansehen

RsiBoosterStrategy-Strategie

Überblick

RsiBoosterStrategy ist eine StockSharp-Portierung des MetaTrader Expert Advisors RSI booster. Die Strategie vergleicht den schnellen RSI-Wert der aktuellen Kerze mit einem verzögerten RSI, der die vorherige Kerze verwendet. Überschreitet die Differenz ein vom Benutzer festgelegtes Verhältnis, eröffnet die Strategie eine Marktposition und verwaltet den Trade anschließend mit festen Stops, Take-Profit-Zielen, einem optionalen Trailing Stop und einer Kette von Gegenorders zur Verlustaufholung.

Die Strategie basiert auf der High-Level-API von StockSharp. Sie abonniert eine einzelne Kerzenserie, nutzt die integrierten RelativeStrengthIndex-Indikatoren und verwendet das Strategie-Parametersystem, damit alle Eingaben in Designer optimiert werden können.

Handelslogik

  1. Auf jeder abgeschlossenen Kerze werden zwei RSI-Indikatoren berechnet.
    • Der schnelle RSI verwendet FirstRsiPeriod und FirstRsiPrice und liest die neueste Kerze.
    • Der verzögerte RSI verwendet SecondRsiPeriod und SecondRsiPrice, die Strategie behält jedoch den vorherigen Wert bei, sodass er als Verzögerung um eine Bar wirkt.
  2. Wenn fast RSI - delayed RSI größer als Ratio ist, kauft die Strategie, sofern keine Long-Position offen ist. Liegt die Differenz unter -Ratio, verkauft sie, sofern keine Short-Position offen ist.
  3. OnlyOnePositionPerBar stellt sicher, dass pro Richtung höchstens ein Einstieg für denselben Kerzenzeitstempel erfolgt.
  4. Nach jeder Kerze bewertet die Strategie Stop-Loss-, Take-Profit- und Trailing-Regeln. Wird eine der Bedingungen ausgelöst, wird die Position sofort geschlossen.
  5. Wird eine Position mit negativem realisiertem PnL geschlossen, kann die optionale Aufhollogik eine Gegenposition (entgegengesetzte Richtung) mit demselben Volumen eröffnen. Die Anzahl verketteter Aufholtrades ist durch ReturnOrdersMax begrenzt.

Risikomanagement

  • Stop-Loss - über StopLossPips in Instrumentenpunkten ausgedrückt. Die Position wird geschlossen, wenn der Preis das Stop-Niveau kreuzt.
  • Take-Profit - über TakeProfitPips in Instrumentenpunkten ausgedrückt.
  • Trailing Stop - wenn über TrailingStopPips aktiviert, beginnt der Stop zu trailen, sobald der Gewinn die konfigurierte Distanz überschreitet. TrailingStepPips definiert die minimale Verbesserung, bevor das Trailing-Niveau verschoben wird.
  • Return-Order - wird aktiviert, wenn ReturnOrderEnabled true ist. Nach einem Verlusttrade eröffnet die Strategie sofort eine Marktorder in die entgegengesetzte Richtung und zählt dabei, wie viele Aufholorders ausgegeben wurden.

Parameter

Parameter Beschreibung
Volume Handelsvolumen für jede Marktorder (Lots oder Kontrakte).
Ratio Minimale RSI-Differenz, die zum Eröffnen einer Position erforderlich ist.
StopLossPips Stop-Loss-Distanz in Instrumentenpunkten.
TakeProfitPips Take-Profit-Distanz in Instrumentenpunkten.
TrailingStopPips Trailing-Stop-Distanz in Instrumentenpunkten.
TrailingStepPips Minimale Verbesserung vor dem Verschieben des Trailing Stops.
OnlyOnePositionPerBar Verhindert mehrere Einstiege während derselben Kerze.
ReturnOrderEnabled Aktiviert die Aufhollogik mit Gegenorder.
ReturnOrdersMax Maximale Anzahl aufeinanderfolgender Aufholorders.
FirstRsiPeriod Periode des schnellen RSI.
FirstRsiPrice Preisquelle für den schnellen RSI (entspricht den angewandten Preis-Modi von MetaTrader).
SecondRsiPeriod Periode des verzögerten RSI.
SecondRsiPrice Preisquelle für den verzögerten RSI (entspricht den angewandten Preis-Modi von MetaTrader).
CandleType Für die Analyse verwendete Kerzenserie.

Hinweise

  • Die Umrechnung des Preisschritts berücksichtigt den PriceStep des Instruments, sofern verfügbar. Stellt das Instrument keinen Preisschritt bereit, wird als Fallback 0.0001 verwendet.
  • Der Zähler der Aufholkette wird zurückgesetzt, wenn ein profitabler Trade auftritt oder die konfigurierte Höchstzahl von Aufholorders erreicht ist.
  • Die Strategie zeichnet beide RSI-Indikatoren zusammen mit den ausgeführten Trades im Chartbereich, damit sie schnell visuell geprüft werden können.
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;

public class RsiBoosterStrategy : Strategy
{
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<int> _stopLossPoints;
	private readonly StrategyParam<int> _takeProfitPoints;

	private ExponentialMovingAverage _fast;
	private ExponentialMovingAverage _slow;

	private decimal _prevFast;
	private decimal _prevSlow;
	private decimal _entryPrice;
	private int _cooldown;

	public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
	public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
	public int StopLossPoints { get => _stopLossPoints.Value; set => _stopLossPoints.Value = value; }
	public int TakeProfitPoints { get => _takeProfitPoints.Value; set => _takeProfitPoints.Value = value; }

	public RsiBoosterStrategy()
	{
		_fastPeriod = Param(nameof(FastPeriod), 14).SetGreaterThanZero().SetDisplay("Fast Period", "Fast EMA period", "Indicator");
		_slowPeriod = Param(nameof(SlowPeriod), 50).SetGreaterThanZero().SetDisplay("Slow Period", "Slow EMA period", "Indicator");
		_stopLossPoints = Param(nameof(StopLossPoints), 200).SetNotNegative().SetDisplay("Stop Loss", "Stop-loss in price steps", "Risk");
		_takeProfitPoints = Param(nameof(TakeProfitPoints), 400).SetNotNegative().SetDisplay("Take Profit", "Take-profit in price steps", "Risk");
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
	{
		yield return (Security, TimeSpan.FromMinutes(5).TimeFrame());
	}

	protected override void OnReseted()
	{
		base.OnReseted();
		_fast = null; _slow = null;
		_prevFast = 0; _prevSlow = 0; _entryPrice = 0; _cooldown = 0;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_fast = new ExponentialMovingAverage { Length = FastPeriod };
		_slow = new ExponentialMovingAverage { Length = SlowPeriod };
		var subscription = SubscribeCandles(TimeSpan.FromMinutes(5).TimeFrame());
		subscription.Bind(_fast, _slow, ProcessCandle);
		subscription.Start();
	}

	private void ProcessCandle(ICandleMessage candle, decimal fastValue, decimal slowValue)
	{
		if (candle.State != CandleStates.Finished) return;
		if (!_fast.IsFormed || !_slow.IsFormed) { _prevFast = fastValue; _prevSlow = slowValue; return; }
		if (_cooldown > 0) { _cooldown--; _prevFast = fastValue; _prevSlow = slowValue; return; }

		var close = candle.ClosePrice;
		var step = Security?.PriceStep ?? 1m;

		if (Position > 0 && _entryPrice > 0)
		{
			if (StopLossPoints > 0 && close <= _entryPrice - StopLossPoints * step) { SellMarket(); _entryPrice = 0; _cooldown = 100; _prevFast = fastValue; _prevSlow = slowValue; return; }
			if (TakeProfitPoints > 0 && close >= _entryPrice + TakeProfitPoints * step) { SellMarket(); _entryPrice = 0; _cooldown = 100; _prevFast = fastValue; _prevSlow = slowValue; return; }
		}
		else if (Position < 0 && _entryPrice > 0)
		{
			if (StopLossPoints > 0 && close >= _entryPrice + StopLossPoints * step) { BuyMarket(); _entryPrice = 0; _cooldown = 100; _prevFast = fastValue; _prevSlow = slowValue; return; }
			if (TakeProfitPoints > 0 && close <= _entryPrice - TakeProfitPoints * step) { BuyMarket(); _entryPrice = 0; _cooldown = 100; _prevFast = fastValue; _prevSlow = slowValue; return; }
		}

		if (_prevFast <= _prevSlow && fastValue > slowValue && Position <= 0)
		{ if (Position < 0) BuyMarket(); BuyMarket(); _entryPrice = close; _cooldown = 100; }
		else if (_prevFast >= _prevSlow && fastValue < slowValue && Position >= 0)
		{ if (Position > 0) SellMarket(); SellMarket(); _entryPrice = close; _cooldown = 100; }

		_prevFast = fastValue; _prevSlow = slowValue;
	}
}