La estrategia AOCCI es una conversión directa del asesor experto MetaTrader 4 "AOCCI". Combina filtros de impulso y reversión media mediante el uso del Awesome Oscillator (AO) y el Commodity Channel Index (CCI) junto con un pivote de piso diario. La versión convertida funciona en el nivel alto de StockSharp API y mantiene la misma lógica protectora que el script original.
Lógica
Preparación de datos
Utiliza velas intradiarias (por defecto 1 hora) para generar señales.
Utiliza velas diarias para calcular el pivote del día anterior completado (máximo + mínimo + cierre dividido por 3).
Realiza un seguimiento de los últimos seis precios de apertura intradía para detectar grandes brechas.
Filtro de espacios
Cualquier diferencia de un solo paso que exceda el umbral del Big Jump Filter cancela la señal actual.
Cualquier diferencia combinada de dos pasos que exceda el umbral del Filtro de doble salto también cancela la señal.
Comprobaciones de indicadores
AO debe ser mayor que cero y CCI debe ser no negativo en la barra actual.
Al menos uno de los siguientes debe ser cierto en la barra anterior: AO por debajo de cero, CCI en cero o por debajo, o precio por debajo del pivote.
Filtro direccional
El precio de cierre debe permanecer por encima del nivel de pivote.
Pedidos
El asesor experto original solo abre operaciones largas porque la condición corta duplica la lógica larga. La conversión mantiene este comportamiento.
Las órdenes de mercado utilizan el Volumen de órdenes configurado.
Protección
El stop-loss inicial y la toma de ganancias se expresan en incrementos de precios.
El trailing stop opcional refuerza el stop una vez que el precio se mueve a favor de la posición al menos en la distancia de seguimiento.
Parámetros
Nombre
Descripción
CciPeriod
Período para el índice del canal de productos básicos (por defecto 55).
SignalCandleOffset
Se aplica compensación adicional al hacer referencia a velas diarias históricas (predeterminado 0).
StopLossPoints
Distancia de stop-loss en pasos de precio.
TakeProfitPoints
Distancia de obtención de beneficios en pasos de precio.
TrailingStopPoints
Distancia del trailing stop en pasos de precio (0 desactiva el trailing).
BigJumpPoints
Brecha de apertura máxima permitida de una sola barra expresada en incrementos de precio.
DoubleJumpPoints
Brecha combinada máxima permitida de dos barras expresada en incrementos de precios.
OrderVolume
Volumen utilizado al enviar órdenes de mercado.
CandleType
Tipo de vela intradiaria (barras de una hora predeterminadas).
DailyCandleType
Tipo de vela diaria utilizada para el cálculo del pivote.
Notas de uso
La estrategia requiere suscripciones de datos tanto intradía como diarias.
El paso de precio (tamaño de tick) del valor seleccionado se utiliza para traducir los parámetros de riesgo basados en puntos en precios reales.
La gestión de trailing stop se aplica a las velas completadas, reflejando el comportamiento del EA original.
Debido a que la versión original MQL4 nunca activa operaciones cortas, la conversión mantiene intencionalmente el mismo conjunto de reglas.
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// AOCCI Pivot strategy - CCI crossover with momentum filter.
/// Buys when CCI crosses above 0 with positive momentum.
/// Sells when CCI crosses below 0 with negative momentum.
/// </summary>
public class AocciPivotFilterStrategy : Strategy
{
private readonly StrategyParam<int> _cciPeriod;
private readonly StrategyParam<int> _momentumPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevCci;
private bool _hasPrev;
public int CciPeriod { get => _cciPeriod.Value; set => _cciPeriod.Value = value; }
public int MomentumPeriod { get => _momentumPeriod.Value; set => _momentumPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public AocciPivotFilterStrategy()
{
_cciPeriod = Param(nameof(CciPeriod), 14)
.SetDisplay("CCI Period", "CCI period", "Indicators");
_momentumPeriod = Param(nameof(MomentumPeriod), 10)
.SetDisplay("Momentum Period", "Momentum period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevCci = 0m;
_hasPrev = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var cci = new CommodityChannelIndex { Length = CciPeriod };
var mom = new Momentum { Length = MomentumPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(cci, mom, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal cciValue, decimal momValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!_hasPrev)
{
_prevCci = cciValue;
_hasPrev = true;
return;
}
// CCI crosses above 0 with positive momentum
if (_prevCci <= 0 && cciValue > 0 && momValue > 0 && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
// CCI crosses below 0 with negative momentum
else if (_prevCci >= 0 && cciValue < 0 && momValue < 0 && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
_prevCci = cciValue;
}
}