Ver no GitHub

Estratégia Fácil de Robô

Visão geral

Easy Robot é um Expert Advisor que segue o impulso e negocia uma vez por vela horária concluída. Quando a vela anterior fecha em alta a estratégia abre uma nova posição comprada; quando fecha em baixa, abre uma posição curta. Apenas uma posição pode estar ativa a qualquer momento, espelhando totalmente a lógica MetaTrader 4 original.

Regras comerciais

  1. Assine o tipo de vela horária selecionado pelo parâmetro CandleType (o padrão é H1).
  2. Assim que a vela terminar, compare seu fechamento com a abertura:
    • Fechar > Aberto: envia uma ordem de compra a mercado se nenhuma posição estiver aberta.
    • Fechar <Abrir: envia uma ordem de venda a mercado se estiver estável.
  3. O tamanho da posição usa a propriedade da estratégia Volume, exatamente como a versão MQL que dependia de CheckVolumeValue com um padrão de 0,01 lote.
  4. Os níveis de stop-loss e take-profit dependem de um indicador Average True Range com período AtrPeriod (padrão 14):
    • Distância de parada = ATR * StopFactor.
    • Tome distância = ATR * TakeFactor.
    • Ambas as distâncias são normalizadas pela distância mínima de tick/pip, de modo que as ordens de proteção nunca são colocadas mais próximas do que a corretora permite.
  5. As ordens protetoras são registradas imediatamente após a ordem de mercado através de SetStopLoss e SetTakeProfit, proporcionando o mesmo comportamento de OrderSend com os parâmetros sl e tp.
  6. O rastreamento opcional é ativado quando UseTrailingStop é verdadeiro. Depois que a negociação acumula lucro TrailingStartPips (MetaTrader pips, ou seja, pontos ajustados para cotações decimais de 3/5), o stop é movido para mais perto por TrailingStepPips e é empurrado ainda mais somente quando novos extremos de lucro são alcançados. O trailing respeita a distância mínima de parada da corretora para evitar modificações inválidas.
  7. As cotações para cálculos de stop usam o melhor bid/ask quando disponível, voltando ao último preço ou fechamento da vela, correspondendo às referências originais Bid/Ask.

Parâmetros

Nome Padrão Descrição
TakeFactor 4.2 Multiplicador de ATR para distância de lucro (mapeia para TakeFactor entrada em MQL).
StopFactor 4.9 Multiplicador ATR para distância de stop-loss (mapeia para StopFactor).
UseTrailingStop verdade Ativa o estilo de rastreamento MetaTrader (UseTstop).
TrailingStartPips 40 Lucro em pips antes do início do trailing (Tstart).
TrailingStepPips 19 Etapa Pip aplicada ao rastrear atualizações (Tstep).
AtrPeriod 14 período ATR de cálculo para dimensionamento de volatilidade.
CandleType H1 Série de velas usada para sinais e entrada ATR.

Notas

  • A estratégia redefine os preços de entrada e stop armazenados sempre que a posição retorna a zero, garantindo um estado limpo para o próximo sinal.
  • A distância mínima de parada é estimada através do tamanho do pip do instrumento (ou da etapa de preço quando o tamanho do pip não está disponível). Isso reproduz o auxiliar SC do arquivo de inclusão MQL.
  • StartProtection() é chamado uma vez no início para que a plataforma possa gerenciar saídas de emergência, se necessário.
namespace StockSharp.Samples.Strategies;

using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;

/// <summary>
/// Easy Robot strategy: simple EMA + RSI trend following.
/// Buys when close above EMA and RSI above 50.
/// Sells when close below EMA and RSI below 50.
/// </summary>
public class EasyRobotStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _emaPeriod;
	private readonly StrategyParam<int> _rsiPeriod;
	private bool _wasBullish;
	private bool _hasPrevSignal;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
	public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }

	public EasyRobotStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_emaPeriod = Param(nameof(EmaPeriod), 50)
			.SetGreaterThanZero()
			.SetDisplay("EMA Period", "EMA period", "Indicators");
		_rsiPeriod = Param(nameof(RsiPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("RSI Period", "RSI period", "Indicators");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_wasBullish = false;
		_hasPrevSignal = false;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_hasPrevSignal = false;
		var ema = new ExponentialMovingAverage { Length = EmaPeriod };
		var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(ema, rsi, ProcessCandle).Start();
	}

	private void ProcessCandle(ICandleMessage candle, decimal ema, decimal rsi)
	{
		if (candle.State != CandleStates.Finished) return;
		var close = candle.ClosePrice;
		var isBullish = close > ema && rsi > 50;

		if (_hasPrevSignal && isBullish != _wasBullish)
		{
			if (isBullish && Position <= 0)
				BuyMarket();
			else if (!isBullish && close < ema && rsi < 50 && Position >= 0)
				SellMarket();
		}

		_wasBullish = isBullish;
		_hasPrevSignal = true;
	}
}