Ver no GitHub

Multifiltro NTOqF

Visão geral

A estratégia NTOqF Multi-Filter transporta o MetaTrader 4 consultor especialista "NTOqF" (versões V1 – V3) para o StockSharp de alto nível API. O robô original combina vários osciladores e filtros de acompanhamento de tendências, cada um dos quais pode ser ativado ou desativado de forma independente. Esta versão C# preserva a mesma configurabilidade, oferece suporte a prazos separados para cada indicador e aplica gerenciamento comercial por meio de paradas fixas, metas de lucro e um trailing stop opcional expresso em pips.

Lógica estratégica

Filtros indicadores

  • RSI filtro – gera um sinal longo quando o valor de RSI (no turno configurado) estiver abaixo de RSI Lower e um sinal curto quando o valor estiver acima de RSI Upper. Leituras neutras cancelam entradas.
  • Stochastic filtro – compara %K e %D. Quando Use Stochastic High/Low está ativado, a linha principal também deve estar acima de Stoch High para posições longas ou abaixo de Stoch Low para posições curtas; caso contrário, cruzamentos simples de %K/%D serão usados.
  • ADX filtro – usa +DI versus –DI para determinar a direção. Quando a opção Use ADX Main está habilitada, a linha principal ADX deve exceder ADX Main antes que qualquer entrada seja aceita.
  • Parabolic SAR filtro – interpreta o valor SAR relativo ao fechamento da barra selecionada. Valores acima do preço favorecem as posições compradas (refletindo o comportamento no código MQL), valores abaixo favorecem as posições vendidas.
  • Filtro de média móvel – compara a média móvel selecionada (com mudança positiva opcional) com o preço de fechamento na mudança base. Preço acima da MM favorece posições compradas; preço abaixo favorece shorts.

Todos os filtros habilitados devem concordar na mesma direção. Se algum filtro retornar um estado neutro (por exemplo, RSI permanecendo entre seus limites), nenhuma posição será aberta.

Regras de entrada

  • Os sinais são avaliados no período de negociação principal (Candle Type).
  • Só é permitida uma posição por vez; a estratégia espera o fechamento da posição anterior antes de entrar em uma nova.
  • O volume do pedido é obtido de Trade Volume (lotes).

Regras de saída

  • Stop Loss/Take Profit fixos – expresso em pips e convertido em compensações de preço usando o tamanho do passo do instrumento. Defina um parâmetro como 0 para desativar o nível correspondente.
  • Trailing stop – quando ativado, o stop é seguido quando o lucro não realizado excede a distância final e o stop atual fica atrás do preço em mais do que essa distância. As posições longas movem o stop para cima, as posições curtas o movem para baixo.

Comportamento multi-período

Cada indicador pode assinar seu próprio cronograma. Um valor de período de tempo de 0 reutiliza o período de negociação principal, enquanto valores positivos representam assinaturas de TimeFrameCandle baseadas em minutos. Os valores dos indicadores são avaliados apenas em velas concluídas e respeitam o parâmetro Shift para que a estratégia possa espelhar o comportamento de "retrospectiva" do especialista MetaTrader original.

Parâmetros

  • Tipo de vela – período de negociação usado para impulsionar as execuções.
  • Volume – volume de ordens de mercado (lotes).
  • Take Profit (pips) – meta de lucro; 0 desativa.
  • Stop Loss (pips) – stop de proteção; 0 desativa.
  • Usar Trailing / Trailing Stop (pips) – habilite e dimensione o trailing stop.
  • Shift – número de velas concluídas ao ler os valores do indicador e preço.
  • RSI parâmetros – alternância, período, limites superior/inferior e período.
  • Stochastic parâmetros – alternância, %K/%D/comprimentos de desaceleração, níveis de confirmação altos/baixos opcionais e período de tempo.
  • ADX parâmetros – alternância, período, período de DI, limite de linha principal opcional e período principal.
  • Parabolic SAR parâmetros – alternância, etapa de aceleração, aceleração máxima e período de tempo.
  • Parâmetros de média móvel – alternância, período, mudança adicional aplicada ao buffer MA, método de média (SMA/EMA/SMMA/LWMA), preço aplicado e período de tempo.

