Ver en GitHub

Estrategia AMkA Signal

Descripción general

Esta estrategia utiliza la derivada de la Media Móvil Adaptativa de Kaufman (KAMA) combinada con un filtro de volatilidad basado en la desviación estándar. Se abre una posición larga cuando la tasa de cambio de KAMA supera un umbral dinámico; se abre una posición corta cuando cae por debajo del umbral negativo. El umbral se calcula multiplicando la desviación estándar de los cambios de KAMA por un factor definido por el usuario.

Parámetros

  • KAMA Length – período de retrospección para el indicador KAMA.
  • Fast Period – período rápido de EMA utilizado en el suavizado de KAMA.
  • Slow Period – período lento de EMA utilizado en el suavizado de KAMA.
  • Deviation Multiplier – multiplicador aplicado a la desviación estándar para formar el umbral de señal.
  • Take Profit – porcentaje para la fijación automática de beneficios.
  • Stop Loss – porcentaje para el stop de protección.
  • Candle Type – marco temporal de las velas utilizadas para los cálculos.

Lógica de trading

  1. Suscribirse a velas del marco temporal seleccionado.
  2. Calcular KAMA para cada vela y calcular su cambio respecto al valor anterior.
  3. Actualizar el indicador de desviación estándar con los valores de cambio.
  4. Cuando el cambio supera Deviation Multiplier * StdDev, abrir o cerrar posiciones:
    • Si el cambio es mayor que el umbral: cerrar posiciones cortas y abrir larga.
    • Si el cambio es menor que el umbral negativo: cerrar posiciones largas y abrir corta.
  5. Las órdenes de protección para take profit y stop loss se gestionan automáticamente con StartProtection.

Notas

La estrategia trabaja únicamente con velas completadas y usa tabulaciones para la indentación en el código fuente. Todos los comentarios están escritos en inglés según lo requerido.

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>
/// AMkA based strategy using KAMA derivative and standard deviation filter.
/// Buys when KAMA rises above volatility threshold and sells when it falls below.
/// </summary>
public class AmkaSignalStrategy : Strategy
{
	private readonly StrategyParam<int> _length;
	private readonly StrategyParam<decimal> _deviationMultiplier;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevKama;
	private bool _hasPrev;

	public int Length { get => _length.Value; set => _length.Value = value; }
	public decimal DeviationMultiplier { get => _deviationMultiplier.Value; set => _deviationMultiplier.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public AmkaSignalStrategy()
	{
		_length = Param(nameof(Length), 10)
			.SetGreaterThanZero()
			.SetDisplay("KAMA Length", "Lookback period for the adaptive moving average", "Indicator");

		_deviationMultiplier = Param(nameof(DeviationMultiplier), 1.0m)
			.SetGreaterThanZero()
			.SetDisplay("Deviation Multiplier", "Multiplier for standard deviation filter", "Indicator");

		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe for indicator calculation", "General");
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
		=> [(Security, CandleType)];

	protected override void OnReseted()
	{
		base.OnReseted();
		_prevKama = 0;
		_hasPrev = false;
	}

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

		var kama = new KaufmanAdaptiveMovingAverage { Length = Length };
		var stdev = new StandardDeviation { Length = Length };

		SubscribeCandles(CandleType).Bind(kama, stdev, ProcessCandle).Start();
	}

	private void ProcessCandle(ICandleMessage candle, decimal kamaValue, decimal stdevValue)
	{
		if (candle.State != CandleStates.Finished) return;

		if (!_hasPrev)
		{
			_prevKama = kamaValue;
			_hasPrev = true;
			return;
		}

		var delta = kamaValue - _prevKama;
		_prevKama = kamaValue;

		if (stdevValue <= 0) return;

		var threshold = stdevValue * DeviationMultiplier;

		if (delta > threshold && Position <= 0)
		{
			if (Position < 0) BuyMarket();
			BuyMarket();
		}
		else if (delta < -threshold && Position >= 0)
		{
			if (Position > 0) SellMarket();
			SellMarket();
		}
	}
}