Ver en GitHub

Nina EA Estrategia

Descripción general

La estrategia Nina EA es un seguidor de tendencias de una posición convertido del experto MetaTrader 4 "NinaEA". El robot original utiliza un indicador personalizado llamado NINA y opera cada vez que la diferencia entre los amortiguadores alcistas y bajistas del indicador cruza por encima o por debajo de cero. En la versión StockSharp, el indicador personalizado se reemplaza con el indicador SuperTrend incorporado, que también publica buffers alcistas y bajistas separados. Un cambio en la dirección de SuperTrend sirve como indicador de cruce por cero: cuando la tendencia se vuelve alcista, la estrategia compra, y cuando se vuelve bajista, vende.

La estrategia siempre mantiene como máximo una posición abierta. Una señal opuesta cierra inmediatamente la posición existente y establece una nueva operación en la nueva dirección. Se puede habilitar un stop-loss opcional expresado en puntos de precio para imitar la entrada original "StopLoss".

Lógica de trading

  1. Suscríbase a la serie de velas configuradas y calcule SuperTrend con el período y el multiplicador ATR suministrados.
  2. Espere hasta que se formen tanto la estrategia como el indicador antes de reaccionar a las señales.
  3. En cada vela completa:
    • Si se toca un precio stop protector, salga de la posición abierta en el mercado.
    • Si SuperTrend cambia de bajista a alcista, cierre cualquier exposición corta y compre con el volumen configurado.
    • Si SuperTrend cambia de alcista a bajista, cierre cualquier exposición larga y venda con el volumen configurado.
    • Almacene la dirección actual de SuperTrend para detectar el siguiente giro.

La lógica replica el comportamiento del experto MetaTrader, donde nina = Buffer0 - Buffer1 y un cambio de signo impulsan tanto las salidas como las nuevas entradas.

Gestión de posiciones y riesgos

  • Sólo puede haber una posición activa a la vez; todas las operaciones invierten la dirección en lugar de acumular varias órdenes.
  • Un stop-loss opcional en puntos de precio se calcula a partir del precio de cumplimiento. Para una operación larga, el stop se coloca debajo de la entrada y para una operación corta, se coloca encima de la entrada. Poner el parámetro a cero desactiva la parada.
  • Se llama a StartProtection() para que se puedan configurar las protecciones integradas StockSharp si se desea.

Parámetros

Parámetro Predeterminado Descripción
Volume 0.1 Volumen de pedidos utilizado para cada nueva entrada.
AtrPeriod 10 periodo ATR pasado al cálculo de SuperTrend (mapa el PeriodWATR original).
AtrMultiplier 1 multiplicador ATR para SuperTrend (asigna el Kwatr original).
StopLossPoints 0 Distancia de stop-loss opcional en puntos de precio. Zero mantiene el stop deshabilitado, idéntico al código MetaTrader que enviaba órdenes de mercado sin precio de stop.
CandleType TimeFrame(1 minute) Serie de velas que alimenta el indicador y la lógica comercial.

Notas de conversión

  • El experto MetaTrader se basó en el indicador personalizado NINA. Sus dos amortiguadores se interpretaron como líneas SuperTrend alcistas/bajistas porque sólo su diferencia y su signo importaban para el trading. SuperTrend expone la misma información a través de su indicador IsUpTrend, lo que lo convierte en un reemplazo de alto nivel adecuado que no requiere manejo manual del búfer.
  • La lógica de cierre de órdenes refleja el bucle OrdersTotal() del guión original: un cambio de tendencia primero favorece la posición actual y luego abre una operación en la nueva dirección.
  • Las entradas MetaTrader no utilizadas (highlow, cbars, from, maP, SMAspread, Slippage) se omiten porque no influyen en las reglas comerciales del archivo original.

Consejos de uso

  1. Adjunte la estrategia a un valor y configure el período de vela que coincida con su prueba MetaTrader.
  2. Ajuste el período ATR y el multiplicador para replicar el comportamiento del indicador original.
  3. Aumente StopLossPoints si desea un límite de riesgo estricto; de lo contrario, déjelo en cero para salidas basadas puramente en señales.
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>
/// SuperTrend-based strategy from NinaEA.
/// Trades on SuperTrend direction flips - buy on up trend, sell on down trend.
/// </summary>
public class NinaEaStrategy : Strategy
{
	private readonly StrategyParam<int> _atrPeriod;
	private readonly StrategyParam<decimal> _atrMultiplier;
	private readonly StrategyParam<DataType> _candleType;

	private bool? _previousTrendUp;

	public int AtrPeriod { get => _atrPeriod.Value; set => _atrPeriod.Value = value; }
	public decimal AtrMultiplier { get => _atrMultiplier.Value; set => _atrMultiplier.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public NinaEaStrategy()
	{
		_atrPeriod = Param(nameof(AtrPeriod), 10)
			.SetDisplay("ATR Period", "ATR length for SuperTrend", "Indicators");

		_atrMultiplier = Param(nameof(AtrMultiplier), 1m)
			.SetDisplay("ATR Multiplier", "SuperTrend multiplier", "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();
		_previousTrendUp = null;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		_previousTrendUp = null;

		var superTrend = new SuperTrend
		{
			Length = AtrPeriod,
			Multiplier = AtrMultiplier
		};

		var subscription = SubscribeCandles(CandleType);
		subscription
			.BindEx(superTrend, ProcessCandle)
			.Start();
	}

	private void ProcessCandle(ICandleMessage candle, IIndicatorValue superTrendValue)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (!superTrendValue.IsFinal)
			return;

		var stValue = (SuperTrendIndicatorValue)superTrendValue;
		var isUpTrend = stValue.IsUpTrend;

		if (_previousTrendUp is bool prevUp)
		{
			// Trend flipped to up - go long
			if (isUpTrend && !prevUp)
			{
				if (Position < 0)
					BuyMarket();
				if (Position <= 0)
					BuyMarket();
			}
			// Trend flipped to down - go short
			else if (!isUpTrend && prevUp)
			{
				if (Position > 0)
					SellMarket();
				if (Position >= 0)
					SellMarket();
			}
		}

		_previousTrendUp = isUpTrend;
	}
}