Ver no GitHub

Glam Trader (confirmação de vários prazos)

Visão geral

A estratégia replica o consultor especialista original MetaTrader "GLAM Trader" combinando informações de três períodos de tempo:

  • Um EMA(3) rápido no gráfico de 15 minutos captura o viés da tendência de curto prazo.
  • Um filtro Laguerre com gama 0,7 aplicado a velas de 5 minutos mede se o preço está sendo negociado acima ou abaixo de seu caminho suavizado.
  • O Awesome Oscillator em velas horárias fornece uma verificação de impulso alinhada com a definição de Bill Williams.

Somente quando todos os três componentes concordam é que a estratégia abre uma negociação, com o objetivo de filtrar o ruído que apareceria quando qualquer período de tempo fosse avaliado isoladamente.

Lógica de negociação

  1. Preparação de dados
    • Velas de 15 minutos alimentam um ExponentialMovingAverage com comprimento EmaPeriod (padrão 3).
    • Velas de 5 minutos alimentam um LaguerreFilter com suavização LaguerreGamma.
    • Velas de 60 minutos alimentam um AwesomeOscillator.
    • Para cada período de tempo, o último fechamento da vela finalizado é armazenado para reproduzir a comparação original do indicador versus preço.
  2. Condições de entrada
    • Longo: o EMA está acima do fechamento atual de 15 minutos, Laguerre está acima do último fechamento de 5 minutos e Awesome Oscillator está acima do último fechamento horário.
    • Short: cada um dos três indicadores deve ficar abaixo do fechamento correspondente.
  3. Gerenciamento de riscos
    • Distâncias separadas de stop-loss e take-profit (expressas em pontos de instrumento) para negociações longas e curtas.
    • Os trailing stops são ativados quando o preço percorre pelo menos a distância móvel especificada além do preço de entrada. A parada é aumentada na direção da tendência sem recuar.
    • Todas as ações de proteção (take-profit, stop-loss, trailing stop) fecham toda a posição com ordens de mercado, espelhando a implementação MQL.

Parâmetros

Nome Descrição Padrão
TradeVolume Tamanho do pedido para novas posições. 0,1
PrimaryCandleType Período usado para EMA e sinal principal. Velas de 15 minutos
LaguerreCandleType Prazo analisado pelo filtro Laguerre. Velas de 5 minutos
AwesomeCandleType Prazo analisado pelo Awesome Oscillator. Velas de 60 minutos
EmaPeriod Duração de EMA no período principal. 3
LaguerreGamma Parâmetro gama para o filtro Laguerre. 0,7
LongStopLossPoints Distância stop-loss para negociações longas, em pontos. 20
ShortStopLossPoints Distância stop-loss para negociações curtas, em pontos. 20
LongTakeProfitPoints Distância de lucro para negociações longas, em pontos. 50
ShortTakeProfitPoints Distância de lucro para negociações curtas, em pontos. 50
LongTrailingPoints Distância final para negociações longas, em pontos. 15
ShortTrailingPoints Distância final para negociações curtas, em pontos. 15

Notas

  • A estratégia assina três fluxos de velas independentes e mantém apenas os valores finalizados mais recentes, evitando buffers manuais de histórico.
  • Todos os comentários e mensagens de registro permanecem em inglês para maior clareza, correspondendo às convenções do projeto.
  • Ajuste os parâmetros de risco baseados em pontos de acordo com o PriceStep do instrumento para que os níveis de proteção reflitam o tamanho do tick da corretora.
using System;
using System.Collections.Generic;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Glam Trader strategy - EMA crossover with momentum confirmation.
/// Buys when fast EMA crosses above slow EMA and momentum is positive.
/// Sells when fast EMA crosses below slow EMA and momentum is negative.
/// </summary>
public class GlamTraderSimpleStrategy : Strategy
{
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<int> _momentumPeriod;
	private readonly StrategyParam<DataType> _candleType;

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

	public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
	public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
	public int MomentumPeriod { get => _momentumPeriod.Value; set => _momentumPeriod.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public GlamTraderSimpleStrategy()
	{
		_fastPeriod = Param(nameof(FastPeriod), 8)
			.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");

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

		_momentumPeriod = Param(nameof(MomentumPeriod), 14)
			.SetDisplay("Momentum Period", "Momentum lookback", "Indicators");

		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
	protected override void OnReseted() { base.OnReseted(); _prevFast = 0m; _prevSlow = 0m; _hasPrev = false; }

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

		_hasPrev = false;

		var fast = new ExponentialMovingAverage { Length = FastPeriod };
		var slow = new ExponentialMovingAverage { Length = SlowPeriod };
		var mom = new Momentum { Length = MomentumPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fast, slow, mom, ProcessCandle)
			.Start();
	}

	private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow, decimal mom)
	{
		if (candle.State != CandleStates.Finished)
			return;

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

		// Fast crosses above slow + positive momentum = buy
		if (_prevFast <= _prevSlow && fast > slow && mom > 0 && Position <= 0)
		{
			if (Position < 0)
				BuyMarket();
			BuyMarket();
		}
		// Fast crosses below slow + negative momentum = sell
		else if (_prevFast >= _prevSlow && fast < slow && mom < 0 && Position >= 0)
		{
			if (Position > 0)
				SellMarket();
			SellMarket();
		}

		_prevFast = fast;
		_prevSlow = slow;
	}
}