Puerto C# detallado del asesor experto clásico MetaTrader 4 MQL/7696/Fractured_fractals.mq4. La estrategia vigila a los recién confirmados
Williams niveles fractales, colas de órdenes de parada de ruptura y senderos corren el riesgo de utilizar las oscilaciones fractales anteriores. El tamaño de la posición sigue el
Lógica original de riesgo por operación con la reducción de volumen adaptativa "DecreaseFactor" después de las reducciones.
Detalles
Fuente: Convertido de MQL/7696/Fractured_fractals.mq4.
Régimen de mercado: Continuación de ruptura, funciona en cualquier instrumento que forme estructuras fractales confiables.
Tipos de órdenes: utiliza órdenes de parada para entradas y órdenes de parada de protección para salidas.
Dimensionamiento de la posición: modelo de riesgo porcentual controlado por MaximumRiskPercent con amortiguación de la racha de pérdidas a través de DecreaseFactor.
Parámetros predeterminados:
MaximumRiskPercent = 2%
DecreaseFactor = 3
CandleType = período de tiempo de 1 hora
Indicadores principales: Detección fractal nativa de cinco barras Williams implementada en la estrategia.
Tipo de estrategia: Ruptura simétrica larga/corta con paradas finales basadas en fractales.
Lógica de la estrategia
Detección de fractales
Mantiene una ventana móvil de cinco máximos y mínimos de velas para reproducir los buffers iFractals de MetaTrader.
Se confirma un nuevo fractal ascendente cuando el máximo medio excede los dos máximos circundantes en cada lado; un fractal hacia abajo requiere el
medio bajo para ser el más bajo en la secuencia de cinco compases.
Cuando aparece un nuevo fractal, se almacena junto con los tres valores anteriores, reflejando los EA, pfu y
pfu.1 buffers de estilo para comparaciones posteriores y cálculos finales.
Configuración de entrada
Las operaciones largas requieren que el fractal ascendente más reciente supere al anterior y el último fractal a la baja para definir un piso de riesgo.
Luego, la estrategia coloca un stop de compra ligeramente por encima del fractal (compensación del diferencial) con un stop de protección por debajo del oponente.
abajo fractal.
Las operaciones cortas reflejan la lógica: un fractal inferior combinado con un fractal superior genera una parada de venta y una barrera protectora.
deténgase por encima del fractal superior más la extensión.
Sólo se permite una orden pendiente por dirección. Si la estructura fractal invalida el patrón (por ejemplo, el último fractal no
ya supera la anterior: la orden pendiente se cancela inmediatamente.
Detener la gestión
Una vez posicionado, el robot sigue la parada protectora usando el fractal anterior en el lado de entrada, restando/sumando el actual
difundir. La parada sólo se mueve a favor de la operación.
Cuando la dirección de la posición cambia o se cierra, la orden de parada no utilizada se cancela para evitar una exposición obsoleta.
Gestión de riesgos
CalculateOrderVolume replica el cálculo de riesgo por operación de EA: el tamaño de la posición es la relación entre la provisión de riesgo monetario y
la distancia entre los niveles de entrada y parada.
La valoración de la cuenta prefiere Portfolio.CurrentValue; si no está disponible, la rutina vuelve a la propiedad Volume de la estrategia
multiplicado por el precio.
Después de dos o más operaciones perdedoras consecutivas, el volumen se reduce en losses / DecreaseFactor, emulando el MetaTrader
DecreaseFactor comportamiento.
Seguimiento del ciclo comercial
Los agregados OnOwnTradeReceived completan los ciclos comerciales, rastrean el PnL flotante y actualizan la racha de pérdidas una vez que regresa el volumen.
a plano. Esto mantiene la lógica de riesgo alineada con el experto MT4 donde se utilizó HistoryTotal para analizar resultados anteriores.
Notas de uso
Adjunte la estrategia a cualquier par de valores/cartera y elija una resolución CandleType adecuada que coincida con la original.
EA configuración.
Asegúrese de que las cotizaciones de nivel 1 estén disponibles: la estimación del diferencial se basa en la mejor oferta/demanda; si no está disponible, la estrategia vuelve a
PriceStep.
Las órdenes de suspensión suponen que el corredor admite paradas del lado del servidor. Reemplace el registro BuyStop/SellStop con órdenes de mercado si
requerido por su adaptador.
Debido a que el procesamiento ocurre al cierre de la vela, las señales fractales intrabar solo actúan al final de cada barra, reproduciendo el
Evaluación barra por barra del asesor experto.
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()