La estrategia Sobres de 5 minutos reproduce el experto MetaTrader que intercambia velas de cinco minutos alrededor de una envolvente de media móvil ponderada lineal.
Busca picos de precios que se extienden mucho más allá de las bandas y luego entra en la dirección de reversión a la media.
Un filtro de diferencial, un stop-loss estático, un take-profit opcional y un trailing stop reflejan la gestión del dinero original.
Lógica de trading
Indicador: Media Móvil Lineal Ponderada (LWMA) calculada sobre el precio medio (alto+bajo)/2 con un periodo de 3.
Ancho del sobre: 0,05% de desviación del valor LWMA (bandas superior e inferior).
Detección de señal (evaluada según la vela completada anteriormente y la oferta actual):
Largo: el mínimo de la vela anterior se mantiene a más de DistancePoints por debajo de la banda inferior y la oferta actual también está más allá de esa distancia.
Corto: el máximo de la vela anterior se mantiene a más de DistancePoints por encima de la banda superior y la oferta actual también está más allá de esa distancia.
Filtros:
Sólo una posición a la vez (las nuevas entradas requieren que la posición actual sea plana).
Si MaxSpreadPoints es mayor que cero, el diferencial entre oferta y demanda debe permanecer por debajo de este umbral antes de enviar un nuevo pedido.
Gestión del riesgo
Volumen de orden: el parámetro TradeVolume controla el tamaño de la orden de mercado.
Stop-loss: StopLossPoints convierte a distancia de precio absoluta utilizando el tamaño del tick del instrumento.
Take-profit: Optional TakeProfitPoints; póngalo en cero para desactivarlo.
Trailing stop: Optional TrailingStopPoints; póngalo en cero para desactivarlo.
Protección: El asistente StartProtection aplica todas las salidas con órdenes de mercado, coincidiendo con el comportamiento de MetaTrader.
Parámetros
TradeVolume = 1m
DistancePoints = 140
EnvelopePeriod = 3
EnvelopeDeviationPercent = 0.05m
StopLossPoints = 250
TakeProfitPoints = 0
TrailingStopPoints = 120
MaxSpreadPoints = 25
CandleType = TimeFrame(5 minutes)
Etiquetas
Categoría: Reversión a la media
Dirección: Ambos
Indicators: WeightedMovingAverage
Stops: Yes (fixed + trailing)
Plazo: Intradiario (M5)
Complejidad: Principiante
Nivel de riesgo: medio
Estacionalidad: No
Redes neuronales: No
Divergencia: No
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// 5 Mins Envelopes strategy: envelope breakout using SMA with deviation bands.
/// Buys when price crosses above upper envelope, sells when below lower envelope.
/// </summary>
public class FiveMinsEnvelopesStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _maPeriod;
private readonly StrategyParam<decimal> _deviation;
private bool _wasAboveUpper;
private bool _wasBelowLower;
private bool _hasPrevSignal;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int MaPeriod { get => _maPeriod.Value; set => _maPeriod.Value = value; }
public decimal Deviation { get => _deviation.Value; set => _deviation.Value = value; }
public FiveMinsEnvelopesStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_maPeriod = Param(nameof(MaPeriod), 50)
.SetGreaterThanZero()
.SetDisplay("MA Period", "Moving average period", "Indicators");
_deviation = Param(nameof(Deviation), 0.3m)
.SetDisplay("Deviation %", "Envelope deviation percent", "Indicators");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_wasAboveUpper = false;
_wasBelowLower = false;
_hasPrevSignal = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrevSignal = false;
var sma = new SimpleMovingAverage { Length = MaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(sma, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal smaValue)
{
if (candle.State != CandleStates.Finished) return;
var close = candle.ClosePrice;
var upper = smaValue * (1 + Deviation / 100m);
var lower = smaValue * (1 - Deviation / 100m);
var aboveUpper = close > upper;
var belowLower = close < lower;
if (_hasPrevSignal)
{
if (aboveUpper && !_wasAboveUpper && Position <= 0)
BuyMarket();
else if (belowLower && !_wasBelowLower && Position >= 0)
SellMarket();
}
_wasAboveUpper = aboveUpper;
_wasBelowLower = belowLower;
_hasPrevSignal = true;
}
}
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 SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
class five_mins_envelopes_strategy(Strategy):
def __init__(self):
super(five_mins_envelopes_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(30)))
self._ma_period = self.Param("MaPeriod", 50)
self._deviation = self.Param("Deviation", 0.3)
self._was_above_upper = False
self._was_below_lower = False
self._has_prev_signal = False
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def MaPeriod(self):
return self._ma_period.Value
@MaPeriod.setter
def MaPeriod(self, value):
self._ma_period.Value = value
@property
def Deviation(self):
return self._deviation.Value
@Deviation.setter
def Deviation(self, value):
self._deviation.Value = value
def OnReseted(self):
super(five_mins_envelopes_strategy, self).OnReseted()
self._was_above_upper = False
self._was_below_lower = False
self._has_prev_signal = False
def OnStarted2(self, time):
super(five_mins_envelopes_strategy, self).OnStarted2(time)
self._has_prev_signal = False
sma = SimpleMovingAverage()
sma.Length = self.MaPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(sma, self._process_candle).Start()
def _process_candle(self, candle, sma_value):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
sma_val = float(sma_value)
upper = sma_val * (1 + float(self.Deviation) / 100.0)
lower = sma_val * (1 - float(self.Deviation) / 100.0)
above_upper = close > upper
below_lower = close < lower
if self._has_prev_signal:
if above_upper and not self._was_above_upper and self.Position <= 0:
self.BuyMarket()
elif below_lower and not self._was_below_lower and self.Position >= 0:
self.SellMarket()
self._was_above_upper = above_upper
self._was_below_lower = below_lower
self._has_prev_signal = True
def CreateClone(self):
return five_mins_envelopes_strategy()