Estrategia de Patrones de Velas Bj
Esta estrategia busca los patrones de velas Dragonfly Doji y Gravestone Doji. Un Dragonfly Doji con una larga mecha inferior puede señalar reversión alcista, mientras que un Gravestone Doji con una larga mecha superior puede indicar reversión bajista. La estrategia compra después de un Dragonfly Doji y vende después de un Gravestone Doji.
Detalles
- Criterios de entrada: Dragonfly Doji → largo; Gravestone Doji → corto.
- Largo/Corto: Ambos.
- Criterios de salida: Señal opuesta o discrecional.
- Stops: No.
- Valores predeterminados:
CandleType= 15 minutosDojiThreshold= 0.1
- 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
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Bj Candle Patterns strategy.
/// A doji has a body of at most DojiThreshold of its high-low range. A Dragonfly Doji also has an upper wick of at most
/// DojiThreshold of the range (a long lower wick) and goes long; a Gravestone Doji has a lower wick of at most DojiThreshold of the
/// range (a long upper wick) and goes short. The opposite pattern reverses the position.
/// </summary>
public class BjCandlePatternsStrategy : Strategy
{
private readonly StrategyParam<decimal> _dojiThreshold;
private readonly StrategyParam<DataType> _candleType;
/// <summary>
/// Maximum body and short-wick size as a fraction of the candle range.
/// </summary>
public decimal DojiThreshold
{
get => _dojiThreshold.Value;
set => _dojiThreshold.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public BjCandlePatternsStrategy()
{
_dojiThreshold = Param(nameof(DojiThreshold), 0.1m)
.SetRange(0m, 1m)
.SetDisplay("Doji Threshold", "Maximum body and short-wick size as a fraction of the range", "Patterns");
_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 OnStarted2(DateTime time)
{
base.OnStarted2(time);
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;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var range = candle.HighPrice - candle.LowPrice;
if (range <= 0)
return;
var bodyTop = Math.Max(candle.OpenPrice, candle.ClosePrice);
var bodyBottom = Math.Min(candle.OpenPrice, candle.ClosePrice);
var limit = DojiThreshold * range;
if (bodyTop - bodyBottom > limit)
return;
var dragonfly = candle.HighPrice - bodyTop <= limit;
var gravestone = bodyBottom - candle.LowPrice <= limit;
if (dragonfly && !gravestone && Position <= 0)
BuyMarket(Volume + Math.Abs(Position));
else if (gravestone && !dragonfly && Position >= 0)
SellMarket(Volume + Math.Abs(Position));
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Decimal
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Strategies import Strategy
class bj_candle_patterns_strategy(Strategy):
"""
Bj Candle Patterns strategy.
A doji has a body of at most DojiThreshold of its high-low range. A Dragonfly Doji also has an upper wick of at most
DojiThreshold of the range (a long lower wick) and goes long; a Gravestone Doji has a lower wick of at most DojiThreshold of the
range (a long upper wick) and goes short. The opposite pattern reverses the position.
"""
def __init__(self):
super(bj_candle_patterns_strategy, self).__init__()
self._doji_threshold = self.Param("DojiThreshold", 0.1).SetRange(0.0, 1.0).SetDisplay("Doji Threshold", "Maximum body and short-wick size as a fraction of the range", "Patterns")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(15))).SetDisplay("Candle Type", "Type of candles to use", "General")
@property
def candle_type(self):
return self._candle_type.Value
def OnStarted2(self, time):
super(bj_candle_patterns_strategy, self).OnStarted2(time)
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
if not self.IsFormedAndOnlineAndAllowTrading():
return
rng = candle.HighPrice - candle.LowPrice
if rng <= 0:
return
body_top = max(candle.OpenPrice, candle.ClosePrice)
body_bottom = min(candle.OpenPrice, candle.ClosePrice)
limit = Decimal(self._doji_threshold.Value) * rng
if body_top - body_bottom > limit:
return
dragonfly = candle.HighPrice - body_top <= limit
gravestone = body_bottom - candle.LowPrice <= limit
if dragonfly and not gravestone and self.Position <= 0:
self.BuyMarket(self.Volume + abs(self.Position))
elif gravestone and not dragonfly and self.Position >= 0:
self.SellMarket(self.Volume + abs(self.Position))
def CreateClone(self):
return bj_candle_patterns_strategy()