Wandelt den MetaTrader 4 Expertenberater „Anubis“ in den StockSharp hohen Level API um.
Verwendet einen 4-stündigen Commodity Channel Index (CCI)-Filter zusammen mit einem 15-minütigen MACD-Crossover.
Wendet adaptive Positionsgröße, Stop-Loss, Breakeven-Schutz, ATR-gesteuerte Exits und einen auf der Standardabweichung basierenden Take-Profit an.
Strategielogik
Daten
Primärer Zeitrahmen: 15-Minuten-Kerzen (SignalCandleType), verwendet für MACD- und ATR-Berechnungen.
Höherer Zeitrahmen: 4-Stunden-Kerzen (TrendCandleType), verwendet für CCI-Filterung und Standardabweichungsmessung.
Indikatoren
CommodityChannelIndex mit konfigurierbarem Zeitraum bei der 4H-Serie.
StandardDeviation (Länge 30) bei 4H schließt, um die Take-Profit-Distanz abzuschätzen.
MovingAverageConvergenceDivergenceSignal (schnell/langsam/Signal konfigurierbar) bei 15 Millionen Kerzen.
AverageTrueRange (Länge 12) auf 15 Mio. Kerzen für volatilitätsbasierte Exits.
Einträge
Short: Wenn 4H CCI über CciThreshold liegt, zeigen die beiden vorherigen MACD-Werte einen bearischen Crossover (MACD kreuzt sein Signal), MACD war positiv, es gibt keine offenen Long-Positionen und der Preis hat sich seit dem letzten Short-Einstieg um mindestens PriceFilterPoints bewegt.
Long: symmetrische Bedingung mit CCI unter -CciThreshold, MACD nach oben kreuzend, während negativ, keine offenen Kurzschlüsse und der Mindestabstandsfilter erfüllt.
Risikomanagement
Das Basisvolumen wird durch VolumeValue definiert und wird durch das Kontokapital (2× über 14.000, 3,2× über 22.000) und durch LossFactor nach einem Verlusthandel skaliert.
Die maximale Anzahl gleichzeitiger Trades pro Richtung ist durch MaxLongTrades und MaxShortTrades begrenzt.
Harter Stop-Loss platziert praktisch bei StopLossPoints * PriceStep vom durchschnittlichen Einstiegspreis.
Breakeven wird aktiviert, sobald der Preis um BreakevenPoints steigt, und die Position wird sofort geschlossen, wenn der Preis zum Einstiegsniveau zurückkehrt.
Ausgänge
Der Take-Profit der Standardabweichung schließt die Position, sobald sich der Preis um StdDevMultiplier * StdDev zu seinen Gunsten bewegt.
Aggressive Exits werden ausgelöst, wenn der vorherige Kerzenbereich CloseAtrMultiplier * ATR überschreitet.
MACD-Verlangsamungsausgänge erfordern sowohl einen ausreichenden Gewinn (ProfitThresholdPoints) als auch eine Umkehr der MACD-Steigung (vorheriges MACD vor weniger als oder mehr als zwei Balken, je nach Richtung).
Der Schutzstopp schließt den Handel, wenn der Preis die Stop-Loss-Distanz durchbricht oder nach der Breakeven-Aktivierung auf den Einstiegspunkt zurückfällt.
Parameter
Name
Beschreibung
VolumeValue
Grundauftragsvolumen.
CciThreshold
Absoluter Schwellenwert für den 4H CCI-Filter.
CciPeriod
Zeitraum des 4H CCI-Indikators.
StopLossPoints
Stop-Loss-Distanz in Punkten.
BreakevenPoints
Profitieren Sie von den erforderlichen Punkten, um die Gewinnschwelle zu erreichen.
MacdFastPeriod
Schneller Zeitraum von EMA für MACD.
MacdSlowPeriod
Langsamer Zeitraum von EMA für MACD.
MacdSignalPeriod
Signalisieren Sie einen Zeitraum von EMA für MACD.
LossFactor
Der Volumenmultiplikator wird nach einem Verlusthandel angewendet.
MaxShortTrades
Maximale Anzahl gleichzeitiger kurzer Einträge.
MaxLongTrades
Maximale Anzahl gleichzeitiger langer Einträge.
CloseAtrMultiplier
ATR-Multiplikator für vorzeitige Ausstiege.
ProfitThresholdPoints
Zusätzlicher Gewinnpuffer (Punkte), bevor MACD beendet wird.
StdDevMultiplier
Standardabweichungsmultiplikator für den Take-Profit.
PriceFilterPoints
Minimale Preisbewegung zwischen aufeinanderfolgenden Einträgen.
SignalCandleType
Primärer Zeitrahmen für MACD und ATR.
TrendCandleType
Längerer Zeitrahmen für CCI und Standardabweichung.
Notizen
Die Strategie basiert auf gültigen Security.PriceStep-Metadaten, um punktbasierte Parameter in Preisentfernungen zu übersetzen.
Die Schutzlogik wird über explizite Prüfungen anstelle ausstehender Stop-/Limit-Orders implementiert und spiegelt das ursprüngliche EA-Verhalten mit virtuellen Stops wider.
Die Python-Version wird gemäß den Aufgabenanweisungen absichtlich weggelassen.
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Anubis CCI + MACD strategy.
/// Buys when CCI crosses above 0 and MACD histogram is positive.
/// Sells when CCI crosses below 0 and MACD histogram is negative.
/// </summary>
public class AnubisCciMacdStrategy : Strategy
{
private readonly StrategyParam<int> _cciPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevCci;
private bool _hasPrev;
public int CciPeriod { get => _cciPeriod.Value; set => _cciPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public AnubisCciMacdStrategy()
{
_cciPeriod = Param(nameof(CciPeriod), 14)
.SetDisplay("CCI Period", "CCI lookback period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevCci = 0m;
_hasPrev = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var cci = new CommodityChannelIndex { Length = CciPeriod };
var macd = new MovingAverageConvergenceDivergenceSignal();
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(cci, macd, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue cciValue, IIndicatorValue macdValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!cciValue.IsFinal || !macdValue.IsFinal)
return;
var cci = cciValue.ToDecimal();
var macdVal = (MovingAverageConvergenceDivergenceSignalValue)macdValue;
if (macdVal.Macd is not decimal macd || macdVal.Signal is not decimal signal)
return;
var histogram = macd - signal;
if (!_hasPrev)
{
_prevCci = cci;
_hasPrev = true;
return;
}
// CCI crosses above 0 with bullish MACD
if (_prevCci <= 0 && cci > 0 && histogram > 0 && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
// CCI crosses below 0 with bearish MACD
else if (_prevCci >= 0 && cci < 0 && histogram < 0 && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
_prevCci = cci;
}
}
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, MovingAverageConvergenceDivergenceSignal
from StockSharp.Algo.Strategies import Strategy
class anubis_cci_macd_strategy(Strategy):
"""Anubis CCI + MACD strategy.
Buys when CCI crosses above 0 and MACD histogram is positive.
Sells when CCI crosses below 0 and MACD histogram is negative."""
def __init__(self):
super(anubis_cci_macd_strategy, self).__init__()
self._cci_period = self.Param("CciPeriod", 14) \
.SetDisplay("CCI Period", "CCI lookback period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_cci = 0.0
self._has_prev = False
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def CciPeriod(self):
return self._cci_period.Value
def OnReseted(self):
super(anubis_cci_macd_strategy, self).OnReseted()
self._prev_cci = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(anubis_cci_macd_strategy, self).OnStarted2(time)
self._has_prev = False
cci = CommodityChannelIndex()
cci.Length = self.CciPeriod
macd = MovingAverageConvergenceDivergenceSignal()
subscription = self.SubscribeCandles(self.CandleType)
subscription.BindEx(cci, macd, self._process_candle).Start()
def _process_candle(self, candle, cci_value, macd_value):
if candle.State != CandleStates.Finished:
return
if not cci_value.IsFinal or not macd_value.IsFinal:
return
cci = float(cci_value)
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
histogram = float(macd_raw) - float(signal_raw)
if not self._has_prev:
self._prev_cci = cci
self._has_prev = True
return
# CCI crosses above 0 with bullish MACD
if self._prev_cci <= 0 and cci > 0 and histogram > 0 and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
# CCI crosses below 0 with bearish MACD
elif self._prev_cci >= 0 and cci < 0 and histogram < 0 and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_cci = cci
def CreateClone(self):
return anubis_cci_macd_strategy()