Ver no GitHub

Estratégia de trader LCS MACD

Esta estratégia é uma versão StockSharp do consultor especialista "LCS-MACD-Trader" MetaTrader 4. Ele negocia cruzamentos MACD que ocorrem abaixo/acima da linha zero e, opcionalmente, requer uma confirmação do oscilador Stochastic. A lógica também reflete os filtros de hora do dia originais e o gerenciamento de ponto de equilíbrio/stop móvel no estilo MetaTrader.

Como funciona

  • Entradas longas são acionadas quando a linha MACD cruza acima de sua linha de sinal enquanto ambas permanecem abaixo de zero. Se o filtro estocástico estiver habilitado, a linha %D deve estar acima de %K dentro do lookback especificado e a vela atual deve mostrar %D caindo abaixo de %K.
  • As entradas curtas são acionadas quando a linha MACD cruza abaixo de sua linha de sinal enquanto ambas permanecem acima de zero. Com o filtro estocástico ativado, a linha %D deve ter estado recentemente abaixo de %K e agora volta a subir acima dela.
  • A negociação só é permitida dentro de três janelas intradiárias configuráveis que replicam as configurações de EA.
  • As distâncias de take-profit, stop-loss, ponto de equilíbrio e trailing-stop são expressas em pips e convertidas usando o tamanho do ponto do instrumento.
  • Apenas uma posição líquida por direção é mantida (rede StockSharp). O empilhamento de posições é permitido até MaxOrders lotes; sinais opostos aguardam até que a posição líquida atual seja fechada pela gestão de risco.

Parâmetros

Nome Descrição Padrão
CandleType Série de velas usada para cálculos de indicadores. Período de 15 minutos
FastEmaPeriod Período EMA rápido no MACD. 12
SlowEmaPeriod Período EMA lento no MACD. 26
SignalPeriod Período da linha de sinal no MACD. 9
UseStochasticFilter Exigir confirmação estocástica antes das entradas. verdade
BarsToCheckStochastic Máximo de barras fechadas desde a relação estocástica oposta. 5
StochasticKPeriod Comprimento de lookback de %K. 5
StochasticDPeriod Comprimento de suavização de %D. 3
StochasticSlowing Suavização adicional aplicada a %K. 3
TradeVolume Tamanho do lote utilizado por entrada. 0,1
TakeProfitPips Distância de lucro em pips. 100
StopLossPips Distância de stop-loss em pips. 100
MaxOrders Máximo de entradas empilhadas por direção. 5
EnableTrailing Ative a lógica de trailing stop estilo MetaTrader. falso
TrailingActivationPips Lucro necessário antes do início do trailing. 50
TrailingDistancePips Distância mantida pelo trailing stop. 25
BreakEvenActivationPips Lucro necessário para mover o stop para o ponto de equilíbrio. 25
BreakEvenOffsetPips Pips adicionais adicionados ao colocar o ponto de equilíbrio. 1
Session1Start/End, Session2Start/End, Session3Start/End Janelas de negociação intradiária. 08h15-08h35, 13h45-14h42, 22h15-22h45

Notas

  • A estratégia pressupõe uma conta de compensação. Fecha posições existentes através das regras de risco configuradas em vez de cobrir ordens opostas como a versão MT4 original.
  • A conversão de pip usa o tamanho do ponto do instrumento. Para símbolos FX de 5 dígitos, a lógica dimensiona automaticamente os valores de pip em 10 para corresponder à configuração do multiplicador EA.
  • A lógica de trailing stop e ponto de equilíbrio é avaliada em velas finalizadas e usa o máximo/mínimo de cada barra para emular o comportamento MetaTrader baseado em ticks.
using System;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// LCS MACD Trader: MACD zero-line cross with RSI filter and ATR stops.
/// </summary>
public class LcsMacdTraderStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastEmaLength;
	private readonly StrategyParam<int> _slowEmaLength;
	private readonly StrategyParam<int> _rsiLength;
	private readonly StrategyParam<int> _atrLength;

	private decimal _prevMacd;
	private decimal _entryPrice;

	public LcsMacdTraderStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe.", "General");

		_fastEmaLength = Param(nameof(FastEmaLength), 12)
			.SetDisplay("Fast EMA", "Fast EMA period.", "Indicators");

		_slowEmaLength = Param(nameof(SlowEmaLength), 26)
			.SetDisplay("Slow EMA", "Slow EMA period.", "Indicators");

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

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

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

	public int FastEmaLength
	{
		get => _fastEmaLength.Value;
		set => _fastEmaLength.Value = value;
	}

	public int SlowEmaLength
	{
		get => _slowEmaLength.Value;
		set => _slowEmaLength.Value = value;
	}

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

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

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

		_prevMacd = 0;
		_entryPrice = 0;
	}

		protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		_prevMacd = 0;
		_entryPrice = 0;

		var fastEma = new ExponentialMovingAverage { Length = FastEmaLength };
		var slowEma = new ExponentialMovingAverage { Length = SlowEmaLength };
		var rsi = new RelativeStrengthIndex { Length = RsiLength };
		var atr = new AverageTrueRange { Length = AtrLength };

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

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

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

		var macd = fastVal - slowVal;

		if (_prevMacd == 0 || atrVal <= 0)
		{
			_prevMacd = macd;
			return;
		}

		var close = candle.ClosePrice;

		if (Position > 0)
		{
			if (close >= _entryPrice + atrVal * 2.5m || close <= _entryPrice - atrVal * 1.5m || macd < 0)
			{
				SellMarket();
				_entryPrice = 0;
			}
		}
		else if (Position < 0)
		{
			if (close <= _entryPrice - atrVal * 2.5m || close >= _entryPrice + atrVal * 1.5m || macd > 0)
			{
				BuyMarket();
				_entryPrice = 0;
			}
		}

		if (Position == 0)
		{
			if (macd > 0 && _prevMacd <= 0 && rsiVal > 45)
			{
				_entryPrice = close;
				BuyMarket();
			}
			else if (macd < 0 && _prevMacd >= 0 && rsiVal < 55)
			{
				_entryPrice = close;
				SellMarket();
			}
		}

		_prevMacd = macd;
	}
}