Auf GitHub ansehen

GG-RSI-CCI-Strategie

Diese Strategie repliziert den GG-RSI-CCI MetaTrader Expert Advisor mithilfe der StockSharp High-Level-API. Sie kombiniert die Indikatoren Relative Strength Index (RSI) und Commodity Channel Index (CCI), jeweils geglättet durch zwei gleitende Durchschnitte. Eine Position wird eröffnet, wenn beide Indikatoren in dieselbe Richtung zeigen.

Logik

  1. Indikatoren
    • RSI und CCI mit demselben Zeitraum berechnen.
    • Jeden Indikator mit einem schnellen und einem langsamen gleitenden Durchschnitt glätten.
  2. Signale
    • Kaufen wenn der schnelle RSI über dem langsamen RSI liegt und der schnelle CCI über dem langsamen CCI liegt.
    • Verkaufen wenn der schnelle RSI unter dem langsamen RSI liegt und der schnelle CCI unter dem langsamen CCI liegt.
    • Wenn der Modus auf Flat gesetzt ist, schließt jeder neutrale Zustand die aktuelle Position.
  3. Risikomanagement
    • Die Strategie ruft StartProtection einmalig beim Start auf. Stop-Loss- und Take-Profit-Niveaus können über den Risikomanager der Plattform konfiguriert werden.

Parameter

Name Beschreibung
CandleType Zeitrahmen für die Berechnungen.
Length RSI- und CCI-Periode.
FastPeriod Schnelle Glättungsperiode.
SlowPeriod Langsame Glättungsperiode.
Volume Auftragsvolumen.
AllowBuyOpen Long-Positionen öffnen aktivieren.
AllowSellOpen Short-Positionen öffnen aktivieren.
AllowBuyClose Short-Positionen schließen aktivieren.
AllowSellClose Long-Positionen schließen aktivieren.
Mode Trend schließt nur bei entgegengesetzten Signalen; Flat schließt auch bei neutralen Signalen.

Hinweise

Die Strategie verarbeitet nur abgeschlossene Kerzen und verwendet High-Level-Auftragshelfer (BuyMarket / SellMarket). Sie vermeidet direkten Zugriff auf Indikatorpuffer und speichert den Status intern.

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;
using StockSharp.Algo;

namespace StockSharp.Samples.Strategies;



