Uma imagem espelhada da versão altista, esta configuração busca reversões baixistas rápidas. Após duas velas altistas fortes que empurram a novas máximas, uma vela baixista decisiva fecha abaixo da mínima da barra anterior. Uma breve tendência de alta prévia ajuda a confirmar o esgotamento dos compradores.
Os testes indicam um retorno anual médio de aproximadamente 88%. Tem melhor desempenho no mercado de ações.
O algoritmo rastreia uma janela deslizante de três velas. Quando o padrão aparece e qualquer requisito de tendência de alta é atendido, uma posição vendida é tomada com o stop acima da máxima do padrão. As regras são diretas, então os sinais ocorrem imediatamente no fechamento da vela.
A operação é encerrada no stop protetor ou quando outro padrão se forma. Como ela joga com retrações de curto prazo dentro de um potencial movimento de baixa, funciona melhor em mercados voláteis.
Detalhes
Critérios de entrada: Duas velas altistas com máximas mais altas, seguidas de uma vela baixista fechando abaixo da mínima da barra do meio.
Comprado/Vendido: Somente vendido.
Critérios de saída: Stop-loss ou próximo padrão.
Stops: Sim, acima da máxima do padrão.
Valores padrão:
CandleType = 15 minute
StopLossPercent = 1
RequireUptrend = true
UptrendLength = 5
Filtros:
Categoria: Padrão
Direção: Vendido
Indicadores: Candlestick
Stops: Sim
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>
/// Three-Bar Reversal Down strategy.
/// Pattern: 1st bar bullish, 2nd bar bullish with higher high, 3rd bar bearish closing below 2nd low.
/// Uses SMA for exit.
/// </summary>
public class ThreeBarReversalDownStrategy : Strategy
{
private readonly StrategyParam<int> _maPeriod;
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _cooldownBars;
private ICandleMessage _bar1;
private ICandleMessage _bar2;
private int _cooldown;
/// <summary>
/// MA Period.
/// </summary>
public int MAPeriod
{
get => _maPeriod.Value;
set => _maPeriod.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Cooldown bars.
/// </summary>
public int CooldownBars
{
get => _cooldownBars.Value;
set => _cooldownBars.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public ThreeBarReversalDownStrategy()
{
_maPeriod = Param(nameof(MAPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("MA Period", "Period for SMA", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(1).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
_cooldownBars = Param(nameof(CooldownBars), 500)
.SetRange(1, 1000)
.SetDisplay("Cooldown Bars", "Bars to wait between trades", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_bar1 = null;
_bar2 = null;
_cooldown = default;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_bar1 = null;
_bar2 = null;
_cooldown = 0;
var sma = new SimpleMovingAverage { Length = MAPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(sma, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, sma);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal smaValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (_cooldown > 0)
{
_cooldown--;
_bar1 = _bar2;
_bar2 = candle;
return;
}
if (_bar1 != null && _bar2 != null)
{
// Three-bar reversal down
var bar1Bullish = _bar1.ClosePrice > _bar1.OpenPrice;
var bar2Bullish = _bar2.ClosePrice > _bar2.OpenPrice;
var bar2HigherHigh = _bar2.HighPrice > _bar1.HighPrice;
var bar3Bearish = candle.ClosePrice < candle.OpenPrice;
var bar3BelowBar2Low = candle.ClosePrice < _bar2.LowPrice;
var threeBarDown = bar1Bullish && bar2Bullish && bar2HigherHigh && bar3Bearish && bar3BelowBar2Low;
// Three-bar reversal up
var bar1Bearish = _bar1.ClosePrice < _bar1.OpenPrice;
var bar2Bearish = _bar2.ClosePrice < _bar2.OpenPrice;
var bar2LowerLow = _bar2.LowPrice < _bar1.LowPrice;
var bar3Bullish = candle.ClosePrice > candle.OpenPrice;
var bar3AboveBar2High = candle.ClosePrice > _bar2.HighPrice;
var threeBarUp = bar1Bearish && bar2Bearish && bar2LowerLow && bar3Bullish && bar3AboveBar2High;
if (Position == 0 && threeBarDown)
{
SellMarket();
_cooldown = CooldownBars;
}
else if (Position == 0 && threeBarUp)
{
BuyMarket();
_cooldown = CooldownBars;
}
else if (Position > 0 && candle.ClosePrice < smaValue)
{
SellMarket();
_cooldown = CooldownBars;
}
else if (Position < 0 && candle.ClosePrice > smaValue)
{
BuyMarket();
_cooldown = CooldownBars;
}
}
_bar1 = _bar2;
_bar2 = candle;
}
}
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 SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
class three_bar_reversal_down_strategy(Strategy):
"""
Three-Bar Reversal Down strategy.
Pattern: 1st bar bullish, 2nd bar bullish with higher high, 3rd bar bearish closing below 2nd low.
Uses SMA for exit.
"""
def __init__(self):
super(three_bar_reversal_down_strategy, self).__init__()
self._ma_period = self.Param("MAPeriod", 20).SetDisplay("MA Period", "Period for SMA", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(1))).SetDisplay("Candle Type", "Type of candles to use", "General")
self._cooldown_bars = self.Param("CooldownBars", 500).SetDisplay("Cooldown Bars", "Bars to wait between trades", "General")
self._bar1 = None
self._bar2 = None
self._cooldown = 0
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(three_bar_reversal_down_strategy, self).OnReseted()
self._bar1 = None
self._bar2 = None
self._cooldown = 0
def OnStarted2(self, time):
super(three_bar_reversal_down_strategy, self).OnStarted2(time)
self._bar1 = None
self._bar2 = None
self._cooldown = 0
sma = SimpleMovingAverage()
sma.Length = self._ma_period.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(sma, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, sma)
self.DrawOwnTrades(area)
def _process_candle(self, candle, sma_val):
if candle.State != CandleStates.Finished:
return
if self._cooldown > 0:
self._cooldown -= 1
self._bar1 = self._bar2
self._bar2 = candle
return
if self._bar1 is not None and self._bar2 is not None:
# Three-bar reversal down
bar1_bullish = self._bar1.ClosePrice > self._bar1.OpenPrice
bar2_bullish = self._bar2.ClosePrice > self._bar2.OpenPrice
bar2_higher_high = self._bar2.HighPrice > self._bar1.HighPrice
bar3_bearish = candle.ClosePrice < candle.OpenPrice
bar3_below_bar2_low = candle.ClosePrice < self._bar2.LowPrice
three_bar_down = bar1_bullish and bar2_bullish and bar2_higher_high and bar3_bearish and bar3_below_bar2_low
# Three-bar reversal up
bar1_bearish = self._bar1.ClosePrice < self._bar1.OpenPrice
bar2_bearish = self._bar2.ClosePrice < self._bar2.OpenPrice
bar2_lower_low = self._bar2.LowPrice < self._bar1.LowPrice
bar3_bullish = candle.ClosePrice > candle.OpenPrice
bar3_above_bar2_high = candle.ClosePrice > self._bar2.HighPrice
three_bar_up = bar1_bearish and bar2_bearish and bar2_lower_low and bar3_bullish and bar3_above_bar2_high
sv = float(sma_val)
close = float(candle.ClosePrice)
cd = self._cooldown_bars.Value
if self.Position == 0 and three_bar_down:
self.SellMarket()
self._cooldown = cd
elif self.Position == 0 and three_bar_up:
self.BuyMarket()
self._cooldown = cd
elif self.Position > 0 and close < sv:
self.SellMarket()
self._cooldown = cd
elif self.Position < 0 and close > sv:
self.BuyMarket()
self._cooldown = cd
self._bar1 = self._bar2
self._bar2 = candle
def CreateClone(self):
return three_bar_reversal_down_strategy()