Esta estrategia transfiere el asesor experto de MetaTrader Trickerless RHMP al nivel alto de StockSharp API. Mantiene las múltiples etapas.
lógica de entrada del robot original: combina la confirmación del índice direccional promedio, la estructura de promedio móvil suavizada y
Gestión de posiciones basada en la volatilidad, siguiendo las convenciones marco documentadas en AGENTS.md.
Lógica de trading
Indicadores
Rango verdadero promedio (ATR) con período configurable para dimensionar la volatilidad.
Índice direccional promedio (ADX) con componentes completos +DI/-DI para calificar la fuerza de la tendencia.
Dos promedios móviles suavizados (SMMA) que representan los filtros de tendencia rápida y lenta.
Evaluación de tendencias
La pendiente lenta de SMMA debe estar dentro del corredor MinSlopePips…MaxSlopePips (medido en pips de instrumento).
ADX debe exceder AdxThreshold y aumentar en comparación con la vela anterior.
El precio debe mantenerse al menos TrendSpacePips alejado del SMMA rápido para evitar la congestión.
Un sesgo alcista requiere la SMMA rápida por encima de la SMMA lenta, +DI ≥ -DI y un promedio ascendente rápido. El sesgo bajista refleja estos
cheques.
Entradas principales
Cuando el sesgo alcista (o bajista) está activo, la estrategia abre una orden larga (o corta) con volumen OrderVolume, respetando
MaxNetPositions y esperando al menos SleepInterval entre entradas.
Si existe una posición neta opuesta, primero se aplana para mantener la cobertura desactivada.
Entradas con picos
Si el rango de velas actual excede CandleSpikeMultiplier veces el rango anterior, la estrategia puede disparar un auxiliar
posición en la dirección del cuerpo de la vela cuando los componentes ADX concuerden. La posición utiliza OrderVolume * SpikeVolumeMultiplier.
Gestión del riesgo
Stop-loss, take-profit y trailing-stop opcionales basados en ATR (StopLossAtrMultiplier, TakeProfitAtrMultiplier, TrailingAtrMultiplier).
Protección para toda la sesión: una vez que el PnL alcanzado alcanza DailyProfitTarget (fracción del capital inicial), se bloquean las nuevas entradas.
El interruptor de emergencia global EmergencyExit cierra todas las posiciones inmediatamente cuando se activa.
Parámetros
Nombre
Descripción
Predeterminado
CandleType
Plazo utilizado para todos los cálculos.
velas de 5 minutos
OrderVolume
Volumen base para cada entrada.
0,03
AtrPeriod
ATR longitud retrospectiva.
14
AdxPeriod
ADX longitud retrospectiva.
14
AdxThreshold
Valor mínimo de ADX para permitir el comercio.
10
FastMaPeriod
Período de media móvil suavizado rápidamente.
60
SlowMaPeriod
Período de media móvil suavizado lentamente.
120
MinSlopePips / MaxSlopePips
Corredor de pendiente permitido para el SMMA lento.
2 / 9
TrendSpacePips
Distancia mínima de precio desde la SMMA rápida (en pips).
5
CandleSpikeMultiplier
Cuánto mayor debe ser el rango de la vela para desencadenar entradas pico.
7
TakeProfitAtrMultiplier
ATR múltiplos para obtener ganancias.
1.0
StopLossAtrMultiplier
ATR múltiplos para stop-loss.
1.5
TrailingAtrMultiplier
ATR múltiplos para trailing-stop (0 desactivaciones).
0
MaxNetPositions
Número máximo de unidades de posición neta simultáneas.
1
SleepInterval
Tiempo mínimo entre entradas consecutivas.
24 minutos
DailyProfitTarget
Fracción del capital inicial que bloquea la negociación una vez alcanzado.
0,045
AllowNewEntries
Interruptor maestro para habilitar/deshabilitar entradas.
cierto
SpikeVolumeMultiplier
Multiplicador de volumen para entradas de picos.
1.0
EmergencyExit
Cierra todas las posiciones inmediatamente cuando es verdadero.
falso
Notas
El puerto StockSharp se centra en el nivel alto limpio API en lugar de la microgestión billete por billete de MetaTrader. Todos
La lógica de administración del dinero se implementa a través de niveles basados en Volume y ATR.
El EA original tenía varias comprobaciones de saldo y margen. Estos se aproximan con el DailyProfitTarget, MaxNetPositions
y ATR parámetros de tamaño para que el comportamiento se mantenga alineado sin llamadas directas a la cuenta MT4.
Debido a que la estrategia utiliza promedios suavizados, asegúrese de que haya un período de calentamiento suficiente antes de evaluar las operaciones.
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Simplified from "Trickerless RHMP" MetaTrader expert.
/// Uses fast/slow EMA crossover for entries.
/// Fast EMA above slow = buy, below = sell.
/// </summary>
public class TrickerlessRhmpStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastMaPeriod;
private readonly StrategyParam<int> _slowMaPeriod;
private ExponentialMovingAverage _fastMa;
private ExponentialMovingAverage _slowMa;
private decimal? _prevFast;
private decimal? _prevSlow;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int FastMaPeriod
{
get => _fastMaPeriod.Value;
set => _fastMaPeriod.Value = value;
}
public int SlowMaPeriod
{
get => _slowMaPeriod.Value;
set => _slowMaPeriod.Value = value;
}
public TrickerlessRhmpStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
.SetDisplay("Candle Type", "Primary timeframe", "General");
_fastMaPeriod = Param(nameof(FastMaPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("Fast MA", "Fast EMA period", "Indicators");
_slowMaPeriod = Param(nameof(SlowMaPeriod), 50)
.SetGreaterThanZero()
.SetDisplay("Slow MA", "Slow SMA period (computed manually)", "Indicators");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevFast = null;
_prevSlow = null;
_fastMa = new ExponentialMovingAverage { Length = FastMaPeriod };
_slowMa = new ExponentialMovingAverage { Length = SlowMaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(_fastMa, _slowMa, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, _fastMa);
DrawIndicator(area, _slowMa);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal fastValue, decimal slowValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!_fastMa.IsFormed || !_slowMa.IsFormed)
{
_prevFast = fastValue;
_prevSlow = slowValue;
return;
}
if (_prevFast is null || _prevSlow is null)
{
_prevFast = fastValue;
_prevSlow = slowValue;
return;
}
var volume = Volume;
if (volume <= 0)
volume = 1;
var crossUp = _prevFast.Value <= _prevSlow.Value && fastValue > slowValue;
var crossDown = _prevFast.Value >= _prevSlow.Value && fastValue < slowValue;
if (crossUp)
{
if (Position <= 0)
BuyMarket(Position < 0 ? Math.Abs(Position) + volume : volume);
}
else if (crossDown)
{
if (Position >= 0)
SellMarket(Position > 0 ? Math.Abs(Position) + volume : volume);
}
_prevFast = fastValue;
_prevSlow = slowValue;
}
/// <inheritdoc />
protected override void OnReseted()
{
_fastMa = null;
_slowMa = null;
_prevFast = null;
_prevSlow = null;
base.OnReseted();
}
}