Alineación EMA 10/20/50
Esta estrategia solo largos entra cuando EMA(10) > EMA(20) > EMA(50) y sale cuando las EMA se alinean en orden descendente. El trading está restringido a un rango de fechas configurable.
Detalles
- Criterios de entrada: EMA(10) por encima de EMA(20) por encima de EMA(50) dentro del rango de fechas especificado.
- Largo/Corto: Solo largos.
- Criterios de salida: Las EMA se alinean a la baja (EMA(10) < EMA(20) < EMA(50)).
- Stops: No.
- Valores predeterminados:
StartTime= new DateTimeOffset(2023, 5, 17, 0, 0, 0, TimeSpan.Zero)EndTime= new DateTimeOffset(2025, 5, 17, 0, 0, 0, TimeSpan.Zero)CandleType= TimeSpan.FromMinutes(1)
- Filtros:
- Categoría: Tendencia
- Dirección: Largo
- Indicadores: EMA
- Stops: No
- Complejidad: Principiante
- Marco temporal: Intradía
- Estacionalidad: No
- Redes neuronales: No
- Divergencia: No
- Nivel de riesgo: Bajo
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>
/// EMA 10/20/50 alignment strategy.
/// Long only: buys when EMA(10) is above EMA(20) and EMA(20) is above EMA(50) and closes the long when the three EMAs align
/// in descending order. Entries are allowed only for candles between StartTime and EndTime.
/// </summary>
public class Ema102050AlignmentStrategy : Strategy
{
private readonly StrategyParam<DateTimeOffset> _startTime;
private readonly StrategyParam<DateTimeOffset> _endTime;
private readonly StrategyParam<DataType> _candleType;
/// <summary>
/// Start of the trading date range.
/// </summary>
public DateTimeOffset StartTime
{
get => _startTime.Value;
set => _startTime.Value = value;
}
/// <summary>
/// End of the trading date range.
/// </summary>
public DateTimeOffset EndTime
{
get => _endTime.Value;
set => _endTime.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public Ema102050AlignmentStrategy()
{
_startTime = Param(nameof(StartTime), new DateTimeOffset(2023, 5, 17, 0, 0, 0, TimeSpan.Zero))
.SetDisplay("Start Time", "Start of the trading date range", "General");
_endTime = Param(nameof(EndTime), new DateTimeOffset(2025, 5, 17, 0, 0, 0, TimeSpan.Zero))
.SetDisplay("End Time", "End of the trading date range", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(1).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var ema10 = new ExponentialMovingAverage { Length = 10 };
var ema20 = new ExponentialMovingAverage { Length = 20 };
var ema50 = new ExponentialMovingAverage { Length = 50 };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ema10, ema20, ema50, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, ema10);
DrawIndicator(area, ema20);
DrawIndicator(area, ema50);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal ema10, decimal ema20, decimal ema50)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var inRange = candle.OpenTime >= StartTime.UtcDateTime && candle.OpenTime <= EndTime.UtcDateTime;
if (Position <= 0 && inRange && ema10 > ema20 && ema20 > ema50)
BuyMarket(Volume + Math.Abs(Position));
else if (Position > 0 && ema10 < ema20 && ema20 < ema50)
SellMarket(Position);
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, DateTimeOffset
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class ema_10_20_50_alignment_strategy(Strategy):
"""
EMA 10/20/50 alignment strategy.
Long only: buys when EMA(10) is above EMA(20) and EMA(20) is above EMA(50) and closes the long when the three EMAs align
in descending order. Entries are allowed only for candles between StartTime and EndTime.
"""
def __init__(self):
super(ema_10_20_50_alignment_strategy, self).__init__()
self._start_time = self.Param("StartTime", DateTimeOffset(2023, 5, 17, 0, 0, 0, TimeSpan.Zero)).SetDisplay("Start Time", "Start of the trading date range", "General")
self._end_time = self.Param("EndTime", DateTimeOffset(2025, 5, 17, 0, 0, 0, TimeSpan.Zero)).SetDisplay("End Time", "End of the trading date range", "General")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(1))).SetDisplay("Candle Type", "Type of candles to use", "General")
@property
def candle_type(self):
return self._candle_type.Value
def OnStarted2(self, time):
super(ema_10_20_50_alignment_strategy, self).OnStarted2(time)
ema10 = ExponentialMovingAverage()
ema10.Length = 10
ema20 = ExponentialMovingAverage()
ema20.Length = 20
ema50 = ExponentialMovingAverage()
ema50.Length = 50
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(ema10, ema20, ema50, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ema10)
self.DrawIndicator(area, ema20)
self.DrawIndicator(area, ema50)
self.DrawOwnTrades(area)
def _process_candle(self, candle, ema10_value, ema20_value, ema50_value):
if candle.State != CandleStates.Finished:
return
if not self.IsFormedAndOnlineAndAllowTrading():
return
ema10 = float(ema10_value)
ema20 = float(ema20_value)
ema50 = float(ema50_value)
open_ticks = candle.OpenTime.Ticks
in_range = self._start_time.Value.UtcDateTime.Ticks <= open_ticks <= self._end_time.Value.UtcDateTime.Ticks
if self.Position <= 0 and in_range and ema10 > ema20 and ema20 > ema50:
self.BuyMarket(self.Volume + abs(self.Position))
elif self.Position > 0 and ema10 < ema20 and ema20 < ema50:
self.SellMarket(self.Position)
def CreateClone(self):
return ema_10_20_50_alignment_strategy()