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;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import LinearReg, Highest, Lowest
from StockSharp.Algo.Strategies import Strategy
class multi_time_frame_regression_strategy(Strategy):
"""
Multi Time Frame Regression: linear regression channel with highest/lowest boundaries.
"""
def __init__(self):
super(multi_time_frame_regression_strategy, self).__init__()
self._regression_length = self.Param("RegressionLength", 20).SetDisplay("Regression", "LinReg period", "Indicators")
self._channel_length = self.Param("ChannelLength", 20).SetDisplay("Channel", "Channel period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).SetDisplay("Candle Type", "Candles", "General")
self._prev_lr = 0.0
self._has_prev = False
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(multi_time_frame_regression_strategy, self).OnReseted()
self._prev_lr = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(multi_time_frame_regression_strategy, self).OnStarted2(time)
lr = LinearReg()
lr.Length = self._regression_length.Value
highest = Highest()
highest.Length = self._channel_length.Value
lowest = Lowest()
lowest.Length = self._channel_length.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(lr, highest, lowest, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, lr)
self.DrawOwnTrades(area)
def _process_candle(self, candle, lr_val, high_val, low_val):
if candle.State != CandleStates.Finished:
return
lr = float(lr_val)
h = float(high_val)
l = float(low_val)
close = float(candle.ClosePrice)
slope = lr - self._prev_lr if self._has_prev else 0.0
ch_mid = (h + l) / 2.0
ch_width = h - l
if ch_width <= 0:
self._prev_lr = lr
self._has_prev = True
return
upper = ch_mid + ch_width * 0.4
lower = ch_mid - ch_width * 0.4
if self.Position > 0 and (close >= upper or slope < 0):
self.SellMarket()
elif self.Position < 0 and (close <= lower or slope > 0):
self.BuyMarket()
if self.Position == 0:
if close <= lower and slope >= 0:
self.BuyMarket()
elif close >= upper and slope <= 0:
self.SellMarket()
self._prev_lr = lr
self._has_prev = True
def CreateClone(self):
return multi_time_frame_regression_strategy()