Estrategia de Patrón de Vela Envolvente
Esta estrategia opera sobre un patrón envolvente seleccionado. Elija entre envolvente alcista o bajista y un lado de la operación para abrir cuando aparezca el patrón. La posición se mantiene durante un número fijo de barras antes de cerrarse.
Detalles
- Criterios de entrada: Patrón envolvente seleccionado (alcista o bajista).
- Largo/Corto: Largo o corto configurable.
- Criterios de salida: Posición cerrada tras el número especificado de barras.
- Stops: No.
- Valores predeterminados:
CandleType= 15 minutosHoldPeriods= 17Pattern= BullishSide= Long
- Filtros:
- Categoría: Patrón
- Dirección: Ambos
- Indicadores: Candlestick
- Stops: No
- Complejidad: Principiante
- Marco temporal: Intradía
- Estacionalidad: No
- Redes neuronales: No
- Divergencia: No
- Nivel de riesgo: Medio
namespace StockSharp.Samples.Strategies;
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
/// <summary>
/// Trades the selected candle-body engulfing pattern and exits after HoldPeriods bars.
/// </summary>
public class EngulfingCandlestickStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _holdPeriods;
private readonly StrategyParam<string> _pattern;
private readonly StrategyParam<Sides> _side;
private decimal? _previousOpen;
private decimal _previousClose;
private int _barsHeld;
private Order _pendingOrder;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int HoldPeriods { get => _holdPeriods.Value; set => _holdPeriods.Value = value; }
public string Pattern { get => _pattern.Value; set => _pattern.Value = value; }
public Sides Side { get => _side.Value; set => _side.Value = value; }
public EngulfingCandlestickStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(15).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
_holdPeriods = Param(nameof(HoldPeriods), 17)
.SetGreaterThanZero()
.SetDisplay("Hold Periods", "Bars to hold the position", "Trading");
_pattern = Param(nameof(Pattern), "Bullish")
.SetDisplay("Pattern", "Bullish or Bearish engulfing", "Trading");
_side = Param(nameof(Side), Sides.Buy)
.SetDisplay("Side", "Buy for long, Sell for short", "Trading");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_previousOpen = null;
_previousClose = 0m;
_barsHeld = 0;
_pendingOrder = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
if (Pattern != "Bullish" && Pattern != "Bearish")
throw new ArgumentOutOfRangeException(nameof(Pattern), Pattern, "Choose Bullish or Bearish.");
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;
var bullish = _previousOpen is decimal open && _previousClose < open
&& candle.ClosePrice > candle.OpenPrice && candle.OpenPrice <= _previousClose && candle.ClosePrice >= open;
var bearish = _previousOpen is decimal previousOpen && _previousClose > previousOpen
&& candle.ClosePrice < candle.OpenPrice && candle.OpenPrice >= _previousClose && candle.ClosePrice <= previousOpen;
if (Position != 0)
_barsHeld++;
if (_pendingOrder?.State is OrderStates.Done or OrderStates.Failed)
_pendingOrder = null;
if (_pendingOrder is null && IsFormedAndOnlineAndAllowTrading())
{
if (Position != 0 && _barsHeld >= HoldPeriods)
_pendingOrder = Position > 0 ? SellMarket(Position) : BuyMarket(-Position);
else if (Position == 0 && (Pattern == "Bullish" ? bullish : bearish))
{
_pendingOrder = Side == Sides.Buy ? BuyMarket() : SellMarket();
_barsHeld = 0;
}
}
_previousOpen = candle.OpenPrice;
_previousClose = candle.ClosePrice;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, ArgumentOutOfRangeException
from StockSharp.Messages import DataType, CandleStates, Sides, OrderStates
from StockSharp.Algo.Strategies import Strategy
class engulfing_candlestick_strategy(Strategy):
"""Trades a selected engulfing pattern and exits after HoldPeriods bars."""
def __init__(self):
super(engulfing_candlestick_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(15))) \
.SetDisplay("Candle Type", "Type of candles to use", "General")
self._hold_periods = self.Param("HoldPeriods", 17) \
.SetDisplay("Hold Periods", "Bars to hold the position", "Trading")
self._pattern = self.Param("Pattern", "Bullish") \
.SetDisplay("Pattern", "Bullish or Bearish engulfing", "Trading")
self._side = self.Param("Side", Sides.Buy) \
.SetDisplay("Side", "Buy for long, Sell for short", "Trading")
self._previous_open = None
self._previous_close = None
self._bars_held = 0
self._pending_order = None
@property
def candle_type(self):
return self._candle_type.Value
def GetWorkingSecurities(self):
return [(self.Security, self.candle_type)]
def OnReseted(self):
super(engulfing_candlestick_strategy, self).OnReseted()
self._previous_open = None
self._previous_close = None
self._bars_held = 0
self._pending_order = None
def OnStarted2(self, time):
super(engulfing_candlestick_strategy, self).OnStarted2(time)
if self._pattern.Value not in ("Bullish", "Bearish"):
raise ArgumentOutOfRangeException("Pattern", self._pattern.Value, "Choose Bullish or Bearish.")
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
bullish = (self._previous_open is not None and self._previous_close < self._previous_open
and candle.ClosePrice > candle.OpenPrice and candle.OpenPrice <= self._previous_close
and candle.ClosePrice >= self._previous_open)
bearish = (self._previous_open is not None and self._previous_close > self._previous_open
and candle.ClosePrice < candle.OpenPrice and candle.OpenPrice >= self._previous_close
and candle.ClosePrice <= self._previous_open)
if self.Position != 0:
self._bars_held += 1
if self._pending_order is not None and self._pending_order.State in (OrderStates.Done, OrderStates.Failed):
self._pending_order = None
if self._pending_order is None and self.IsFormedAndOnlineAndAllowTrading():
if self.Position != 0 and self._bars_held >= int(self._hold_periods.Value):
self._pending_order = self.SellMarket(self.Position) if self.Position > 0 else self.BuyMarket(-self.Position)
elif self.Position == 0 and (bullish if self._pattern.Value == "Bullish" else bearish):
self._pending_order = self.BuyMarket() if self._side.Value == Sides.Buy else self.SellMarket()
self._bars_held = 0
self._previous_open = candle.OpenPrice
self._previous_close = candle.ClosePrice
def CreateClone(self):
return engulfing_candlestick_strategy()