Una estrategia de seguimiento de tendencia basada en el indicador SilverTrend personalizado. El indicador construye un canal de precios dinámico utilizando el máximo más alto y el mínimo más bajo en una ventana de lookback y un factor de riesgo. Una señal de trading ocurre cuando el precio cruza el canal y la dirección de la tendencia se revierte.
Detalles
Entrada: Comprar cuando el indicador cambia a una tendencia alcista. Vender cuando el indicador cambia a una tendencia bajista.
Salida: La posición se revierte en la señal opuesta.
Indicadores: Highest, Lowest, SimpleMovingAverage (dentro del cálculo de SilverTrend).
Stops: Ninguno.
Valores predeterminados:
Ssp = 9 — número de barras para el cálculo del canal.
Risk = 3 — porcentaje que reduce el ancho del canal.
CandleType = velas de 1 hora.
Dirección: Tanto largo como corto.
El indicador SilverTrend calcula el rango promedio de máximos y mínimos durante Ssp + 1 barras y encuentra el máximo más alto y el mínimo más bajo durante Ssp barras. Los límites del canal son:
Si el cierre cae por debajo de smin, la tendencia se vuelve bajista. Si el cierre sube por encima de smax, la tendencia se vuelve alcista. Se genera una señal cuando la tendencia cambia, y la estrategia invierte inmediatamente su posición en consecuencia.
using System;
using System.Linq;
using System.Collections.Generic;
using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Strategy based on SilverTrend indicator -- trades reversals based on
/// price channel breakouts with a risk-based filter.
/// </summary>
public class SilverTrendStrategy : Strategy
{
private readonly StrategyParam<int> _ssp;
private readonly StrategyParam<int> _risk;
private readonly StrategyParam<DataType> _candleType;
private Highest _highest;
private Lowest _lowest;
private bool? _uptrend;
private bool? _prevUptrend;
public int Ssp { get => _ssp.Value; set => _ssp.Value = value; }
public int Risk { get => _risk.Value; set => _risk.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public SilverTrendStrategy()
{
_ssp = Param(nameof(Ssp), 9)
.SetGreaterThanZero()
.SetDisplay("SSP", "Lookback length for price channel", "Indicator");
_risk = Param(nameof(Risk), 3)
.SetGreaterThanZero()
.SetDisplay("Risk", "Risk factor used to tighten the channel", "Indicator");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Timeframe for indicator", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_highest = null;
_lowest = null;
_uptrend = null;
_prevUptrend = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_highest = new Highest { Length = Ssp };
_lowest = new Lowest { Length = Ssp };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(_highest, _lowest, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal maxHigh, decimal minLow)
{
if (candle.State != CandleStates.Finished)
return;
if (!_highest.IsFormed || !_lowest.IsFormed)
return;
var k = 33 - Risk;
var smin = minLow + (maxHigh - minLow) * k / 100m;
var smax = maxHigh - (maxHigh - minLow) * k / 100m;
var uptrend = _uptrend ?? false;
if (candle.ClosePrice < smin)
uptrend = false;
else if (candle.ClosePrice > smax)
uptrend = true;
var reversed = _uptrend is not null && uptrend != _uptrend;
if (IsFormedAndOnlineAndAllowTrading() && reversed)
{
if (uptrend && Position <= 0)
BuyMarket();
else if (!uptrend && Position >= 0)
SellMarket();
}
_prevUptrend = _uptrend;
_uptrend = uptrend;
}
}
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 Highest, Lowest
from StockSharp.Algo.Strategies import Strategy
class silver_trend_strategy(Strategy):
def __init__(self):
super(silver_trend_strategy, self).__init__()
self._ssp = self.Param("Ssp", 9) \
.SetDisplay("SSP", "Lookback length for price channel", "Indicator")
self._risk = self.Param("Risk", 3) \
.SetDisplay("Risk", "Risk factor used to tighten the channel", "Indicator")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Timeframe for indicator", "General")
self._uptrend = None
@property
def ssp(self):
return self._ssp.Value
@property
def risk(self):
return self._risk.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(silver_trend_strategy, self).OnReseted()
self._uptrend = None
def OnStarted2(self, time):
super(silver_trend_strategy, self).OnStarted2(time)
highest = Highest()
highest.Length = self.ssp
lowest = Lowest()
lowest.Length = self.ssp
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(highest, lowest, self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def process_candle(self, candle, max_high, min_low):
if candle.State != CandleStates.Finished:
return
max_high = float(max_high)
min_low = float(min_low)
k = 33 - self.risk
smin = min_low + (max_high - min_low) * k / 100.0
smax = max_high - (max_high - min_low) * k / 100.0
close = float(candle.ClosePrice)
uptrend = self._uptrend if self._uptrend is not None else False
if close < smin:
uptrend = False
elif close > smax:
uptrend = True
reversed_trend = self._uptrend is not None and uptrend != self._uptrend
if reversed_trend:
if uptrend and self.Position <= 0:
self.BuyMarket()
elif not uptrend and self.Position >= 0:
self.SellMarket()
self._uptrend = uptrend
def CreateClone(self):
return silver_trend_strategy()