Esta estratégia opera rompimentos através da linha de pivô diária. Calcula os níveis de pivô clássicos dos traders de floor a partir da máxima, mínima e fechamento do dia anterior. Uma posição comprada é aberta quando o preço de fechamento cruza acima do pivô. Uma posição vendida é aberta quando o preço de fechamento cruza abaixo do pivô.
Após a entrada, o sistema utiliza um dos níveis de suporte ou resistência tanto como alvo de lucro quanto de stop loss. O nível é selecionado pelo parâmetro Target Level:
1 – usa Support1/Resistance1.
2 – usa Support2/Resistance2.
3 – usa Support3/Resistance3.
Se Intraday Only estiver ativado, todas as posições abertas são fechadas às 23:00 horário da plataforma.
Detalhes
Critérios de entrada
Comprado: fechamento anterior ≤ pivô e fechamento atual > pivô.
Vendido: fechamento anterior ≥ pivô e fechamento atual < pivô.
Critérios de saída
Comprado: fechamento ≥ nível de resistência selecionado ou fechamento ≤ nível de suporte selecionado.
Vendido: fechamento ≤ nível de suporte selecionado ou fechamento ≥ nível de resistência selecionado.
Se Intraday Only for verdadeiro, todas as posições são fechadas às 23:00.
Indicadores: apenas cálculo clássico de pivô.
Período: configurável; velas de 5 minutos por padrão.
Stops: stop-loss e take-profit baseados no nível de pivô escolhido.
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Pivot-based breakout strategy.
/// Buys when close crosses above calculated pivot, sells when it crosses below.
/// Uses support/resistance levels for exits.
/// </summary>
public class TcpPivotStopStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private decimal _pivot;
private decimal _res1, _sup1;
private decimal _prevClose;
private decimal _prevHigh;
private decimal _prevLow;
private int _barCount;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public TcpPivotStopStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Time frame", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_pivot = _res1 = _sup1 = 0;
_prevClose = _prevHigh = _prevLow = 0;
_barCount = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
SubscribeCandles(CandleType).Bind(ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished) return;
_barCount++;
// Recalculate pivot every 12 bars (~2 days for 4h candles)
if (_barCount % 12 == 0 && _prevHigh > 0)
{
_pivot = (_prevHigh + _prevLow + _prevClose) / 3m;
_res1 = 2m * _pivot - _prevLow;
_sup1 = 2m * _pivot - _prevHigh;
}
_prevHigh = candle.HighPrice;
_prevLow = candle.LowPrice;
var close = candle.ClosePrice;
if (_pivot > 0 && _prevClose > 0)
{
// Cross above pivot => long
if (_prevClose <= _pivot && close > _pivot && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
// Cross below pivot => short
else if (_prevClose >= _pivot && close < _pivot && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
// Exit long at resistance or support
else if (Position > 0 && (close >= _res1 || close <= _sup1))
{
SellMarket();
}
// Exit short at support or resistance
else if (Position < 0 && (close <= _sup1 || close >= _res1))
{
BuyMarket();
}
}
_prevClose = close;
}
}
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.Strategies import Strategy
class tcp_pivot_stop_strategy(Strategy):
"""Pivot-based breakout with support/resistance exits."""
def __init__(self):
super(tcp_pivot_stop_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))).SetDisplay("Candle Type", "Time frame", "General")
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, value): self._candle_type.Value = value
def OnReseted(self):
super(tcp_pivot_stop_strategy, self).OnReseted()
self._pivot = 0
self._res1 = 0
self._sup1 = 0
self._prev_close = 0
self._prev_high = 0
self._prev_low = 0
self._bar_count = 0
def OnStarted2(self, time):
super(tcp_pivot_stop_strategy, self).OnStarted2(time)
self._pivot = 0
self._res1 = 0
self._sup1 = 0
self._prev_close = 0
self._prev_high = 0
self._prev_low = 0
self._bar_count = 0
sub = self.SubscribeCandles(self.CandleType)
sub.Bind(self.OnProcess).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, sub)
self.DrawOwnTrades(area)
def OnProcess(self, candle):
if candle.State != CandleStates.Finished:
return
self._bar_count += 1
high = float(candle.HighPrice)
low = float(candle.LowPrice)
close = float(candle.ClosePrice)
# Recalculate pivot every 12 bars
if self._bar_count % 12 == 0 and self._prev_high > 0:
self._pivot = (self._prev_high + self._prev_low + self._prev_close) / 3.0
self._res1 = 2.0 * self._pivot - self._prev_low
self._sup1 = 2.0 * self._pivot - self._prev_high
self._prev_high = high
self._prev_low = low
if self._pivot > 0 and self._prev_close > 0:
# Cross above pivot => long
if self._prev_close <= self._pivot and close > self._pivot and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
# Cross below pivot => short
elif self._prev_close >= self._pivot and close < self._pivot and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
# Exit long at resistance or support
elif self.Position > 0 and (close >= self._res1 or close <= self._sup1):
self.SellMarket()
# Exit short at support or resistance
elif self.Position < 0 and (close <= self._sup1 or close >= self._res1):
self.BuyMarket()
self._prev_close = close
def CreateClone(self):
return tcp_pivot_stop_strategy()