Ver en GitHub

Estrategia AMMA Trend

Descripción general

La estrategia usa el indicador Modified Moving Average (AMMA) para capturar cambios de tendencia a corto plazo. Analiza la dirección de la pendiente de AMMA en las velas recientes y abre una posición en la dirección de la tendencia emergente mientras cierra la opuesta.

Cómo funciona

  1. Se calcula una ModifiedMovingAverage con un período configurable en el marco temporal seleccionado.
  2. En cada vela terminada, la estrategia compara los últimos tres valores de AMMA.
  3. Si los valores del indicador forman una secuencia ascendente y el valor más reciente es mayor que el anterior, se abre una posición larga. Se cierra cualquier posición corta.
  4. Si los valores del indicador forman una secuencia descendente y el valor más reciente es menor que el anterior, se abre una posición corta. Se cierra cualquier posición larga.

Parámetros

  • CandleType – marco temporal de las velas utilizadas para los cálculos.
  • MaPeriod – período de la media móvil modificada.
  • AllowLongEntry – habilitar la apertura de posiciones largas.
  • AllowShortEntry – habilitar la apertura de posiciones cortas.
  • AllowLongExit – habilitar el cierre de posiciones largas.
  • AllowShortExit – habilitar el cierre de posiciones cortas.

Notas

La estrategia opera únicamente en velas completadas y se apoya en los métodos incorporados BuyMarket y SellMarket para la ejecución de órdenes. Las funciones de gestión de riesgo pueden añadirse externamente usando las propiedades estándar de Strategy.

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>
/// AMMA Trend strategy using Modified Moving Average direction changes.
/// Buys when MMA turns up, sells when MMA turns down.
/// </summary>
public class AmmaTrendStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _maPeriod;

	private decimal? _mma0;
	private decimal? _mma1;
	private decimal? _mma2;
	private decimal? _mma3;

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

	public AmmaTrendStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Type of candles to use for analysis", "General");

		_maPeriod = Param(nameof(MaPeriod), 25)
			.SetGreaterThanZero()
			.SetDisplay("AMMA Period", "Period of the modified moving average", "Indicator");
	}

	/// <inheritdoc />
	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
	{
		return [(Security, CandleType)];
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_mma0 = _mma1 = _mma2 = _mma3 = null;
	}

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

		var mma = new SmoothedMovingAverage { Length = MaPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(mma, ProcessCandle).Start();

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

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

		_mma3 = _mma2;
		_mma2 = _mma1;
		_mma1 = _mma0;
		_mma0 = mmaValue;

		if (_mma1 is null || _mma2 is null || _mma3 is null)
			return;

		// Upward movement detected: MMA turned from falling to rising
		if (_mma2 < _mma3 && _mma1 > _mma2 && Position <= 0)
		{
			if (Position < 0) BuyMarket();
			BuyMarket();
		}
		// Downward movement detected: MMA turned from rising to falling
		else if (_mma2 > _mma3 && _mma1 < _mma2 && Position >= 0)
		{
			if (Position > 0) SellMarket();
			SellMarket();
		}
	}
}