Esta estrategia opera rupturas a través de la línea de pivote diaria. Calcula los niveles de pivote clásicos de los operadores de piso a partir del máximo, mínimo y cierre del día anterior. Se abre una posición larga cuando el precio de cierre cruza por encima del pivote. Se abre una posición corta cuando el precio de cierre cruza por debajo del pivote.
Tras la entrada, el sistema utiliza uno de los niveles de soporte o resistencia tanto como objetivo de beneficio como de stop loss. El nivel se selecciona mediante el parámetro Target Level:
1 – utiliza Support1/Resistance1.
2 – utiliza Support2/Resistance2.
3 – utiliza Support3/Resistance3.
Si Intraday Only está activado, todas las posiciones abiertas se cierran a las 23:00 hora de la plataforma.
Detalles
Criterios de entrada
Largo: cierre anterior ≤ pivote y cierre actual > pivote.
Corto: cierre anterior ≥ pivote y cierre actual < pivote.
Criterios de salida
Largo: cierre ≥ nivel de resistencia seleccionado o cierre ≤ nivel de soporte seleccionado.
Corto: cierre ≤ nivel de soporte seleccionado o cierre ≥ nivel de resistencia seleccionado.
Si Intraday Only es verdadero, todas las posiciones se cierran a las 23:00.
Indicadores: solo cálculo clásico de pivote.
Marco temporal: configurable; velas de 5 minutos por defecto.
Stops: stop-loss y take-profit basados en el nivel de pivote elegido.
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()