Estrategia basada en el tiempo que compara los precios de apertura de dos barras pasadas en una hora específica. Si la barra más antigua está por encima de la reciente por un umbral, se abre una operación corta. Si la barra reciente está por encima de la más antigua, se abre una operación larga. Cada posición usa stop loss y take profit fijos y se cierra después de un tiempo máximo de mantenimiento.
Detalles
Criterios de entrada: A TradeTime comparar precios de apertura de T1 y T2 barras atrás. Si Open[T1] - Open[T2] supera DeltaShort, vender; si Open[T2] - Open[T1] supera DeltaLong, comprar.
Largo/Corto: Ambas direcciones.
Criterios de salida: Stop loss, take profit o MaxOpenTime horas tras la entrada.
Stops: Stop loss y take profit fijos en puntos.
Valores predeterminados:
TakeProfitLong = 39
StopLossLong = 147
TakeProfitShort = 15
StopLossShort = 6000
TradeTime = 18
T1 = 6
T2 = 2
DeltaLong = 6
DeltaShort = 21
Volume = 0.01
MaxOpenTime = 504
Filtros:
Categoría: Basada en tiempo
Dirección: Ambos
Indicadores: Ninguno
Stops: Fijo
Complejidad: Principiante
Marco temporal: Intradía (1h)
Estacionalidad: No
Redes neuronales: No
Divergencia: No
Nivel de riesgo: Medio
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>
/// Time-based strategy comparing open prices with ATR-based stop/take.
/// </summary>
public class GeedoStrategy : Strategy
{
private readonly StrategyParam<int> _lookback;
private readonly StrategyParam<int> _atrPeriod;
private readonly StrategyParam<DataType> _candleType;
private readonly List<decimal> _openHistory = new();
private decimal _entryPrice;
public int Lookback { get => _lookback.Value; set => _lookback.Value = value; }
public int AtrPeriod { get => _atrPeriod.Value; set => _atrPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public GeedoStrategy()
{
_lookback = Param(nameof(Lookback), 6)
.SetGreaterThanZero()
.SetDisplay("Lookback", "Open price lookback bars", "Indicators");
_atrPeriod = Param(nameof(AtrPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("ATR Period", "ATR period for stops", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_openHistory.Clear();
_entryPrice = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var atr = new StandardDeviation { Length = AtrPeriod };
SubscribeCandles(CandleType).Bind(atr, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal atrVal)
{
if (candle.State != CandleStates.Finished) return;
_openHistory.Add(candle.OpenPrice);
if (_openHistory.Count > Lookback + 1)
_openHistory.RemoveAt(0);
if (_openHistory.Count <= Lookback) return;
if (atrVal <= 0) return;
var close = candle.ClosePrice;
// Exit check
if (Position > 0 && _entryPrice > 0)
{
if (close <= _entryPrice - atrVal * 2 || close >= _entryPrice + atrVal * 1.5m)
{
SellMarket();
_entryPrice = 0;
return;
}
}
else if (Position < 0 && _entryPrice > 0)
{
if (close >= _entryPrice + atrVal * 2 || close <= _entryPrice - atrVal * 1.5m)
{
BuyMarket();
_entryPrice = 0;
return;
}
}
var pastOpen = _openHistory[0];
var currentOpen = _openHistory[^1];
var diff = currentOpen - pastOpen;
// Price rising => long
if (diff > atrVal * 0.5m && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
_entryPrice = close;
}
// Price falling => short
else if (diff < -atrVal * 0.5m && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
_entryPrice = 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.Indicators import StandardDeviation
from StockSharp.Algo.Strategies import Strategy
class geedo_strategy(Strategy):
def __init__(self):
super(geedo_strategy, self).__init__()
self._lookback = self.Param("Lookback", 6) \
.SetDisplay("Lookback", "Open price lookback bars", "Indicators")
self._atr_period = self.Param("AtrPeriod", 14) \
.SetDisplay("ATR Period", "ATR period for stops", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._open_history = []
self._entry_price = 0.0
@property
def lookback(self):
return self._lookback.Value
@property
def atr_period(self):
return self._atr_period.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(geedo_strategy, self).OnReseted()
self._open_history = []
self._entry_price = 0.0
def OnStarted2(self, time):
super(geedo_strategy, self).OnStarted2(time)
atr = StandardDeviation()
atr.Length = self.atr_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(atr, self.on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def on_process(self, candle, atr_val):
if candle.State != CandleStates.Finished:
return
self._open_history.append(candle.OpenPrice)
if len(self._open_history) > self.lookback + 1:
self._open_history.pop(0)
if len(self._open_history) <= self.lookback:
return
if atr_val <= 0:
return
close = candle.ClosePrice
# Exit check
if self.Position > 0 and self._entry_price > 0:
if close <= self._entry_price - atr_val * 2 or close >= self._entry_price + atr_val * 1.5:
self.SellMarket()
self._entry_price = 0
return
elif self.Position < 0 and self._entry_price > 0:
if close >= self._entry_price + atr_val * 2 or close <= self._entry_price - atr_val * 1.5:
self.BuyMarket()
self._entry_price = 0
return
past_open = self._open_history[0]
current_open = self._open_history[-1]
diff = current_open - past_open
# Price rising => long
if diff > atr_val * 0.5 and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
self._entry_price = close
# Price falling => short
elif diff < -atr_val * 0.5 and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._entry_price = close
def CreateClone(self):
return geedo_strategy()