Esta estrategia es una conversión del experto MQL exp_3xma_ishimoku. Utiliza el indicador Ichimoku con periodos reducidos y actúa de manera contraria a las rupturas de la nube.
La línea Kijun se compara con los límites de la nube Ichimoku. Cuando Kijun cae desde arriba de la nube hacia su interior, la estrategia cierra posiciones cortas y abre una posición larga si está permitido comprar. Cuando Kijun sube desde abajo de la nube hacia su interior, las posiciones largas se cierran y se puede abrir una posición corta.
El marco temporal predeterminado para el análisis son velas de 4 horas.
Parámetros
Tenkan Period – longitud de la línea Tenkan-sen.
Kijun Period – longitud de la línea Kijun-sen.
Senkou Span B Period – periodo del segundo tramo Senkou.
Allow Buy – habilitar la apertura de posiciones largas.
Allow Sell – habilitar la apertura de posiciones cortas.
Candle Type – serie de velas utilizada para el cálculo del indicador.
Cómo funciona
Se suscribe a la serie de velas seleccionada y vincula el indicador Ichimoku.
Procesa únicamente velas finalizadas.
Detecta cuándo la línea Kijun cruza los bordes de la nube.
Cierra posiciones opuestas y abre una nueva en la dirección de la señal si está permitido.
Descargo de responsabilidad
Este ejemplo es con fines educativos y no constituye asesoramiento financiero. Úselo bajo su propio riesgo.
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>
/// Ichimoku cloud strategy.
/// Buys when Kijun crosses down into cloud, sells on opposite.
/// </summary>
public class Exp3XmaIshimokuStrategy : Strategy
{
private readonly StrategyParam<int> _tenkanPeriod;
private readonly StrategyParam<int> _kijunPeriod;
private readonly StrategyParam<int> _senkouSpanPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal? _prevKijun;
private decimal? _prevUpper;
private decimal? _prevLower;
public int TenkanPeriod { get => _tenkanPeriod.Value; set => _tenkanPeriod.Value = value; }
public int KijunPeriod { get => _kijunPeriod.Value; set => _kijunPeriod.Value = value; }
public int SenkouSpanPeriod { get => _senkouSpanPeriod.Value; set => _senkouSpanPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public Exp3XmaIshimokuStrategy()
{
_tenkanPeriod = Param(nameof(TenkanPeriod), 3)
.SetGreaterThanZero()
.SetDisplay("Tenkan Period", "Tenkan-sen period", "Ichimoku");
_kijunPeriod = Param(nameof(KijunPeriod), 6)
.SetGreaterThanZero()
.SetDisplay("Kijun Period", "Kijun-sen period", "Ichimoku");
_senkouSpanPeriod = Param(nameof(SenkouSpanPeriod), 9)
.SetGreaterThanZero()
.SetDisplay("Senkou B Period", "Senkou Span B period", "Ichimoku");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle type", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevKijun = null;
_prevUpper = null;
_prevLower = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var ichimoku = new Ichimoku();
ichimoku.Tenkan.Length = TenkanPeriod;
ichimoku.Kijun.Length = KijunPeriod;
ichimoku.SenkouB.Length = SenkouSpanPeriod;
SubscribeCandles(CandleType)
.BindEx(ichimoku, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue ichimokuValue)
{
if (candle.State != CandleStates.Finished)
return;
var ich = (IIchimokuValue)ichimokuValue;
if (ich.Kijun is not decimal kijun ||
ich.SenkouA is not decimal senkouA ||
ich.SenkouB is not decimal senkouB)
return;
var upper = Math.Max(senkouA, senkouB);
var lower = Math.Min(senkouA, senkouB);
if (_prevKijun is null)
{
_prevKijun = kijun;
_prevUpper = upper;
_prevLower = lower;
return;
}
// Buy when Kijun crosses down into cloud
var crossDown = _prevKijun > _prevUpper && kijun <= upper;
// Sell when Kijun crosses up out of cloud
var crossUp = _prevKijun < _prevLower && kijun >= lower;
if (crossDown && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (crossUp && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
_prevKijun = kijun;
_prevUpper = upper;
_prevLower = lower;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Math
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import Ichimoku
from StockSharp.Algo.Strategies import Strategy
class exp3_xma_ishimoku_strategy(Strategy):
def __init__(self):
super(exp3_xma_ishimoku_strategy, self).__init__()
self._tenkan_period = self.Param("TenkanPeriod", 3) \
.SetDisplay("Tenkan Period", "Tenkan-sen period", "Ichimoku")
self._kijun_period = self.Param("KijunPeriod", 6) \
.SetDisplay("Kijun Period", "Kijun-sen period", "Ichimoku")
self._senkou_span_period = self.Param("SenkouSpanPeriod", 9) \
.SetDisplay("Senkou B Period", "Senkou Span B period", "Ichimoku")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candle type", "General")
self._prev_kijun = None
self._prev_upper = None
self._prev_lower = None
@property
def TenkanPeriod(self):
return self._tenkan_period.Value
@TenkanPeriod.setter
def TenkanPeriod(self, value):
self._tenkan_period.Value = value
@property
def KijunPeriod(self):
return self._kijun_period.Value
@KijunPeriod.setter
def KijunPeriod(self, value):
self._kijun_period.Value = value
@property
def SenkouSpanPeriod(self):
return self._senkou_span_period.Value
@SenkouSpanPeriod.setter
def SenkouSpanPeriod(self, value):
self._senkou_span_period.Value = value
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
def OnStarted2(self, time):
super(exp3_xma_ishimoku_strategy, self).OnStarted2(time)
ichimoku = Ichimoku()
ichimoku.Tenkan.Length = self.TenkanPeriod
ichimoku.Kijun.Length = self.KijunPeriod
ichimoku.SenkouB.Length = self.SenkouSpanPeriod
self.SubscribeCandles(self.CandleType) \
.BindEx(ichimoku, self.ProcessCandle) \
.Start()
def ProcessCandle(self, candle, ichimoku_value):
if candle.State != CandleStates.Finished:
return
kijun_raw = ichimoku_value.Kijun
senkou_a_raw = ichimoku_value.SenkouA
senkou_b_raw = ichimoku_value.SenkouB
if kijun_raw is None or senkou_a_raw is None or senkou_b_raw is None:
return
kijun = float(kijun_raw)
senkou_a = float(senkou_a_raw)
senkou_b = float(senkou_b_raw)
upper = max(senkou_a, senkou_b)
lower = min(senkou_a, senkou_b)
if self._prev_kijun is None:
self._prev_kijun = kijun
self._prev_upper = upper
self._prev_lower = lower
return
cross_down = self._prev_kijun > self._prev_upper and kijun <= upper
cross_up = self._prev_kijun < self._prev_lower and kijun >= lower
if cross_down and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif cross_up and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_kijun = kijun
self._prev_upper = upper
self._prev_lower = lower
def OnReseted(self):
super(exp3_xma_ishimoku_strategy, self).OnReseted()
self._prev_kijun = None
self._prev_upper = None
self._prev_lower = None
def CreateClone(self):
return exp3_xma_ishimoku_strategy()