Fibonacci Estrategia de retroceso de entradas potenciales
Descripción general
La Fibonacci estrategia de retroceso de entradas potenciales recrea el MetaTrader experto EA_PUB_FibonacciPotentialEntries. El algoritmo espera cotizaciones activas de Nivel 1 y luego coloca dos órdenes pendientes alrededor de los niveles de retroceso Fibonacci proporcionados manualmente. Cuando se alcanza el objetivo de beneficio compartido, la estrategia reduce cada posición en un 50% y mueve el tope de protección al punto de equilibrio para la cantidad restante.
Mapeo de la lógica original.
Órdenes de entrada: se emiten dos órdenes límite una vez que los precios de mejor oferta y mejor oferta están disponibles:
Primer pedido: realizado al 50% de retroceso (P50Level). El stop-loss está anclado tres diferenciales por debajo (modo alcista) o por encima (modo bajista) del nivel del 61%.
Segunda orden: colocada en el retroceso del 61% (P61Level) con el stop-loss definido a tres diferenciales del punto medio entre los niveles del 61% y el 100%.
Sesgo de dirección: la entrada bType original se convierte en el parámetro MarketBias (Bull para límites de compra, Bear para límites de venta).
Asignación de riesgos: la primera operación siempre arriesga 0.7% del capital de la cartera. La segunda operación consume la porción restante de RiskPercent (max(RiskPercent - 0.7, 0)), manteniendo la división utilizada por EA.
Cálculo del volumen: el riesgo se traduce al tamaño de la posición hasta Portfolio.CurrentValue (con alternativas a CurrentBalance y BeginValue) junto con el paso de precio, el costo del paso y el multiplicador del instrumento.
Obtención de ganancias parcial: cuando el precio cruza TargetLevel, cada operación ejecutada envía una orden de mercado para cerrar la mitad de su volumen abierto. Luego, la orden de parada se mueve al precio de entrada registrado, coincidiendo con la secuencia OrderClose + OrderModify de EA.
Parámetros
Nombre
Descripción
P50Level
Precio asignado al 50% de retroceso Fibonacci.
P61Level
Precio asignado al retroceso del 61,8% Fibonacci.
P100Level
Precio asignado al retroceso del 100% Fibonacci (utilizado para el punto medio de parada).
TargetLevel
Objetivo de ganancias compartido para ambas operaciones.
RiskPercent
Presupuesto de riesgo total en porcentaje del patrimonio (debe ser ≥ 0,7).
MarketBias
Elige una campaña larga (Bull) o corta (Bear).
Detalles de ejecución
Suscríbase a cotizaciones de nivel 1 a través de SubscribeLevel1() y espere valores de oferta y demanda positivos.
Calcule el diferencial, los niveles de parada y el tamaño de las posiciones. Los pedidos se envían una vez por ejecución y no se volverán a crear automáticamente después (el mismo comportamiento que el experto MQL).
Al ejecutarse, la estrategia registra el precio de entrada promedio, coloca la orden de parada adecuada y rastrea el volumen abierto por tramo.
Cuando el mercado imprime más allá de TargetLevel, la estrategia envía una orden de mercado de cierre parcial por tramo y posteriormente mueve el tope al punto de equilibrio para la cantidad restante.
Las órdenes stop se cancelan cuando no queda volumen o cuando la estrategia se detiene.
Notas y limitaciones
El stop-loss se regenera cada vez que cambia el tamaño de la posición. Si el corredor rechaza las órdenes de suspensión, verifique los permisos del conector y ajuste la configuración específica del intercambio en consecuencia.
La toma de ganancias no se registra como orden pendiente. En cambio, el algoritmo refleja el EA al monitorear el nivel de precios y gestionar las salidas en tiempo real.
Debido a que los pedidos se crean solo una vez, reinicie la estrategia para actualizar los pedidos pendientes después de que cambien los parámetros (idéntico al flujo de trabajo MetaTrader.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Fibonacci Retracement Entries strategy: EMA trend with Fibonacci retracement levels.
/// Buys on retracement to 61.8% in uptrend, sells on retracement to 38.2% in downtrend.
/// </summary>
public class FibonacciPotentialEntriesRetracementStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<int> _lookback;
private readonly StrategyParam<int> _signalCooldownCandles;
private decimal _high;
private decimal _low;
private int _barCount;
private int _candlesSinceTrade;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public int Lookback { get => _lookback.Value; set => _lookback.Value = value; }
public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }
public FibonacciPotentialEntriesRetracementStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_emaPeriod = Param(nameof(EmaPeriod), 50)
.SetGreaterThanZero()
.SetDisplay("EMA Period", "EMA period", "Indicators");
_lookback = Param(nameof(Lookback), 50)
.SetGreaterThanZero()
.SetDisplay("Lookback", "Lookback for high/low", "General");
_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 6)
.SetGreaterThanZero()
.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_high = 0;
_low = decimal.MaxValue;
_barCount = 0;
_candlesSinceTrade = SignalCooldownCandles;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_high = 0;
_low = decimal.MaxValue;
_barCount = 0;
_candlesSinceTrade = SignalCooldownCandles;
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(ema, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal emaValue)
{
if (candle.State != CandleStates.Finished) return;
if (_candlesSinceTrade < SignalCooldownCandles)
_candlesSinceTrade++;
if (candle.HighPrice > _high) _high = candle.HighPrice;
if (candle.LowPrice < _low) _low = candle.LowPrice;
_barCount++;
if (_barCount < 20) return;
var range = _high - _low;
if (range <= 0) return;
var close = candle.ClosePrice;
var fib618 = _high - range * 0.618m;
var fib382 = _high - range * 0.382m;
if (close > emaValue && close <= fib618 && Position <= 0 && _candlesSinceTrade >= SignalCooldownCandles)
{
BuyMarket();
_candlesSinceTrade = 0;
}
else if (close < emaValue && close >= fib382 && Position >= 0 && _candlesSinceTrade >= SignalCooldownCandles)
{
SellMarket();
_candlesSinceTrade = 0;
}
}
}
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 fibonacci_potential_entries_retracement_strategy(Strategy):
def __init__(self):
super(fibonacci_potential_entries_retracement_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(30)))
self._ema_period = self.Param("EmaPeriod", 50)
self._lookback = self.Param("Lookback", 50)
self._signal_cooldown_candles = self.Param("SignalCooldownCandles", 6)
self._high = 0.0
self._low = float('inf')
self._bar_count = 0
self._candles_since_trade = 6
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def EmaPeriod(self):
return self._ema_period.Value
@EmaPeriod.setter
def EmaPeriod(self, value):
self._ema_period.Value = value
@property
def Lookback(self):
return self._lookback.Value
@Lookback.setter
def Lookback(self, value):
self._lookback.Value = value
@property
def SignalCooldownCandles(self):
return self._signal_cooldown_candles.Value
@SignalCooldownCandles.setter
def SignalCooldownCandles(self, value):
self._signal_cooldown_candles.Value = value
def OnReseted(self):
super(fibonacci_potential_entries_retracement_strategy, self).OnReseted()
self._high = 0.0
self._low = float('inf')
self._bar_count = 0
self._candles_since_trade = self.SignalCooldownCandles
def OnStarted2(self, time):
super(fibonacci_potential_entries_retracement_strategy, self).OnStarted2(time)
self._high = 0.0
self._low = float('inf')
self._bar_count = 0
self._candles_since_trade = self.SignalCooldownCandles
ema = ExponentialMovingAverage()
ema.Length = self.EmaPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(ema, self._process_candle).Start()
def _process_candle(self, candle, ema_value):
if candle.State != CandleStates.Finished:
return
if self._candles_since_trade < self.SignalCooldownCandles:
self._candles_since_trade += 1
high = float(candle.HighPrice)
low = float(candle.LowPrice)
close = float(candle.ClosePrice)
ema_val = float(ema_value)
if high > self._high:
self._high = high
if low < self._low:
self._low = low
self._bar_count += 1
if self._bar_count < 20:
return
range_val = self._high - self._low
if range_val <= 0:
return
fib618 = self._high - range_val * 0.618
fib382 = self._high - range_val * 0.382
if close > ema_val and close <= fib618 and self.Position <= 0 and self._candles_since_trade >= self.SignalCooldownCandles:
self.BuyMarket()
self._candles_since_trade = 0
elif close < ema_val and close >= fib382 and self.Position >= 0 and self._candles_since_trade >= self.SignalCooldownCandles:
self.SellMarket()
self._candles_since_trade = 0
def CreateClone(self):
return fibonacci_potential_entries_retracement_strategy()