SMC Trader Camel CCI MACD Strategie
Überblick
Diese Strategie ist eine StockSharp-Portierung des MetaTrader 4-Expertenberaters "Steve Cartwright Trader Camel CCI MACD".
Es reproduziert die ursprüngliche Handelslogik basierend auf einem exponentiellen gleitenden Durchschnittskanal im Kamelstil.
ein MACD-Trendfilter und Schwellenwerte für den Commodity Channel Index (CCI). Trades werden nach Abschluss ausgeführt
Kerzen, um deterministisches Verhalten sicherzustellen und nahe am Bar-für-Bar-Workflow der MQL-Version zu bleiben.
Handelslogik
- Indikatoren
- Zwei exponentielle gleitende Durchschnitte (EMA) mit derselben Periode werden auf Kerzenhochs und -tiefs angewendet, um das zu bilden
Kamelkanal. Ein Ausbruch des vorherigen Schlusskurses über diese Hüllkurven hinaus signalisiert die Stärke des Momentums.
- Ein Standard-MACD-Indikator (schneller EMA, langsamer EMA und Signallinie) wird verwendet, um die zugrunde liegende Trendrichtung zu bestätigen.
- Ein CCI-Indikator validiert die Momentumstärke anhand der standardmäßig überkauften/überverkauften Niveaus von ±100.
- Lange Einträge
- Der vorherige Kerzenschluss liegt über dem Kamelhoch EMA.
- Der vorherige MACD-Hauptwert liegt über Null und über der Signallinie.
- Der vorherige CCI-Wert liegt über dem positiven Schwellenwert.
- Es ist keine aktive Position offen und es erfolgte kein Ausstieg innerhalb des aktuellen Candle-Zeitrahmens (verhindert einen schnellen Wiedereinstieg).
- Kurze Einträge
- Der vorherige Kerzenschluss liegt unter dem Kameltief EMA.
- Der vorherige MACD-Hauptwert liegt unter Null und unterhalb der Signallinie.
- Der vorherige CCI-Wert liegt unter dem negativen Schwellenwert.
- Gleiche flache Positions- und Abklingbedingungen wie bei langen Setups.
- Ausgänge
- Long-Positionen werden geschlossen, wenn der vorherige MACD-Hauptwert die Signallinie unterschreitet oder wenn der vorherige CCI
Der Wert fällt unter den positiven Schwellenwert.
- Short-Positionen werden geschlossen, wenn der vorherige MACD-Hauptwert die Signallinie überschreitet.
- Nach jedem Austritt wird vor neuen Eintritten eine Abklingzeit von einer Kerzendauer erzwungen.
Die Strategie handelt höchstens einmal pro Balken, da jede Entscheidung auf Daten der zuvor abgeschlossenen Kerze basiert.
Parameter
| Parameter |
Beschreibung |
Standard |
CandleType |
Kerzendatentyp/Zeitrahmen, der für alle Indikatoren verwendet wird. |
1-stündiger Zeitrahmen |
CamelLength |
Länge des Hoch-/Tief-EMA-Kanals. |
34 |
CciPeriod |
Länge des CCI-Filters. |
20 |
MacdFastPeriod |
Schnelle EMA-Länge für MACD. |
12 |
MacdSlowPeriod |
Langsame EMA-Länge für MACD. |
26 |
MacdSignalPeriod |
Signalglättungszeitraum für MACD. |
9 |
CciThreshold |
Absoluter CCI-Pegel, der für Einträge überschritten werden muss (symmetrisch angewendet). |
100 |
Alle Parameter sind dank der SetOptimize-Aufrufe durch den StockSharp-Optimierer optimierbar.
Risikomanagement
- Bestellungen werden über
BuyMarket und SellMarket gesendet, wobei die Strategieeigenschaft Volume geerbt wird.
StartProtection() ist aktiviert, um standardmäßige StockSharp-Schutzhelfer zu initialisieren.
- Im ursprünglichen Algorithmus ist kein fester Stop-Loss oder Take-Profit definiert; Exits basieren ausschließlich auf Indikatorsignalen.
Diagramme
Die Strategie zeichnet automatisch die Kamel-Indikatoren EMA-Kanal, MACD und CCI zusammen mit eigenen Trades auf.
Dies repliziert die visuellen Hinweise, die in der MT4-Implementierung verwendet wurden.
Notizen
- Der Abklingzeit-Timer verwendet die von
CandleType.Arg abgeleitete Kerzendauer. Stellen Sie sicher, dass CandleType ein enthält
TimeSpan-Argument, wenn Sie den Zeitrahmen ändern.
- Da alle Entscheidungen auf den Werten des vorherigen Balkens basieren, spiegelt die Reihenfolge der Operationen die
iMACD, iCCI wider.
und iMA (mit Shift=1) ruft in der Quelle EA auf.
namespace StockSharp.Samples.Strategies;
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
/// <summary>
/// Strategy combining CCI and MACD signal crossover with EMA trend filter.
/// Buy when MACD crosses above signal with CCI positive and price above EMA.
/// Sell when MACD crosses below signal with CCI negative and price below EMA.
/// </summary>
public class SmcTraderCamelCciMacd1Strategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _emaLength;
private readonly StrategyParam<int> _macdFastPeriod;
private readonly StrategyParam<int> _macdSlowPeriod;
private readonly StrategyParam<int> _macdSignalPeriod;
private readonly StrategyParam<int> _cciPeriod;
private decimal? _prevMacdMain;
private decimal? _prevMacdSignal;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int EmaLength { get => _emaLength.Value; set => _emaLength.Value = value; }
public int MacdFastPeriod { get => _macdFastPeriod.Value; set => _macdFastPeriod.Value = value; }
public int MacdSlowPeriod { get => _macdSlowPeriod.Value; set => _macdSlowPeriod.Value = value; }
public int MacdSignalPeriod { get => _macdSignalPeriod.Value; set => _macdSignalPeriod.Value = value; }
public int CciPeriod { get => _cciPeriod.Value; set => _cciPeriod.Value = value; }
public SmcTraderCamelCciMacd1Strategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_emaLength = Param(nameof(EmaLength), 34)
.SetDisplay("EMA Length", "Trend EMA period", "Indicators");
_macdFastPeriod = Param(nameof(MacdFastPeriod), 12)
.SetDisplay("MACD Fast", "Fast EMA for MACD", "Indicators");
_macdSlowPeriod = Param(nameof(MacdSlowPeriod), 26)
.SetDisplay("MACD Slow", "Slow EMA for MACD", "Indicators");
_macdSignalPeriod = Param(nameof(MacdSignalPeriod), 9)
.SetDisplay("MACD Signal", "Signal line period", "Indicators");
_cciPeriod = Param(nameof(CciPeriod), 20)
.SetDisplay("CCI Period", "CCI period", "Indicators");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevMacdMain = null;
_prevMacdSignal = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevMacdMain = null;
_prevMacdSignal = null;
var ema = new ExponentialMovingAverage { Length = EmaLength };
var macd = new MovingAverageConvergenceDivergenceSignal
{
Macd =
{
ShortMa = { Length = MacdFastPeriod },
LongMa = { Length = MacdSlowPeriod }
},
SignalMa = { Length = MacdSignalPeriod }
};
var cci = new CommodityChannelIndex { Length = CciPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(macd, cci, ema, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue macdValue, IIndicatorValue cciValue, IIndicatorValue emaValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!macdValue.IsFinal || !cciValue.IsFinal || !emaValue.IsFinal)
return;
if (macdValue is not MovingAverageConvergenceDivergenceSignalValue macdData)
return;
if (macdData.Macd is not decimal macdMain || macdData.Signal is not decimal macdSignal)
return;
var cci = cciValue.ToDecimal();
var emaVal = emaValue.ToDecimal();
if (_prevMacdMain is not decimal prevMain || _prevMacdSignal is not decimal prevSignal)
{
_prevMacdMain = macdMain;
_prevMacdSignal = macdSignal;
return;
}
var macdBullCross = prevMain <= prevSignal && macdMain > macdSignal;
var macdBearCross = prevMain >= prevSignal && macdMain < macdSignal;
// Long: MACD bullish cross + CCI > 0 + price above EMA
if (Position <= 0 && macdBullCross && cci > 0 && candle.ClosePrice > emaVal)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
// Short: MACD bearish cross + CCI < 0 + price below EMA
else if (Position >= 0 && macdBearCross && cci < 0 && candle.ClosePrice < emaVal)
{
if (Position > 0)
SellMarket();
SellMarket();
}
_prevMacdMain = macdMain;
_prevMacdSignal = macdSignal;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Math
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import (
CommodityChannelIndex,
ExponentialMovingAverage,
MovingAverageConvergenceDivergenceSignal
)
from StockSharp.Algo.Strategies import Strategy
class smc_trader_camel_cci_macd1_strategy(Strategy):
"""Strategy combining CCI and MACD signal crossover with EMA trend filter.
Buy when MACD crosses above signal with CCI positive and price above EMA.
Sell when MACD crosses below signal with CCI negative and price below EMA."""
def __init__(self):
super(smc_trader_camel_cci_macd1_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._ema_length = self.Param("EmaLength", 34) \
.SetDisplay("EMA Length", "Trend EMA period", "Indicators")
self._macd_fast_period = self.Param("MacdFastPeriod", 12) \
.SetDisplay("MACD Fast", "Fast EMA for MACD", "Indicators")
self._macd_slow_period = self.Param("MacdSlowPeriod", 26) \
.SetDisplay("MACD Slow", "Slow EMA for MACD", "Indicators")
self._macd_signal_period = self.Param("MacdSignalPeriod", 9) \
.SetDisplay("MACD Signal", "Signal line period", "Indicators")
self._cci_period = self.Param("CciPeriod", 20) \
.SetDisplay("CCI Period", "CCI period", "Indicators")
self._prev_macd_main = None
self._prev_macd_signal = None
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def EmaLength(self):
return self._ema_length.Value
@property
def MacdFastPeriod(self):
return self._macd_fast_period.Value
@property
def MacdSlowPeriod(self):
return self._macd_slow_period.Value
@property
def MacdSignalPeriod(self):
return self._macd_signal_period.Value
@property
def CciPeriod(self):
return self._cci_period.Value
def OnReseted(self):
super(smc_trader_camel_cci_macd1_strategy, self).OnReseted()
self._prev_macd_main = None
self._prev_macd_signal = None
def OnStarted2(self, time):
super(smc_trader_camel_cci_macd1_strategy, self).OnStarted2(time)
self._prev_macd_main = None
self._prev_macd_signal = None
ema = ExponentialMovingAverage()
ema.Length = self.EmaLength
macd = MovingAverageConvergenceDivergenceSignal()
macd.Macd.ShortMa.Length = self.MacdFastPeriod
macd.Macd.LongMa.Length = self.MacdSlowPeriod
macd.SignalMa.Length = self.MacdSignalPeriod
cci = CommodityChannelIndex()
cci.Length = self.CciPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.BindEx(macd, cci, ema, self._process_candle).Start()
def _process_candle(self, candle, macd_value, cci_value, ema_value):
if candle.State != CandleStates.Finished:
return
if not macd_value.IsFinal or not cci_value.IsFinal or not ema_value.IsFinal:
return
macd_raw = macd_value.Macd if hasattr(macd_value, 'Macd') else None
signal_raw = macd_value.Signal if hasattr(macd_value, 'Signal') else None
if macd_raw is None or signal_raw is None:
return
macd_main = float(macd_raw)
macd_signal = float(signal_raw)
cci_val = float(cci_value)
ema_val = float(ema_value)
if self._prev_macd_main is None or self._prev_macd_signal is None:
self._prev_macd_main = macd_main
self._prev_macd_signal = macd_signal
return
prev_main = self._prev_macd_main
prev_signal = self._prev_macd_signal
macd_bull_cross = prev_main <= prev_signal and macd_main > macd_signal
macd_bear_cross = prev_main >= prev_signal and macd_main < macd_signal
close = float(candle.ClosePrice)
# Long: MACD bullish cross + CCI > 0 + price above EMA
if self.Position <= 0 and macd_bull_cross and cci_val > 0 and close > ema_val:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
# Short: MACD bearish cross + CCI < 0 + price below EMA
elif self.Position >= 0 and macd_bear_cross and cci_val < 0 and close < ema_val:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_macd_main = macd_main
self._prev_macd_signal = macd_signal
def CreateClone(self):
return smc_trader_camel_cci_macd1_strategy()