Auf GitHub ansehen

EMA SAR Power-Strategie

Diese Intraday-Strategie kombiniert schnelle und langsame exponentielle gleitende Durchschnitte mit Parabolic SAR und Bulls/Bears-Power-Indikatoren. Sie handelt nur während aktiver Marktstunden und erfordert ausreichend freie Margin vor dem Einstieg in eine Position.

Das System geht short, wenn die schnelle EMA unter der langsamen EMA liegt, Parabolic SAR über dem Kerzenhoch sitzt und Bears Power steigt, während sie negativ bleibt. Es geht long, wenn die schnelle EMA über der langsamen EMA liegt, Parabolic SAR unter dem Kerzentief liegt und Bulls Power fällt, aber noch positiv ist. Jeder Trade platziert einen weiten Stop-Loss und einen näheren Take-Profit.

Dynamischer Margin-Filter

Vor dem Handel prüft die Strategie die freie Margin des Portfolios. Abhängig von deren Wert erhöht sich die erforderliche Mindestmarge stufenweise: 600 → 1000 → 1300 → 1500 → 1800 → 2000 → 2500. Der Handel wird übersprungen, wenn die freie Margin unter den aktuellen Schwellenwert fällt.

Details

  • Einstiegskriterien:
    • Short: EMA3 < EMA34 && SAR > High && BearsPower < 0 && BearsPower > BearsPower[1].
    • Long: EMA3 > EMA34 && SAR < Low && BullsPower > 0 && BullsPower < BullsPower[1].
  • Long/Short: Beide Seiten.
  • Stop/Ziel: Stop-Loss bei 2000 Punkten, Take-Profit bei 400 Punkten.
  • Zeitfilter: Handelt nur zwischen 09:00 und 16:59 Brokerzeit.
  • Indikatoren:
    • Exponentielle gleitende Durchschnitte (3, 34) auf Median-Preis.
    • Parabolic SAR (Schritt 0.02, Maximum 0.2).
    • Bulls Power (13) und Bears Power (13).
  • Standardvolumen: 30 Kontrakte.
  • Zeitrahmen: 15-Minuten-Kerzen.
  • Filter:
    • Kategorie: Trendfolge
    • Richtung: Beide
    • Indikatoren: Mehrere
    • Stops: Ja
    • Komplexität: Moderat
    • Zeitrahmen: Intraday
    • 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 with Parabolic SAR confirmation.
/// Buys when fast EMA above slow EMA and SAR below price.
/// Sells when fast EMA below slow EMA and SAR above price.
/// </summary>
public class EmaSarPowerStrategy : Strategy
{
	private readonly StrategyParam<int> _fastLength;
	private readonly StrategyParam<int> _slowLength;
	private readonly StrategyParam<DataType> _candleType;

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

	public int FastLength { get => _fastLength.Value; set => _fastLength.Value = value; }
	public int SlowLength { get => _slowLength.Value; set => _slowLength.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public EmaSarPowerStrategy()
	{
		_fastLength = Param(nameof(FastLength), 3)
			.SetGreaterThanZero()
			.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");

		_slowLength = Param(nameof(SlowLength), 34)
			.SetGreaterThanZero()
			.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 fastEma = new ExponentialMovingAverage { Length = FastLength };
		var slowEma = new ExponentialMovingAverage { Length = SlowLength };
		var sar = new ParabolicSar();

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fastEma, slowEma, sar, ProcessCandle)
			.Start();

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

	private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow, decimal sar)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (!_hasPrev)
		{
			_prevFast = fast;
			_prevSlow = slow;
			_hasPrev = true;
			return;
		}

		// Buy: EMA crossover up + SAR below price
		if (_prevFast <= _prevSlow && fast > slow && sar < candle.LowPrice)
		{
			if (Position <= 0)
				BuyMarket();
		}
		// Sell: EMA crossover down + SAR above price
		else if (_prevFast >= _prevSlow && fast < slow && sar > candle.HighPrice)
		{
			if (Position >= 0)
				SellMarket();
		}

		_prevFast = fast;
		_prevSlow = slow;
	}
}