Ver no GitHub

Estratégia de regressão multiperíodo

Uma estratégia multiperíodo que combina canais de regressão linear em velas M1, M5 e H1. A inclinação de regressão do canal H1 define a tendência dominante, enquanto os canais M5 e M1 fornecem locais de entrada precisos perto do suporte e da resistência.

Lógica de negociação

  • Feeds de dados: nove timeframes de velas padrão (M1, M5, M15, M30, H1, H4, D1, W1, MN1).
  • Indicadores: cada feed é processado por um canal de regressão linear de comprimento configurável. O canal fornece uma linha central e bandas superiores/inferiores simétricas com base no desvio máximo dos fechamentos recentes.
  • Filtro de tendência: a estratégia considera apenas negociações curtas quando a inclinação do canal H1 for negativa e negociações longas quando for positiva.
  • Entrada:
    • Curto – o máximo M5 e o máximo M1 mais recentes perfuram suas bandas superiores do canal enquanto a inclinação H1 é negativa.
    • Longo – o mínimo M5 e o mínimo M1 mais recentes atingem suas bandas de canal mais baixas enquanto a inclinação H1 é positiva.
  • Tratamento de ordens: os lançamentos são executados com ordens de mercado utilizando o volume configurado. As metas de stop-loss e take-profit são derivadas da meia largura e da linha central do canal M5, respectivamente.
  • Saída: as posições são fechadas nas velas M1 quando o preço atinge o stop de proteção ou o alvo da linha central.
  • Gerenciamento de posições: no máximo uma posição de mercado está aberta a qualquer momento.

Parâmetros

Nome Descrição
EnableTrading Permite que a estratégia faça pedidos quando habilitada.
BarsToCount Número de barras usadas em cada canal de regressão (padrão 50).
Volume Volume de ordens de mercado em lotes.

Notas

  • Janelas de regressão mais longas proporcionam inclinações de canal mais suaves, mas reações mais lentas.
  • A exibição da inclinação de vários períodos de tempo é útil para monitorar o alinhamento em intervalos mais altos, mesmo que apenas a inclinação H1 bloqueie as entradas.
  • Os níveis de proteção são recalculados cada vez que uma nova vela M5 se forma; a recalibração frequente mantém o risco fortemente acoplado à geometria atual do canal.
using System;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Linear regression channel strategy.
/// Uses LinearReg as the center line with Highest/Lowest to form a channel.
/// Sells at upper channel, buys at lower channel, with trend filter from regression slope.
/// </summary>
public class MultiTimeFrameRegressionStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _regressionLength;
	private readonly StrategyParam<int> _channelLength;

	private decimal _prevLrValue;
	private bool _hasPrev;

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

		_regressionLength = Param(nameof(RegressionLength), 20)
			.SetDisplay("Regression Length", "Period for linear regression.", "Indicators");

		_channelLength = Param(nameof(ChannelLength), 20)
			.SetDisplay("Channel Length", "Period for highest/lowest channel.", "Indicators");
	}

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

	public int RegressionLength
	{
		get => _regressionLength.Value;
		set => _regressionLength.Value = value;
	}

	public int ChannelLength
	{
		get => _channelLength.Value;
		set => _channelLength.Value = value;
	}

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

		_prevLrValue = 0;
		_hasPrev = false;
	}

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

		_prevLrValue = 0;
		_hasPrev = false;

		var lr = new LinearReg { Length = RegressionLength };
		var highest = new Highest { Length = ChannelLength };
		var lowest = new Lowest { Length = ChannelLength };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(lr, highest, lowest, ProcessCandle)
			.Start();

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

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

		var close = candle.ClosePrice;

		// Determine slope direction from regression
		var slope = _hasPrev ? lrValue - _prevLrValue : 0m;

		// Channel boundaries
		var channelMid = (highestValue + lowestValue) / 2m;
		var channelWidth = highestValue - lowestValue;

		if (channelWidth <= 0)
		{
			_prevLrValue = lrValue;
			_hasPrev = true;
			return;
		}

		// Upper/lower thresholds
		var upperThreshold = channelMid + channelWidth * 0.4m;
		var lowerThreshold = channelMid - channelWidth * 0.4m;

		// Exit conditions
		if (Position > 0 && (close >= upperThreshold || slope < 0))
		{
			SellMarket();
		}
		else if (Position < 0 && (close <= lowerThreshold || slope > 0))
		{
			BuyMarket();
		}

		// Entry conditions
		if (Position == 0)
		{
			if (close <= lowerThreshold && slope >= 0)
			{
				// Price near lower channel with flat/rising regression
				BuyMarket();
			}
			else if (close >= upperThreshold && slope <= 0)
			{
				// Price near upper channel with flat/falling regression
				SellMarket();
			}
		}

		_prevLrValue = lrValue;
		_hasPrev = true;
	}
}