Auf GitHub ansehen

Lossless MA-Strategie

Diese Strategie handelt Kreuzungen zwischen einem schnellen und einem langsamen Simple Moving Average (SMA). Optional vermeidet sie die Realisierung von Verlusten, indem sie Verlustpositionen auf Break-even verschiebt, wenn das entgegengesetzte Signal erscheint.

Funktionsweise

  1. Indikatoren
    • Schneller SMA
    • Langsamer SMA
  2. Einstiege
    • Long wenn Schneller SMA > Langsamer SMA und die aktuelle Richtung nicht Long ist.
    • Short wenn Schneller SMA < Langsamer SMA und die aktuelle Richtung nicht Short ist.
    • Zusätzliche Einstiege sind erlaubt, wenn Close Losses deaktiviert ist und die Anzahl der offenen Positionen unter Max Deals liegt.
  3. Ausstiege
    • Bei einem entgegengesetzten Kreuzungssignal.
    • Wenn Close Losses aktiviert ist, wird die Position sofort geschlossen.
    • Wenn Close Losses deaktiviert ist und der Trade im Verlust liegt, wird eine Limit-Order zum Einstiegspreis gesetzt, um bei Break-even auszusteigen.

Parameter

Name Beschreibung Standard
FastLength Periode des schnellen SMA. 10
SlowLength Periode des langsamen SMA. 30
MaxDeals Maximale Anzahl gleichzeitiger Positionen. 5
CloseLosses Verlustpositionen sofort schließen. true
Volume Ordervolumen. 1
CandleType Kerzen für Berechnungen. 1-minute

Hinweise

Die Strategie verwendet Marktorders für Ein- und Ausstiege. Wenn CloseLosses deaktiviert ist, versucht sie Positionen zu schützen, indem sie eine Limit-Order zum Einstiegspreis platziert, anstatt mit Verlust zu schließen.

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>
/// Lossless Moving Average strategy.
/// Trades fast and slow SMA crossovers.
/// </summary>
public class LosslessMaStrategy : Strategy
{
	private readonly StrategyParam<int> _fastLength;
	private readonly StrategyParam<int> _slowLength;
	private readonly StrategyParam<DataType> _candleType;

	private decimal? _prevFast;
	private decimal? _prevSlow;

	/// <summary>
	/// Fast SMA period.
	/// </summary>
	public int FastLength { get => _fastLength.Value; set => _fastLength.Value = value; }

	/// <summary>
	/// Slow SMA period.
	/// </summary>
	public int SlowLength { get => _slowLength.Value; set => _slowLength.Value = value; }

	/// <summary>
	/// Type of candles used for calculations.
	/// </summary>
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	/// <summary>
	/// Constructor.
	/// </summary>
	public LosslessMaStrategy()
	{
		_fastLength = Param(nameof(FastLength), 10)
			.SetGreaterThanZero()
			.SetDisplay("Fast MA", "Fast SMA length", "Parameters");

		_slowLength = Param(nameof(SlowLength), 30)
			.SetGreaterThanZero()
			.SetDisplay("Slow MA", "Slow SMA length", "Parameters");

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

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

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

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

		var fastMa = new ExponentialMovingAverage { Length = FastLength };
		var slowMa = new ExponentialMovingAverage { Length = SlowLength };

		var subscription = SubscribeCandles(CandleType);

		subscription
			.Bind(fastMa, slowMa, ProcessCandle)
			.Start();

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

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

		if (!IsFormedAndOnlineAndAllowTrading())
			return;

		var prevFast = _prevFast;
		var prevSlow = _prevSlow;

		_prevFast = fastValue;
		_prevSlow = slowValue;

		if (prevFast is null || prevSlow is null)
			return;

		// Bullish crossover
		if (prevFast <= prevSlow && fastValue > slowValue && Position <= 0)
		{
			if (Position < 0)
				BuyMarket();
			BuyMarket();
		}

		// Bearish crossover
		if (prevFast >= prevSlow && fastValue < slowValue && Position >= 0)
		{
			if (Position > 0)
				SellMarket();
			SellMarket();
		}
	}
}