Esta estrategia abre una sola operación por día a una hora especificada basándose en la diferencia entre las aperturas de velas pasadas.
Cómo Funciona
Esperar el Momento de Operar: La estrategia monitorea los tiempos de apertura de velas. Una vez que la hora es mayor que TradeTime, el trading se permite en la próxima ocurrencia de esa hora.
Generación de Señales:
Cuando la hora actual es igual a TradeTime, la estrategia compara el precio de apertura de hace t1 barras con el precio de apertura de hace t2 barras.
Si la diferencia Open[t1] - Open[t2] supera DeltaShort puntos, se abre una posición corta.
Si la diferencia Open[t2] - Open[t1] supera DeltaLong puntos, se abre una posición larga.
Gestión de Posiciones:
Para posiciones largas, la estrategia sale cuando el precio alcanza TakeProfitLong por encima de la entrada o StopLossLong por debajo.
Para posiciones cortas, sale cuando el precio se mueve TakeProfitShort por debajo o StopLossShort por encima de la entrada.
Las posiciones también se cierran si permanecen abiertas más de MaxOpenTime horas.
La estrategia opera con un volumen fijo y no entra en nuevas operaciones hasta el día siguiente.
Parámetros
Nombre
Descripción
CandleType
Fuente de velas para la estrategia.
Volume
Volumen de la orden.
TakeProfitLong
Toma de ganancias en puntos para operaciones largas.
StopLossLong
Stop loss en puntos para operaciones largas.
TakeProfitShort
Toma de ganancias en puntos para operaciones cortas.
StopLossShort
Stop loss en puntos para operaciones cortas.
TradeTime
Hora del día en que se evalúan las señales.
T1
Número de barras hacia atrás para el primer precio de apertura.
T2
Número de barras hacia atrás para el segundo precio de apertura.
DeltaLong
Diferencia mínima (en puntos) entre Open[t2] y Open[t1] para abrir una operación larga.
DeltaShort
Diferencia mínima (en puntos) entre Open[t1] y Open[t2] para abrir una operación corta.
MaxOpenTime
Tiempo máximo de mantenimiento en horas.
Notas
Solo se procesan velas completadas.
La estrategia usa el paso de precio del instrumento para convertir umbrales basados en puntos en precios absolutos.
No se utilizan indicadores adicionales.
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>
/// Scalping strategy comparing past open prices with EMA trend filter.
/// </summary>
public class LotScalpStrategy : Strategy
{
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevOpen;
private decimal _prevPrevOpen;
private int _barCount;
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public LotScalpStrategy()
{
_emaPeriod = Param(nameof(EmaPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("EMA Period", "EMA period for trend", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle source", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_prevOpen = 0;
_prevPrevOpen = 0;
_barCount = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
SubscribeCandles(CandleType).Bind(ema, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal emaValue)
{
if (candle.State != CandleStates.Finished) return;
_barCount++;
var close = candle.ClosePrice;
var open = candle.OpenPrice;
if (_barCount >= 3)
{
var diff = _prevPrevOpen - _prevOpen;
// Open prices diverging downward + close above EMA => buy
if (diff > 0 && close > emaValue && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
// Open prices diverging upward + close below EMA => sell
else if (diff < 0 && close < emaValue && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
}
_prevPrevOpen = _prevOpen;
_prevOpen = open;
}
}
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 ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class lot_scalp_strategy(Strategy):
def __init__(self):
super(lot_scalp_strategy, self).__init__()
self._ema_period = self.Param("EmaPeriod", 20) \
.SetDisplay("EMA Period", "EMA period for trend", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candle source", "General")
self._prev_open = 0.0
self._prev_prev_open = 0.0
self._bar_count = 0
@property
def ema_period(self):
return self._ema_period.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(lot_scalp_strategy, self).OnReseted()
self._prev_open = 0.0
self._prev_prev_open = 0.0
self._bar_count = 0
def OnStarted2(self, time):
super(lot_scalp_strategy, self).OnStarted2(time)
ema = ExponentialMovingAverage()
ema.Length = self.ema_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(ema, self.on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def on_process(self, candle, ema_value):
if candle.State != CandleStates.Finished:
return
self._bar_count += 1
close = candle.ClosePrice
open = candle.OpenPrice
if self._bar_count >= 3:
diff = self._prev_prev_open - self._prev_open
# Open prices diverging downward + close above EMA => buy
if diff > 0 and close > ema_value and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
# Open prices diverging upward + close below EMA => sell
elif diff < 0 and close < ema_value and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_prev_open = self._prev_open
self._prev_open = open
def CreateClone(self):
return lot_scalp_strategy()