Eine Strategie, die gestaffelte Positionen eröffnet, wenn der Stochastik-Oszillator auf Vier-Stunden-Kerzen Extremwerte erreicht. Es wird zunächst eine Marktorder platziert, gefolgt von einem Raster aus Limitorders. Positionen werden geschlossen, sobald ein Gewinnziel erreicht ist und der Trend durch gleitende Durchschnitte und Bollinger Bänder bestätigt wird.
Einstiegsregeln
Stochastik-Oszillator (%K-Länge 21, Glättung 3) auf H4-Kerzen verwenden.
Wenn %K ≥ Überkauft-Niveau:
Zum Marktpreis verkaufen.
Bis zu acht zusätzliche SellLimit-Orders oberhalb des aktuellen Preises in konfigurierten Pip-Abständen platzieren.
Wenn %K ≤ Überverkauft-Niveau:
Zum Marktpreis kaufen.
Bis zu acht zusätzliche BuyLimit-Orders unterhalb des aktuellen Preises in konfigurierten Pip-Abständen platzieren.
Ausstiegsregeln
Realisierter Gewinn erreicht ProfitTarget und Preis bestätigt Trend:
Long-Positionen werden geschlossen, wenn der Kurs über dem unteren Bollinger Band liegt und die 200-Perioden-SMA über der 55-Perioden-SMA liegt.
Short-Positionen werden geschlossen, wenn der Kurs unter dem oberen Bollinger Band liegt und die 200-Perioden-SMA unter der 55-Perioden-SMA liegt.
Ausstehende Kauf-Limits werden storniert, wenn %K ≥ 90 und die 200-Perioden-SMA ≤ 55-Perioden-SMA.
Ausstehende Verkauf-Limits werden storniert, wenn %K ≤ 10 und die 200-Perioden-SMA ≥ 55-Perioden-SMA.
Parameter
StochLength – %K-Periode für den Stochastik.
OverboughtLevel – Niveau, ab dem verkauft wird.
OversoldLevel – Niveau, ab dem gekauft wird.
ProfitTarget – erforderlicher realisierter Gewinn zum Schließen offener Positionen.
Order2Offset … Order9Offset – Pip-Abstände für zusätzliche Limitorders.
CandleType – Zeitrahmen der Kerzen, Standard 4 Stunden.
Indikatoren
StochasticOscillator
BollingerBands
SMA (200 und 55)
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 inspired by Elliott wave concept.
/// </summary>
public class ElliottTraderStrategy : 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 ElliottTraderStrategy()
{
_fastPeriod = Param(nameof(FastPeriod), 12)
.SetGreaterThanZero()
.SetDisplay("Fast Period", "Fast EMA period", "Indicator");
_slowPeriod = Param(nameof(SlowPeriod), 26)
.SetGreaterThanZero()
.SetDisplay("Slow Period", "Slow EMA period", "Indicator");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle type", "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;
}
}