Expert MACD EURUSD 1 Stunde-Strategie
Überblick
Diese Strategie ist eine C#-Übersetzung des MetaTrader 5-Expertenberaters Expert MACD EURUSD 1 Hour. Sie handelt auf Stunden-Kerzen mit dem MACD-Indikator mit kurzen, langen und Signalperioden von 5 / 15 / 3. Die Strategie sucht nach einer starken Momentum-Verschiebung, bei der die MACD-Hauptlinie den Nullpegel nach oben oder unten kreuzt, während die Signallinie die Bewegung bestätigt. Ein Trailing Stop wird verwendet, um offene Positionen zu schützen, und Trades werden geschlossen, wenn die MACD-Steigung gegen die aktuelle Position dreht.
Parameter
FastLength – schnelle EMA-Periode für MACD (Standard: 5).
SlowLength – langsame EMA-Periode für MACD (Standard: 15).
SignalLength – Signallinen-Periode für MACD (Standard: 3).
TrailingPoints – Trailing-Stop-Abstand in Kurseinheiten (Standard: 25).
CandleType – Zeitrahmen der Kerzen (Standard: 1 Stunde).
- Die
Volume-Eigenschaft der Strategie steuert die Ordergröße.
Handelslogik
Long-Einstieg
- Signallinien-Werte:
mac8 > mac7 > mac6 und mac6 < mac5 (Signallinie steigt).
- Hauptlinien-Werte:
mac4 > mac3 < mac2 < mac1 (Hauptlinie steigt nach einem Rückgang).
mac2 < -0.00020, mac4 < 0 und mac1 > 0.00020 – Hauptlinie kreuzt den Nullpegel nach oben.
- Wenn alle Bedingungen erfüllt sind und keine Long-Position offen ist, zu Marktpreisen kaufen.
Short-Einstieg
- Signallinien-Werte:
mac8 < mac7 < mac6 und mac6 > mac5 (Signallinie fällt).
- Hauptlinien-Werte:
mac4 < mac3 > mac2 > mac1 (Hauptlinie fällt nach einem Hoch).
mac2 > 0.00020, mac4 > 0 und mac1 < -0.00035 – Hauptlinie kreuzt den Nullpegel nach unten.
- Wenn alle Bedingungen erfüllt sind und keine Short-Position offen ist, zu Marktpreisen verkaufen.
Ausstiegsregeln
- Ein Long schließen, wenn der aktuelle Hauptwert unter dem vorherigen liegt.
- Ein Short schließen, wenn der aktuelle Hauptwert über dem vorherigen liegt.
- Der Trailing Stop aktualisiert sich auf jeder Kerze und steigt aus, wenn der Preis das Stop-Niveau kreuzt.
Hinweise
Dieses Beispiel demonstriert die Verwendung der High-Level-API von StockSharp mit Indikatorbindung und manueller Trailing-Stop-Verwaltung. Es ist für Bildungszwecke gedacht und beinhaltet kein Geldmanagement über den festen Volume-Parameter hinaus.
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>
/// MACD based strategy converted from MetaTrader 5 Expert Advisor.
/// Uses MACD indicator with custom pattern checks on recent values and optional trailing stop.
/// </summary>
public class ExpertMacdEurusd1HourStrategy : Strategy
{
private readonly StrategyParam<int> _fastLength;
private readonly StrategyParam<int> _slowLength;
private readonly StrategyParam<int> _signalLength;
private readonly StrategyParam<decimal> _trailingPoints;
private readonly StrategyParam<DataType> _candleType;
private ExponentialMovingAverage _fastEma;
private ExponentialMovingAverage _slowEma;
private ExponentialMovingAverage _signalEma;
private decimal _main0, _main1;
private decimal _signal0, _signal1;
private int _counter;
/// <summary>
/// Fast EMA length for MACD.
/// </summary>
public int FastLength { get => _fastLength.Value; set => _fastLength.Value = value; }
/// <summary>
/// Slow EMA length for MACD.
/// </summary>
public int SlowLength { get => _slowLength.Value; set => _slowLength.Value = value; }
/// <summary>
/// Signal line length for MACD.
/// </summary>
public int SignalLength { get => _signalLength.Value; set => _signalLength.Value = value; }
/// <summary>
/// Trailing stop distance in price points.
/// </summary>
public decimal TrailingPoints { get => _trailingPoints.Value; set => _trailingPoints.Value = value; }
/// <summary>
/// Candle type for analysis.
/// </summary>
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
/// <summary>
/// Initialize strategy with default parameters.
/// </summary>
public ExpertMacdEurusd1HourStrategy()
{
_fastLength = Param(nameof(FastLength), 12)
.SetDisplay("Fast Length", "Fast EMA length for MACD", "Parameters")
;
_slowLength = Param(nameof(SlowLength), 26)
.SetDisplay("Slow Length", "Slow EMA length for MACD", "Parameters")
;
_signalLength = Param(nameof(SignalLength), 9)
.SetDisplay("Signal Length", "Signal length for MACD", "Parameters")
;
_trailingPoints = Param(nameof(TrailingPoints), 25m)
.SetDisplay("Trailing Points", "Trailing stop distance in points", "Risk");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Working timeframe", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_main0 = _main1 = 0m;
_signal0 = _signal1 = 0m;
_counter = 0;
_fastEma = null;
_slowEma = null;
_signalEma = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_fastEma = new ExponentialMovingAverage { Length = FastLength };
_slowEma = new ExponentialMovingAverage { Length = SlowLength };
_signalEma = new ExponentialMovingAverage { Length = SignalLength };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ProcessCandle)
.Start();
StartProtection(
new Unit(2000m, UnitTypes.Absolute),
new Unit(1000m, UnitTypes.Absolute));
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
var fast = _fastEma.Process(candle.ClosePrice, candle.CloseTime, true).ToDecimal();
var slow = _slowEma.Process(candle.ClosePrice, candle.CloseTime, true).ToDecimal();
if (!_fastEma.IsFormed || !_slowEma.IsFormed)
return;
var main = fast - slow;
var signal = _signalEma.Process(main, candle.CloseTime, true).ToDecimal();
if (!_signalEma.IsFormed)
return;
// shift stored values
_main1 = _main0;
_main0 = main;
_signal1 = _signal0;
_signal0 = signal;
if (_counter < 3)
{
_counter++;
return;
}
var buySignal = _main1 <= _signal1 && _main0 > _signal0 && _main0 < 0m;
var sellSignal = _main1 >= _signal1 && _main0 < _signal0 && _main0 > 0m;
if (buySignal && Position <= 0)
BuyMarket();
else if (sellSignal && Position >= 0)
SellMarket();
}
}
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, Unit, UnitTypes
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
from indicator_extensions import *
class expert_macd_eurusd1_hour_strategy(Strategy):
def __init__(self):
super(expert_macd_eurusd1_hour_strategy, self).__init__()
self._fast_length = self.Param("FastLength", 12)
self._slow_length = self.Param("SlowLength", 26)
self._signal_length = self.Param("SignalLength", 9)
self._trailing_points = self.Param("TrailingPoints", 25.0)
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1)))
self._fast_ema = None
self._slow_ema = None
self._signal_ema = None
self._main0 = 0.0
self._main1 = 0.0
self._signal0 = 0.0
self._signal1 = 0.0
self._counter = 0
@property
def FastLength(self):
return self._fast_length.Value
@FastLength.setter
def FastLength(self, value):
self._fast_length.Value = value
@property
def SlowLength(self):
return self._slow_length.Value
@SlowLength.setter
def SlowLength(self, value):
self._slow_length.Value = value
@property
def SignalLength(self):
return self._signal_length.Value
@SignalLength.setter
def SignalLength(self, value):
self._signal_length.Value = value
@property
def TrailingPoints(self):
return self._trailing_points.Value
@TrailingPoints.setter
def TrailingPoints(self, value):
self._trailing_points.Value = value
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
def OnStarted2(self, time):
super(expert_macd_eurusd1_hour_strategy, self).OnStarted2(time)
self._main0 = 0.0
self._main1 = 0.0
self._signal0 = 0.0
self._signal1 = 0.0
self._counter = 0
self._fast_ema = ExponentialMovingAverage()
self._fast_ema.Length = self.FastLength
self._slow_ema = ExponentialMovingAverage()
self._slow_ema.Length = self.SlowLength
self._signal_ema = ExponentialMovingAverage()
self._signal_ema.Length = self.SignalLength
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(self.ProcessCandle).Start()
self.StartProtection(
Unit(2000.0, UnitTypes.Absolute),
Unit(1000.0, UnitTypes.Absolute))
def ProcessCandle(self, candle):
if candle.State != CandleStates.Finished:
return
t = candle.OpenTime
fast_result = process_float(self._fast_ema, candle.ClosePrice, t, True)
slow_result = process_float(self._slow_ema, candle.ClosePrice, t, True)
if not self._fast_ema.IsFormed or not self._slow_ema.IsFormed:
return
fast_val = float(fast_result)
slow_val = float(slow_result)
main = fast_val - slow_val
signal_result = process_float(self._signal_ema, main, t, True)
if not self._signal_ema.IsFormed:
return
signal = float(signal_result)
self._main1 = self._main0
self._main0 = main
self._signal1 = self._signal0
self._signal0 = signal
if self._counter < 3:
self._counter += 1
return
buy_signal = self._main1 <= self._signal1 and self._main0 > self._signal0 and self._main0 < 0.0
sell_signal = self._main1 >= self._signal1 and self._main0 < self._signal0 and self._main0 > 0.0
if buy_signal and self.Position <= 0:
self.BuyMarket()
elif sell_signal and self.Position >= 0:
self.SellMarket()
def OnReseted(self):
super(expert_macd_eurusd1_hour_strategy, self).OnReseted()
self._main0 = 0.0
self._main1 = 0.0
self._signal0 = 0.0
self._signal1 = 0.0
self._counter = 0
self._fast_ema = None
self._slow_ema = None
self._signal_ema = None
def CreateClone(self):
return expert_macd_eurusd1_hour_strategy()