Notas

  • As filas de indicadores respeitam o Shift configurado, garantindo que os sinais sejam baseados em valores históricos da mesma forma que o especialista MQL.
  • A lógica de trailing só é ativada quando a negociação já está lucrando mais do que a distância de trailing e o stop está a mais do que essa distância do preço, correspondendo ao comportamento do EA original.
  • Nenhuma versão Python é fornecida para este pacote de estratégia.
using System;
using System.Collections.Generic;

using Ecng.Common;

using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;

namespace StockSharp.Samples.Strategies;

/// <summary>
/// NtoQf: RSI + EMA multi-filter strategy with ATR trailing.
/// Combines RSI overbought/oversold with EMA trend confirmation.
/// </summary>
public class NtoQfStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _rsiLength;
	private readonly StrategyParam<int> _emaLength;
	private readonly StrategyParam<int> _atrLength;
	private readonly StrategyParam<decimal> _rsiUpper;
	private readonly StrategyParam<decimal> _rsiLower;

	private decimal _prevRsi;

	public NtoQfStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe.", "General");

		_rsiLength = Param(nameof(RsiLength), 14)
			.SetDisplay("RSI Length", "RSI period.", "Indicators");

		_emaLength = Param(nameof(EmaLength), 50)
			.SetDisplay("EMA Length", "EMA trend filter.", "Indicators");

		_atrLength = Param(nameof(AtrLength), 14)
			.SetDisplay("ATR Length", "ATR period for trailing.", "Indicators");

		_rsiUpper = Param(nameof(RsiUpper), 70m)
			.SetDisplay("RSI Upper", "Overbought level.", "Signals");

		_rsiLower = Param(nameof(RsiLower), 30m)
			.SetDisplay("RSI Lower", "Oversold level.", "Signals");
	}

	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	public int RsiLength
	{
		get => _rsiLength.Value;
		set => _rsiLength.Value = value;
	}

	public int EmaLength
	{
		get => _emaLength.Value;
		set => _emaLength.Value = value;
	}

	public int AtrLength
	{
		get => _atrLength.Value;
		set => _atrLength.Value = value;
	}

	public decimal RsiUpper
	{
		get => _rsiUpper.Value;
		set => _rsiUpper.Value = value;
	}

	public decimal RsiLower
	{
		get => _rsiLower.Value;
		set => _rsiLower.Value = value;
	}

	/// <inheritdoc />
	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
		=> [(Security, CandleType)];

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();

		_prevRsi = 0;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		var rsi = new RelativeStrengthIndex { Length = RsiLength };
		var ema = new ExponentialMovingAverage { Length = EmaLength };
		var atr = new AverageTrueRange { Length = AtrLength };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(rsi, ema, atr, ProcessCandle)
			.Start();

		StartProtection(
			takeProfit: new Unit(3, UnitTypes.Percent),
			stopLoss: new Unit(2, UnitTypes.Percent));

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawIndicator(area, ema);
			DrawOwnTrades(area);
		}
	}

	private void ProcessCandle(ICandleMessage candle, decimal rsiVal, decimal emaVal, decimal atrVal)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (_prevRsi == 0 || atrVal <= 0)
		{
			_prevRsi = rsiVal;
			return;
		}

		var close = candle.ClosePrice;

		// Entry: RSI exits extreme zone, confirmed by EMA trend
		if (Position == 0)
		{
			if (_prevRsi < RsiLower && rsiVal >= RsiLower && close > emaVal)
			{
				BuyMarket();
			}
			else if (_prevRsi > RsiUpper && rsiVal <= RsiUpper && close < emaVal)
			{
				SellMarket();
			}
		}

		_prevRsi = rsiVal;
	}
}