La estrategia ROC es un puerto StockSharp del asesor experto MetaTrader almacenado en MQL/26938/ROC.mq4. Opera con un solo símbolo y evalúa la acción del precio utilizando una cadena de promedios móviles ponderados lineales (LWMA), un modelo de tasa de cambio personalizado (ROC), mayor impulso de marco temporal y un filtro mensual MACD. Se conservan las características originales de administración del dinero, como el punto de equilibrio, los trailingstops basados en pips, la protección del capital y los objetivos de ganancias denominados en dinero.
Lógica de entrada
La estrategia se suscribe a tres flujos de datos:
Velas comerciales principales definidas por la propiedad CandleType.
Un marco de tiempo más alto para el oscilador de impulso de 14 períodos (seleccionado automáticamente según el marco de tiempo de negociación).
Velas mensuales para el filtro de confirmación MACD.
En cada vela comercial terminada se deben cumplir las siguientes condiciones para abrir una posición:
El modelo personalizado ROC debe informar una tendencia alcista (Line4 < Line5) para compras o una tendencia bajista (Line4 > Line5) para ventas.
La LWMA rápida calculada sobre el precio típico debe cotizar por encima de la LWMA lenta para compras y por debajo para ventas.
Cualquiera de las últimas tres lecturas de impulso tomadas del período de tiempo superior debe exceder el umbral de compra o venta configurado (desviación absoluta de 100).
La línea principal mensual MACD debe permanecer por encima de su línea de señal para compras y por debajo para ventas.
El tamaño de la posición respeta el límite MaxTrades y, opcionalmente, escala el siguiente volumen comercial después de pérdidas consecutivas cuando IncreaseFactor es mayor que cero.
Lógica de salida
Las órdenes clásicas de stop-loss y take-profit se proyectan en MetaTrader puntos tan pronto como cambia el tamaño de la posición.
El bloque de equilibrio opcional mueve el tope de protección al precio de entrada más el desplazamiento configurado una vez que se alcanza la distancia de activación en puntos.
Los trailingstops basados en pips ajustan el valor de stop en cada cierre de vela.
Las comprobaciones de administración de dinero cierran la posición cuando se alcanza un objetivo de divisa o de porcentaje y pueden rastrear las ganancias flotantes al detectar retrocesos mayores que StopLossMoney después de que las ganancias exceden TakeProfitMoney.
Una parada de acciones compara la reducción flotante con las acciones más altas registradas y liquida la posición cuando se excede el porcentaje permitido.
Establecer ExitStrategy en true realiza la rutina de salida de emergencia y cierra la posición actual en el mercado.
Parámetros
Nombre
Descripción
LotSize
Volumen comercial base abierto en cada señal.
IncreaseFactor
Vuelve a calcular el siguiente volumen después de operaciones perdedoras consecutivas.
Fuerza una posición plana inmediata cuando está habilitado.
Notas
El período de tiempo más alto para el indicador de impulso se deriva automáticamente del período de tiempo de negociación para que coincida con la declaración de cambio original en el código MetaTrader.
Todos los cálculos de indicadores utilizan el nivel alto Bind API, por lo que no se requieren solicitudes de datos manuales.
La estrategia es solo de compensación: cuando aparece una nueva señal larga mientras se mantienen posiciones cortas, la exposición corta se cierra primero antes de entrar en posición larga, reflejando el comportamiento de la EA original en cuentas sin cobertura.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Rate of Change strategy: uses ROC indicator with WMA trend filter.
/// Buys when ROC crosses above zero and fast WMA > slow WMA.
/// Sells when ROC crosses below zero and fast WMA less than slow WMA.
/// </summary>
public class RocStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _rocPeriod;
private readonly StrategyParam<int> _fastMaPeriod;
private readonly StrategyParam<int> _slowMaPeriod;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int RocPeriod
{
get => _rocPeriod.Value;
set => _rocPeriod.Value = value;
}
public int FastMaPeriod
{
get => _fastMaPeriod.Value;
set => _fastMaPeriod.Value = value;
}
public int SlowMaPeriod
{
get => _slowMaPeriod.Value;
set => _slowMaPeriod.Value = value;
}
public RocStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_rocPeriod = Param(nameof(RocPeriod), 12)
.SetGreaterThanZero()
.SetDisplay("ROC Period", "Rate of Change period", "Indicators");
_fastMaPeriod = Param(nameof(FastMaPeriod), 5)
.SetGreaterThanZero()
.SetDisplay("Fast WMA", "Fast WMA period", "Indicators");
_slowMaPeriod = Param(nameof(SlowMaPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("Slow WMA", "Slow WMA period", "Indicators");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var roc = new RateOfChange { Length = RocPeriod };
var fastMa = new WeightedMovingAverage { Length = FastMaPeriod };
var slowMa = new WeightedMovingAverage { Length = SlowMaPeriod };
decimal? prevRoc = null;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(roc, fastMa, slowMa, (candle, rocVal, fastMaVal, slowMaVal) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (prevRoc.HasValue)
{
if (prevRoc.Value <= 0 && rocVal > 0 && fastMaVal > slowMaVal && Position <= 0)
BuyMarket();
else if (prevRoc.Value >= 0 && rocVal < 0 && fastMaVal < slowMaVal && Position >= 0)
SellMarket();
}
prevRoc = rocVal;
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, fastMa);
DrawIndicator(area, slowMa);
DrawOwnTrades(area);
}
}
}
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 RateOfChange, WeightedMovingAverage
from StockSharp.Algo.Strategies import Strategy
class roc_strategy(Strategy):
def __init__(self):
super(roc_strategy, self).__init__()
self._roc_period = self.Param("RocPeriod", 12) \
.SetDisplay("ROC Period", "Rate of Change period", "Indicators")
self._fast_ma_period = self.Param("FastMaPeriod", 5) \
.SetDisplay("Fast WMA", "Fast WMA period", "Indicators")
self._slow_ma_period = self.Param("SlowMaPeriod", 20) \
.SetDisplay("Slow WMA", "Slow WMA period", "Indicators")
self._roc = None
self._fast_ma = None
self._slow_ma = None
self._prev_roc = None
@property
def roc_period(self):
return self._roc_period.Value
@property
def fast_ma_period(self):
return self._fast_ma_period.Value
@property
def slow_ma_period(self):
return self._slow_ma_period.Value
def OnReseted(self):
super(roc_strategy, self).OnReseted()
self._roc = None
self._fast_ma = None
self._slow_ma = None
self._prev_roc = None
def OnStarted2(self, time):
super(roc_strategy, self).OnStarted2(time)
self._roc = RateOfChange()
self._roc.Length = self.roc_period
self._fast_ma = WeightedMovingAverage()
self._fast_ma.Length = self.fast_ma_period
self._slow_ma = WeightedMovingAverage()
self._slow_ma.Length = self.slow_ma_period
subscription = self.SubscribeCandles(DataType.TimeFrame(TimeSpan.FromMinutes(30)))
subscription.Bind(self._roc, self._fast_ma, self._slow_ma, self._process_candle)
subscription.Start()
def _process_candle(self, candle, roc_value, fast_ma_value, slow_ma_value):
if candle.State != CandleStates.Finished:
return
if not self._roc.IsFormed or not self._fast_ma.IsFormed or not self._slow_ma.IsFormed:
return
roc_val = float(roc_value)
fast_val = float(fast_ma_value)
slow_val = float(slow_ma_value)
if self._prev_roc is not None:
if self._prev_roc <= 0.0 and roc_val > 0.0 and fast_val > slow_val and self.Position <= 0:
self.BuyMarket()
elif self._prev_roc >= 0.0 and roc_val < 0.0 and fast_val < slow_val and self.Position >= 0:
self.SellMarket()
self._prev_roc = roc_val
def CreateClone(self):
return roc_strategy()