Ver no GitHub

Estratégia legada de captura de tendências

Trend Capture Legacy Strategy transporta o MetaTrader especialista TrendCapture.mq4 para o StockSharp API de alto nível. A versão C# mantém o conjunto de regras original com base na direção Parabolic SAR, um filtro baixo ADX e gerenciamento simples de equilíbrio financeiro.

Ideias centrais

  • Processe velas concluídas do período de tempo selecionado e alimente-as com Parabolic SAR (0.02/0.2) e Índice Direcional Médio (14).
  • Entre apenas quando ADX estiver abaixo de AdxThreshold, sinalizando um mercado calmo onde as reversões de SAR são mais confiáveis.
  • Lembre-se da direção e do resultado da última negociação fechada: repita o mesmo lado após um vencedor, vire para o lado oposto após um perdedor.
  • Aplique níveis de stop-loss e take-profit de distância fixa (configurados em faixas de preço) e mova o stop para o ponto de equilíbrio quando a negociação ganhar BreakEvenGuard pontos.
  • Dimensionar o volume do pedido a partir do valor do portfólio disponível e MaximumRisk; retorne à estratégia Volume quando as informações do portfólio não estiverem disponíveis.

Parâmetros

Nome Padrão Descrição
SarStep 0,02 Etapa inicial de aceleração Parabolic SAR.
SarMax 0,2 Aceleração máxima Parabolic SAR.
AdxPeriod 14 ADX período médio.
AdxThreshold 20 Valor máximo de ADX que ainda permite uma nova entrada.
TakeProfitPoints 180 Distância de lucro em faixas de preço.
StopLossPoints 50 Distância de stop-loss em faixas de preço.
BreakEvenGuard 5 Buffer de lucro (em pontos) necessário antes de mover o stop para entrada.
MaximumRisk 0,03 Fração da margem livre utilizada para dimensionamento da posição.
CandleType Velas de 1 hora Prazo para cálculos de indicadores e sinais de negociação.

Gerenciamento de pedidos

  • As entradas longas exigem o preço de fechamento acima de SAR com baixo ADX; as posições vendidas exigem o preço de fechamento abaixo de SAR com o mesmo filtro ADX.
  • Os níveis de stop-loss e take-profit são recalculados em cada entrada e avaliados em cada vela concluída.
  • A ativação do ponto de equilíbrio simplesmente muda o stop para o preço de entrada. Se nenhum stop-loss estiver configurado (distância zero ou negativa), a guarda é ignorada.

Indicadores

  • ParabolicSar para polarização direcional.
  • AverageDirectionalIndex para o filtro de força (apenas a linha principal ADX é usada).

Notas

  • A estratégia usa BindEx para evitar acesso direto ao buffer, seguindo as diretrizes do projeto.
  • O cálculo do volume baseado em portfólio respeita as restrições do conselho (LotStep, MinVolume, MaxVolume).
  • O histórico de negociação necessário para polarização de direção é coletado por meio de OnNewMyTrade, portanto, os preenchimentos parciais permanecem suportados.
using System;



using StockSharp.Algo.Indicators;

using StockSharp.Algo.Strategies;

using StockSharp.BusinessEntities;

using StockSharp.Messages;



namespace StockSharp.Samples.Strategies;



public class TrendCaptureLegacyStrategy : Strategy

{

	private readonly StrategyParam<int> _fastPeriod;

	private readonly StrategyParam<int> _slowPeriod;

	private readonly StrategyParam<DataType> _candleType;



	private decimal _prevFast; private decimal _prevSlow; private bool _hasPrev;

	private int _cooldown;



	public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }

	public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }

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



	public TrendCaptureLegacyStrategy()

	{

		_fastPeriod = Param(nameof(FastPeriod), 10).SetDisplay("Fast EMA", "Fast EMA period", "Indicators");

		_slowPeriod = Param(nameof(SlowPeriod), 30).SetDisplay("Slow EMA", "Slow EMA period", "Indicators");

		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(15).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");

	}



	/// <inheritdoc />

	protected override void OnReseted()

	{

		base.OnReseted();

		_prevFast = default;

		_prevSlow = default;

		_hasPrev = default;

		_cooldown = default;

	}



	/// <inheritdoc />

	protected override void OnStarted2(DateTime time)

	{

		base.OnStarted2(time);

		_hasPrev = false;

		var fast = new ExponentialMovingAverage { Length = FastPeriod };

		var slow = new ExponentialMovingAverage { Length = SlowPeriod };

		var subscription = SubscribeCandles(CandleType);

		subscription.Bind(fast, slow, ProcessCandle).Start();

	}



	private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)

	{

		if (candle.State != CandleStates.Finished) return;

		if (!IsFormedAndOnlineAndAllowTrading()) return;

		if (!_hasPrev) { _prevFast = fast; _prevSlow = slow; _hasPrev = true; return; }

		if (_cooldown > 0)

		{

			_cooldown--;

			_prevFast = fast; _prevSlow = slow;

			return;

		}



		if (_prevFast <= _prevSlow && fast > slow && Position <= 0)

		{

			var volume = Volume + Math.Abs(Position);

			BuyMarket(volume);

			_cooldown = 2;

		}

		else if (_prevFast >= _prevSlow && fast < slow && Position >= 0)

		{

			var volume = Volume + Math.Abs(Position);

			SellMarket(volume);

			_cooldown = 2;

		}

		_prevFast = fast; _prevSlow = slow;

	}

}