Auf GitHub ansehen

ColorXvaMA Digit StDev-Strategie

Überblick

Diese Strategie handelt basierend darauf, wie weit der Preis von einem exponentiellen gleitenden Durchschnitt (EMA) abweicht. Zwei Abweichungsmultiplikatoren (K1 und K2) definieren innere und äußere Bänder, die aus der Standardabweichung des Preises berechnet werden.

Wenn der Preis um K2 Standardabweichungen über den EMA steigt, geht die Strategie in eine Long-Position. Wenn der Preis um K2 Standardabweichungen unter den EMA fällt, geht sie in eine Short-Position. Bestehende Positionen werden geschlossen, sobald die Abweichung in das durch K1 definierte innere Band zurückehrt.

Parameter

  • EMA Length – Periode des exponentiellen gleitenden Durchschnitts.
  • StdDev Length – Periode für die Berechnung der Standardabweichung.
  • Deviation K1 – Multiplikator für das innere Band zum Schließen von Positionen.
  • Deviation K2 – Multiplikator für das äußere Band zum Öffnen von Positionen.
  • Candle Type – Zeitrahmen der Kerzen.

Indikatoren

  • Exponential Moving Average
  • StandardDeviation

Funktionsweise

  1. Kerzen des gewählten Zeitrahmens abonnieren.
  2. EMA und Standardabweichung des Preises berechnen.
  3. Preisabweichung vom EMA berechnen.
  4. Long/Short einsteigen, wenn die Abweichung ±K2×StdDev überschreitet.
  5. Aussteigen, wenn die Abweichung in ±K1×StdDev zurückkehrt.

Dieser Ansatz versucht, starke Mittelwertabweichungen zu erfassen und bei der Umkehr auszusteigen.

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 that enters positions based on price deviation from EMA and standard deviation.
/// Opens long when price is above EMA by K2*StdDev and short when below by K2*StdDev.
/// Closes positions when deviation returns within K1*StdDev.
/// </summary>
public class ColorXvaMaDigitStDevStrategy : Strategy
{
	private readonly StrategyParam<int> _maLength;
	private readonly StrategyParam<int> _stdLength;
	private readonly StrategyParam<decimal> _k1;
	private readonly StrategyParam<decimal> _k2;
	private readonly StrategyParam<DataType> _candleType;

	/// <summary>
	/// EMA period length.
	/// </summary>
	public int MaLength { get => _maLength.Value; set => _maLength.Value = value; }

	/// <summary>
	/// Standard deviation period.
	/// </summary>
	public int StdLength { get => _stdLength.Value; set => _stdLength.Value = value; }

	/// <summary>
	/// Inner deviation multiplier.
	/// </summary>
	public decimal K1 { get => _k1.Value; set => _k1.Value = value; }

	/// <summary>
	/// Outer deviation multiplier.
	/// </summary>
	public decimal K2 { get => _k2.Value; set => _k2.Value = value; }

	/// <summary>
	/// Candle type used by the strategy.
	/// </summary>
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	/// <summary>
	/// Initializes parameters.
	/// </summary>
	public ColorXvaMaDigitStDevStrategy()
	{
		_maLength = Param(nameof(MaLength), 15)
			.SetGreaterThanZero()
			.SetDisplay("EMA Length", "Period for the exponential moving average", "Parameters");

		_stdLength = Param(nameof(StdLength), 9)
			.SetGreaterThanZero()
			.SetDisplay("StdDev Length", "Period for standard deviation", "Parameters");

		_k1 = Param(nameof(K1), 1.5m)
			.SetDisplay("Deviation K1", "Inner band multiplier", "Parameters");

		_k2 = Param(nameof(K2), 2.5m)
			.SetDisplay("Deviation K2", "Outer band multiplier", "Parameters");

		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe for market data", "General");
	}

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

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

		var ema = new ExponentialMovingAverage { Length = MaLength };
		var std = new StandardDeviation { Length = StdLength };

		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(ema, std, ProcessCandle).Start();

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

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

		if (!IsFormedAndOnlineAndAllowTrading())
			return;

		if (stdValue == 0m)
			return;

		var deviation = candle.ClosePrice - emaValue;
		var filter1 = K1 * stdValue;
		var filter2 = K2 * stdValue;

		// Open long when price exceeds the upper band
		if (Position <= 0 && deviation > filter2)
		{
			BuyMarket();
		}
		// Open short when price falls below the lower band
		else if (Position >= 0 && deviation < -filter2)
		{
			SellMarket();
		}
		// Close long when price returns inside inner band
		else if (Position > 0 && deviation < filter1)
		{
			SellMarket();
		}
		// Close short when price returns inside inner band
		else if (Position < 0 && deviation > -filter1)
		{
			BuyMarket();
		}
	}
}