Estrategia Market Slayer
Esta estrategia utiliza un cruce de medias móviles ponderadas con confirmación de tendencia SSL en un marco temporal superior. Se abre una posición larga cuando la WMA corta cruza por encima de la WMA larga con tendencia alcista; se abre una posición corta en condiciones opuestas. Se puede habilitar opcionalmente un take profit y stop loss absolutos.
Detalles
- Criterios de entrada:
- Largo: la WMA corta cruza por encima de la WMA larga y el SSL del marco temporal superior es alcista.
- Corto: la WMA corta cruza por debajo de la WMA larga y el SSL del marco temporal superior es bajista.
- Largo/Corto: Ambos lados.
- Criterios de salida:
- El filtro de tendencia cambia al lado opuesto.
- Stop loss o take profit opcionales cuando están habilitados.
- Stops: Opcional.
- Valores predeterminados:
ShortLength= 10.LongLength= 20.ConfirmationTrendValue= 2.CandleType= TimeSpan.FromMinutes(5).TimeFrame().TrendCandleType= TimeSpan.FromMinutes(240).TimeFrame().TakeProfitEnabled= false.TakeProfitValue= 20.StopLossEnabled= false.StopLossValue= 50.
- Filtros:
- Categoría: Seguimiento de tendencia
- Dirección: Ambos
- Indicadores: WMA, SSL
- Stops: Opcional
- Complejidad: Básico
- Marco temporal: Intradía
- 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;
public class MarketSlayerStrategy : Strategy
{
private readonly StrategyParam<int> _shortLength;
private readonly StrategyParam<int> _longLength;
private readonly StrategyParam<int> _confirmationTrendValue;
private readonly StrategyParam<DataType> _candleType;
private WeightedMovingAverage _trendWmaHigh;
private WeightedMovingAverage _trendWmaLow;
private WeightedMovingAverage _shortWma;
private WeightedMovingAverage _longWma;
private int _trendHlv;
private bool _isTrendBullish;
private decimal? _prevShort;
private decimal? _prevLong;
public int ShortLength { get => _shortLength.Value; set => _shortLength.Value = value; }
public int LongLength { get => _longLength.Value; set => _longLength.Value = value; }
public int ConfirmationTrendValue { get => _confirmationTrendValue.Value; set => _confirmationTrendValue.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public MarketSlayerStrategy()
{
_shortLength = Param(nameof(ShortLength), 10);
_longLength = Param(nameof(LongLength), 20);
_confirmationTrendValue = Param(nameof(ConfirmationTrendValue), 2);
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame());
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_trendWmaHigh = null;
_trendWmaLow = null;
_shortWma = null;
_longWma = null;
_trendHlv = 0;
_isTrendBullish = false;
_prevShort = null;
_prevLong = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_shortWma = new WeightedMovingAverage { Length = ShortLength };
_longWma = new WeightedMovingAverage { Length = LongLength };
_trendWmaHigh = new WeightedMovingAverage { Length = ConfirmationTrendValue };
_trendWmaLow = new WeightedMovingAverage { Length = ConfirmationTrendValue };
_prevShort = _prevLong = null;
_trendHlv = 0;
_isTrendBullish = false;
var subscription = SubscribeCandles(CandleType);
subscription.Bind(_shortWma, _longWma, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal shortWma, decimal longWma)
{
if (candle.State != CandleStates.Finished)
return;
// Update trend using candle high/low
var t = candle.ServerTime;
var highVal = _trendWmaHigh.Process(new DecimalIndicatorValue(_trendWmaHigh, candle.HighPrice, t));
var lowVal = _trendWmaLow.Process(new DecimalIndicatorValue(_trendWmaLow, candle.LowPrice, t));
if (_trendWmaHigh.IsFormed && _trendWmaLow.IsFormed)
{
var high = highVal.ToDecimal();
var low = lowVal.ToDecimal();
if (candle.ClosePrice > high)
_trendHlv = 1;
else if (candle.ClosePrice < low)
_trendHlv = -1;
var sslDown = _trendHlv < 0 ? high : low;
var sslUp = _trendHlv < 0 ? low : high;
_isTrendBullish = sslUp > sslDown;
}
if (!_shortWma.IsFormed || !_longWma.IsFormed)
{
_prevShort = shortWma;
_prevLong = longWma;
return;
}
if (_prevShort.HasValue && _prevLong.HasValue)
{
var crossUp = _prevShort <= _prevLong && shortWma > longWma;
var crossDown = _prevShort >= _prevLong && shortWma < longWma;
if (crossUp && _isTrendBullish && Position <= 0)
BuyMarket();
if (crossDown && !_isTrendBullish && Position >= 0)
SellMarket();
if (Position > 0 && !_isTrendBullish)
SellMarket();
if (Position < 0 && _isTrendBullish)
BuyMarket();
}
_prevShort = shortWma;
_prevLong = longWma;
}
}
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
from StockSharp.Algo.Strategies import Strategy
from indicator_extensions import *
class market_slayer_strategy(Strategy):
def __init__(self):
super(market_slayer_strategy, self).__init__()
self._short_length = self.Param("ShortLength", 10) \
.SetDisplay("Short Length", "Short WMA period", "General")
self._long_length = self.Param("LongLength", 20) \
.SetDisplay("Long Length", "Long WMA period", "General")
self._confirmation_trend_value = self.Param("ConfirmationTrendValue", 2) \
.SetDisplay("Confirmation Trend Value", "Trend WMA period", "General")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._trend_hlv = 0
self._is_trend_bullish = False
self._prev_short = None
self._prev_long = None
@property
def candle_type(self):
return self._candle_type.Value
@candle_type.setter
def candle_type(self, value):
self._candle_type.Value = value
def OnReseted(self):
super(market_slayer_strategy, self).OnReseted()
self._trend_hlv = 0
self._is_trend_bullish = False
self._prev_short = None
self._prev_long = None
def OnStarted2(self, time):
super(market_slayer_strategy, self).OnStarted2(time)
self._trend_hlv = 0
self._is_trend_bullish = False
self._prev_short = None
self._prev_long = None
self._short_wma = WeightedMovingAverage()
self._short_wma.Length = self._short_length.Value
self._long_wma = WeightedMovingAverage()
self._long_wma.Length = self._long_length.Value
self._trend_wma_high = WeightedMovingAverage()
self._trend_wma_high.Length = self._confirmation_trend_value.Value
self._trend_wma_low = WeightedMovingAverage()
self._trend_wma_low.Length = self._confirmation_trend_value.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(self._short_wma, self._long_wma, self.OnProcess).Start()
def OnProcess(self, candle, short_wma, long_wma):
if candle.State != CandleStates.Finished:
return
t = candle.ServerTime
high_result = process_float(self._trend_wma_high, candle.HighPrice, t, True)
low_result = process_float(self._trend_wma_low, candle.LowPrice, t, True)
if self._trend_wma_high.IsFormed and self._trend_wma_low.IsFormed:
high_v = float(high_result)
low_v = float(low_result)
close = float(candle.ClosePrice)
if close > high_v:
self._trend_hlv = 1
elif close < low_v:
self._trend_hlv = -1
if self._trend_hlv < 0:
ssl_down = high_v
ssl_up = low_v
else:
ssl_down = low_v
ssl_up = high_v
self._is_trend_bullish = ssl_up > ssl_down
sv = float(short_wma)
lv = float(long_wma)
if not self._short_wma.IsFormed or not self._long_wma.IsFormed:
self._prev_short = sv
self._prev_long = lv
return
if self._prev_short is not None and self._prev_long is not None:
cross_up = self._prev_short <= self._prev_long and sv > lv
cross_down = self._prev_short >= self._prev_long and sv < lv
if cross_up and self._is_trend_bullish and self.Position <= 0:
self.BuyMarket()
if cross_down and not self._is_trend_bullish and self.Position >= 0:
self.SellMarket()
if self.Position > 0 and not self._is_trend_bullish:
self.SellMarket()
if self.Position < 0 and self._is_trend_bullish:
self.BuyMarket()
self._prev_short = sv
self._prev_long = lv
def CreateClone(self):
return market_slayer_strategy()