El patrón Tres Soldados Blancos es una reversión alcista clásica compuesta por tres velas alcistas fuertes consecutivas. Después de una tendencia bajista, esta secuencia a menudo marca el inicio de un movimiento sostenido al alza, ya que la presión compradora supera a los vendedores.
Las pruebas indican un rendimiento anual promedio de aproximadamente 175%. Funciona mejor en el mercado de acciones.
La estrategia entra largo una vez que se forma el tercer soldado, esperando el seguimiento del aumento en el impulso. Las operaciones cortas no se toman porque el setup es puramente alcista, pero el sistema permite cerrar posiciones cortas iniciadas por otros métodos.
Los stops se colocan a poca distancia por debajo del patrón para protegerse contra señales falsas, y las posiciones se cierran si el precio cierra de nuevo por debajo de ese nivel.
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 minutos
StopLossPercent = 2
La estrategia solo compra. El stop se coloca StopLossPercent por debajo del mínimo más bajo del patrón y la posición se cierra cuando una vela cierra por debajo.
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>
/// Three White Soldiers strategy.
/// While flat it buys after three bullish candles in a row, each closing above the previous close.
/// The stop lies StopLossPercent below the pattern's lowest low, and a close beyond it closes the position.
/// </summary>
public class ThreeWhiteSoldiersStrategy : Strategy
{
private readonly StrategyParam<decimal> _stopLossPercent;
private readonly StrategyParam<DataType> _candleType;
private readonly List<ICandleMessage> _candles = [];
private decimal _stopPrice;
/// <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 ThreeWhiteSoldiersStrategy()
{
_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)
SellMarket(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 && c1.ClosePrice > c1.OpenPrice && c2.ClosePrice > c2.OpenPrice && c1.ClosePrice > c0.ClosePrice && c2.ClosePrice > c1.ClosePrice))
return;
BuyMarket(Volume);
_stopPrice = Math.Min(Math.Min(c0.LowPrice, c1.LowPrice), c2.LowPrice) * (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 three_white_soldiers_strategy(Strategy):
"""
Three White Soldiers strategy.
While flat it buys after three bullish candles in a row, each closing above the previous close.
The stop lies StopLossPercent below the pattern's lowest low, and a close beyond it closes the position.
"""
def __init__(self):
super(three_white_soldiers_strategy, self).__init__()
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(three_white_soldiers_strategy, self).OnReseted()
self._candles = []
self._stop_price = Decimal(0)
def OnStarted2(self, time):
super(three_white_soldiers_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.SellMarket(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 c1.ClosePrice > c1.OpenPrice and c2.ClosePrice > c2.OpenPrice and c1.ClosePrice > c0.ClosePrice and c2.ClosePrice > c1.ClosePrice):
return
self.BuyMarket(self.Volume)
self._stop_price = min(c0.LowPrice, c1.LowPrice, c2.LowPrice) * (Decimal(1) - Decimal(self._stop_loss_percent.Value) / Decimal(100))
def CreateClone(self):
return three_white_soldiers_strategy()