Die Strategie repliziert den MetaTrader 5 Expert Advisor "55 MA", indem sie zwei Punkte eines gleitenden 55-Perioden-Durchschnitts vergleicht und handelt, sobald ihre Differenz einen konfigurierbaren Schwellenwert überschreitet. Alle Berechnungen werden auf abgeschlossenen Kerzen innerhalb einer benutzerdefinierten Intraday-Sitzung durchgeführt, und die Handelsrichtung kann optional invertiert werden. Der Algorithmus bewahrt das ursprüngliche Verhalten, bei dem eine Short-Position eröffnet wird, wenn keine bullische Bedingung erfüllt ist.
Handelslogik
Die ausgewählte Kerzenserie abonnieren und einen gleitenden Durchschnitt mit der gewählten Länge, Methode und dem angewandten Preis berechnen.
Die neuesten Werte des gleitenden Durchschnitts in einem Puffer halten, damit auf die Werte bei den Balkenindizes BarA und BarB zugegriffen werden kann, auch wenn ein horizontaler MA-Shift verwendet wird.
Wenn eine abgeschlossene Kerze innerhalb des [StartHour, EndHour)-Fensters eintrifft:
Den MA-Wert bei BarA + MaShift und BarB + MaShift abrufen.
Wenn der Wert bei BarA den Wert bei BarB um mehr als DifferenceThreshold überschreitet, eine Long-Position eröffnen, es sei denn, ReverseSignals ist aktiviert.
Wenn der Wert bei BarA niedriger ist als der Wert bei BarB um mehr als DifferenceThreshold, eine Short-Position eröffnen (oder eine Long-Position wenn ReverseSignals aktiviert ist).
Andernfalls behält die Strategie das ursprüngliche EA-Verhalten bei und löst einen Short-Einstieg aus.
Orders werden immer zum Marktpreis mit dem Strategie-Volume gesendet. Wenn CloseOppositePositions aktiviert ist, wird die angeforderte Größe erhöht, um eine etwaige entgegengesetzte Exposition zu schließen, bevor die neue Position aufgebaut wird.
Optionale Stop-Loss- und Take-Profit-Schutzmaßnahmen werden über StartProtection angehängt. Abstände werden in Pips angegeben, wobei ein Pip dem PriceStep multipliziert mit 10 für Instrumente mit 3 oder 5 Dezimalstellen entspricht.
Eingaben
Name
Typ
Standard
Beschreibung
CandleType
DataType
1-Minuten-Zeitrahmen
Kerzenserie für Berechnungen und Signale.
StopLossPips
int
30
Stop-Loss-Abstand in Pips. Auf 0 setzen zum Deaktivieren.
TakeProfitPips
int
50
Take-Profit-Abstand in Pips. Auf 0 setzen zum Deaktivieren.
StartHour
int
8
Inklusive Stunde (0-23) die den Beginn der Handelssitzung markiert.
EndHour
int
21
Exklusive Stunde (0-23) die das Ende der Handelssitzung markiert. Muss größer als StartHour sein.
DifferenceThreshold
decimal
0.0001
Minimale absolute Differenz zwischen den verglichenen MA-Werten, die ein Richtungssignal auslöst.
BarA
int
0
Index des ersten Balkens für den MA-Vergleich (0 = aktuelle Kerze).
BarB
int
1
Index des zweiten Balkens für den MA-Vergleich.
ReverseSignals
bool
false
Invertiert die bullischen und bärischen Bedingungen.
CloseOppositePositions
bool
false
Wenn aktiviert, wird die Ordergröße erhöht, um eine Position in der entgegengesetzten Richtung zu schließen, bevor der neue Trade eröffnet wird.
MaShift
int
0
Horizontale Verschiebung auf die Linie des gleitenden Durchschnitts. Positive Werte greifen auf ältere MA-Punkte zu.
Preis als MA-Eingabe (Close, Open, High, Low, Median, Typical, Weighted).
Positionsmanagement
Das Strategie-Volume einstellen, um die Basis-Handelsgröße zu steuern. Es wird mit der aktuellen Position kombiniert, wenn CloseOppositePositions aktiv ist.
Stop-Loss- und Take-Profit-Schutzmaßnahmen sind optional. Sie werden nur angehängt, wenn der jeweilige Pip-Abstand größer als null ist.
Hinweise
Das Handelsfenster arbeitet in der Instrumentenzeit; Signale außerhalb von [StartHour, EndHour) werden übersprungen.
Wenn MaShift negative Indizes erzeugt, wartet die Strategie, bis genug Geschichte angesammelt ist, und spiegelt damit das ursprüngliche EA-Verhalten wider, bei dem verschobene Puffer EMPTY_VALUE zurückgeben können.
Da der ursprüngliche Expert immer standardmäßig eine Verkaufsorder auslöst, wenn der Differenzschwellenwert nicht erreicht wird, behält die konvertierte Strategie dieselbe Logik für volle Treue. DifferenceThreshold anpassen, wenn dieses Verhalten unerwünscht ist.
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>
/// 55 MA bar comparison strategy. Compares candle body with MA direction.
/// </summary>
public class FiftyFiveMaBarComparisonStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _maPeriod;
private decimal? _prevMa;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int MaPeriod
{
get => _maPeriod.Value;
set => _maPeriod.Value = value;
}
public FiftyFiveMaBarComparisonStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Timeframe", "General");
_maPeriod = Param(nameof(MaPeriod), 55)
.SetGreaterThanZero()
.SetDisplay("MA Period", "Moving average period", "Indicators");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevMa = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevMa = null;
var sma = new SimpleMovingAverage { Length = MaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(sma, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, sma);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal maVal)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
{
_prevMa = maVal;
return;
}
if (_prevMa == null)
{
_prevMa = maVal;
return;
}
var close = candle.ClosePrice;
var bullishBar = candle.ClosePrice > candle.OpenPrice;
var bearishBar = candle.ClosePrice < candle.OpenPrice;
var maRising = maVal > _prevMa.Value;
var maFalling = maVal < _prevMa.Value;
_prevMa = maVal;
// Bullish bar + rising MA + close above MA → buy
if (bullishBar && maRising && close > maVal && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
// Bearish bar + falling MA + close below MA → sell
else if (bearishBar && maFalling && close < maVal && Position >= 0)
{
if (Position > 0)
SellMarket();
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
from StockSharp.Algo.Indicators import SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
class fifty_five_ma_bar_comparison_strategy(Strategy):
def __init__(self):
super(fifty_five_ma_bar_comparison_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Timeframe", "General")
self._ma_period = self.Param("MaPeriod", 55) \
.SetDisplay("MA Period", "Moving average period", "Indicators")
self._prev_ma = None
@property
def CandleType(self):
return self._candle_type.Value
@property
def MaPeriod(self):
return self._ma_period.Value
def OnReseted(self):
super(fifty_five_ma_bar_comparison_strategy, self).OnReseted()
self._prev_ma = None
def OnStarted2(self, time):
super(fifty_five_ma_bar_comparison_strategy, self).OnStarted2(time)
self._prev_ma = None
sma = SimpleMovingAverage()
sma.Length = self.MaPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(sma, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, sma)
self.DrawOwnTrades(area)
def _on_process(self, candle, ma_value):
if candle.State != CandleStates.Finished:
return
mv = float(ma_value)
if not self.IsFormedAndOnlineAndAllowTrading():
self._prev_ma = mv
return
if self._prev_ma is None:
self._prev_ma = mv
return
close = float(candle.ClosePrice)
open_price = float(candle.OpenPrice)
bullish_bar = close > open_price
bearish_bar = close < open_price
ma_rising = mv > self._prev_ma
ma_falling = mv < self._prev_ma
self._prev_ma = mv
# Bullish bar + rising MA + close above MA
if bullish_bar and ma_rising and close > mv and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
# Bearish bar + falling MA + close below MA
elif bearish_bar and ma_falling and close < mv and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
def CreateClone(self):
return fifty_five_ma_bar_comparison_strategy()