Estrategia Corta de Vela de Alerta EMA 5
La estrategia EMA 5 Alert Candle Short espera tres velas que toquen la EMA de 5 períodos y luego identifica una vela que se mantiene por encima de ella. Se abre una posición corta cuando la siguiente vela rompe el mínimo de la vela de alerta, con el take profit colocado a una distancia igual al stop loss.
Detalles
- Criterios de entrada: después de tres velas que tocan la EMA, corto en la ruptura del mínimo de una vela que no toca la EMA.
- Largo/Corto: Solo corto.
- Criterios de salida: stop loss en el máximo de la vela de alerta, take profit a igual distancia.
- Stops: Sí, basado en el rango de la vela de alerta.
- Valores predeterminados:
EmaPeriod = 5RiskPerTrade = 2mCandleType = TimeSpan.FromMinutes(5).TimeFrame()
- Filtros:
- Categoría: Ruptura
- Dirección: Corto
- Indicadores: EMA
- Stops: Sí
- Complejidad: Básico
- Marco temporal: Intradía (5m)
- 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;
/// <summary>
/// EMA 5 alert candle short strategy.
/// After at least three consecutive candles touching the EMA, a candle whose low stays above the EMA becomes the alert candle.
/// When a following candle breaks below the alert candle low a short is opened with the stop at the alert candle high and the
/// take profit at the same distance below the entry. A later candle that stays above the EMA replaces the alert candle.
/// </summary>
public class Ema5AlertCandleShortStrategy : Strategy
{
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<decimal> _riskPerTrade;
private readonly StrategyParam<DataType> _candleType;
private int _touchCount;
private decimal? _alertHigh;
private decimal? _alertLow;
private decimal _stopPrice;
private decimal _takePrice;
/// <summary>
/// EMA period.
/// </summary>
public int EmaPeriod
{
get => _emaPeriod.Value;
set => _emaPeriod.Value = value;
}
/// <summary>
/// Risk per trade in percent of capital.
/// </summary>
public decimal RiskPerTrade
{
get => _riskPerTrade.Value;
set => _riskPerTrade.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public Ema5AlertCandleShortStrategy()
{
_emaPeriod = Param(nameof(EmaPeriod), 5)
.SetGreaterThanZero()
.SetDisplay("EMA Period", "EMA period", "Indicators");
_riskPerTrade = Param(nameof(RiskPerTrade), 2m)
.SetNotNegative()
.SetDisplay("Risk Per Trade %", "Risk per trade in percent of capital", "Risk");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).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 OnReseted()
{
base.OnReseted();
ResetState();
}
private void ResetState()
{
_touchCount = 0;
_alertHigh = null;
_alertLow = null;
_stopPrice = 0m;
_takePrice = 0m;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
ResetState();
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ema, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, ema);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal ema)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (Position < 0)
{
if (candle.HighPrice >= _stopPrice || candle.LowPrice <= _takePrice)
BuyMarket(-Position);
UpdatePattern(candle, ema);
return;
}
if (_alertHigh is decimal alertHigh && _alertLow is decimal alertLow && candle.LowPrice < alertLow)
{
var entry = candle.ClosePrice;
var risk = alertHigh - entry;
_alertHigh = null;
_alertLow = null;
_touchCount = 0;
if (risk > 0m)
{
_stopPrice = alertHigh;
_takePrice = entry - risk;
SellMarket(Volume);
return;
}
}
UpdatePattern(candle, ema);
}
private void UpdatePattern(ICandleMessage candle, decimal ema)
{
var touches = candle.LowPrice <= ema && candle.HighPrice >= ema;
if (touches)
{
// A touch after an alert candle starts a new sequence of touching candles.
_touchCount = _alertHigh == null ? _touchCount + 1 : 1;
_alertHigh = null;
_alertLow = null;
}
else if (candle.LowPrice > ema && (_touchCount >= 3 || _alertHigh != null))
{
_alertHigh = candle.HighPrice;
_alertLow = candle.LowPrice;
}
else
{
_touchCount = 0;
_alertHigh = null;
_alertLow = null;
}
}
}
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 ema_5_alert_candle_short_strategy(Strategy):
"""
EMA 5 alert candle short strategy.
After at least three consecutive candles touching the EMA, a candle whose low stays above the EMA becomes the alert candle.
When a following candle breaks below the alert candle low a short is opened with the stop at the alert candle high and the
take profit at the same distance below the entry. A later candle that stays above the EMA replaces the alert candle.
"""
def __init__(self):
super(ema_5_alert_candle_short_strategy, self).__init__()
self._ema_period = self.Param("EmaPeriod", 5).SetGreaterThanZero().SetDisplay("EMA Period", "EMA period", "Indicators")
self._risk_per_trade = self.Param("RiskPerTrade", 2.0).SetNotNegative().SetDisplay("Risk Per Trade %", "Risk per trade in percent of capital", "Risk")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).SetDisplay("Candle Type", "Type of candles to use", "General")
self._reset_state()
@property
def candle_type(self):
return self._candle_type.Value
def _reset_state(self):
self._touch_count = 0
self._alert_high = None
self._alert_low = None
self._stop_price = 0.0
self._take_price = 0.0
def OnReseted(self):
super(ema_5_alert_candle_short_strategy, self).OnReseted()
self._reset_state()
def OnStarted2(self, time):
super(ema_5_alert_candle_short_strategy, self).OnStarted2(time)
self._reset_state()
ema = ExponentialMovingAverage()
ema.Length = self._ema_period.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(ema, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ema)
self.DrawOwnTrades(area)
def _process_candle(self, candle, ema_value):
if candle.State != CandleStates.Finished:
return
if not self.IsFormedAndOnlineAndAllowTrading():
return
ema = float(ema_value)
high = float(candle.HighPrice)
low = float(candle.LowPrice)
if self.Position < 0:
if high >= self._stop_price or low <= self._take_price:
self.BuyMarket(-self.Position)
self._update_pattern(high, low, ema)
return
if self._alert_high is not None and self._alert_low is not None and low < self._alert_low:
alert_high = self._alert_high
entry = float(candle.ClosePrice)
risk = alert_high - entry
self._alert_high = None
self._alert_low = None
self._touch_count = 0
if risk > 0:
self._stop_price = alert_high
self._take_price = entry - risk
self.SellMarket(self.Volume)
return
self._update_pattern(high, low, ema)
def _update_pattern(self, high, low, ema):
touches = low <= ema and high >= ema
if touches:
# A touch after an alert candle starts a new sequence of touching candles.
self._touch_count = self._touch_count + 1 if self._alert_high is None else 1
self._alert_high = None
self._alert_low = None
elif low > ema and (self._touch_count >= 3 or self._alert_high is not None):
self._alert_high = high
self._alert_low = low
else:
self._touch_count = 0
self._alert_high = None
self._alert_low = None
def CreateClone(self):
return ema_5_alert_candle_short_strategy()