La estrategia ValidateMe traslada el marco de validación básico del asesor experto MQL4 original. La lógica se centra en verificar la disponibilidad de fondos, verificar que las distancias para detener las pérdidas y obtener ganancias respeten las restricciones cambiarias y luego disparar una orden de mercado única en la dirección elegida. La estrategia monitorea continuamente los eventos de ejecución comercial y abre una nueva posición solo cuando no hay posiciones u órdenes activas presentes.
Lógica de trading
La estrategia se suscribe a los datos de ticks de la seguridad configurada.
Cuando la estrategia está en línea, formada y se permite el comercio, verifica que no haya posiciones abiertas ni órdenes activas presentes.
Luego envía una orden de mercado en la dirección configurada (compra o venta) utilizando el tamaño de lote definido.
Un módulo de protección adjunta inmediatamente órdenes de toma de ganancias y de limitación de pérdidas calculadas a partir de distancias de pips, lo que garantiza el cumplimiento de los niveles de parada del corredor (ajustados por precios fraccionados).
Una vez que se cierra la posición, la estrategia espera el siguiente tick y repite la validación antes de enviar una nueva orden.
Parámetros
Parámetro
Descripción
Obtener ganancias (pips)
Distancia del precio de entrada al take-profit en pips. Debe ser mayor que cero.
Detener pérdidas (pips)
Distancia desde el precio de entrada hasta el stop-loss en pips. Debe ser mayor que cero.
Muchos
Volumen comercial en lotes utilizados para cada orden de mercado.
Dirección
Dirección de la orden de mercado (Compra o Venta).
Gestión del riesgo
La estrategia utiliza StartProtection con compensaciones absolutas para registrar órdenes de obtención de beneficios y de limitación de pérdidas.
El tamaño del pip se calcula a partir del paso del precio del valor y la precisión decimal para imitar el comportamiento de MetaTrader (los símbolos de 5 y 3 dígitos utilizan un tamaño de diez puntos).
La estrategia activa nuevas órdenes solo si no hay órdenes existentes activas, evitando la acumulación de órdenes.
Notas de uso
Adjunte la estrategia a un valor y establezca el volumen y la dirección deseados.
Configure las distancias de toma de ganancias y límite de pérdidas en pips de acuerdo con los requisitos del corredor.
La estrategia no se basa en indicadores y pretende ser un marco de validación más que un sistema comercial completo.
El control del riesgo de la cartera (por ejemplo, reducción máxima) se puede combinar externamente si es necesario.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// ValidateMe strategy: RSI crossover at oversold/overbought levels.
/// Buys when RSI crosses above 30, sells when RSI crosses below 70.
/// </summary>
public class ValidateMeStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _period;
private decimal _prevRsi;
private bool _hasPrev;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int Period { get => _period.Value; set => _period.Value = value; }
public ValidateMeStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_period = Param(nameof(Period), 14)
.SetGreaterThanZero()
.SetDisplay("Period", "RSI period", "Indicators");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevRsi = 0;
_hasPrev = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var rsi = new RelativeStrengthIndex { Length = Period };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(rsi, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal rsiValue)
{
if (candle.State != CandleStates.Finished) return;
if (_hasPrev)
{
if (_prevRsi < 30 && rsiValue >= 30 && Position <= 0)
BuyMarket();
else if (_prevRsi > 70 && rsiValue <= 70 && Position >= 0)
SellMarket();
}
_prevRsi = rsiValue;
_hasPrev = true;
}
}
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 RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class validate_me_strategy(Strategy):
def __init__(self):
super(validate_me_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5)))
self._period = self.Param("Period", 14)
self._prev_rsi = 0.0
self._has_prev = False
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def Period(self):
return self._period.Value
@Period.setter
def Period(self, value):
self._period.Value = value
def OnReseted(self):
super(validate_me_strategy, self).OnReseted()
self._prev_rsi = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(validate_me_strategy, self).OnStarted2(time)
self._has_prev = False
rsi = RelativeStrengthIndex()
rsi.Length = self.Period
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(rsi, self._process_candle).Start()
def _process_candle(self, candle, rsi_value):
if candle.State != CandleStates.Finished:
return
rsi_val = float(rsi_value)
if self._has_prev:
if self._prev_rsi < 30 and rsi_val >= 30 and self.Position <= 0:
self.BuyMarket()
elif self._prev_rsi > 70 and rsi_val <= 70 and self.Position >= 0:
self.SellMarket()
self._prev_rsi = rsi_val
self._has_prev = True
def CreateClone(self):
return validate_me_strategy()