Este sistema de ruptura establece la dirección de la operación usando la vela del día anterior.
Si el cierre previo está por encima del máximo de ese día, la estrategia busca largos, mientras que un cierre por debajo del mínimo la vuelve bajista.
En el marco temporal de 15 minutos observa las últimas dos velas completadas.
Se abre una posición larga cuando la vela anterior cierra por encima del máximo de dos barras atrás.
Se abre una posición corta cuando el cierre anterior cae por debajo del mínimo de dos barras atrás.
Detalles
Criterios de entrada:
El cierre del día anterior por encima/por debajo de su rango establece el sesgo alcista/bajista.
Largo: cierre previo de 15m > máximo de dos barras atrás.
Corto: cierre previo de 15m < mínimo de dos barras atrás.
Largo/Corto: Ambos lados.
Criterios de salida: No definidos, la señal inversa cierra.
Stops: Sugerido en el lado opuesto de la barra de ruptura.
Valores predeterminados:
CandleType = 15 minutos
Filtros:
Categoría: Ruptura
Dirección: Ambos
Indicadores: Velas
Stops: Opcional
Complejidad: Bajo
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>
/// Anand's breakout strategy based on short-term trend and price level breakouts.
/// Uses EMA for trend and breakout of previous candle high/low for entry.
/// </summary>
public class AnandsStrategy : Strategy
{
private readonly StrategyParam<int> _emaLength;
private readonly StrategyParam<int> _cooldownBars;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevHigh;
private decimal _prevLow;
private int _barIndex;
private int _lastTradeBar;
/// <summary>
/// EMA period for trend filter.
/// </summary>
public int EmaLength
{
get => _emaLength.Value;
set => _emaLength.Value = value;
}
/// <summary>
/// Cooldown bars between trades.
/// </summary>
public int CooldownBars
{
get => _cooldownBars.Value;
set => _cooldownBars.Value = value;
}
/// <summary>
/// Trading candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public AnandsStrategy()
{
_emaLength = Param(nameof(EmaLength), 5)
.SetDisplay("EMA Length", "EMA trend filter period", "Indicator");
_cooldownBars = Param(nameof(CooldownBars), 10)
.SetDisplay("Cooldown Bars", "Bars between trades", "Trading");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Trading timeframe", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevHigh = 0;
_prevLow = 0;
_barIndex = 0;
_lastTradeBar = -100;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var ema = new ExponentialMovingAverage { Length = EmaLength };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(ema, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, ema);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal emaValue)
{
if (candle.State != CandleStates.Finished)
return;
_barIndex++;
if (_prevHigh == 0 || _prevLow == 0)
{
_prevHigh = candle.HighPrice;
_prevLow = candle.LowPrice;
return;
}
var cooldownOk = _barIndex - _lastTradeBar > CooldownBars;
var upTrend = candle.ClosePrice > emaValue;
var downTrend = candle.ClosePrice < emaValue;
// Breakout above previous candle high in uptrend
if (upTrend && candle.ClosePrice > _prevHigh && Position <= 0 && cooldownOk)
{
BuyMarket();
_lastTradeBar = _barIndex;
}
// Breakout below previous candle low in downtrend
else if (downTrend && candle.ClosePrice < _prevLow && Position >= 0 && cooldownOk)
{
SellMarket();
_lastTradeBar = _barIndex;
}
_prevHigh = candle.HighPrice;
_prevLow = candle.LowPrice;
}
}
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 CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
from datatype_extensions import *
class anands_strategy(Strategy):
"""
Anand's breakout strategy based on short-term trend and price level breakouts.
Uses EMA for trend and breakout of previous candle high/low for entry.
"""
def __init__(self):
super(anands_strategy, self).__init__()
self._ema_length = self.Param("EmaLength", 5) \
.SetDisplay("EMA Length", "EMA trend filter period", "Indicator")
self._cooldown_bars = self.Param("CooldownBars", 10) \
.SetDisplay("Cooldown Bars", "Bars between trades", "Trading")
self._candle_type = self.Param("CandleType", tf(5)) \
.SetDisplay("Candle Type", "Trading timeframe", "General")
self._prev_high = 0.0
self._prev_low = 0.0
self._bar_index = 0
self._last_trade_bar = -100
@property
def EmaLength(self): return self._ema_length.Value
@EmaLength.setter
def EmaLength(self, v): self._ema_length.Value = v
@property
def CooldownBars(self): return self._cooldown_bars.Value
@CooldownBars.setter
def CooldownBars(self, v): self._cooldown_bars.Value = v
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, v): self._candle_type.Value = v
def OnReseted(self):
super(anands_strategy, self).OnReseted()
self._prev_high = 0.0
self._prev_low = 0.0
self._bar_index = 0
self._last_trade_bar = -100
def OnStarted2(self, time):
super(anands_strategy, self).OnStarted2(time)
ema = ExponentialMovingAverage()
ema.Length = self.EmaLength
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(ema, self.ProcessCandle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ema)
self.DrawOwnTrades(area)
def ProcessCandle(self, candle, ema_value):
if candle.State != CandleStates.Finished:
return
self._bar_index += 1
if self._prev_high == 0 or self._prev_low == 0:
self._prev_high = float(candle.HighPrice)
self._prev_low = float(candle.LowPrice)
return
close = float(candle.ClosePrice)
cooldown_ok = self._bar_index - self._last_trade_bar > self.CooldownBars
up_trend = close > ema_value
down_trend = close < ema_value
if up_trend and close > self._prev_high and self.Position <= 0 and cooldown_ok:
self.BuyMarket()
self._last_trade_bar = self._bar_index
elif down_trend and close < self._prev_low and self.Position >= 0 and cooldown_ok:
self.SellMarket()
self._last_trade_bar = self._bar_index
self._prev_high = float(candle.HighPrice)
self._prev_low = float(candle.LowPrice)
def CreateClone(self):
"""!! REQUIRED!! Creates a new instance of the strategy."""
return anands_strategy()