La Estrategia de Verificación OHLC replica el clásico asesor experto de MetaTrader que inspecciona la estructura de apertura, máximo, mínimo y cierre de la vela anterior. La estrategia evalúa el cuerpo de la vela en un desplazamiento histórico configurable y abre una nueva posición en la dirección de ese cuerpo con la posibilidad de invertir la señal. Está diseñada para una ejecución simple basada en la acción del precio sin depender de osciladores o medias móviles.
Lógica de trading
La estrategia se suscribe a la serie de velas configurada y espera a que la barra finalice antes de procesar.
Para cada vela finalizada, el motor almacena el precio de apertura y cierre para que el desplazamiento definido por el usuario ("SignalShift") pueda referenciar barras más antiguas.
Un cuerpo alcista (cierre por encima de la apertura) genera una señal larga, mientras que un cuerpo bajista (cierre por debajo de la apertura) genera una señal corta. Si el cuerpo es plano no se crea ninguna operación.
El indicador ReverseSignals puede invertir la dirección de la operación, reproduciendo el modo de trading inverso del asesor experto original.
Cuando no existe una posición activa, la estrategia intenta abrir una orden de mercado en la dirección detectada siempre que el diferencial actual esté dentro del umbral permitido de SpreadLimitPips. El diferencial se monitorea usando el flujo del libro de órdenes.
Cuando ya existe una posición, la señal opuesta activa el cierre de la posición en lugar de una reversión completa, siguiendo la lógica MQL.
Las protecciones opcionales de stop-loss y take-profit se inician al arrancar usando distancias en pips convertidas al paso de precio del instrumento, recreando el comportamiento de gestión del dinero MQL.
Parámetros
Parámetro
Predeterminado
Descripción
CandleType
Marco temporal de 5 minutos
Serie de datos utilizada para la evaluación OHLC.
StopLossPips
50
Distancia del stop-loss medida en pips; 0 desactiva el stop.
TakeProfitPips
100
Distancia del take-profit medida en pips; 0 desactiva el objetivo.
ReverseSignals
false
Invierte la dirección de las señales largas y cortas.
SpreadLimitPips
1
Diferencial máximo, en pips, permitido al abrir una nueva posición.
SignalShift
1
Número de velas completadas hacia atrás usadas para el cálculo de la señal (1 = vela anterior).
OrderVolume
1
Volumen enviado con cada orden de mercado.
Notas de uso
La estrategia utiliza los metadatos del instrumento para convertir valores en pips a distancias de paso de precio. Los instrumentos con 3 o 5 decimales reciben automáticamente el ajuste estándar de diez puntos por pip.
La suscripción al libro de órdenes debe estar habilitada en el feed de datos para que las verificaciones de diferencial funcionen correctamente. Si no hay cotizaciones bid/ask disponibles, la estrategia omitirá la apertura de nuevas operaciones.
Los stops de protección se inician una vez durante OnStarted. Cambiar los parámetros de stop posteriormente requiere reiniciar la estrategia para aplicar las nuevas protecciones.
Dado que la estrategia solo reacciona al cuerpo de la vela, los valores de máximo y mínimo se ignoran exactamente como en la versión original de MetaTrader.
Pasos de despliegue
Adjunte la estrategia a un instrumento que suministre tanto velas como cotizaciones del libro de órdenes.
Configure los parámetros según el estilo de trading deseado (marco temporal, distancias en pips y volumen).
Lance la estrategia. Esperará a la próxima vela completada antes de realizar cualquier acción.
Monitoree el registro en busca de rechazos por diferencial o operaciones ejecutadas, y ajuste los parámetros según sea necesario.
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// OHLC check strategy. Trades based on candle structure (bullish/bearish body).
/// </summary>
public class OhlcCheckStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _confirmBars;
private int _bullCount;
private int _bearCount;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int ConfirmBars
{
get => _confirmBars.Value;
set => _confirmBars.Value = value;
}
public OhlcCheckStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Timeframe", "General");
_confirmBars = Param(nameof(ConfirmBars), 3)
.SetGreaterThanZero()
.SetDisplay("Confirm Bars", "Consecutive candles to confirm direction", "Trading");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_bullCount = 0;
_bearCount = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_bullCount = 0;
_bearCount = 0;
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;
if (candle.ClosePrice > candle.OpenPrice)
{
_bullCount++;
_bearCount = 0;
}
else if (candle.ClosePrice < candle.OpenPrice)
{
_bearCount++;
_bullCount = 0;
}
// Consecutive bullish candles → buy
if (_bullCount >= ConfirmBars && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
_bullCount = 0;
}
// Consecutive bearish candles → sell
else if (_bearCount >= ConfirmBars && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
_bearCount = 0;
}
}
}
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.Strategies import Strategy
class ohlc_check_strategy(Strategy):
def __init__(self):
super(ohlc_check_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Timeframe", "General")
self._confirm_bars = self.Param("ConfirmBars", 3) \
.SetDisplay("Confirm Bars", "Consecutive candles to confirm direction", "Trading")
self._bull_count = 0
self._bear_count = 0
@property
def CandleType(self):
return self._candle_type.Value
@property
def ConfirmBars(self):
return self._confirm_bars.Value
def OnReseted(self):
super(ohlc_check_strategy, self).OnReseted()
self._bull_count = 0
self._bear_count = 0
def OnStarted2(self, time):
super(ohlc_check_strategy, self).OnStarted2(time)
self._bull_count = 0
self._bear_count = 0
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def _on_process(self, candle):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
open_price = float(candle.OpenPrice)
if close > open_price:
self._bull_count += 1
self._bear_count = 0
elif close < open_price:
self._bear_count += 1
self._bull_count = 0
cb = int(self.ConfirmBars)
# Consecutive bullish candles
if self._bull_count >= cb and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
self._bull_count = 0
# Consecutive bearish candles
elif self._bear_count >= cb and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._bear_count = 0
def CreateClone(self):
return ohlc_check_strategy()