Ver no GitHub

Envelopes de 5 minutos

A estratégia 5Mins Envelopes reproduz o especialista MetaTrader que negocia velas de cinco minutos em torno de um envelope de média móvel ponderada linear. Procura picos de preços que se estendem muito além das bandas e depois entra na direção de reversão à média. Um filtro de spread, stop-loss estático, take-profit opcional e trailing stop refletem a gestão de dinheiro original.

Lógica de negociação

  • Indicador: Média Móvel Linear Ponderada (LWMA) calculada sobre o preço mediano (máximo+mínimo)/2 com período 3.
  • Largura do envelope: desvio de 0,05% do valor LWMA (bandas superior e inferior).
  • Detecção de sinal (avaliado na vela concluída anterior e no lance atual):
    • Longo: o mínimo da vela anterior fica mais de DistancePoints abaixo da faixa inferior e o lance atual também está além dessa distância.
    • Curta: a máxima da vela anterior fica mais de DistancePoints acima da faixa superior e o lance atual também está além dessa distância.
  • Filtros:
    • Apenas uma posição por vez (novas entradas exigem que a posição atual seja plana).
    • Se MaxSpreadPoints for maior que zero, o spread de compra/venda deverá permanecer abaixo desse limite antes de enviar um novo pedido.

Gestão de risco

  • Volume da ordem: o parâmetro TradeVolume controla o tamanho da ordem de mercado.
  • Stop-loss: StopLossPoints converte para a distância absoluta do preço usando o tamanho do tick do instrumento.
  • Realização de lucro: Opcional TakeProfitPoints; definido como zero para desativar.
  • Parada final: Opcional TrailingStopPoints; definido como zero para desativar.
  • Proteção: O auxiliar StartProtection aplica todas as saídas com ordens de mercado, correspondendo ao comportamento MetaTrader.

Parâmetros

  • TradeVolume = 1m
  • DistancePoints = 140
  • EnvelopePeriod = 3
  • EnvelopeDeviationPercent = 0.05m
  • StopLossPoints = 250
  • TakeProfitPoints = 0
  • TrailingStopPoints = 120
  • MaxSpreadPoints = 25
  • CandleType = TimeFrame(5 minutes)

Etiquetas

  • Categoria: Reversão à Média
  • Direção: Ambos
  • Indicadores: WeightedMovingAverage
  • Stops: Sim (fixo + final)
  • Prazo: intradiário (M5)
  • Complexidade: Iniciante
  • Nível de risco: Médio
  • Sazonalidade: Não
  • Redes Neurais: Não
  • Divergência: Não
namespace StockSharp.Samples.Strategies;

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

/// <summary>
/// 5 Mins Envelopes strategy: envelope breakout using SMA with deviation bands.
/// Buys when price crosses above upper envelope, sells when below lower envelope.
/// </summary>
public class FiveMinsEnvelopesStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _maPeriod;
	private readonly StrategyParam<decimal> _deviation;
	private bool _wasAboveUpper;
	private bool _wasBelowLower;
	private bool _hasPrevSignal;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int MaPeriod { get => _maPeriod.Value; set => _maPeriod.Value = value; }
	public decimal Deviation { get => _deviation.Value; set => _deviation.Value = value; }

	public FiveMinsEnvelopesStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_maPeriod = Param(nameof(MaPeriod), 50)
			.SetGreaterThanZero()
			.SetDisplay("MA Period", "Moving average period", "Indicators");
		_deviation = Param(nameof(Deviation), 0.3m)
			.SetDisplay("Deviation %", "Envelope deviation percent", "Indicators");
	}

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

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_hasPrevSignal = false;
		var sma = new SimpleMovingAverage { Length = MaPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(sma, ProcessCandle).Start();
	}

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

		var close = candle.ClosePrice;
		var upper = smaValue * (1 + Deviation / 100m);
		var lower = smaValue * (1 - Deviation / 100m);
		var aboveUpper = close > upper;
		var belowLower = close < lower;

		if (_hasPrevSignal)
		{
			if (aboveUpper && !_wasAboveUpper && Position <= 0)
				BuyMarket();
			else if (belowLower && !_wasBelowLower && Position >= 0)
				SellMarket();
		}

		_wasAboveUpper = aboveUpper;
		_wasBelowLower = belowLower;
		_hasPrevSignal = true;
	}
}