Auf GitHub ansehen

Schnelle langsame RVI-Crossover-Strategie

Überblick

Diese Strategie repliziert den MetaTrader-Expertenberater _HPCS_FastSlowRVIsCrossOver_MT4_EA_V01_WE. Es wird gehandelt, wenn die Hauptlinie des Relative Vigor Index (RVI) während der konfigurierten Handelssitzung seine Signallinie kreuzt. Pro Kerze ist nur ein Trade zulässig, und die Strategie unterstützt optionale Stop-Loss-, Take-Profit- und Trailing-Stop-Distanzen, ausgedrückt in Pips.

Handelslogik

  1. Erstellen Sie zeitbasierte Standardkerzen, die durch den Parameter Kerzentyp ausgewählt werden.
  2. Berechnen Sie den RVI mit der konfigurierten RVI-Periode und einem einfachen gleitenden Durchschnitt über 4 Perioden als Signallinie.
  3. Wenn der RVI über die Signallinie steigt, schließen Sie alle Short-Positionen und eröffnen/skalieren Sie in eine Long-Position.
  4. Wenn der RVI unter die Signallinie fällt, schließen Sie alle Long-Positionen und eröffnen/skalieren Sie in eine Short-Position.
  5. Ignorieren Sie Signale, die außerhalb des Intervalls Startzeit und Stoppzeit auftreten.
  6. Erteilen Sie Schutzanordnungen gemäß den ausgewählten Risikoparametern. Trailing Stops werden von der Schutz-Engine StockSharp verwaltet.
  7. Vermeiden Sie doppelte Einträge bei derselben Kerze, indem Sie nur einmal pro Balken reagieren.

Parameter

Name Beschreibung
RVI-Zeitraum Anzahl der vom Relative Vigor Index verwendeten Balken.
Gewinnmitnahme (Pips) Optionale Take-Profit-Distanz, gemessen in Pips. Zum Deaktivieren auf Null setzen.
Stop-Loss (Pips) Optionale Stop-Loss-Distanz, gemessen in Pips. Zum Deaktivieren auf Null setzen.
Trailing Stop (Pips) Optionale Trailing-Stop-Distanz in Pips. Auf Null setzen, um das Nachziehen zu deaktivieren.
Trailing Step (Pips) Minimale günstige Bewegung, die erforderlich ist, bevor der Trailing Stop verschärft wird. Funktioniert nur, wenn der Trailing Stop aktiv ist.
Volumen Bei jedem Eintrag übermitteltes Bestellvolumen.
Kerzentyp Zeitrahmen oder benutzerdefinierter Kerzendatentyp, der für die Analyse verwendet wird.
Startzeit Beginn des täglichen Handelsfensters (einschließlich).
Stoppzeit Ende des täglichen Handelsfensters (exklusiv).

Notizen

  • Die Pip-Größe wird an die Sicherheits-Tick-Größe angepasst, um der Handhabung von MetaTrader-Punkten zu entsprechen (5- und 3-stellige Symbole verwenden einen 10-fachen Multiplikator).
  • Rufen Sie StartProtection einmal innerhalb von OnStarted auf, um Schutzanordnungen und die Nachverfolgungsverwaltung zu aktivieren.
  • Alle Kommentare im Quellcode sind in englischer Sprache verfasst, wie es die Projektrichtlinien vorschreiben.
using System;

using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Fast and slow Relative Vigor Index crossover strategy.
/// Opens a long position when the RVI average line crosses above the signal line,
/// and opens a short position on the opposite crossover.
/// </summary>
public class FastSlowRviCrossoverStrategy : Strategy
{
	private readonly StrategyParam<int> _rviPeriod;
	private readonly StrategyParam<DataType> _candleType;

	private decimal? _previousAverage;
	private decimal? _previousSignal;

	public int RviPeriod
	{
		get => _rviPeriod.Value;
		set => _rviPeriod.Value = value;
	}

	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	public FastSlowRviCrossoverStrategy()
	{
		_rviPeriod = Param(nameof(RviPeriod), 20)
			.SetGreaterThanZero()
			.SetDisplay("RVI Period", "Period for the Relative Vigor Index", "Indicators");

		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
			.SetDisplay("Candle Type", "Candles used for analysis", "General");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_previousAverage = null;
		_previousSignal = null;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_previousAverage = null;
		_previousSignal = null;

		var rvi = new ExponentialMovingAverage { Length = RviPeriod };
		var signal = new ExponentialMovingAverage { Length = RviPeriod * 2 };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(rvi, signal, ProcessCandle)
			.Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawIndicator(area, rvi);
			DrawIndicator(area, signal);
			DrawOwnTrades(area);
		}
	}

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

		if (!IsFormedAndOnlineAndAllowTrading())
			return;

		if (_previousAverage.HasValue && _previousSignal.HasValue)
		{
			var longSignal = _previousAverage.Value <= _previousSignal.Value && avgValue > sigValue;
			var shortSignal = _previousAverage.Value >= _previousSignal.Value && avgValue < sigValue;

			if (longSignal && Position <= 0)
			{
				BuyMarket();
			}
			else if (shortSignal && Position >= 0)
			{
				SellMarket();
			}
		}

		_previousAverage = avgValue;
		_previousSignal = sigValue;
	}
}