Diese Strategie ist ein StockSharp-Port des MetaTrader-Experten "Exp_ColorXDerivative". Sie arbeitet auf einem konfigurierbaren Kerzen-Zeitrahmen (standardmäßig 12-Stunden-Kerzen) und analysiert das ColorXDerivative-Momentum-Histogramm. Der Indikator misst, wie schnell die gewählte Kursquelle über einen festen Versatz hinweg ändert, glättet das Ergebnis mit einem gleitenden Durchschnitt und klassifiziert dann jeden Balken in einen von fünf Farbzuständen. Trades folgen derselben Logik wie im ursprünglichen EA: Der Roboter kauft, wenn sich bullisches Momentum beschleunigt oder eine bärische Bewegung beginnt sich zusammenzuziehen, und verkauft, wenn bärischer Druck zunimmt oder ein bullisches Bein an Stärke verliert.
Indikatorlogik
Jede Kerze in den ausgewählten AppliedPrice umwandeln (Schlusskurs, Eröffnungskurs, gewichteter Schlusskurs, Demark usw.).
Die Kursderivate berechnen: (price[0] - price[shift]) * 100 / shift, wobei shift = DerivativePeriod.
Die Derivate mit der ausgewählten Methode glätten (SMA, EMA, SMMA, LWMA oder Jurik). Der standardmäßige Jurik-gleitende Durchschnitt reproduziert die JJMA-Glättung der MQL-Implementierung.
Einen Farbzustand zuweisen:
0 – Derivate > 0 und steigend (starke bullische Beschleunigung).
3 – Derivate < 0, aber steigend (bärische Bewegung zieht sich zusammen).
4 – Derivate < 0 und fallend (bärische Beschleunigung).
Ein Signalversatz steuert, welcher abgeschlossene Balken ausgewertet wird (1 = letzter geschlossener Balken, 2 = vorheriger Balken usw.).
Handelsregeln
Long-Einstieg: aktiviert wenn EnableLongEntry wahr ist und:
die aktuelle Farbe 0 ist, während die vorherige Farbe nicht 0 war (Momentum dreht scharf bullisch), oder
die aktuelle Farbe 3 ist, während die vorherige Farbe 4 oder 2 war (bärische Bewegung beginnt sich zusammenzuziehen).
Short-Einstieg: aktiviert wenn EnableShortEntry wahr ist und:
die aktuelle Farbe 4 ist, während die vorherige Farbe nicht 4 war (bärische Beschleunigung beginnt), oder
die aktuelle Farbe 1 ist, während die vorherige Farbe 0 oder 2 war (bullische Bewegung lässt nach).
Long-Ausstieg: ausgelöst wenn die aktuelle Farbe 1 oder 4 ist und EnableLongExit wahr ist.
Short-Ausstieg: ausgelöst wenn die aktuelle Farbe 0 oder 3 ist und EnableShortExit wahr ist.
Aufträge werden als Marktaufträge mit dem OrderVolume-Parameter gesendet. Positionsschließungen werden vor neuen Einstiegen ausgeführt, um die sequentielle Logik des ursprünglichen EAs nachzuahmen.
Risikomanagement
Optionale Stop-Loss- und Take-Profit-Abstände werden über StopLossTicks und TakeProfitTicks bereitgestellt. Wenn einer der Werte über null liegt, ruft die Strategie StartProtection auf und konvertiert Ticks in Kursschritte mithilfe der Step-Größe des Wertpapiers. Der Stop-/Zielschutz läuft einmal und ist mit Auto-Trading oder Backtesting kompatibel.
Parameter
OrderVolume – Marktordergröße.
CandleType – Zeitrahmen für die Indikatorberechnungen (Standard: 12-Stunden-Zeitrahmen).
DerivativePeriod – Abstand in Balken für den Derivatversatz.
AppliedPrice – Kursquelle für die Derivate (Schlusskurs, Median, gewichtet, Demark usw.).
SmoothingMethod – Glättungsfilter auf die Derivate angewendet. Unterstützte Werte: SMA, EMA, SMMA, LWMA, Jurik.
SmoothingLength – Periode des Glättungsfilters.
SignalShift – Wie viele abgeschlossene Balken zurück die Farbwerte gelesen werden (1 = neuester geschlossener Balken).
StopLossTicks / TakeProfitTicks – optionale Schutzabstände in Wertpapierschritten.
EnableLongEntry, EnableShortEntry, EnableLongExit, EnableShortExit – Schalter entsprechend den ursprünglichen EA-Eingaben.
Hinweise
Die Strategie reproduziert die indikatorgesteuerte Logik des MetaTrader-EAs ohne zusätzliche Geldverwaltungsfunktionen.
Jurik-Glättung ist die engste Annäherung an den im MQL-Bibliothek verwendeten JJMA-Filter; andere Optionen werden auf die Standard-StockSharp-gleitenden Durchschnitte abgebildet.
Die Farbhistorie wird intern gespeichert, sodass die Optimierung von SignalShift genauso wie in der MetaTrader-Version funktioniert.
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 X Derivative strategy (simplified). Uses Momentum to detect
/// acceleration/deceleration and generate reversal signals.
/// </summary>
public class ColorXDerivativeStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _momentumLength;
private readonly StrategyParam<int> _emaLength;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int MomentumLength
{
get => _momentumLength.Value;
set => _momentumLength.Value = value;
}
public int EmaLength
{
get => _emaLength.Value;
set => _emaLength.Value = value;
}
public ColorXDerivativeStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candles", "General");
_momentumLength = Param(nameof(MomentumLength), 34)
.SetGreaterThanZero()
.SetDisplay("Momentum Length", "Derivative lookback", "Indicators");
_emaLength = Param(nameof(EmaLength), 7)
.SetGreaterThanZero()
.SetDisplay("EMA Length", "Smoothing period", "Indicators");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var momentum = new Momentum { Length = MomentumLength };
var ema = new ExponentialMovingAverage { Length = EmaLength };
decimal prevMom = 0;
var hasPrev = false;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(momentum, ema, (ICandleMessage candle, decimal momValue, decimal emaValue) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!hasPrev)
{
prevMom = momValue;
hasPrev = true;
return;
}
if (!IsFormedAndOnlineAndAllowTrading())
{
prevMom = momValue;
return;
}
var close = candle.ClosePrice;
// Momentum turning positive with price above EMA
if (prevMom <= 0 && momValue > 0 && close > emaValue && Position <= 0)
BuyMarket();
// Momentum turning negative with price below EMA
else if (prevMom >= 0 && momValue < 0 && close < emaValue && Position >= 0)
SellMarket();
prevMom = momValue;
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, ema);
DrawOwnTrades(area);
}
}
}
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 Momentum, ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class color_x_derivative_strategy(Strategy):
def __init__(self):
super(color_x_derivative_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candles", "General")
self._momentum_length = self.Param("MomentumLength", 34) \
.SetDisplay("Momentum Length", "Derivative lookback", "Indicators")
self._ema_length = self.Param("EmaLength", 7) \
.SetDisplay("EMA Length", "Smoothing period", "Indicators")
self._prev_mom = 0.0
self._has_prev = False
@property
def CandleType(self):
return self._candle_type.Value
@property
def MomentumLength(self):
return self._momentum_length.Value
@property
def EmaLength(self):
return self._ema_length.Value
def OnReseted(self):
super(color_x_derivative_strategy, self).OnReseted()
self._prev_mom = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(color_x_derivative_strategy, self).OnStarted2(time)
self._prev_mom = 0.0
self._has_prev = False
momentum = Momentum()
momentum.Length = self.MomentumLength
ema = ExponentialMovingAverage()
ema.Length = self.EmaLength
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(momentum, ema, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ema)
self.DrawOwnTrades(area)
def _on_process(self, candle, mom_value, ema_value):
if candle.State != CandleStates.Finished:
return
mv = float(mom_value)
if not self._has_prev:
self._prev_mom = mv
self._has_prev = True
return
if not self.IsFormedAndOnlineAndAllowTrading():
self._prev_mom = mv
return
close = float(candle.ClosePrice)
ev = float(ema_value)
if self._prev_mom <= 0 and mv > 0 and close > ev and self.Position <= 0:
self.BuyMarket()
elif self._prev_mom >= 0 and mv < 0 and close < ev and self.Position >= 0:
self.SellMarket()
self._prev_mom = mv
def CreateClone(self):
return color_x_derivative_strategy()