Diese Strategie ist eine StockSharp-Implementierung des "ColorXMACDCandle"-Expert Advisors. Sie handelt mit dem MACD-Indikator und interpretiert Farbänderungen des Histogramms oder seiner Signallinie als Einstiegssignale.
Idee
Die Strategie analysiert die Neigung einer MACD-Komponente:
Histogramm-Modus – Ein neuer Histogrammbalken, der über den vorherigen Balken steigt, signalisiert wachsendes bullishes Momentum. Ein neuer Balken, der unter den vorherigen fällt, signalisiert bearishes Momentum.
Signallinienmodus – Stattdessen wird die Neigung der MACD-Signallinie verwendet. Eine aufwärts gerichtete Neigung wirkt als Kaufsignal, während eine abwärts gerichtete Neigung als Verkaufssignal wirkt.
Wenn die gewählte Komponente aufwärts dreht und vorher nicht gestiegen war, kann eine Short-Position geschlossen und eine neue Long-Position eröffnet werden. Wenn die Komponente abwärts dreht und vorher nicht gefallen war, kann eine Long-Position geschlossen und eine Short-Position eröffnet werden.
Das Verhalten beim Öffnen und Schließen von Positionen wird durch separate Parameter gesteuert, sodass der Benutzer jede Aktion unabhängig aktivieren oder deaktivieren kann.
Parameter
Mode – Signalquelle: Histogram oder SignalLine.
FastPeriod – Schneller EMA-Zeitraum für MACD.
SlowPeriod – Langsamer EMA-Zeitraum für MACD.
SignalPeriod – MACD-Signal-Glättungszeitraum.
EnableBuyOpen – Eröffnung von Long-Positionen erlauben.
EnableSellOpen – Eröffnung von Short-Positionen erlauben.
EnableBuyClose – Schließen von Long-Positionen erlauben.
EnableSellClose – Schließen von Short-Positionen erlauben.
CandleType – Kerzentyp für Berechnungen.
Handelsregeln
Abonniere die ausgewählte Kerzenserie und berechne den MACD-Indikator.
Verfolge die Neigung des Histogramms oder der Signallinie je nach ausgewähltem Modus.
Wenn die Neigung aufwärts dreht, schließe alle Short-Positionen (wenn erlaubt) und öffne optional eine Long-Position.
Wenn die Neigung abwärts dreht, schließe alle Long-Positionen (wenn erlaubt) und öffne optional eine Short-Position.
Die Strategie enthält keine Stop-Loss- oder Take-Profit-Mechanismen. Risikomanagement kann bei Bedarf separat hinzugefügt werden.
using System;
using System.Linq;
using System.Collections.Generic;
using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Strategy that reacts to slope changes of the MACD histogram.
/// Buys when histogram slope turns up, sells when it turns down.
/// </summary>
public class ColorXMacdCandleStrategy : Strategy
{
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<int> _signalPeriod;
private readonly StrategyParam<DataType> _candleType;
private ExponentialMovingAverage _signalMa;
private decimal? _prevHist;
private decimal? _prevPrevHist;
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public int SignalPeriod { get => _signalPeriod.Value; set => _signalPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public ColorXMacdCandleStrategy()
{
_fastPeriod = Param(nameof(FastPeriod), 12)
.SetGreaterThanZero()
.SetDisplay("Fast Period", "Fast EMA period", "MACD");
_slowPeriod = Param(nameof(SlowPeriod), 26)
.SetGreaterThanZero()
.SetDisplay("Slow Period", "Slow EMA period", "MACD");
_signalPeriod = Param(nameof(SignalPeriod), 9)
.SetGreaterThanZero()
.SetDisplay("Signal Period", "Signal line period", "MACD");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle type for calculations", "Common");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_signalMa = null;
_prevHist = null;
_prevPrevHist = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var macd = new MovingAverageConvergenceDivergence();
macd.ShortMa.Length = FastPeriod;
macd.LongMa.Length = SlowPeriod;
_signalMa = new ExponentialMovingAverage { Length = SignalPeriod };
Indicators.Add(_signalMa);
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(macd, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, macd);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue macdValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!macdValue.IsFormed)
return;
var macdLine = macdValue.GetValue<decimal>();
var signalResult = _signalMa.Process(macdValue);
if (!signalResult.IsFormed)
return;
var signalLine = signalResult.GetValue<decimal>();
var hist = macdLine - signalLine;
if (!IsFormedAndOnlineAndAllowTrading())
{
_prevPrevHist = _prevHist;
_prevHist = hist;
return;
}
if (_prevHist is decimal ph && _prevPrevHist is decimal pph)
{
var wasRising = ph > pph;
var nowRising = hist > ph;
// Histogram slope turns up -> buy
if (!wasRising && nowRising && Position <= 0)
BuyMarket();
// Histogram slope turns down -> sell
else if (wasRising && !nowRising && Position >= 0)
SellMarket();
}
_prevPrevHist = _prevHist;
_prevHist = hist;
}
}
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 MovingAverageConvergenceDivergence, ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class color_xmacd_candle_strategy(Strategy):
def __init__(self):
super(color_xmacd_candle_strategy, self).__init__()
self._fast_period = self.Param("FastPeriod", 12) \
.SetDisplay("Fast Period", "Fast EMA period", "MACD")
self._slow_period = self.Param("SlowPeriod", 26) \
.SetDisplay("Slow Period", "Slow EMA period", "MACD")
self._signal_period = self.Param("SignalPeriod", 9) \
.SetDisplay("Signal Period", "Signal line period", "MACD")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candle type for calculations", "Common")
self._signal_ma = None
self._prev_hist = None
self._prev_prev_hist = None
@property
def fast_period(self):
return self._fast_period.Value
@property
def slow_period(self):
return self._slow_period.Value
@property
def signal_period(self):
return self._signal_period.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(color_xmacd_candle_strategy, self).OnReseted()
self._signal_ma = None
self._prev_hist = None
self._prev_prev_hist = None
def OnStarted2(self, time):
super(color_xmacd_candle_strategy, self).OnStarted2(time)
macd = MovingAverageConvergenceDivergence()
macd.ShortMa.Length = self.fast_period
macd.LongMa.Length = self.slow_period
self._signal_ma = ExponentialMovingAverage()
self._signal_ma.Length = self.signal_period
self.Indicators.Add(self._signal_ma)
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(macd, self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, macd)
self.DrawOwnTrades(area)
def process_candle(self, candle, macd_value):
if candle.State != CandleStates.Finished:
return
if not macd_value.IsFormed:
return
macd_line = float(macd_value)
signal_result = self._signal_ma.Process(macd_value)
if not signal_result.IsFormed:
return
signal_line = float(signal_result)
hist = macd_line - signal_line
if self._prev_hist is not None and self._prev_prev_hist is not None:
was_rising = self._prev_hist > self._prev_prev_hist
now_rising = hist > self._prev_hist
if not was_rising and now_rising and self.Position <= 0:
self.BuyMarket()
elif was_rising and not now_rising and self.Position >= 0:
self.SellMarket()
self._prev_prev_hist = self._prev_hist
self._prev_hist = hist
def CreateClone(self):
return color_xmacd_candle_strategy()