Estrategia de seguimiento de tendencia que combina el Parabolic SAR con un filtro ADX. Las operaciones largas ocurren cuando el precio cierra por encima del valor SAR mientras el ADX permanece por debajo de un umbral, señalando una tendencia naciente. Las operaciones cortas se abren en la condición opuesta.
Detalles
Criterios de entrada: Precio por encima/debajo del Parabolic SAR con ADX por debajo de AdxLevel.
Largo/Corto: Ambos direcciones.
Criterios de salida: Stop loss, take profit o señal opuesta.
Stops: Stop loss fijo, take profit y ajuste de break-even.
Valores predeterminados:
SarStep = 0.02
SarMax = 0.2
AdxPeriod = 14
AdxLevel = 20
StopLoss = 1800 puntos
TakeProfit = 500 puntos
BreakEven = 50 puntos
CandleType = TimeSpan.FromMinutes(1)
Filtros:
Categoría: Tendencia
Dirección: Ambos
Indicadores: Parabolic SAR, ADX
Stops: Sí
Complejidad: Básico
Marco temporal: Intradía (1m)
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>
/// Trend following strategy using Parabolic SAR with EMA confirmation.
/// </summary>
public class TrendCaptureStrategy : Strategy
{
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevClose;
private decimal _prevEma;
private decimal _prevSar;
private bool _hasPrev;
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public TrendCaptureStrategy()
{
_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", "Type of candles", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_prevClose = 0;
_prevEma = 0;
_prevSar = 0;
_hasPrev = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var sar = new ParabolicSar();
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
SubscribeCandles(CandleType).Bind(sar, ema, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal sarValue, decimal emaValue)
{
if (candle.State != CandleStates.Finished) return;
var close = candle.ClosePrice;
if (!_hasPrev)
{
_prevClose = close;
_prevEma = emaValue;
_prevSar = sarValue;
_hasPrev = true;
return;
}
var aboveSar = close > sarValue;
var belowSar = close < sarValue;
var prevAboveSar = _prevClose > _prevSar;
var prevBelowSar = _prevClose < _prevSar;
if (!prevAboveSar && aboveSar && close > emaValue && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (!prevBelowSar && belowSar && close < emaValue && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
_prevClose = close;
_prevEma = emaValue;
_prevSar = sarValue;
}
}
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 ParabolicSar, ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class trend_capture_strategy(Strategy):
def __init__(self):
super(trend_capture_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", "Type of candles", "General")
self._prev_close = 0.0
self._prev_ema = 0.0
self._prev_sar = 0.0
self._has_prev = False
@property
def ema_period(self):
return self._ema_period.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(trend_capture_strategy, self).OnReseted()
self._prev_close = 0.0
self._prev_ema = 0.0
self._prev_sar = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(trend_capture_strategy, self).OnStarted2(time)
sar = ParabolicSar()
ema = ExponentialMovingAverage()
ema.Length = self.ema_period
self.SubscribeCandles(self.candle_type).Bind(sar, ema, self.process_candle).Start()
def process_candle(self, candle, sar_value, ema_value):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
sv = float(sar_value)
ev = float(ema_value)
if not self._has_prev:
self._prev_close = close
self._prev_ema = ev
self._prev_sar = sv
self._has_prev = True
return
above_sar = close > sv
below_sar = close < sv
prev_above_sar = self._prev_close > self._prev_sar
prev_below_sar = self._prev_close < self._prev_sar
if not prev_above_sar and above_sar and close > ev and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif not prev_below_sar and below_sar and close < ev and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_close = close
self._prev_ema = ev
self._prev_sar = sv
def CreateClone(self):
return trend_capture_strategy()