Estrategia basada en la ruptura del Kumo (nube) de Ichimoku.
Las pruebas indican un retorno anual promedio de aproximadamente 70%. Funciona mejor en el mercado de acciones.
Este enfoque se basa en las señales de la nube Ichimoku. El precio rompiendo por encima de la nube con Tenkan-sen cruzando sobre Kijun-sen desencadena una compra, mientras que la ruptura opuesta por debajo de la nube inicia un corto. Las posiciones se mantienen hasta que el precio vuelve a través de la nube.
La nube delinea niveles clave de soporte y resistencia, por lo que el sistema espera cierres decisivos más allá de ella. Combinando múltiples componentes de Ichimoku, la estrategia evita operaciones de menor probabilidad durante mercados laterales.
Detalles
Criterios de entrada: Señales basadas en Ichimoku.
Largo/Corto: Ambos directions.
Criterios de salida: Señal opuesta.
Stops: No.
Valores predeterminados:
TenkanPeriod = 9
KijunPeriod = 26
SenkouSpanPeriod = 52
CandleType = TimeSpan.FromMinutes(15)
Filtros:
Categoría: Ruptura
Dirección: Ambos
Indicadores: Ichimoku
Stops: No
Complejidad: Básico
Marco temporal: Intradía (15m)
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>
/// Strategy based on Ichimoku Kumo (cloud) breakout.
/// Trades on Tenkan/Kijun crosses with cloud confirmation.
/// </summary>
public class IchimokuKumoBreakoutStrategy : Strategy
{
private readonly StrategyParam<int> _tenkanPeriod;
private readonly StrategyParam<int> _kijunPeriod;
private readonly StrategyParam<int> _senkouSpanPeriod;
private readonly StrategyParam<DataType> _candleType;
private bool _prevTenkanAboveKijun;
private bool _hasPrevValues;
private int _candlesSinceLastTrade;
/// <summary>
/// Period for Tenkan-sen line.
/// </summary>
public int TenkanPeriod
{
get => _tenkanPeriod.Value;
set => _tenkanPeriod.Value = value;
}
/// <summary>
/// Period for Kijun-sen line.
/// </summary>
public int KijunPeriod
{
get => _kijunPeriod.Value;
set => _kijunPeriod.Value = value;
}
/// <summary>
/// Period for Senkou Span B.
/// </summary>
public int SenkouSpanPeriod
{
get => _senkouSpanPeriod.Value;
set => _senkouSpanPeriod.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Initialize the Ichimoku Kumo Breakout strategy.
/// </summary>
public IchimokuKumoBreakoutStrategy()
{
_tenkanPeriod = Param(nameof(TenkanPeriod), 9)
.SetDisplay("Tenkan-sen Period", "Period for Tenkan-sen line", "Indicators")
.SetOptimize(7, 13, 2);
_kijunPeriod = Param(nameof(KijunPeriod), 26)
.SetDisplay("Kijun-sen Period", "Period for Kijun-sen line", "Indicators")
.SetOptimize(20, 30, 2);
_senkouSpanPeriod = Param(nameof(SenkouSpanPeriod), 52)
.SetDisplay("Senkou Span B Period", "Period for Senkou Span B", "Indicators")
.SetOptimize(40, 60, 4);
_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();
_prevTenkanAboveKijun = default;
_hasPrevValues = default;
_candlesSinceLastTrade = default;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var tenkan = new Highest { Length = TenkanPeriod };
var tenkanLow = new Lowest { Length = TenkanPeriod };
var kijun = new Highest { Length = KijunPeriod };
var kijunLow = new Lowest { Length = KijunPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(tenkan, tenkanLow, kijun, kijunLow, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal tenkanHigh, decimal tenkanLow, decimal kijunHigh, decimal kijunLow)
{
if (candle.State != CandleStates.Finished)
return;
var tenkan = (tenkanHigh + tenkanLow) / 2m;
var kijun = (kijunHigh + kijunLow) / 2m;
if (tenkan == 0 || kijun == 0)
return;
var tenkanAboveKijun = tenkan > kijun;
_candlesSinceLastTrade++;
if (!_hasPrevValues)
{
_hasPrevValues = true;
_prevTenkanAboveKijun = tenkanAboveKijun;
return;
}
// Detect cross
var isCross = tenkanAboveKijun != _prevTenkanAboveKijun;
_prevTenkanAboveKijun = tenkanAboveKijun;
if (!isCross)
return;
// Cooldown to avoid too many trades
if (_candlesSinceLastTrade < 4)
return;
if (tenkanAboveKijun && Position <= 0)
{
BuyMarket();
_candlesSinceLastTrade = 0;
}
else if (!tenkanAboveKijun && Position >= 0)
{
SellMarket();
_candlesSinceLastTrade = 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 Highest, Lowest
from StockSharp.Algo.Strategies import Strategy
class ichimoku_kumo_breakout_strategy(Strategy):
"""
Ichimoku Kumo breakout. Tenkan/Kijun cross with cloud confirmation.
"""
def __init__(self):
super(ichimoku_kumo_breakout_strategy, self).__init__()
self._tenkan_period = self.Param("TenkanPeriod", 9).SetDisplay("Tenkan Period", "Tenkan-sen period", "Indicators")
self._kijun_period = self.Param("KijunPeriod", 26).SetDisplay("Kijun Period", "Kijun-sen period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).SetDisplay("Candle Type", "Timeframe", "General")
self._prev_tenkan_above = False
self._has_prev = False
self._candles_since_trade = 0
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(ichimoku_kumo_breakout_strategy, self).OnReseted()
self._prev_tenkan_above = False
self._has_prev = False
self._candles_since_trade = 0
def OnStarted2(self, time):
super(ichimoku_kumo_breakout_strategy, self).OnStarted2(time)
tenkan_h = Highest()
tenkan_h.Length = self._tenkan_period.Value
tenkan_l = Lowest()
tenkan_l.Length = self._tenkan_period.Value
kijun_h = Highest()
kijun_h.Length = self._kijun_period.Value
kijun_l = Lowest()
kijun_l.Length = self._kijun_period.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(tenkan_h, tenkan_l, kijun_h, kijun_l, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def _process_candle(self, candle, th, tl, kh, kl):
if candle.State != CandleStates.Finished:
return
tenkan = (float(th) + float(tl)) / 2.0
kijun = (float(kh) + float(kl)) / 2.0
if tenkan == 0 or kijun == 0:
return
tenkan_above = tenkan > kijun
self._candles_since_trade += 1
if not self._has_prev:
self._has_prev = True
self._prev_tenkan_above = tenkan_above
return
is_cross = tenkan_above != self._prev_tenkan_above
self._prev_tenkan_above = tenkan_above
if not is_cross:
return
if self._candles_since_trade < 4:
return
if tenkan_above and self.Position <= 0:
self.BuyMarket()
self._candles_since_trade = 0
elif not tenkan_above and self.Position >= 0:
self.SellMarket()
self._candles_since_trade = 0
def CreateClone(self):
return ichimoku_kumo_breakout_strategy()