Estrategia de Línea de Activación (Trigger Line)
La estrategia Trigger Line combina una línea de tendencia ponderada con una media móvil de mínimos cuadrados (LSMA). Se abre una posición larga cuando la línea de tendencia ponderada cruza por encima de la LSMA, mientras que se abre una posición corta cuando cruza por debajo.
Cómo funciona
- Entrada larga: la línea de tendencia ponderada cruza por encima de la LSMA.
- Salida larga: la línea de tendencia ponderada cruza por debajo de la LSMA.
- Entrada corta: la línea de tendencia ponderada cruza por debajo de la LSMA.
- Salida corta: la línea de tendencia ponderada cruza por encima de la LSMA.
- Indicadores: Media Móvil Ponderada, Regresión Lineal (LSMA).
Parámetros
- WT Period – período de retroceso para la línea de tendencia ponderada.
- LSMA Period – período de suavizado para la LSMA.
- Candle Type – marco temporal de las velas utilizadas para los cálculos.
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>
/// Trigger Line cross strategy based on weighted trend line and LSMA.
/// </summary>
public class TriggerLineStrategy : Strategy
{
private readonly StrategyParam<int> _wmaPeriod;
private readonly StrategyParam<int> _lsmaPeriod;
private readonly StrategyParam<DataType> _candleType;
private WeightedMovingAverage _wma;
private LinearReg _lsma;
private bool _initialized;
private decimal _prevLine;
private decimal _prevSignal;
public TriggerLineStrategy()
{
_wmaPeriod = Param(nameof(WmaPeriod), 24)
.SetDisplay("WT Period", "Period for weighted trend line", "Trigger Line");
_lsmaPeriod = Param(nameof(LsmaPeriod), 6)
.SetDisplay("LSMA Period", "Period for least squares moving average", "Trigger Line");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Candle type used for the strategy", "General");
}
public int WmaPeriod
{
get => _wmaPeriod.Value;
set => _wmaPeriod.Value = value;
}
public int LsmaPeriod
{
get => _lsmaPeriod.Value;
set => _lsmaPeriod.Value = value;
}
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_initialized = false;
_prevLine = 0m;
_prevSignal = 0m;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_initialized = false;
_prevLine = 0m;
_prevSignal = 0m;
_wma = new WeightedMovingAverage { Length = WmaPeriod };
_lsma = new LinearReg { Length = LsmaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(_wma, _lsma, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal wmaValue, decimal lsmaValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!_initialized)
{
_prevLine = wmaValue;
_prevSignal = lsmaValue;
_initialized = true;
return;
}
if (!IsFormedAndOnlineAndAllowTrading())
{
_prevLine = wmaValue;
_prevSignal = lsmaValue;
return;
}
var crossUp = _prevLine <= _prevSignal && wmaValue > lsmaValue;
var crossDown = _prevLine >= _prevSignal && wmaValue < lsmaValue;
if (crossUp && Position <= 0)
BuyMarket();
else if (crossDown && Position >= 0)
SellMarket();
_prevLine = wmaValue;
_prevSignal = lsmaValue;
}
}
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 WeightedMovingAverage, LinearReg
from StockSharp.Algo.Strategies import Strategy
class trigger_line_strategy(Strategy):
def __init__(self):
super(trigger_line_strategy, self).__init__()
self._wma_period = self.Param("WmaPeriod", 24) \
.SetDisplay("WT Period", "Period for weighted trend line", "Trigger Line")
self._lsma_period = self.Param("LsmaPeriod", 6) \
.SetDisplay("LSMA Period", "Period for least squares moving average", "Trigger Line")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Candle type used for the strategy", "General")
self._initialized = False
self._prev_line = 0.0
self._prev_signal = 0.0
@property
def wma_period(self):
return self._wma_period.Value
@property
def lsma_period(self):
return self._lsma_period.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(trigger_line_strategy, self).OnReseted()
self._initialized = False
self._prev_line = 0.0
self._prev_signal = 0.0
def OnStarted2(self, time):
super(trigger_line_strategy, self).OnStarted2(time)
self._initialized = False
self._prev_line = 0.0
self._prev_signal = 0.0
wma = WeightedMovingAverage()
wma.Length = int(self.wma_period)
lsma = LinearReg()
lsma.Length = int(self.lsma_period)
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(wma, lsma, self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def process_candle(self, candle, wma_value, lsma_value):
if candle.State != CandleStates.Finished:
return
wma_value = float(wma_value)
lsma_value = float(lsma_value)
if not self._initialized:
self._prev_line = wma_value
self._prev_signal = lsma_value
self._initialized = True
return
cross_up = self._prev_line <= self._prev_signal and wma_value > lsma_value
cross_down = self._prev_line >= self._prev_signal and wma_value < lsma_value
if cross_up and self.Position <= 0:
self.BuyMarket()
elif cross_down and self.Position >= 0:
self.SellMarket()
self._prev_line = wma_value
self._prev_signal = lsma_value
def CreateClone(self):
return trigger_line_strategy()