Esta estrategia es una traducción en C# del asesor experto MQL original C_Factor_HLH4_buy_only. Demuestra cómo portar estrategias de MetaTrader a la API de alto nivel de StockSharp.
Lógica de la estrategia
Utiliza velas de marco temporal de cuatro horas.
Abre una posición larga cuando la vela actual cierra por encima del máximo de la vela anterior.
Sale de la posición larga cuando el precio de cierre:
supera el mínimo de la vela anterior en 100 ticks, o
cae por debajo del máximo de la vela anterior en 20 ticks.
La gestión del riesgo se maneja con distancias de stop-loss y take-profit configurables.
El volumen de la orden se calcula a partir del porcentaje del capital de la cuenta arriesgado por operación.
Parámetros
Nombre
Descripción
StopLoss
Distancia en ticks para el stop de protección.
TakeProfit
Distancia en ticks para el objetivo de beneficio.
RiskPercent
Porcentaje del capital de la cuenta arriesgado en cada operación.
CandleType
Tipo y marco temporal de la vela para el análisis (por defecto: velas de 4 horas).
Notas
La estrategia opera solo en largo y está diseñada con fines educativos. Ajuste los parámetros y la configuración de riesgo antes de usarla en trading real.
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>
/// C Factor HLH4 buy-only strategy.
/// Buys when close breaks above previous high, sells on EMA cross.
/// </summary>
public class CFactorHlh4BuyOnlyStrategy : Strategy
{
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevHigh;
private decimal _prevLow;
private bool _hasPrev;
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public CFactorHlh4BuyOnlyStrategy()
{
_emaPeriod = Param(nameof(EmaPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("EMA Period", "EMA period for trend filter", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle type", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_prevHigh = 0;
_prevLow = 0;
_hasPrev = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
SubscribeCandles(CandleType)
.Bind(ema, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal emaVal)
{
if (candle.State != CandleStates.Finished) return;
if (!_hasPrev)
{
_prevHigh = candle.HighPrice;
_prevLow = candle.LowPrice;
_hasPrev = true;
return;
}
var close = candle.ClosePrice;
if (close > _prevHigh && Position <= 0 && close > emaVal)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (close < _prevLow && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
_prevHigh = candle.HighPrice;
_prevLow = candle.LowPrice;
}
}
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.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class c_factor_hlh4_buy_only_strategy(Strategy):
def __init__(self):
super(c_factor_hlh4_buy_only_strategy, self).__init__()
self._ema_period = self.Param("EmaPeriod", 20) \
.SetDisplay("EMA Period", "EMA period for trend filter", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candle type", "General")
self._prev_high = 0.0
self._prev_low = 0.0
self._has_prev = False
@property
def ema_period(self):
return self._ema_period.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(c_factor_hlh4_buy_only_strategy, self).OnReseted()
self._prev_high = 0.0
self._prev_low = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(c_factor_hlh4_buy_only_strategy, self).OnStarted2(time)
ema = ExponentialMovingAverage()
ema.Length = self.ema_period
self.SubscribeCandles(self.candle_type).Bind(ema, self.process_candle).Start()
def process_candle(self, candle, ema_val):
if candle.State != CandleStates.Finished:
return
ev = float(ema_val)
if not self._has_prev:
self._prev_high = float(candle.HighPrice)
self._prev_low = float(candle.LowPrice)
self._has_prev = True
return
close = float(candle.ClosePrice)
if close > self._prev_high and self.Position <= 0 and close > ev:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif close < self._prev_low and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_high = float(candle.HighPrice)
self._prev_low = float(candle.LowPrice)
def CreateClone(self):
return c_factor_hlh4_buy_only_strategy()