Detaillierte C#-Portierung des klassischen MetaTrader 4 Expert Advisors MQL/7696/Fractured_fractals.mq4. Die Strategie wartet auf neu bestätigte
Williams Fraktalniveaus, Warteschlangen-Breakout-Stop-Orders und Trails-Risiko unter Verwendung der vorherigen Fraktalschwünge. Die Positionsgrößenbestimmung folgt dem
Ursprüngliche Risiko-pro-Trade-Logik mit der adaptiven „DecreaseFactor“-Volumenreduzierung nach Drawdowns.
Einzelheiten
Quelle: Konvertiert von MQL/7696/Fractured_fractals.mq4.
Marktregime: Fortsetzung des Ausbruchs, funktioniert bei jedem Instrument, das zuverlässige fraktale Strukturen bildet.
Ordertypen: Verwendet Stop-Orders für Einstiege und schützende Stop-Orders für Ausstiege.
Positionsgrößenbestimmung: Prozentuales Risikomodell, gesteuert durch MaximumRiskPercent mit Verluststreak-Dämpfung durch DecreaseFactor.
Standardparameter:
MaximumRiskPercent = 2 %
DecreaseFactor = 3
CandleType = 1-stündiger Zeitrahmen
Kernindikatoren: Native Fünf-Balken-Williams-Fraktalerkennung in der Strategie implementiert.
Strategietyp: Symmetrischer Long/Short-Breakout mit fraktalbasierten Trailing-Stops.
Strategielogik
Fraktale Erkennung
Behält ein rollierendes Fenster mit fünf Kerzenhochs und -tiefs bei, um die iFractals-Puffer von MetaTrader zu reproduzieren.
Ein neues Aufwärts-Fraktal wird bestätigt, wenn das mittlere Hoch die beiden umgebenden Hochs auf jeder Seite überschreitet; Ein Down-Fraktal erfordert das
Mitteltief ist der tiefste Wert in der fünftaktigen Sequenz.
Wenn ein neues Fraktal erscheint, wird es zusammen mit den drei vorherigen Werten gespeichert und spiegelt die Werte cfu, pfu und von EA wider
Puffer im pfu.1-Stil für spätere Vergleiche und nachträgliche Berechnungen.
Eintragseinrichtung
Für Long-Trades ist es erforderlich, dass das jüngste Aufwärts-Fraktal das vorherige übersteigt und das jüngste Abwärts-Fraktal eine Risikountergrenze definiert.
Die Strategie platziert dann einen Kaufstopp leicht über dem Fraktal (Spread-Kompensation) und einen Schutzstopp unter dem Gegenwert
Down-Fraktal.
Short-Trades spiegeln die Logik wider: Ein Fraktal mit einem niedrigeren Tief in Kombination mit einem Fraktal mit einem höheren Aufwärtstrend erzeugt einen Verkaufsstopp und einen Schutz
Stoppen Sie über dem Aufwärts-Fraktal-Plus-Spread.
Es ist nur eine ausstehende Bestellung pro Richtung zulässig. Wenn die fraktale Struktur das Muster ungültig macht – zum Beispiel die neueste fraktale Nr
länger als die vorherige – die ausstehende Bestellung wird sofort storniert.
Stoppen Sie die Verwaltung
Sobald der Bot positioniert ist, verfolgt er den Schutzstopp mithilfe des vorherigen Fraktals auf der Eintrittsseite und subtrahiert/addiert den Strom
verbreiten. Der Stop bewegt sich nur zu Gunsten des Handels.
Wenn sich die Positionsrichtung ändert oder schließt, wird die ungenutzte Stop-Order gelöscht, um ein veraltetes Exposure zu verhindern.
Risikomanagement
CalculateOrderVolume repliziert die Risiko-pro-Trade-Berechnung von EA: Die Positionsgröße ist das Verhältnis der monetären Risikotoleranz zu
der Abstand zwischen Einstiegs- und Stoppebene.
Kontobewertung bevorzugt Portfolio.CurrentValue; Wenn die Routine nicht verfügbar ist, greift sie auf die Volume-Eigenschaft der Strategie zurück
multipliziert mit dem Preis.
Nach zwei oder mehr aufeinanderfolgenden Verlustgeschäften wird das Volumen um losses / DecreaseFactor reduziert, was dem MetaTrader entspricht.
DecreaseFactor Verhalten.
Verfolgung des Handelszyklus
OnOwnTradeReceived aggregiert Füllungen in Handelszyklen, verfolgt variable PnL und aktualisiert die Verluststrähne, sobald das Volumen zurückkehrt
zu flach. Dadurch bleibt die Risikologik an der des MT4-Experten ausgerichtet, bei dem HistoryTotal zur Analyse früherer Ergebnisse verwendet wurde.
Nutzungshinweise
Hängen Sie die Strategie an ein beliebiges Wertpapier-/Portfoliopaar an und wählen Sie eine geeignete CandleType-Auflösung, die dem Original entspricht
EA eingerichtet.
Stellen Sie sicher, dass Notierungen der Stufe 1 verfügbar sind – die Spread-Schätzung basiert auf dem besten Geld-/Briefkurs; Bei Nichtverfügbarkeit wird auf die Strategie zurückgegriffen
PriceStep.
Bei den Stop-Orders wird davon ausgegangen, dass der Broker serverseitige Stops unterstützt. Ersetzen Sie die BuyStop/SellStop-Registrierung durch Marktaufträge, wenn
wird von Ihrem Adapter benötigt.
Da die Verarbeitung beim Kerzenschluss erfolgt, werden intrabar-fraktale Signale nur am Ende jedes Balkens bearbeitet und reproduzieren
Bar-für-Bar-Bewertung des Fachberaters.
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>
/// Fractured Fractals strategy - Highest/Lowest channel breakout with ATR filter.
/// Buys when close crosses above channel midpoint and ATR confirms volatility.
/// Sells when close crosses below channel midpoint.
/// </summary>
public class FracturedFractalsMql4Strategy : Strategy
{
private readonly StrategyParam<int> _channelPeriod;
private readonly StrategyParam<int> _atrPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevClose;
private decimal _prevMid;
private bool _hasPrev;
public int ChannelPeriod { get => _channelPeriod.Value; set => _channelPeriod.Value = value; }
public int AtrPeriod { get => _atrPeriod.Value; set => _atrPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public FracturedFractalsMql4Strategy()
{
_channelPeriod = Param(nameof(ChannelPeriod), 15)
.SetDisplay("Channel Period", "Highest/Lowest lookback", "Indicators");
_atrPeriod = Param(nameof(AtrPeriod), 14)
.SetDisplay("ATR Period", "ATR lookback", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
protected override void OnReseted() { base.OnReseted(); _prevClose = 0m; _prevMid = 0m; _hasPrev = false; }
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var highest = new Highest { Length = ChannelPeriod };
var lowest = new Lowest { Length = ChannelPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(highest, lowest, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal highest, decimal lowest)
{
if (candle.State != CandleStates.Finished)
return;
var close = candle.ClosePrice;
var mid = (highest + lowest) / 2;
if (!_hasPrev)
{
_prevClose = close;
_prevMid = mid;
_hasPrev = true;
return;
}
// Close crosses above midpoint = buy
if (_prevClose <= _prevMid && close > mid && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
// Close crosses below midpoint = sell
else if (_prevClose >= _prevMid && close < mid && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
_prevClose = close;
_prevMid = mid;
}
}
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 Highest, Lowest
from StockSharp.Algo.Strategies import Strategy
class fractured_fractals_mql4_strategy(Strategy):
def __init__(self):
super(fractured_fractals_mql4_strategy, self).__init__()
self._channel_period = self.Param("ChannelPeriod", 15).SetDisplay("Channel Period", "Highest/Lowest lookback", "Indicators")
self._atr_period = self.Param("AtrPeriod", 14).SetDisplay("ATR Period", "ATR lookback", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))).SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_close = 0.0
self._prev_mid = 0.0
self._has_prev = False
@property
def channel_period(self): return self._channel_period.Value
@property
def candle_type(self): return self._candle_type.Value
def OnReseted(self):
super(fractured_fractals_mql4_strategy, self).OnReseted()
self._prev_close = 0.0
self._prev_mid = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(fractured_fractals_mql4_strategy, self).OnStarted2(time)
self._has_prev = False
highest = Highest()
highest.Length = self.channel_period
lowest = Lowest()
lowest.Length = self.channel_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(highest, lowest, self.process_candle).Start()
def process_candle(self, candle, highest, lowest):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
mid = (float(highest) + float(lowest)) / 2.0
if not self._has_prev:
self._prev_close = close
self._prev_mid = mid
self._has_prev = True
return
if self._prev_close <= self._prev_mid and close > mid and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif self._prev_close >= self._prev_mid and close < mid and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_close = close
self._prev_mid = mid
def CreateClone(self):
return fractured_fractals_mql4_strategy()