Diese Strategie repliziert die Logik des ursprünglichen Experten X_alert_3.mq4. Sie überwacht zwei gleitende Durchschnitte mit konfigurierbaren Parametern und erzeugt eine informative Benachrichtigung, wenn ein Crossover auftritt.
Funktionsweise
Zwei gleitende Durchschnitte werden auf jeder abgeschlossenen Kerze berechnet.
Eine bullische Benachrichtigung wird erzeugt, wenn:
MA1 auf der aktuellen Kerze über MA2 liegt.
MA1 auf der vorherigen Kerze über MA2 liegt.
MA1 vor zwei Kerzen unter MA2 lag.
Eine bärische Benachrichtigung wird erzeugt, wenn:
MA1 auf der aktuellen Kerze unter MA2 liegt.
MA1 auf der vorherigen Kerze unter MA2 liegt.
MA1 vor zwei Kerzen über MA2 lag.
Die Strategie öffnet oder schließt keine Positionen. Sie schreibt nur Nachrichten ins Protokoll.
Parameter
Parameter
Beschreibung
Standard
Ma1Period
Periode des ersten gleitenden Durchschnitts.
1
Ma1Type
Typ des ersten gleitenden Durchschnitts (Simple, Exponential, Smoothed, Weighted).
Simple
Ma2Period
Periode des zweiten gleitenden Durchschnitts.
14
Ma2Type
Typ des zweiten gleitenden Durchschnitts.
Simple
PriceType
Quellpreis für Berechnungen (Close, Open, High, Low, Median, Typical, Weighted).
Median
CandleType
Kerzenserie für die Verarbeitung.
1-Minuten-Zeitrahmen
Hinweise
Die Implementierung verfolgt die letzten zwei Differenzen zwischen den gleitenden Durchschnitten, um Crossovers zu erkennen, ohne direkt auf historische Indikatorwerte zuzugreifen.
Benachrichtigungen werden über AddInfoLog geschrieben, damit die Strategie nebenwirkungsfrei bleibt.
Der MetaTrader-Parameter RunIntervalSeconds ist in StockSharp nicht erforderlich und wurde weggelassen.
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>
/// Strategy based on crossover of two moving averages.
/// Buys when fast MA crosses above slow MA, sells when crosses below.
/// </summary>
public class XAlert3Strategy : Strategy
{
private readonly StrategyParam<int> _ma1Period;
private readonly StrategyParam<int> _ma2Period;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevFast;
private decimal _prevSlow;
private bool _hasPrev;
public int Ma1Period { get => _ma1Period.Value; set => _ma1Period.Value = value; }
public int Ma2Period { get => _ma2Period.Value; set => _ma2Period.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public XAlert3Strategy()
{
_ma1Period = Param(nameof(Ma1Period), 10)
.SetGreaterThanZero()
.SetDisplay("MA1 Period", "Fast moving average period", "Indicators");
_ma2Period = Param(nameof(Ma2Period), 30)
.SetGreaterThanZero()
.SetDisplay("MA2 Period", "Slow moving average period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_prevFast = 0;
_prevSlow = 0;
_hasPrev = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var fast = new ExponentialMovingAverage { Length = Ma1Period };
var slow = new ExponentialMovingAverage { Length = Ma2Period };
SubscribeCandles(CandleType)
.Bind(fast, slow, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
{
if (candle.State != CandleStates.Finished)
return;
if (!_hasPrev)
{
_prevFast = fast;
_prevSlow = slow;
_hasPrev = true;
return;
}
if (_prevFast <= _prevSlow && fast > slow)
{
if (Position < 0) BuyMarket();
if (Position <= 0) BuyMarket();
}
else if (_prevFast >= _prevSlow && fast < slow)
{
if (Position > 0) SellMarket();
if (Position >= 0) SellMarket();
}
_prevFast = fast;
_prevSlow = slow;
}
}
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 ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class x_alert3_strategy(Strategy):
def __init__(self):
super(x_alert3_strategy, self).__init__()
self._ma1_period = self.Param("Ma1Period", 10) \
.SetDisplay("MA1 Period", "Fast moving average period", "Indicators")
self._ma2_period = self.Param("Ma2Period", 30) \
.SetDisplay("MA2 Period", "Slow moving average period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
@property
def ma1_period(self):
return self._ma1_period.Value
@property
def ma2_period(self):
return self._ma2_period.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(x_alert3_strategy, self).OnReseted()
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(x_alert3_strategy, self).OnStarted2(time)
fast = ExponentialMovingAverage()
fast.Length = self.ma1_period
slow = ExponentialMovingAverage()
slow.Length = self.ma2_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(fast, slow, self.on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def on_process(self, candle, fast, slow):
if candle.State != CandleStates.Finished:
return
if not self._has_prev:
self._prev_fast = fast
self._prev_slow = slow
self._has_prev = True
return
if self._prev_fast <= self._prev_slow and fast > slow:
if self.Position < 0:
self.BuyMarket()
if self.Position <= 0:
self.BuyMarket()
elif self._prev_fast >= self._prev_slow and fast < slow:
if self.Position > 0:
self.SellMarket()
if self.Position >= 0:
self.SellMarket()
self._prev_fast = fast
self._prev_slow = slow
def CreateClone(self):
return x_alert3_strategy()