Estrategia de Seguimiento de Tendencia con Parabolic Compra Venta
Combina Parabolic SAR con cruces de medias móviles.
Las entradas largas ocurren cuando el precio está por encima de una SMA de tendencia larga, la EMA rápida cruza por encima de la EMA lenta y el SAR es alcista.
Las entradas cortas usan las condiciones opuestas.
El stop loss se coloca en la SMA de tendencia y el take profit usa una ratio riesgo/recompensa.
Detalles
Entrada:
Largo: precio > SMA de tendencia, EMA rápida cruza por encima de EMA lenta, SAR alcista
Corto: precio < SMA de tendencia, EMA rápida cruza por debajo de EMA lenta, SAR bajista
Salida:
stop en SMA de tendencia
take profit = riesgo/recompensa * distancia desde entrada hasta SMA de tendencia
Indicadores: Parabolic SAR, SMA, EMA
Marco temporal: configurable
Tipo: Seguimiento de tendencia
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 Parabolic Buy Sell strategy using EMA crossover.
/// </summary>
public class TrendFollowingParabolicBuySellStrategy : Strategy
{
private readonly StrategyParam<int> _slowLength;
private readonly StrategyParam<DataType> _candleType;
public int SlowLength { get => _slowLength.Value; set => _slowLength.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public TrendFollowingParabolicBuySellStrategy()
{
_slowLength = Param(nameof(SlowLength), 40)
.SetGreaterThanZero()
.SetDisplay("Slow Length", "Slow EMA period", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Candle type", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var fast = new ExponentialMovingAverage { Length = 14 };
var slow = new ExponentialMovingAverage { Length = SlowLength };
var prevF = 0m; var prevS = 0m; var init = false;
var lastSignal = DateTimeOffset.MinValue;
var cooldown = TimeSpan.FromMinutes(360);
var subscription = SubscribeCandles(CandleType);
subscription.Bind(fast, slow, (candle, f, s) =>
{
if (candle.State != CandleStates.Finished) return;
if (!fast.IsFormed || !slow.IsFormed) return;
if (!init) { prevF = f; prevS = s; init = true; return; }
if (candle.OpenTime - lastSignal >= cooldown)
{
if (prevF <= prevS && f > s && Position <= 0) { BuyMarket(); lastSignal = candle.OpenTime; }
else if (prevF >= prevS && f < s && Position >= 0) { SellMarket(); lastSignal = candle.OpenTime; }
}
prevF = f; prevS = s;
}).Start();
var area = CreateChartArea();
if (area != null) { DrawCandles(area, subscription); DrawIndicator(area, fast); DrawIndicator(area, slow); 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, DateTime
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class trend_following_parabolic_buy_sell_strategy(Strategy):
def __init__(self):
super(trend_following_parabolic_buy_sell_strategy, self).__init__()
self._slow_length = self.Param("SlowLength", 40) .SetDisplay("Slow Length", "Slow EMA period", "General")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) .SetDisplay("Candle Type", "Candle type", "General")
@property
def slow_length(self):
return self._slow_length.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnStarted2(self, time):
super(trend_following_parabolic_buy_sell_strategy, self).OnStarted2(time)
fast = ExponentialMovingAverage()
fast.Length = 14
slow = ExponentialMovingAverage()
slow.Length = self.slow_length
self._prev_f = 0.0
self._prev_s = 0.0
self._init = False
self._last_signal = DateTime.MinValue
self._cooldown = TimeSpan.FromMinutes(360)
subscription = self.SubscribeCandles(self.candle_type)
def on_candle(candle, f, s):
if candle.State != CandleStates.Finished:
return
if not fast.IsFormed or not slow.IsFormed:
return
fv = float(f)
sv = float(s)
if not self._init:
self._prev_f = fv
self._prev_s = sv
self._init = True
return
if candle.OpenTime - self._last_signal >= self._cooldown:
if self._prev_f <= self._prev_s and fv > sv and self.Position <= 0:
self.BuyMarket()
self._last_signal = candle.OpenTime
elif self._prev_f >= self._prev_s and fv < sv and self.Position >= 0:
self.SellMarket()
self._last_signal = candle.OpenTime
self._prev_f = fv
self._prev_s = sv
subscription.Bind(fast, slow, on_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, fast)
self.DrawIndicator(area, slow)
self.DrawOwnTrades(area)
def CreateClone(self):
return trend_following_parabolic_buy_sell_strategy()