Diese Strategie handelt basierend auf der Richtung eines gleitenden Durchschnitts der dritten Generation. Der Indikator ist eine Kombination aus zwei exponentiellen gleitenden Durchschnitten und wird blau, wenn er steigt, und rosa, wenn er fällt. Ein Kaufsignal wird aufgezeichnet, wenn der Durchschnitt nach oben dreht, und ein Verkaufssignal, wenn er nach unten dreht.
Aufträge werden nur zu einer benutzerdefinierten Zeit nach dem Erscheinen eines Signals platziert. Positionen können auch geschlossen werden, wenn das entgegengesetzte Signal erkannt wird oder eine vordefinierte Haltezeit abläuft. Optionale Stop-Loss- und Take-Profit-Level werden in Punkten gemessen.
Parameter
Length – Glättungsperiode des Durchschnitts der dritten Generation.
StartHour – Stunde, zu der neue Positionen eröffnet werden können.
StartMinute – Minute innerhalb der Stunde, wenn Eröffnungen erlaubt sind.
HoldMinutes – maximale Zeit zum Halten einer offenen Position.
Volume – Auftragsvolumen für Einstiege.
StopLoss – Stop-Loss-Abstand in Punkten. 0 deaktiviert den Stop.
TakeProfit – Take-Profit-Abstand in Punkten. 0 deaktiviert das Ziel.
UseLongEntries – Long-Einstiege aktivieren.
UseShortEntries – Short-Einstiege aktivieren.
CloseLongBySignal – Long-Positionen schließen, wenn ein Verkaufssignal erscheint.
CloseShortBySignal – Short-Positionen schließen, wenn ein Kaufsignal erscheint.
CandleType – Zeitrahmen der für Berechnungen verwendeten Kerzen.
Logik
Kerzen des ausgewählten Zeitrahmens abonnieren.
Den gleitenden Durchschnitt der dritten Generation für jede Kerze berechnen.
Erkennen, wenn der Durchschnitt zwischen aufeinanderfolgenden Kerzen steigt oder fällt.
Ein Kauf- oder Verkaufssignal basierend auf der Richtungsänderung speichern.
Zur angegebenen Öffnungszeit in Richtung des gespeicherten Signals einsteigen.
Positionen bei entgegengesetzten Signalen, wenn die Haltezeit abläuft oder wenn Stop-Loss/Take-Profit-Level erreicht werden, schließen.
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>
/// Color 3rd Generation XMA strategy.
/// Uses two EMAs of different periods to approximate 3rd generation moving average.
/// Opens long when fast EMA crosses above slow EMA, short when crosses below.
/// </summary>
public class Color3RdGenXmaStrategy : Strategy
{
private readonly StrategyParam<int> _fastLength;
private readonly StrategyParam<int> _slowLength;
private readonly StrategyParam<decimal> _minSpread;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevFast;
private decimal _prevSlow;
private bool _isFirst = true;
public int FastLength { get => _fastLength.Value; set => _fastLength.Value = value; }
public int SlowLength { get => _slowLength.Value; set => _slowLength.Value = value; }
public decimal MinSpread { get => _minSpread.Value; set => _minSpread.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public Color3RdGenXmaStrategy()
{
_fastLength = Param(nameof(FastLength), 20)
.SetGreaterThanZero()
.SetDisplay("Fast EMA", "Fast EMA period", "General");
_slowLength = Param(nameof(SlowLength), 50)
.SetGreaterThanZero()
.SetDisplay("Slow EMA", "Slow EMA period", "General");
_minSpread = Param(nameof(MinSpread), 20m)
.SetGreaterThanZero()
.SetDisplay("Min Spread", "Minimum EMA spread in price steps", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Timeframe for calculations", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevFast = 0m;
_prevSlow = 0m;
_isFirst = true;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevFast = 0m;
_prevSlow = 0m;
_isFirst = true;
var fastEma = new ExponentialMovingAverage { Length = FastLength };
var slowEma = new ExponentialMovingAverage { Length = SlowLength };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(fastEma, slowEma, 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)
{
if (candle.State != CandleStates.Finished)
return;
if (_isFirst)
{
_prevFast = fast;
_prevSlow = slow;
_isFirst = false;
return;
}
if (!IsFormedAndOnlineAndAllowTrading())
{
_prevFast = fast;
_prevSlow = slow;
return;
}
var step = Security.PriceStep ?? 1m;
var spread = Math.Abs(fast - slow);
if (spread < MinSpread * step)
{
_prevFast = fast;
_prevSlow = slow;
return;
}
var prevAbove = _prevFast > _prevSlow;
var curAbove = fast > slow;
if (!prevAbove && curAbove && Position <= 0)
BuyMarket();
else if (prevAbove && !curAbove && Position >= 0)
SellMarket();
_prevFast = fast;
_prevSlow = slow;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class color_3rd_gen_xma_strategy(Strategy):
def __init__(self):
super(color_3rd_gen_xma_strategy, self).__init__()
self._fast_length = self.Param("FastLength", 20) \
.SetDisplay("Fast EMA", "Fast EMA period", "General")
self._slow_length = self.Param("SlowLength", 50) \
.SetDisplay("Slow EMA", "Slow EMA period", "General")
self._min_spread = self.Param("MinSpread", 20.0) \
.SetDisplay("Min Spread", "Minimum EMA spread in price steps", "General")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Timeframe for calculations", "General")
self._prev_fast = 0.0
self._prev_slow = 0.0
self._is_first = True
@property
def fast_length(self):
return self._fast_length.Value
@property
def slow_length(self):
return self._slow_length.Value
@property
def min_spread(self):
return self._min_spread.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(color_3rd_gen_xma_strategy, self).OnReseted()
self._prev_fast = 0.0
self._prev_slow = 0.0
self._is_first = True
def OnStarted2(self, time):
super(color_3rd_gen_xma_strategy, self).OnStarted2(time)
self._prev_fast = 0.0
self._prev_slow = 0.0
self._is_first = True
fast_ema = ExponentialMovingAverage()
fast_ema.Length = int(self.fast_length)
slow_ema = ExponentialMovingAverage()
slow_ema.Length = int(self.slow_length)
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(fast_ema, slow_ema, self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, fast_ema)
self.DrawIndicator(area, slow_ema)
self.DrawOwnTrades(area)
def process_candle(self, candle, fast, slow):
if candle.State != CandleStates.Finished:
return
fast = float(fast)
slow = float(slow)
if self._is_first:
self._prev_fast = fast
self._prev_slow = slow
self._is_first = False
return
spread = abs(fast - slow)
ms = float(self.min_spread)
price_step = float(self.Security.PriceStep) if self.Security.PriceStep is not None else 1.0
if spread < ms * price_step:
self._prev_fast = fast
self._prev_slow = slow
return
prev_above = self._prev_fast > self._prev_slow
cur_above = fast > slow
if not prev_above and cur_above and self.Position <= 0:
self.BuyMarket()
elif prev_above and not cur_above and self.Position >= 0:
self.SellMarket()
self._prev_fast = fast
self._prev_slow = slow
def CreateClone(self):
return color_3rd_gen_xma_strategy()