Esta estrategia monitorea una media móvil simple (MA) y cierra automáticamente cualquier posición abierta cuando el cierre de la vela cruza la línea de la MA. Está diseñada para traders que gestionan las entradas manualmente o con otros sistemas, pero quieren una salida automatizada cuando el tendencia se invierte.
La lógica rastrea la relación entre el precio de cierre y la MA. Cuando una nueva vela finalizada cruza de un lado de la MA al otro, la estrategia envía una orden de mercado para cerrar la posición. No se abren nuevas posiciones.
Detalles
Criterios de entrada: Ninguno. Las posiciones deben abrirse externamente.
Criterios de salida:
Largo: Cierre anterior por encima de la MA y cierre actual por debajo de la MA activa una venta para cerrar.
Corto: Cierre anterior por debajo de la MA y cierre actual por encima de la MA activa una compra para cerrar.
Largo/Corto: Se soportan ambas direcciones.
Stops: No se usan. El cruce de la MA actúa como señal de salida.
Valores predeterminados:
MA Period = 50.
Candle Type = Marco temporal de 1 minuto.
Filtros:
Categoría: Seguimiento de tendencia
Dirección: Ambos
Indicadores: Único
Stops: No
Complejidad: Simple
Marco temporal: Cualquiera
Estacionalidad: No
Redes neuronales: No
Divergencia: No
Nivel de riesgo: Moderado
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>
/// Price cross MA strategy.
/// </summary>
public class CloseCrossMaStrategy : Strategy
{
private readonly StrategyParam<int> _maPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevDiff;
private bool _hasPrev;
public int MaPeriod { get => _maPeriod.Value; set => _maPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public CloseCrossMaStrategy()
{
_maPeriod = Param(nameof(MaPeriod), 50)
.SetGreaterThanZero()
.SetDisplay("MA Period", "EMA period", "Parameters");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle type", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_prevDiff = 0;
_hasPrev = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var ema = new ExponentialMovingAverage { Length = MaPeriod };
SubscribeCandles(CandleType)
.Bind(ema, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal emaVal)
{
if (candle.State != CandleStates.Finished) return;
var diff = candle.ClosePrice - emaVal;
if (!_hasPrev)
{
_prevDiff = diff;
_hasPrev = true;
return;
}
// Price crosses above EMA
if (_prevDiff <= 0 && diff > 0 && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
// Price crosses below EMA
else if (_prevDiff >= 0 && diff < 0 && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
_prevDiff = diff;
}
}
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 ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class close_cross_ma_strategy(Strategy):
def __init__(self):
super(close_cross_ma_strategy, self).__init__()
self._ma_period = self.Param("MaPeriod", 50) \
.SetDisplay("MA Period", "EMA period", "Parameters")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candle type", "General")
self._prev_diff = 0.0
self._has_prev = False
@property
def ma_period(self):
return self._ma_period.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(close_cross_ma_strategy, self).OnReseted()
self._prev_diff = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(close_cross_ma_strategy, self).OnStarted2(time)
ema = ExponentialMovingAverage()
ema.Length = self.ma_period
self.SubscribeCandles(self.candle_type).Bind(ema, self.process_candle).Start()
def process_candle(self, candle, ema_val):
if candle.State != CandleStates.Finished:
return
diff = float(candle.ClosePrice) - float(ema_val)
if not self._has_prev:
self._prev_diff = diff
self._has_prev = True
return
if self._prev_diff <= 0 and diff > 0 and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif self._prev_diff >= 0 and diff < 0 and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_diff = diff
def CreateClone(self):
return close_cross_ma_strategy()