Esta estrategia replica el MetaTrader 5 Asesor Experto Expert_AMS_ES_CCI usando la API de alto nivel de StockSharp. Busca patrones de reversión de tres velas Morning Star y Evening Star y requiere confirmación del Commodity Channel Index (CCI) antes de abrir nuevas posiciones. La lógica funciona solo con velas terminadas y opera con el valor principal especificado en la configuración de la estrategia.
Lógica de trading
Entrada larga de Morning Star
Detecta tres velas consecutivas que forman un patrón de Estrella de la Mañana:
Vela 1: cuerpo bajista fuerte (tamaño del cuerpo mayor que el cuerpo promedio en la ventana seleccionada).
Vela 2: vela de cuerpo pequeño con un gap más bajo que la vela 1.
Vela 3: cierra por encima del punto medio de la Vela 1.
Confirme que el valor CCI en la barra de señal sea menor que el umbral de entrada negativo (predeterminado −50).
Entrada corta de Evening Star
Detectar un patrón de Estrella Vespertina válido:
Vela 1: fuerte cuerpo alcista.
Vela 2: vela de cuerpo pequeño que se abre por encima de la Vela 1.
Vela 3: cierra por debajo del punto medio de la Vela 1.
Confirme que el valor CCI en la barra de señal sea mayor que el umbral de entrada positivo (predeterminado +50).
Reglas de salida de posición
Cierre las posiciones cortas cuando CCI vuelva a cruzar por encima de −NeutralThreshold o caiga por debajo de +NeutralThreshold (predeterminado ±80).
Cierre las posiciones largas cuando CCI vuelva a cruzar por debajo de +NeutralThreshold o caiga por debajo de −NeutralThreshold.
No se incluyen reglas adicionales de limitación de pérdidas o toma de ganancias; los usuarios pueden agregar protecciones externas si es necesario.
Indicadores
Índice de canales de productos básicos (CCI): filtro de confirmación, período predeterminado 25.
Promedio móvil simple de cuerpos de velas: calcula el tamaño promedio del cuerpo durante las últimas velas BodyAveragePeriod (predeterminado 5) para validar la fuerza del patrón.
Parámetros
Nombre
Descripción
Predeterminado
Notas
CciPeriod
Número de barras utilizadas en el cálculo CCI.
25
Optimizable.
BodyAveragePeriod
Número de velas utilizadas para medir el tamaño corporal promedio.
5
Optimizable.
EntryThreshold
Valor absoluto de CCI requerido para nuevas operaciones.
50
Valor positivo; la estrategia comprueba ±EntryThreshold.
NeutralThreshold
Nivel absoluto CCI que define la zona de salida.
80
Valor positivo; la estrategia comprueba ±NeutralThreshold.
CandleType
Tipo de vela (período de tiempo) utilizado para el análisis.
plazo de 1 hora
Cambie para que coincida con la resolución deseada.
Notas
La estrategia se suscribe a actualizaciones de velas a través de SubscribeCandles y utiliza Bind para recibir valores del indicador.
Las operaciones se ejecutan con órdenes de mercado usando BuyMarket y SellMarket.
Todos los comentarios en el código están escritos en inglés según sea necesario.
Para ampliar la gestión de riesgos, combine la estrategia con StartProtection o módulos personalizados de gestión de dinero.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Morning/Evening Star + CCI strategy.
/// Buys on morning star with negative CCI, sells on evening star with positive CCI.
/// </summary>
public class MorningEveningStarCciStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _cciPeriod;
private readonly StrategyParam<decimal> _cciLevel;
private ICandleMessage _prevCandle;
private ICandleMessage _prevPrevCandle;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int CciPeriod { get => _cciPeriod.Value; set => _cciPeriod.Value = value; }
public decimal CciLevel { get => _cciLevel.Value; set => _cciLevel.Value = value; }
public MorningEveningStarCciStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_cciPeriod = Param(nameof(CciPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("CCI Period", "CCI period", "Indicators");
_cciLevel = Param(nameof(CciLevel), 0m)
.SetDisplay("CCI Level", "CCI threshold for confirmation", "Signals");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevCandle = null;
_prevPrevCandle = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevCandle = null;
_prevPrevCandle = null;
var cci = new CommodityChannelIndex { Length = CciPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(cci, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal cciValue)
{
if (candle.State != CandleStates.Finished) return;
if (_prevCandle != null && _prevPrevCandle != null)
{
var prevBody = Math.Abs(_prevCandle.ClosePrice - _prevCandle.OpenPrice);
var prevRange = _prevCandle.HighPrice - _prevCandle.LowPrice;
var isSmallBody = prevRange > 0 && prevBody < prevRange * 0.3m;
var firstBearish = _prevPrevCandle.OpenPrice > _prevPrevCandle.ClosePrice;
var currBullish = candle.ClosePrice > candle.OpenPrice;
var isMorningStar = firstBearish && isSmallBody && currBullish &&
candle.ClosePrice > _prevPrevCandle.OpenPrice * 0.5m + _prevPrevCandle.ClosePrice * 0.5m;
var firstBullish = _prevPrevCandle.ClosePrice > _prevPrevCandle.OpenPrice;
var currBearish = candle.OpenPrice > candle.ClosePrice;
var isEveningStar = firstBullish && isSmallBody && currBearish &&
candle.ClosePrice < _prevPrevCandle.OpenPrice * 0.5m + _prevPrevCandle.ClosePrice * 0.5m;
if (isMorningStar && cciValue < -CciLevel && Position <= 0)
BuyMarket();
else if (isEveningStar && cciValue > CciLevel && Position >= 0)
SellMarket();
}
_prevPrevCandle = _prevCandle;
_prevCandle = candle;
}
}
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 CommodityChannelIndex
from StockSharp.Algo.Strategies import Strategy
class morning_evening_star_cci_strategy(Strategy):
"""
Morning/Evening Star + CCI: buy on morning star with negative CCI, sell on evening star with positive CCI.
"""
def __init__(self):
super(morning_evening_star_cci_strategy, self).__init__()
self._cci_period = self.Param("CciPeriod", 14).SetDisplay("CCI Period", "CCI period", "Indicators")
self._cci_level = self.Param("CciLevel", 0.0).SetDisplay("CCI Level", "CCI threshold", "Signals")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).SetDisplay("Candle Type", "Candles", "General")
self._prev_candle = None
self._prev_prev_candle = None
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(morning_evening_star_cci_strategy, self).OnReseted()
self._prev_candle = None
self._prev_prev_candle = None
def OnStarted2(self, time):
super(morning_evening_star_cci_strategy, self).OnStarted2(time)
cci = CommodityChannelIndex()
cci.Length = self._cci_period.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(cci, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, cci)
self.DrawOwnTrades(area)
def _process_candle(self, candle, cci_val):
if candle.State != CandleStates.Finished:
return
cci = float(cci_val)
cci_level = float(self._cci_level.Value)
if self._prev_candle is not None and self._prev_prev_candle is not None:
prev_body = abs(float(self._prev_candle.ClosePrice) - float(self._prev_candle.OpenPrice))
prev_range = float(self._prev_candle.HighPrice) - float(self._prev_candle.LowPrice)
is_small_body = prev_range > 0 and prev_body < prev_range * 0.3
pp_open = float(self._prev_prev_candle.OpenPrice)
pp_close = float(self._prev_prev_candle.ClosePrice)
c_open = float(candle.OpenPrice)
c_close = float(candle.ClosePrice)
first_bearish = pp_open > pp_close
curr_bullish = c_close > c_open
is_morning = first_bearish and is_small_body and curr_bullish and c_close > pp_open * 0.5 + pp_close * 0.5
first_bullish = pp_close > pp_open
curr_bearish = c_open > c_close
is_evening = first_bullish and is_small_body and curr_bearish and c_close < pp_open * 0.5 + pp_close * 0.5
if is_morning and cci < -cci_level and self.Position <= 0:
self.BuyMarket()
elif is_evening and cci > cci_level and self.Position >= 0:
self.SellMarket()
self._prev_prev_candle = self._prev_candle
self._prev_candle = candle
def CreateClone(self):
return morning_evening_star_cci_strategy()