Estratégia que opera reversões detectadas pelo indicador Three Line Break.
O indicador compara o máximo e mínimo atuais com o máximo mais alto e o mínimo mais baixo das N velas anteriores concluídas.
Um rompimento acima do máximo recente durante uma tendência de baixa sinaliza uma nova tendência de alta e aciona uma entrada comprada; um rompimento abaixo do mínimo recente durante uma tendência de alta aciona uma entrada vendida.
As posições são invertidas em cada sinal.
Detalhes
Critérios de entrada:
Comprado: Downtrend muda para Uptrend
Vendido: Uptrend muda para Downtrend
Comprado/Vendido: Ambos
Critérios de saída: Sinal oposto (inversão de posição)
Stops: Não
Valores padrão:
LinesBreak = 3
CandleType = TimeSpan.FromHours(12).TimeFrame()
Filtros:
Categoria: Seguidor de tendência
Direção: Ambos
Indicadores: Highest, Lowest (lógica Three Line Break)
Stops: Não
Complexidade: Básico
Período: Swing
Sazonalidade: Não
Redes neurais: Não
Divergência: Não
Nível de risco: Médio
using System;
using System.Linq;
using System.Collections.Generic;
using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Strategy based on the Three Line Break pattern.
/// Detects trend reversals when price breaks above/below recent N-bar high/low.
/// </summary>
public class ThreeLineBreakStrategy : Strategy
{
private readonly StrategyParam<int> _linesBreak;
private readonly StrategyParam<DataType> _candleType;
private Lowest _lowest;
private decimal _prevHigh;
private decimal _prevLow;
private bool _trendUp = true;
public int LinesBreak { get => _linesBreak.Value; set => _linesBreak.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public ThreeLineBreakStrategy()
{
_linesBreak = Param(nameof(LinesBreak), 3)
.SetGreaterThanZero()
.SetDisplay("Lines Break", "Number of lines for trend detection", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Timeframe for analysis", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_lowest = null;
_prevHigh = 0;
_prevLow = 0;
_trendUp = true;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var highest = new Highest { Length = LinesBreak };
_lowest = new Lowest { Length = LinesBreak };
Indicators.Add(_lowest);
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(highest, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, highest);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue highValue)
{
if (candle.State != CandleStates.Finished)
return;
var lowValue = _lowest.Process(highValue);
if (!highValue.IsFormed || !lowValue.IsFormed)
return;
var currentHigh = highValue.GetValue<decimal>();
var currentLow = lowValue.GetValue<decimal>();
if (!IsFormedAndOnlineAndAllowTrading())
{
_prevHigh = currentHigh;
_prevLow = currentLow;
return;
}
if (_prevHigh == 0 || _prevLow == 0)
{
_prevHigh = currentHigh;
_prevLow = currentLow;
return;
}
var trendUp = _trendUp;
if (trendUp && candle.LowPrice < _prevLow)
trendUp = false;
else if (!trendUp && candle.HighPrice > _prevHigh)
trendUp = true;
if (trendUp != _trendUp)
{
if (trendUp && Position <= 0)
BuyMarket();
else if (!trendUp && Position >= 0)
SellMarket();
}
_trendUp = trendUp;
_prevHigh = currentHigh;
_prevLow = currentLow;
}
}
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 Highest, Lowest
from StockSharp.Algo.Strategies import Strategy
class three_line_break_strategy(Strategy):
def __init__(self):
super(three_line_break_strategy, self).__init__()
self._lines_break = self.Param("LinesBreak", 3) \
.SetDisplay("Lines Break", "Number of lines for trend detection", "General")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Timeframe for analysis", "General")
self._lowest = None
self._prev_high = 0.0
self._prev_low = 0.0
self._trend_up = True
@property
def lines_break(self):
return self._lines_break.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(three_line_break_strategy, self).OnReseted()
self._lowest = None
self._prev_high = 0.0
self._prev_low = 0.0
self._trend_up = True
def OnStarted2(self, time):
super(three_line_break_strategy, self).OnStarted2(time)
highest = Highest()
highest.Length = self.lines_break
self._lowest = Lowest()
self._lowest.Length = self.lines_break
self.Indicators.Add(self._lowest)
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(highest, self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, highest)
self.DrawOwnTrades(area)
def process_candle(self, candle, high_value):
if candle.State != CandleStates.Finished:
return
low_value = self._lowest.Process(high_value)
if not high_value.IsFormed or not low_value.IsFormed:
return
current_high = float(high_value)
current_low = float(low_value)
if self._prev_high == 0.0 or self._prev_low == 0.0:
self._prev_high = current_high
self._prev_low = current_low
return
trend_up = self._trend_up
if trend_up and float(candle.LowPrice) < self._prev_low:
trend_up = False
elif not trend_up and float(candle.HighPrice) > self._prev_high:
trend_up = True
if trend_up != self._trend_up:
if trend_up and self.Position <= 0:
self.BuyMarket()
elif not trend_up and self.Position >= 0:
self.SellMarket()
self._trend_up = trend_up
self._prev_high = current_high
self._prev_low = current_low
def CreateClone(self):
return three_line_break_strategy()