Diese Strategie vergleicht zwei einfache gleitende Durchschnitte (SMA) und handelt auf Basis der Divergenz zwischen ihnen.
Sie verwendet die Differenz zwischen dem schnellen und langsamen SMA der vorherigen Kerze als Divergenzmaß. Ist diese Divergenz positiv und innerhalb eines bestimmten Bereichs, eröffnet die Strategie eine Long-Position. Ist die Divergenz negativ und innerhalb des gespiegelten Bereichs, wird eine Short-Position eröffnet. Das Risiko wird durch optionale Stop-Loss- und Take-Profit-Niveaus gesteuert.
Details
Einstiegskriterien:
Long: Vorheriger schneller SMA - vorheriger langsamer SMA >= DvBuySell und <= DvStayOut.
Short: Vorheriger schneller SMA - vorheriger langsamer SMA <= -DvBuySell und >= -DvStayOut.
Ausstiegskriterien: Positionen werden über Stop-Loss oder Take-Profit geschlossen, wenn konfiguriert.
Stops: Unterstützt über StartProtection mit absoluten Preisabständen.
Standardwerte:
FastPeriod = 7
SlowPeriod = 88
DvBuySell = 0.0011
DvStayOut = 0.0079
Filter:
Kategorie: Trendfolge
Richtung: Beide
Indikatoren: SMA
Stops: Optional
Komplexität: Grundlegend
Zeitrahmen: Kurzfristig
Saisonalität: Nein
Neuronale Netze: Nein
Divergenz: Ja
Risikolevel: Mittel
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>
/// Strategy based on divergence between fast and slow EMA.
/// </summary>
public class DivergenceTraderStrategy : 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 DivergenceTraderStrategy()
{
_fastPeriod = Param(nameof(FastPeriod), 12)
.SetGreaterThanZero()
.SetDisplay("Fast Period", "Fast EMA length", "Parameters");
_slowPeriod = Param(nameof(SlowPeriod), 50)
.SetGreaterThanZero()
.SetDisplay("Slow Period", "Slow EMA length", "Parameters");
_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 = FastPeriod };
var slowEma = new ExponentialMovingAverage { Length = SlowPeriod };
SubscribeCandles(CandleType)
.Bind(fastEma, slowEma, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fastValue, decimal slowValue)
{
if (candle.State != CandleStates.Finished) return;
if (!_hasPrev)
{
_prevFast = fastValue;
_prevSlow = slowValue;
_hasPrev = true;
return;
}
var crossUp = _prevFast <= _prevSlow && fastValue > slowValue;
var crossDown = _prevFast >= _prevSlow && fastValue < slowValue;
if (crossUp && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (crossDown && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
_prevFast = fastValue;
_prevSlow = slowValue;
}
}