Estratégias Paralelas
Sistema de rompimento Heikin Ashi com MACD que opera em ambas as direções. Entra quando uma nova tendência Heikin Ashi se alinha com um rompimento acima ou abaixo do Canal Donchian e o MACD confirma o momentum.
Combinar a identificação de tendência do Heikin Ashi com a detecção de rompimentos mantém as operações alinhadas com movimentos frescos. O MACD atua como filtro de momentum para evitar sinais falsos.
Melhor para traders que buscam entradas antecipadas de rompimento após uma reversão de tendência. Funciona em períodos intradiários.
Detalhes
- Critérios de entrada:
- Comprado:
Trend turns bullish && Close > DonchianHigh && MACD > Signal - Vendido:
Trend turns bearish && Close < DonchianLow && MACD < Signal
- Comprado:
- Comprado/Vendido: Ambos
- Critérios de saída:
- Sinal de rompimento oposto
- Stops: Não definidos
- Valores padrão:
DonchianPeriod= 5MacdFast= 12MacdSlow= 26MacdSignal= 9CandleType= TimeSpan.FromMinutes(5).TimeFrame()
- Filtros:
- Categoria: Rompimento
- Direção: Ambos
- Indicadores: Heikin Ashi, Donchian Channel, MACD
- Stops: Não
- Complexidade: Intermediário
- Período: Intradiário
- Sazonalidade: Não
- Redes neurais: Não
- Divergência: Não
- Nível de risco: Médio
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 combining Heikin Ashi trend reversals with Donchian Channel breakouts and MACD confirmation.
/// </summary>
public class ParallelStrategiesStrategy : Strategy
{
private readonly StrategyParam<int> _donchianPeriod;
private readonly StrategyParam<int> _macdFast;
private readonly StrategyParam<int> _macdSlow;
private readonly StrategyParam<int> _macdSignal;
private readonly StrategyParam<DataType> _candleType;
private decimal? _prevUpper;
private decimal? _prevLower;
private int? _prevTrend;
// Heikin Ashi state
private decimal _haOpen;
private decimal _haClose;
private bool _haInitialized;
public int DonchianPeriod { get => _donchianPeriod.Value; set => _donchianPeriod.Value = value; }
public int MacdFast { get => _macdFast.Value; set => _macdFast.Value = value; }
public int MacdSlow { get => _macdSlow.Value; set => _macdSlow.Value = value; }
public int MacdSignal { get => _macdSignal.Value; set => _macdSignal.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public ParallelStrategiesStrategy()
{
_donchianPeriod = Param(nameof(DonchianPeriod), 5)
.SetGreaterThanZero()
.SetDisplay("Donchian Period", "Lookback for breakout calculation", "Indicators");
_macdFast = Param(nameof(MacdFast), 12)
.SetGreaterThanZero()
.SetDisplay("MACD Fast", "Fast EMA period", "Indicators");
_macdSlow = Param(nameof(MacdSlow), 26)
.SetGreaterThanZero()
.SetDisplay("MACD Slow", "Slow EMA period", "Indicators");
_macdSignal = Param(nameof(MacdSignal), 9)
.SetGreaterThanZero()
.SetDisplay("MACD Signal", "Signal line period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Time frame for candles", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevUpper = null;
_prevLower = null;
_prevTrend = null;
_haOpen = 0;
_haClose = 0;
_haInitialized = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var donchian = new DonchianChannels { Length = DonchianPeriod };
var macd = new MovingAverageConvergenceDivergenceSignal(
new MovingAverageConvergenceDivergence(
new ExponentialMovingAverage { Length = MacdSlow },
new ExponentialMovingAverage { Length = MacdFast }),
new ExponentialMovingAverage { Length = MacdSignal });
SubscribeCandles(CandleType)
.BindEx(donchian, macd, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue donchianValue, IIndicatorValue macdValue)
{
if (candle.State != CandleStates.Finished)
return;
var dc = (IDonchianChannelsValue)donchianValue;
var macdV = (IMovingAverageConvergenceDivergenceSignalValue)macdValue;
if (dc.UpperBand is not decimal upper || dc.LowerBand is not decimal lower)
return;
if (macdV.Macd is not decimal macdLine || macdV.Signal is not decimal signalLine)
return;
// Compute Heikin Ashi manually
var haCloseNew = (candle.OpenPrice + candle.HighPrice + candle.LowPrice + candle.ClosePrice) / 4m;
decimal haOpenNew;
if (!_haInitialized)
{
haOpenNew = (candle.OpenPrice + candle.ClosePrice) / 2m;
_haInitialized = true;
}
else
{
haOpenNew = (_haOpen + _haClose) / 2m;
}
_haOpen = haOpenNew;
_haClose = haCloseNew;
var trend = haOpenNew < haCloseNew ? 1 : -1;
if (_prevTrend is int prevTrend)
{
if (trend > 0 && prevTrend < 0 && macdLine > signalLine && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (trend < 0 && prevTrend > 0 && macdLine < signalLine && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
}
_prevUpper = upper;
_prevLower = lower;
_prevTrend = trend;
}
}
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 (
DonchianChannels, ExponentialMovingAverage,
MovingAverageConvergenceDivergence, MovingAverageConvergenceDivergenceSignal
)
from StockSharp.Algo.Strategies import Strategy
class parallel_strategies_strategy(Strategy):
def __init__(self):
super(parallel_strategies_strategy, self).__init__()
self._donchian_period = self.Param("DonchianPeriod", 5) \
.SetDisplay("Donchian Period", "Lookback for breakout calculation", "Indicators")
self._macd_fast = self.Param("MacdFast", 12) \
.SetDisplay("MACD Fast", "Fast EMA period", "Indicators")
self._macd_slow = self.Param("MacdSlow", 26) \
.SetDisplay("MACD Slow", "Slow EMA period", "Indicators")
self._macd_signal = self.Param("MacdSignal", 9) \
.SetDisplay("MACD Signal", "Signal line period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Time frame for candles", "General")
self._prev_upper = None
self._prev_lower = None
self._prev_trend = None
self._ha_open = 0.0
self._ha_close = 0.0
self._ha_initialized = False
@property
def DonchianPeriod(self):
return self._donchian_period.Value
@DonchianPeriod.setter
def DonchianPeriod(self, value):
self._donchian_period.Value = value
@property
def MacdFast(self):
return self._macd_fast.Value
@MacdFast.setter
def MacdFast(self, value):
self._macd_fast.Value = value
@property
def MacdSlow(self):
return self._macd_slow.Value
@MacdSlow.setter
def MacdSlow(self, value):
self._macd_slow.Value = value
@property
def MacdSignal(self):
return self._macd_signal.Value
@MacdSignal.setter
def MacdSignal(self, value):
self._macd_signal.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(parallel_strategies_strategy, self).OnStarted2(time)
donchian = DonchianChannels()
donchian.Length = self.DonchianPeriod
slow_ema = ExponentialMovingAverage()
slow_ema.Length = self.MacdSlow
fast_ema = ExponentialMovingAverage()
fast_ema.Length = self.MacdFast
macd_core = MovingAverageConvergenceDivergence(slow_ema, fast_ema)
sig_ema = ExponentialMovingAverage()
sig_ema.Length = self.MacdSignal
macd = MovingAverageConvergenceDivergenceSignal(macd_core, sig_ema)
self.SubscribeCandles(self.CandleType) \
.BindEx(donchian, macd, self.ProcessCandle) \
.Start()
def ProcessCandle(self, candle, donchian_value, macd_value):
if candle.State != CandleStates.Finished:
return
upper_raw = donchian_value.UpperBand
lower_raw = donchian_value.LowerBand
if upper_raw is None or lower_raw is None:
return
macd_raw = macd_value.Macd
signal_raw = macd_value.Signal
if macd_raw is None or signal_raw is None:
return
upper = float(upper_raw)
lower = float(lower_raw)
macd_line = float(macd_raw)
signal_line = float(signal_raw)
ha_close_new = (float(candle.OpenPrice) + float(candle.HighPrice)
+ float(candle.LowPrice) + float(candle.ClosePrice)) / 4.0
if not self._ha_initialized:
ha_open_new = (float(candle.OpenPrice) + float(candle.ClosePrice)) / 2.0
self._ha_initialized = True
else:
ha_open_new = (self._ha_open + self._ha_close) / 2.0
self._ha_open = ha_open_new
self._ha_close = ha_close_new
trend = 1 if ha_open_new < ha_close_new else -1
if self._prev_trend is not None:
if trend > 0 and self._prev_trend < 0 and macd_line > signal_line and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif trend < 0 and self._prev_trend > 0 and macd_line < signal_line and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_upper = upper
self._prev_lower = lower
self._prev_trend = trend
def OnReseted(self):
super(parallel_strategies_strategy, self).OnReseted()
self._prev_upper = None
self._prev_lower = None
self._prev_trend = None
self._ha_open = 0.0
self._ha_close = 0.0
self._ha_initialized = False
def CreateClone(self):
return parallel_strategies_strategy()