/// <summary>
/// Strategy based on the GG-RSI-CCI indicator.
/// </summary>
public class GgRsiCciStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _length;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<bool> _allowBuyOpen;
	private readonly StrategyParam<bool> _allowSellOpen;
	private readonly StrategyParam<bool> _allowBuyClose;
	private readonly StrategyParam<bool> _allowSellClose;
	private readonly StrategyParam<SignalModes> _mode;

	private SimpleMovingAverage _rsiFast = null!;
	private SimpleMovingAverage _rsiSlow = null!;
	private SimpleMovingAverage _cciFast = null!;
	private SimpleMovingAverage _cciSlow = null!;
	private int _prevSignal;

	/// <summary>
	/// Defines how positions are closed.
	/// </summary>
	public enum SignalModes
	{
		/// <summary>Position is closed only on opposite signal.</summary>
		Trend,
		/// <summary>Position is closed on any neutral signal.</summary>
		Flat,
	}

	public GgRsiCciStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
			.SetDisplay("Candle Type", "Time frame for indicator calculation.", "General");

		_length = Param(nameof(Length), 8)
			.SetGreaterThanZero()
			.SetDisplay("Length", "RSI and CCI period.", "Indicators");

		_fastPeriod = Param(nameof(FastPeriod), 3)
			.SetGreaterThanZero()
			.SetDisplay("Fast Period", "Fast smoothing period.", "Indicators");

		_slowPeriod = Param(nameof(SlowPeriod), 8)
			.SetGreaterThanZero()
			.SetDisplay("Slow Period", "Slow smoothing period.", "Indicators");


		_allowBuyOpen = Param(nameof(AllowBuyOpen), true)
			.SetDisplay("Allow Buy", "Permit opening long positions.", "Permissions");

		_allowSellOpen = Param(nameof(AllowSellOpen), true)
			.SetDisplay("Allow Sell", "Permit opening short positions.", "Permissions");

		_allowBuyClose = Param(nameof(AllowBuyClose), true)
			.SetDisplay("Close Short", "Permit closing short positions.", "Permissions");

		_allowSellClose = Param(nameof(AllowSellClose), true)
			.SetDisplay("Close Long", "Permit closing long positions.", "Permissions");

		_mode = Param(nameof(Mode), SignalModes.Trend)
			.SetDisplay("Mode", "Closing style.", "Trading");
	}

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

	public int Length
	{
		get => _length.Value;
		set => _length.Value = value;
	}

	public int FastPeriod
	{
		get => _fastPeriod.Value;
		set => _fastPeriod.Value = value;
	}

	public int SlowPeriod
	{
		get => _slowPeriod.Value;
		set => _slowPeriod.Value = value;
	}


	public bool AllowBuyOpen
	{
		get => _allowBuyOpen.Value;
		set => _allowBuyOpen.Value = value;
	}

	public bool AllowSellOpen
	{
		get => _allowSellOpen.Value;
		set => _allowSellOpen.Value = value;
	}

	public bool AllowBuyClose
	{
		get => _allowBuyClose.Value;
		set => _allowBuyClose.Value = value;
	}

	public bool AllowSellClose
	{
		get => _allowSellClose.Value;
		set => _allowSellClose.Value = value;
	}

	public SignalModes Mode
	{
		get => _mode.Value;
		set => _mode.Value = value;
	}

	/// <inheritdoc />
	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
	{
		return [(Security, CandleType)];
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();

		_rsiFast?.Reset();
		_rsiSlow?.Reset();
		_cciFast?.Reset();
		_cciSlow?.Reset();
		_prevSignal = -1;
	}

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

		var rsi = new RelativeStrengthIndex { Length = Length };
		var cci = new CommodityChannelIndex { Length = Length };

		_rsiFast = new SimpleMovingAverage { Length = FastPeriod };
		_rsiSlow = new SimpleMovingAverage { Length = SlowPeriod };
		_cciFast = new SimpleMovingAverage { Length = FastPeriod };
		_cciSlow = new SimpleMovingAverage { Length = SlowPeriod };

		_prevSignal = -1;

		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(rsi, cci, ProcessCandle).Start();
	}

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

		if (!IsFormedAndOnlineAndAllowTrading())
			return;

		var rsiFast = _rsiFast.Process(new DecimalIndicatorValue(_rsiFast, rsiValue, candle.OpenTime)).ToDecimal();
		var rsiSlow = _rsiSlow.Process(new DecimalIndicatorValue(_rsiSlow, rsiValue, candle.OpenTime)).ToDecimal();
		var cciFast = _cciFast.Process(new DecimalIndicatorValue(_cciFast, cciValue, candle.OpenTime)).ToDecimal();
		var cciSlow = _cciSlow.Process(new DecimalIndicatorValue(_cciSlow, cciValue, candle.OpenTime)).ToDecimal();

		int signal;
		if (rsiFast > rsiSlow && cciFast > cciSlow && cciValue > 0m)
			signal = 2;
		else if (rsiFast < rsiSlow && cciFast < cciSlow && cciValue < 0m)
			signal = 0;
		else
			signal = 1;

		if (signal == 2)
		{
			if (AllowSellClose && Position < 0)
				BuyMarket(Math.Abs(Position));

			if (AllowBuyOpen && Position <= 0 && _prevSignal != 2)
				BuyMarket(Volume + Math.Abs(Position));
		}
		else if (signal == 0)
		{
			if (AllowBuyClose && Position > 0)
				SellMarket(Position);

			if (AllowSellOpen && Position >= 0 && _prevSignal != 0)
				SellMarket(Volume + Math.Abs(Position));
		}
		else if (Mode == SignalModes.Flat)
		{
			if (AllowBuyClose && Position > 0)
				SellMarket(Position);
			if (AllowSellClose && Position < 0)
				BuyMarket(Math.Abs(Position));
		}

		_prevSignal = signal;
	}
}