Estrategia de Ruptura AutoFib
Esta estrategia traza una extensión de Fibonacci dinámica desde el máximo y mínimo recientes y abre una posición larga cuando el precio rompe por encima del nivel 1.618 durante una tendencia alcista definida por la EMA de 200 períodos. El riesgo se gestiona mediante un stop y objetivo basados en ATR.
Detalles
- Criterios de entrada: Cierre por encima de la extensión 1.618 de Fibonacci y por encima de la EMA200.
- Largo/Corto: Solo largos.
- Criterios de salida: Stop-loss basado en ATR o toma de ganancias de 3×ATR.
- Stops: Sí, basados en ATR.
- Valores predeterminados:
EmaLength= 200AtrLength= 14FibLevel= 1.618PivotPeriod= 10CandleType= 5 minutos
- Filtros:
- Categoría: Ruptura
- Dirección: Largo
- Indicadores: EMA, ATR, Highest, Lowest
- Stops: Sí
- Complejidad: Básico
- Marco temporal: Intradía
- Estacionalidad: No
- Redes neuronales: No
- Divergencia: No
- Nivel de riesgo: Medio
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>
/// AutoFib breakout strategy.
/// The swing low and high of the previous PivotPeriod candles span a Fibonacci extension at low + (high - low) * FibLevel. A
/// close above that level while the close is above the EMA opens a long. Each entry fixes a 1.5 ATR stop-loss and a 3 ATR
/// take-profit from the entry close. Long only.
/// </summary>
public class AutoFibBreakoutStrategy : Strategy
{
private const decimal _stopAtrMultiple = 1.5m;
private const decimal _takeAtrMultiple = 3m;
private readonly StrategyParam<int> _emaLength;
private readonly StrategyParam<int> _atrLength;
private readonly StrategyParam<decimal> _fibLevel;
private readonly StrategyParam<int> _pivotPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal? _prevHigh;
private decimal? _prevLow;
private decimal _stopPrice;
private decimal _takePrice;
/// <summary>
/// Trend EMA period.
/// </summary>
public int EmaLength
{
get => _emaLength.Value;
set => _emaLength.Value = value;
}
/// <summary>
/// ATR period of the stop-loss and take-profit.
/// </summary>
public int AtrLength
{
get => _atrLength.Value;
set => _atrLength.Value = value;
}
/// <summary>
/// Fibonacci extension level of the breakout.
/// </summary>
public decimal FibLevel
{
get => _fibLevel.Value;
set => _fibLevel.Value = value;
}
/// <summary>
/// Candles that define the swing high and low.
/// </summary>
public int PivotPeriod
{
get => _pivotPeriod.Value;
set => _pivotPeriod.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public AutoFibBreakoutStrategy()
{
_emaLength = Param(nameof(EmaLength), 200)
.SetGreaterThanZero()
.SetDisplay("EMA Length", "Trend EMA period", "Trend");
_atrLength = Param(nameof(AtrLength), 14)
.SetGreaterThanZero()
.SetDisplay("ATR Length", "ATR period of the stop-loss and take-profit", "Risk");
_fibLevel = Param(nameof(FibLevel), 1.618m)
.SetGreaterThanZero()
.SetDisplay("Fib Level", "Fibonacci extension level of the breakout", "Fibonacci");
_pivotPeriod = Param(nameof(PivotPeriod), 10)
.SetGreaterThanZero()
.SetDisplay("Pivot Period", "Candles that define the swing high and low", "Fibonacci");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
ResetState();
}
private void ResetState()
{
_prevHigh = null;
_prevLow = null;
_stopPrice = 0m;
_takePrice = 0m;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
ResetState();
var ema = new ExponentialMovingAverage { Length = EmaLength };
var atr = new AverageTrueRange { Length = AtrLength };
var highest = new Highest { Length = PivotPeriod };
var lowest = new Lowest { Length = PivotPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ema, atr, highest, lowest, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, ema);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal ema, decimal atr, decimal highest, decimal lowest)
{
if (candle.State != CandleStates.Finished)
return;
// The swing range comes from the candles before this one.
var prevHigh = _prevHigh;
var prevLow = _prevLow;
_prevHigh = highest;
_prevLow = lowest;
if (prevHigh is not decimal swingHigh || prevLow is not decimal swingLow)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var close = candle.ClosePrice;
if (Position > 0)
{
if (candle.LowPrice <= _stopPrice || candle.HighPrice >= _takePrice)
SellMarket(Position);
return;
}
var extension = swingLow + (swingHigh - swingLow) * FibLevel;
if (Position == 0 && close > extension && close > ema)
{
BuyMarket(Volume);
_stopPrice = close - _stopAtrMultiple * atr;
_takePrice = close + _takeAtrMultiple * atr;
}
}
}
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, AverageTrueRange, Highest, Lowest
from StockSharp.Algo.Strategies import Strategy
STOP_ATR_MULTIPLE = 1.5
TAKE_ATR_MULTIPLE = 3.0
class auto_fib_breakout_strategy(Strategy):
"""
AutoFib breakout strategy.
The swing low and high of the previous PivotPeriod candles span a Fibonacci extension at low + (high - low) * FibLevel. A
close above that level while the close is above the EMA opens a long. Each entry fixes a 1.5 ATR stop-loss and a 3 ATR
take-profit from the entry close. Long only.
"""
def __init__(self):
super(auto_fib_breakout_strategy, self).__init__()
self._ema_length = self.Param("EmaLength", 200) \
.SetGreaterThanZero() \
.SetDisplay("EMA Length", "Trend EMA period", "Trend")
self._atr_length = self.Param("AtrLength", 14) \
.SetGreaterThanZero() \
.SetDisplay("ATR Length", "ATR period of the stop-loss and take-profit", "Risk")
self._fib_level = self.Param("FibLevel", 1.618) \
.SetGreaterThanZero() \
.SetDisplay("Fib Level", "Fibonacci extension level of the breakout", "Fibonacci")
self._pivot_period = self.Param("PivotPeriod", 10) \
.SetGreaterThanZero() \
.SetDisplay("Pivot Period", "Candles that define the swing high and low", "Fibonacci")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Type of candles to use", "General")
self._reset_state()
@property
def CandleType(self):
return self._candle_type.Value
def GetWorkingSecurities(self):
return [(self.Security, self.CandleType)]
def _reset_state(self):
self._prev_high = None
self._prev_low = None
self._stop_price = 0.0
self._take_price = 0.0
def OnReseted(self):
super(auto_fib_breakout_strategy, self).OnReseted()
self._reset_state()
def OnStarted2(self, time):
super(auto_fib_breakout_strategy, self).OnStarted2(time)
self._reset_state()
ema = ExponentialMovingAverage()
ema.Length = self._ema_length.Value
atr = AverageTrueRange()
atr.Length = self._atr_length.Value
highest = Highest()
highest.Length = self._pivot_period.Value
lowest = Lowest()
lowest.Length = self._pivot_period.Value
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(ema, atr, highest, lowest, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ema)
self.DrawOwnTrades(area)
def _process_candle(self, candle, ema_value, atr_value, highest_value, lowest_value):
if candle.State != CandleStates.Finished:
return
# The swing range comes from the candles before this one.
swing_high = self._prev_high
swing_low = self._prev_low
self._prev_high = float(highest_value)
self._prev_low = float(lowest_value)
if swing_high is None or swing_low is None:
return
if not self.IsFormedAndOnlineAndAllowTrading():
return
close = float(candle.ClosePrice)
if self.Position > 0:
if float(candle.LowPrice) <= self._stop_price or float(candle.HighPrice) >= self._take_price:
self.SellMarket(self.Position)
return
extension = swing_low + (swing_high - swing_low) * float(self._fib_level.Value)
atr = float(atr_value)
if self.Position == 0 and close > extension and close > float(ema_value):
self.BuyMarket(self.Volume)
self._stop_price = close - STOP_ATR_MULTIPLE * atr
self._take_price = close + TAKE_ATR_MULTIPLE * atr
def CreateClone(self):
return auto_fib_breakout_strategy()