Auf GitHub ansehen

Aeron Robot Grid-Strategie

Diese Strategie implementiert ein gitterbasiertes Hedging-System, inspiriert vom AeronRobot Expert Advisor. Sie platziert Kauf- und Verkaufsorders in vordefinierten Preisabständen und erhöht das Positionsvolumen nach jeder neuen Order. Der Ansatz zielt darauf ab, kleine Preisschwankungen zu nutzen, während das Risiko durch konfigurierbare Take-Profit-, Stop-Loss- und Trade-Limits gesteuert wird.

Die Strategie arbeitet sowohl mit Long- als auch Short-Positionen. Wenn der Preis sich in durch den Gap-Parameter definierten Schritten bewegt, wird eine neue Order mit einem um LotsFactor multiplizierten Volumen eröffnet. Gewinne werden gesichert, wenn der Preis um TakeProfit Punkte zurückkommt, und Verluste werden begrenzt, wenn die Bewegung StopLoss Punkte erreicht. Das Hedging-Flag ermöglicht es, Positionen auf beiden Seiten gleichzeitig zu halten.

Details

  • Einstiegskriterien:
    • Long: Preis fällt um Gap Punkte vom letzten Kaufpreis.
    • Short: Preis steigt um Gap Punkte vom letzten Verkaufspreis.
  • Volumenverwaltung: Das Volumen jeder neuen Order wird mit LotsFactor multipliziert.
  • Ausstiegskriterien:
    • Positionen einer Seite werden geschlossen, wenn der Gewinn TakeProfit Punkte überschreitet.
    • Positionen einer Seite werden geschlossen, wenn der Verlust StopLoss Punkte überschreitet.
  • Parameter:
    • FirstLot – anfängliches Ordervolumen.
    • LotsFactor – Multiplikator für Folgeorders.
    • Gap – Basisabstand zwischen Gitterebenen in Punkten.
    • GapFactor – Multiplikator, der den Abstand nach jedem Trade erweitert.
    • MaxTrades – maximale Anzahl von Trades pro Seite.
    • Hedging – gleichzeitige Long- und Short-Positionen erlauben.
    • TakeProfit – Ziel in Punkten.
    • StopLoss – Schutzlimit in Punkten.
    • CandleType – Kerzen-Zeitrahmen für die Verarbeitung.
  • Long/Short: beide.
  • Filter:
    • Kategorie: Grid / Mean Reversion
    • Richtung: Beide
    • Indikatoren: Keine
    • Stops: Ja
    • Komplexität: Mittel
    • Zeitrahmen: Kurzfristig
    • Saisonalität: Nein
    • Neuronale Netze: Nein
    • Divergenz: Nein
    • Risikolevel: Hoch
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;

/// <summary>
/// EMA crossover strategy (converted from grid).
/// </summary>
public class AeronRobotStrategy : Strategy
{
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevFast;
	private decimal _prevSlow;
	private bool _hasPrev;

	public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
	public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public AeronRobotStrategy()
	{
		_fastPeriod = Param(nameof(FastPeriod), 12)
			.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");

		_slowPeriod = Param(nameof(SlowPeriod), 26)
			.SetDisplay("Slow EMA", "Slow EMA period", "Indicators");

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

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
		=> [(Security, CandleType)];

	protected override void OnReseted()
	{
		base.OnReseted();
		_prevFast = 0;
		_prevSlow = 0;
		_hasPrev = false;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		var fast = new ExponentialMovingAverage { Length = FastPeriod };
		var slow = new ExponentialMovingAverage { Length = SlowPeriod };

		SubscribeCandles(CandleType).Bind(fast, slow, ProcessCandle).Start();
	}

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

		if (!_hasPrev)
		{
			_prevFast = fastVal;
			_prevSlow = slowVal;
			_hasPrev = true;
			return;
		}

		var crossUp = _prevFast <= _prevSlow && fastVal > slowVal;
		var crossDown = _prevFast >= _prevSlow && fastVal < slowVal;

		if (crossUp && Position <= 0)
		{
			if (Position < 0) BuyMarket();
			BuyMarket();
		}
		else if (crossDown && Position >= 0)
		{
			if (Position > 0) SellMarket();
			SellMarket();
		}

		_prevFast = fastVal;
		_prevSlow = slowVal;
	}
}