El Bebé Abandonado Bajista refleja la versión alcista pero señala un posible techo.
Presenta un doji con gap alcista seguido de un gap bajista, dejando la vela del medio aislada por encima del rango anterior.
Las pruebas indican un rendimiento anual promedio de aproximadamente el 79%. Funciona mejor en el mercado de acciones.
La estrategia vende en corto cuando la tercera vela abre con gap por debajo del doji, con el objetivo de beneficiarse del cambio abrupto en el sentimiento.
El riesgo está limitado con un stop justo por encima del máximo del doji en caso de que el precio se recupere.
Detalles
Criterios de entrada: coincidencia de patrón
Largo/Corto: Ambos
Criterios de salida: stop-loss o señal opuesta
Stops: Sí, basado en porcentaje
Valores predeterminados:
CandleType = 15 minute
DojiBodyPercent = 10
StopLossPercent = 2
El mercado opera las 24 horas, así que los rangos de las velas casi nunca dejan huecos (el mes de muestra tiene como mucho un patrón bajista así); los huecos se miden entre los cuerpos de las velas. El cuerpo del doji es como mucho DojiBodyPercent de su rango. La estrategia solo vende, al cierre de la tercera vela; el stop se coloca StopLossPercent por encima del máximo del doji y la posición se cierra cuando una vela cierra por encima.
Filtros:
Categoría: Patrón
Dirección: Ambos
Indicadores: Candlestick
Stops: Sí
Complejidad: Intermedio
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>
/// Bearish Abandoned Baby strategy.
/// While flat it sells after a bullish candle, a doji whose body gaps above the first body, and a bearish candle whose body gaps below the doji.
/// The stop lies StopLossPercent above the doji's high, and a close beyond it closes the position.
/// </summary>
public class BearishAbandonedBabyStrategy : Strategy
{
private readonly StrategyParam<decimal> _dojiBodyPercent;
private readonly StrategyParam<decimal> _stopLossPercent;
private readonly StrategyParam<DataType> _candleType;
private readonly List<ICandleMessage> _candles = [];
private decimal _stopPrice;
/// <summary>
/// Largest body of the doji, in percent of its range.
/// </summary>
public decimal DojiBodyPercent
{
get => _dojiBodyPercent.Value;
set => _dojiBodyPercent.Value = value;
}
/// <summary>
/// Distance of the stop beyond the pattern, in percent.
/// </summary>
public decimal StopLossPercent
{
get => _stopLossPercent.Value;
set => _stopLossPercent.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public BearishAbandonedBabyStrategy()
{
_dojiBodyPercent = Param(nameof(DojiBodyPercent), 10m)
.SetNotNegative()
.SetDisplay("Doji Body %", "Largest body of the doji, in percent of its range", "Pattern");
_stopLossPercent = Param(nameof(StopLossPercent), 2m)
.SetNotNegative()
.SetDisplay("Stop Loss %", "Distance of the stop beyond the pattern, in percent", "Risk");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(15).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();
_candles.Clear();
_stopPrice = default;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_candles.Clear();
_stopPrice = default;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
_candles.Add(candle);
if (_candles.Count > 3)
_candles.RemoveAt(0);
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (Position < 0)
{
if (candle.ClosePrice >= _stopPrice)
BuyMarket(-Position);
return;
}
if (Position != 0 || _candles.Count < 3)
return;
var c0 = _candles[0];
var c1 = _candles[1];
var c2 = _candles[2];
if (!(c0.ClosePrice > c0.OpenPrice && Math.Abs(c1.ClosePrice - c1.OpenPrice) <= (c1.HighPrice - c1.LowPrice) * DojiBodyPercent / 100m && Math.Min(c1.OpenPrice, c1.ClosePrice) > Math.Max(c0.OpenPrice, c0.ClosePrice) && c2.ClosePrice < c2.OpenPrice && Math.Max(c2.OpenPrice, c2.ClosePrice) < Math.Min(c1.OpenPrice, c1.ClosePrice)))
return;
SellMarket(Volume);
_stopPrice = c1.HighPrice * (1 + StopLossPercent / 100m);
}
}
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, Decimal
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Strategies import Strategy
class bearish_abandoned_baby_strategy(Strategy):
"""
Bearish Abandoned Baby strategy.
While flat it sells after a bullish candle, a doji whose body gaps above the first body, and a bearish candle whose body gaps below the doji.
The stop lies StopLossPercent above the doji's high, and a close beyond it closes the position.
"""
def __init__(self):
super(bearish_abandoned_baby_strategy, self).__init__()
self._doji_body_percent = self.Param("DojiBodyPercent", 10.0).SetNotNegative().SetDisplay("Doji Body %", "Largest body of the doji, in percent of its range", "Pattern")
self._stop_loss_percent = self.Param("StopLossPercent", 2.0).SetNotNegative().SetDisplay("Stop Loss %", "Distance of the stop beyond the pattern, in percent", "Risk")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(15))).SetDisplay("Candle Type", "Type of candles to use", "General")
self._candles = []
self._stop_price = Decimal(0)
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(bearish_abandoned_baby_strategy, self).OnReseted()
self._candles = []
self._stop_price = Decimal(0)
def OnStarted2(self, time):
super(bearish_abandoned_baby_strategy, self).OnStarted2(time)
self._candles = []
self._stop_price = Decimal(0)
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def _process_candle(self, candle):
if candle.State != CandleStates.Finished:
return
self._candles.append(candle)
if len(self._candles) > 3:
self._candles.pop(0)
if not self.IsFormedAndOnlineAndAllowTrading():
return
if self.Position < 0:
if candle.ClosePrice >= self._stop_price:
self.BuyMarket(-self.Position)
return
if self.Position != 0 or len(self._candles) < 3:
return
c0, c1, c2 = self._candles
if not (c0.ClosePrice > c0.OpenPrice and Math.Abs(c1.ClosePrice - c1.OpenPrice) <= (c1.HighPrice - c1.LowPrice) * Decimal(self._doji_body_percent.Value) / Decimal(100) and Math.Min(c1.OpenPrice, c1.ClosePrice) > Math.Max(c0.OpenPrice, c0.ClosePrice) and c2.ClosePrice < c2.OpenPrice and Math.Max(c2.OpenPrice, c2.ClosePrice) < Math.Min(c1.OpenPrice, c1.ClosePrice)):
return
self.SellMarket(self.Volume)
self._stop_price = c1.HighPrice * (Decimal(1) + Decimal(self._stop_loss_percent.Value) / Decimal(100))
def CreateClone(self):
return bearish_abandoned_baby_strategy()