Strategie, die EMA-Kreuzungen mit optionalem Stop-Loss und Take-Profit handelt. Sie kauft, wenn der schnelle EMA den langsamen EMA von unten kreuzt, und verkauft, wenn der schnelle EMA den langsamen EMA von oben kreuzt. Gegenläufige Signale oder Preisziele schließen Positionen.
Details
Einstiegskriterien:
Long: Schneller EMA kreuzt langsamen EMA von unten
Short: Schneller EMA kreuzt langsamen EMA von oben
Long/Short: Beide
Ausstiegskriterien:
Entgegengesetzter EMA-Kreuzung
Long: Kurs erreicht Take-Profit oder Stop-Loss
Short: Kurs erreicht Take-Profit oder Stop-Loss
Stops: Feste Preisoffsets
Standardwerte:
FastPeriod = 13
SlowPeriod = 50
StopLoss = 0.005m
TakeProfit = 0.005m
CandleType = TimeSpan.FromMinutes(5).TimeFrame()
Filter:
Kategorie: Trendfolge
Richtung: Beide
Indikatoren: EMA
Stops: Ja
Komplexität: Grundlegend
Zeitrahmen: Kurzfristig
Saisonalität: Nein
Neuronale Netze: Nein
Divergenz: Nein
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>
/// Simple EMA crossover strategy.
/// </summary>
public class SimulatorStrategy : 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 SimulatorStrategy()
{
_fastPeriod = Param(nameof(FastPeriod), 13)
.SetGreaterThanZero()
.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 50)
.SetGreaterThanZero()
.SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
_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;
}
}