ORB 15m – Rompimiento de los Primeros 15 Minutos (Largo/Corto)
Esta estrategia entra al cierre de la primera barra de 15 minutos después de la apertura de la sesión en hora de Estocolmo. Una primera barra alcista activa una operación larga; una barra bajista activa una operación corta. El tamaño de la posición se calcula a partir del porcentaje de riesgo y la distancia al stop.
Detalles
Criterios de entrada: operar en la primera barra de 15 minutos después de la apertura de la sesión; largo si la barra cierra por encima de su apertura, corto si cierra por debajo.
Criterios de salida: stop-loss en el extremo opuesto de la barra de referencia; take profit opcional en RMultiple veces el riesgo, o al final de la sesión.
Largo/Corto: Ambos.
Stops: Sí.
Valores predeterminados:
RiskPct = 1
TpTenR = true
RMultiple = 10
SessionOpenHour = 15
SessionOpenMinute = 30
SessionEndHour = 22
SessionEndMinute = 0
Filtros:
Categoría: Ruptura
Dirección: Ambos
Indicadores: Ninguno
Stops: Sí
Complejidad: Principiante
Marco temporal: Intradía
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class Orb15mFirst15minBreakoutStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private decimal _orHigh;
private decimal _orLow;
private bool _tradeTakenToday;
private bool _wasInOr;
private DateTime _currentDay;
private bool _orEstablished;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public Orb15mFirst15minBreakoutStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame());
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_orHigh = 0;
_orLow = 0;
_tradeTakenToday = false;
_wasInOr = false;
_currentDay = default;
_orEstablished = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_orHigh = 0;
_orLow = 0;
_tradeTakenToday = false;
_wasInOr = false;
_currentDay = default;
_orEstablished = false;
var sma = new SimpleMovingAverage { Length = 20 };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(sma, (candle, smaVal) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!sma.IsFormed)
return;
var day = candle.OpenTime.Date;
if (_currentDay != day)
{
_currentDay = day;
_orHigh = 0;
_orLow = 0;
_tradeTakenToday = false;
_orEstablished = false;
}
var hour = candle.OpenTime.TimeOfDay.TotalHours;
var inOr = hour < 1;
if (inOr)
{
_orHigh = _orHigh > 0 ? Math.Max(_orHigh, candle.HighPrice) : candle.HighPrice;
_orLow = _orLow > 0 ? Math.Min(_orLow, candle.LowPrice) : candle.LowPrice;
}
if (_wasInOr && !inOr && _orHigh > 0 && _orLow > 0 && _orHigh - _orLow > 0)
_orEstablished = true;
if (!_tradeTakenToday && _orEstablished && !inOr)
{
if (candle.ClosePrice > _orHigh && candle.ClosePrice > smaVal && Position <= 0)
{
BuyMarket();
_tradeTakenToday = true;
}
else if (candle.ClosePrice < _orLow && candle.ClosePrice < smaVal && Position >= 0)
{
SellMarket();
_tradeTakenToday = true;
}
}
_wasInOr = inOr;
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, sma);
DrawOwnTrades(area);
}
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Math
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
class orb_15m_first_15min_breakout_strategy(Strategy):
def __init__(self):
super(orb_15m_first_15min_breakout_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5)))
self._or_high = 0.0
self._or_low = 0.0
self._trade_taken_today = False
self._was_in_or = False
self._current_day = None
self._or_established = False
@property
def candle_type(self):
return self._candle_type.Value
@candle_type.setter
def candle_type(self, value):
self._candle_type.Value = value
def OnReseted(self):
super(orb_15m_first_15min_breakout_strategy, self).OnReseted()
self._or_high = 0.0
self._or_low = 0.0
self._trade_taken_today = False
self._was_in_or = False
self._current_day = None
self._or_established = False
def OnStarted2(self, time):
super(orb_15m_first_15min_breakout_strategy, self).OnStarted2(time)
self._or_high = 0.0
self._or_low = 0.0
self._trade_taken_today = False
self._was_in_or = False
self._current_day = None
self._or_established = False
self._sma = SimpleMovingAverage()
self._sma.Length = 20
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(self._sma, self.OnProcess).Start()
def OnProcess(self, candle, sma_val):
if candle.State != CandleStates.Finished:
return
if not self._sma.IsFormed:
return
sv = float(sma_val)
close = float(candle.ClosePrice)
high = float(candle.HighPrice)
low = float(candle.LowPrice)
day = candle.OpenTime.Date
if self._current_day is None or self._current_day != day:
self._current_day = day
self._or_high = 0.0
self._or_low = 0.0
self._trade_taken_today = False
self._or_established = False
hour = candle.OpenTime.TimeOfDay.TotalHours
in_or = hour < 1
if in_or:
self._or_high = max(self._or_high, high) if self._or_high > 0 else high
self._or_low = min(self._or_low, low) if self._or_low > 0 else low
if self._was_in_or and not in_or and self._or_high > 0 and self._or_low > 0 and self._or_high - self._or_low > 0:
self._or_established = True
if not self._trade_taken_today and self._or_established and not in_or:
if close > self._or_high and close > sv and self.Position <= 0:
self.BuyMarket()
self._trade_taken_today = True
elif close < self._or_low and close < sv and self.Position >= 0:
self.SellMarket()
self._trade_taken_today = True
self._was_in_or = in_or
def CreateClone(self):
return orb_15m_first_15min_breakout_strategy()