Esta estratégia transporta o consultor especialista MetaTrader Trickerless RHMP para o StockSharp de alto nível de API. Ele mantém o multi-estágio
lógica de entrada do robô original – combinando confirmação do Índice Direcional Médio, estrutura de média móvel suavizada e
gerenciamento de posição orientado à volatilidade – seguindo as convenções da estrutura documentadas em AGENTS.md.
Lógica de negociação
Indicadores
Average True Range (ATR) com período configurável para dimensionamento de volatilidade.
Índice direcional médio (ADX) com componentes +DI/-DI completos para qualificar a força da tendência.
Duas médias móveis suavizadas (SMMA) representando os filtros de tendência rápida e lenta.
Avaliação de tendências
A inclinação lenta do SMMA deve estar dentro do corredor MinSlopePips…MaxSlopePips (medido em pips de instrumento).
ADX deve exceder AdxThreshold e subir em comparação com a vela anterior.
O preço deve ficar pelo menos TrendSpacePips longe do SMMA rápido para evitar congestionamento.
Uma tendência de alta requer o SMMA rápido acima do SMMA lento, +DI ≥ -DI e uma média rápida ascendente. A tendência de baixa reflete isso
verificações.
Entradas principais
Quando o viés de alta (ou baixa) está ativo, a estratégia abre uma ordem longa (ou curta) com volume OrderVolume, respeitando
MaxNetPositions e aguardando pelo menos SleepInterval entre as entradas.
Se existir uma posição líquida oposta, ela será nivelada primeiro para manter a cobertura desativada.
Entradas de pico
Se o intervalo da vela atual exceder CandleSpikeMultiplier vezes o intervalo anterior, a estratégia pode disparar um auxiliar
posição na direção do corpo da vela quando os componentes ADX concordam. A posição usa OrderVolume * SpikeVolumeMultiplier.
Gestão de risco
Stop-loss baseado em ATR, take-profit e trailing stop opcional (StopLossAtrMultiplier, TakeProfitAtrMultiplier, TrailingAtrMultiplier).
Proteção em toda a sessão: quando o PnL alcançado atingir DailyProfitTarget (fração do patrimônio inicial), novas entradas serão bloqueadas.
O interruptor de emergência global EmergencyExit fecha todas as posições imediatamente quando alternado.
Parâmetros
Nome
Descrição
Padrão
CandleType
Prazo usado para todos os cálculos.
Velas de 5 minutos
OrderVolume
Volume base para cada entrada.
0,03
AtrPeriod
ATR comprimento de lookback.
14
AdxPeriod
ADX comprimento de lookback.
14
AdxThreshold
Valor mínimo de ADX para permitir a negociação.
10
FastMaPeriod
Período de média móvel suavizada rápida.
60
SlowMaPeriod
Período de média móvel suavizada lenta.
120
MinSlopePips / MaxSlopePips
Corredor de declive permitido para o SMMA lento.
2/9
TrendSpacePips
Distância mínima de preço do SMMA rápido (em pips).
5
CandleSpikeMultiplier
Quanto maior o intervalo da vela deve ser para acionar entradas de pico.
7
TakeProfitAtrMultiplier
ATR múltiplos para obtenção de lucro.
1,0
StopLossAtrMultiplier
ATR múltiplos para stop-loss.
1,5
TrailingAtrMultiplier
ATR múltiplos para trailing-stop (0 desabilita).
0
MaxNetPositions
Número máximo de unidades de posição líquida simultâneas.
1
SleepInterval
Tempo mínimo entre entradas consecutivas.
24 minutos
DailyProfitTarget
Fração do patrimônio inicial que bloqueia a negociação quando alcançada.
0,045
AllowNewEntries
Chave mestre para ativar/desativar entradas.
verdade
SpikeVolumeMultiplier
Multiplicador de volume para entradas de pico.
1,0
EmergencyExit
Fecha todas as posições imediatamente quando verdadeiro.
falso
Notas
A porta StockSharp concentra-se no alto nível limpo API em vez do microgerenciamento ticket por ticket de MetaTrader. Todos
a lógica de gerenciamento de dinheiro é implementada por meio de níveis baseados em Volume e ATR.
O EA original teve várias verificações de saldo e margem. Eles são aproximados com DailyProfitTarget, MaxNetPositions
e ATR parâmetros de dimensionamento para que o comportamento permaneça alinhado sem chamadas diretas de conta MT4.
Como a estratégia utiliza médias suavizadas, certifique-se de que haja um período de aquecimento suficiente antes de avaliar as negociações.
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();
}
}