A Estratégia de Breakout Floor TCPivotStop é uma versão direta do consultor especialista MetaTrader gpfTCPivotStop. A lógica gira em torno
cálculos clássicos de pivô de piso realizados no dia de negociação anterior. No início de cada nova sessão diária a estratégia:
Agrega a máxima, a mínima e o fechamento do dia anterior para calcular o ponto de articulação mais os três primeiros níveis de suporte e resistência.
Verifica se a última barra horária concluída cruzou o pivô de cima ou de baixo.
Abre uma ordem de mercado na direção do cruzamento, ao mesmo tempo em que atribui níveis de stop-loss e take-profit que refletem o
comportamento original do perito.
Apenas uma posição pode estar ativa por vez. O gerenciamento de sessão opcional permite nivelar a exposição quando um novo dia começa.
Regras de negociação
Prazo – Projetado para velas de 1 hora (configurável).
Cálculo dinâmico – usa a máxima, a mínima e o fechamento do dia anterior para calcular Pivot, R1, R2, R3, S1, S2, S3.
Condições de entrada
Digite short quando a última barra concluída fechou abaixo do pivô enquanto a barra anterior fechou acima dele.
Digite long quando a última barra concluída fechou acima do pivô enquanto a barra anterior fechou abaixo dele.
Dimensionamento de posição – Tamanho de lote fixo definido pelo parâmetro OrderVolume.
Condições de saída
Os preços de stop-loss e take-profit são mapeados para os níveis de pivô clássicos.
Se a sinalização CloseAtSessionEnd estiver habilitada, a estratégia liquida as negociações abertas antes do início da próxima sessão.
Os níveis de proteção são monitorados nas máximas/mínimas das velas e executados com ordens de mercado quando tocados.
Parâmetros
Nome
Descrição
Padrão
OrderVolume
Tamanho da negociação para entradas no mercado.
0.1
TakeProfitTarget
Escolhe qual nível dinâmico atua como meta de lucro (1 = mais próximo, 3 = mais distante).
1
CloseAtSessionEnd
Feche qualquer posição aberta assim que uma nova sessão diária começar.
false
CandleType
Período usado para todos os cálculos (de hora em hora por padrão).
H1
Notas
A estratégia executa ordens apenas uma vez por dia quando um novo conjunto dinâmico está disponível, assim como a fonte EA que é acionada no
primeiro tick da sessão diária.
A versão MetaTrader recalculou os tamanhos dos lotes usando o histórico de margem da conta. Esta porta mantém o dimensionamento da posição fixo e
delega a gestão do dinheiro a outros componentes, se necessário.
As ordens de proteção são emuladas monitorando os extremos das velas e enviando ordens de mercado assim que um limite for ultrapassado.
Arquivos
CS/TcpFloorPivotBreakoutStrategy.cs – implementação em C# da lógica de negociação.
README.md – Documentação em inglês (este arquivo).
README_zh.md – Tradução simplificada para chinês.
README_ru.md – Tradução russa.
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class TcpFloorPivotBreakoutStrategy : Strategy
{
private readonly StrategyParam<int> _channelPeriod;
private readonly StrategyParam<int> _cooldownCandles;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevClose;
private decimal _prevMid;
private bool _hasPrev;
private int _cooldownRemaining;
public int ChannelPeriod { get => _channelPeriod.Value; set => _channelPeriod.Value = value; }
public int CooldownCandles { get => _cooldownCandles.Value; set => _cooldownCandles.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public TcpFloorPivotBreakoutStrategy()
{
_channelPeriod = Param(nameof(ChannelPeriod), 48).SetDisplay("Channel Period", "Channel lookback", "Indicators");
_cooldownCandles = Param(nameof(CooldownCandles), 150).SetDisplay("Cooldown", "Candles between signals", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevClose = default;
_prevMid = default;
_hasPrev = default;
_cooldownRemaining = default;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevClose = 0;
_prevMid = 0;
_hasPrev = false;
_cooldownRemaining = 0;
var highest = new Highest { Length = ChannelPeriod };
var lowest = new Lowest { Length = ChannelPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(highest, lowest, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal highest, decimal lowest)
{
if (candle.State != CandleStates.Finished) return;
var close = candle.ClosePrice;
var mid = (highest + lowest) / 2;
if (!_hasPrev) { _prevClose = close; _prevMid = mid; _hasPrev = true; return; }
if (_cooldownRemaining > 0)
{
_cooldownRemaining--;
_prevClose = close;
_prevMid = mid;
return;
}
if (_prevClose <= _prevMid && close > mid && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
_cooldownRemaining = CooldownCandles;
}
else if (_prevClose >= _prevMid && close < mid && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
_cooldownRemaining = CooldownCandles;
}
_prevClose = close;
_prevMid = mid;
}
}
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 tcp_floor_pivot_breakout_strategy(Strategy):
def __init__(self):
super(tcp_floor_pivot_breakout_strategy, self).__init__()
self._channel_period = self.Param("ChannelPeriod", 48).SetDisplay("Channel Period", "Channel lookback", "Indicators")
self._cooldown_candles = self.Param("CooldownCandles", 150).SetDisplay("Cooldown", "Candles between signals", "General")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_close = 0.0
self._prev_mid = 0.0
self._has_prev = False
self._cooldown_remaining = 0
@property
def channel_period(self): return self._channel_period.Value
@property
def cooldown_candles(self): return self._cooldown_candles.Value
@property
def candle_type(self): return self._candle_type.Value
def OnReseted(self):
super(tcp_floor_pivot_breakout_strategy, self).OnReseted()
self._prev_close = 0.0
self._prev_mid = 0.0
self._has_prev = False
self._cooldown_remaining = 0
def OnStarted2(self, time):
super(tcp_floor_pivot_breakout_strategy, self).OnStarted2(time)
self._prev_close = 0.0
self._prev_mid = 0.0
self._has_prev = False
self._cooldown_remaining = 0
highest = Highest()
highest.Length = self.channel_period
lowest = Lowest()
lowest.Length = self.channel_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(highest, lowest, self.process_candle).Start()
def process_candle(self, candle, highest, lowest):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
mid = (float(highest) + float(lowest)) / 2.0
if not self._has_prev:
self._prev_close = close
self._prev_mid = mid
self._has_prev = True
return
if self._cooldown_remaining > 0:
self._cooldown_remaining -= 1
self._prev_close = close
self._prev_mid = mid
return
if self._prev_close <= self._prev_mid and close > mid and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
self._cooldown_remaining = self.cooldown_candles
elif self._prev_close >= self._prev_mid and close < mid and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._cooldown_remaining = self.cooldown_candles
self._prev_close = close
self._prev_mid = mid
def CreateClone(self):
return tcp_floor_pivot_breakout_strategy()