Ver en GitHub

Estrategia Exp KWAN NRP

Descripción general

La estrategia Exp KWAN NRP reproduce el asesor experto original de MetaTrader combinando un oscilador estocástico, índice de fuerza relativa e indicador de momentum en una sola razón. La razón se suaviza con una media móvil configurable, y la pendiente de la línea suavizada determina cuándo abrir o cerrar posiciones. El enfoque funciona en cualquier símbolo o marco temporal y está diseñado para el trading direccional cuando el momentum cambia.

Lógica de trading

  1. Construir la razón KWAN multiplicando la línea %D del estocástico por el valor RSI y dividiendo por la lectura del momentum.
  2. Suavizar la razón con el método de media móvil seleccionado (simple, exponencial, suavizada o ponderada).
  3. Evaluar la pendiente de la línea suavizada en el desplazamiento de barra de señal configurable.
  4. Entrar en posiciones largas cuando la línea gira hacia arriba y salir de posiciones cortas. Entrar en posiciones cortas cuando la línea gira hacia abajo y salir de posiciones largas.
  5. La protección opcional de stop-loss y take-profit puede cerrar automáticamente posiciones después de un movimiento de precio predefinido medido en pasos de precio.

Señales

  • Entrada larga: El valor KWAN suavizado en la barra de señal sube comparado con la barra anterior y las entradas largas están habilitadas.
  • Salida larga: El valor KWAN suavizado gira hacia abajo mientras una posición larga está abierta y las salidas largas están habilitadas.
  • Entrada corta: El valor KWAN suavizado en la barra de señal cae comparado con la barra anterior y las entradas cortas están habilitadas.
  • Salida corta: El valor KWAN suavizado gira hacia arriba mientras una posición corta está abierta y las salidas cortas están habilitadas.

Gestión del riesgo

  • Establezca la propiedad Volume de la estrategia para controlar el tamaño base de la orden. El cambio de posición cierra automáticamente una posición opuesta antes de abrir una nueva.
  • Habilite UseProtection para aplicar niveles de stop-loss y take-profit medidos en pasos de precio del instrumento. Ambas protecciones se pueden usar juntas o por separado.
  • La estrategia se suscribe a velas definidas por CandleType y opera al cierre de velas finalizadas.

Parámetros

Nombre Descripción Predeterminado
CandleType Marco temporal usado para cálculos de indicadores y evaluación de señales. Velas de 1 hora
KPeriod Período de la línea %K del estocástico. 5
DPeriod Período de la línea %D del estocástico. 3
SlowingPeriod Suavizado adicional aplicado a la línea %K del estocástico. 3
RsiPeriod Período del índice de fuerza relativa. 14
MomentumPeriod Período del indicador de momentum. 14
SmoothingMethod Tipo de media móvil aplicada a la razón KWAN (Simple, Exponential, Smoothed, Weighted). Simple
SmoothingLength Longitud de la media móvil de suavizado. 3
SignalBar Número de barras atrás usado para evaluar la pendiente (0 = barra cerrada actual). 1
EnableBuyEntries Permitir abrir posiciones largas en señales alcistas. true
EnableSellEntries Permitir abrir posiciones cortas en señales bajistas. true
EnableBuyExits Permitir cerrar posiciones largas cuando aparece una señal bajista. true
EnableSellExits Permitir cerrar posiciones cortas cuando aparece una señal alcista. true
UseProtection Habilitar protecciones de stop-loss y take-profit. true
StopLossSteps Distancia del stop-loss expresada en pasos de precio. 1000
TakeProfitSteps Distancia del take-profit expresada en pasos de precio. 2000

Notas de uso

  • La razón KWAN puede volverse inestable cuando el indicador de momentum es igual a cero. La estrategia omite automáticamente las señales para esas barras para evitar la división por cero.
  • El parámetro SignalBar permite alinear señales con barras históricas si se necesita confirmación retrasada.
  • Combine con controles de riesgo a nivel de corretaje o filtros adicionales si se requiere para trading en producción.
namespace StockSharp.Samples.Strategies;

using System;

using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;

/// <summary>
/// Strategy replicating the Exp KWAN NRP expert advisor by combining RSI and Momentum signals.
/// Enters long when RSI crosses above 50 and momentum is positive,
/// enters short when RSI crosses below 50 and momentum is negative.
/// </summary>
public class ExpKwanNrpStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _rsiPeriod;
	private readonly StrategyParam<int> _momentumPeriod;

	private decimal _prevRsi;
	private decimal _prevMom;
	private bool _initialized;

	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	public int RsiPeriod
	{
		get => _rsiPeriod.Value;
		set => _rsiPeriod.Value = value;
	}

	public int MomentumPeriod
	{
		get => _momentumPeriod.Value;
		set => _momentumPeriod.Value = value;
	}

	public ExpKwanNrpStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe for calculations", "General");

		_rsiPeriod = Param(nameof(RsiPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("RSI Period", "RSI length", "Indicators");

		_momentumPeriod = Param(nameof(MomentumPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("Momentum Period", "Momentum length", "Indicators");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevRsi = 0m;
		_prevMom = 0m;
		_initialized = false;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		_prevRsi = 0;
		_prevMom = 0;
		_initialized = false;

		var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
		var momentum = new Momentum { Length = MomentumPeriod };

		var subscription = SubscribeCandles(CandleType);

		subscription
			.Bind(rsi, momentum, (ICandleMessage candle, decimal rsiValue, decimal momValue) =>
			{
				if (candle.State != CandleStates.Finished)
					return;

				if (!IsFormedAndOnlineAndAllowTrading())
					return;

				if (!_initialized)
				{
					_prevRsi = rsiValue;
					_prevMom = momValue;
					_initialized = true;
					return;
				}

				var rsiUp = rsiValue > _prevRsi;
				var rsiDown = rsiValue < _prevRsi;
				var momUp = momValue > _prevMom;
				var momDown = momValue < _prevMom;

				// Buy when both RSI and Momentum are turning up
				if (rsiUp && momUp && Position <= 0)
				{
					BuyMarket();
				}
				// Sell when both RSI and Momentum are turning down
				else if (rsiDown && momDown && Position >= 0)
				{
					SellMarket();
				}

				_prevRsi = rsiValue;
				_prevMom = momValue;
			})
			.Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawIndicator(area, rsi);
			DrawOwnTrades(area);
		}
	}
}