Ver en GitHub

Seguidor de tendencias de FT

Descripción general

FT Trend Follower es una StockSharp versión del MetaTrader 4 asesor experto FT_TrendFollower.mq4. La estrategia aprovecha las tendencias a mediano plazo al combinar un ventilador de media móvil múltiple Guppy (GMMA) con un disparador de oscilador de Laguerre, un cruce EMA rápido/lento y un filtro MACD. Las entradas sólo se activan después de que el mercado se sumerge en el paquete GMMA, se recupera de un extremo de Laguerre y la mayoría de las líneas GMMA reanudan su inclinación en la dirección del comercio. La gestión de ganancias refleja el EA original: una parada opcional basada en oscilación, una parada de distancia fija y tres módulos de salida por etapas mutuamente excluyentes impulsados ​​por niveles de pivote diarios o promedios de canal.

Lógica estratégica

Estructura GMMA y detección de tendencias.

  • El ventilador GMMA se extiende desde StartGmmaPeriod hasta EndGmmaPeriod. Los períodos se distribuyen en cinco grupos de BandsPerGroup líneas cada uno, replicando la lógica CountLine original.
  • La dirección de la tendencia compara el grupo GMMA más lento (índice CountLine + CountLine desde el final) con el grupo más rápido a largo plazo (índice CountLine desde el final). Los promedios crecientes a largo plazo definen una tendencia alcista; los que caen definen una tendencia bajista.
  • La confirmación de pendiente cuenta cuántas líneas GMMA a corto, mediano y largo plazo aumentaron o disminuyeron en comparación con la barra anterior. Una operación requiere que el recuento de pendiente ascendente (o descendente) supere la mitad del total de líneas GMMA, imitando el umbral controlvverh/controlvverhS en MetaTrader.

Cebado de señal

  • Cerrar reinicio – Cuando la vela anterior se cierra por debajo de la línea GMMA más lenta, el módulo largo se arma; cuando se cierra por encima de la línea más lenta, el módulo corto se arma. Cruzar nuevamente por encima (o por debajo) del GMMA más rápido borra las banderas de armado, tal como la lógica CloseOk original.
  • Activador de Laguerre: un filtro de Laguerre (LaguerreGamma) primero debe caer por debajo de LaguerreOversold (configuración larga) o subir por encima de LaguerreOverbought (configuración corta) mientras la vela aún respeta la GMMA a largo plazo. Sólo después de que el oscilador retrocede a través del umbral se puede disparar una entrada.
  • EMA cruce: el EMA rápido (FastSignalLength) debe descender por debajo del EMA lenta (SlowSignalLength) para armar el módulo largo y luego cruzar nuevamente por encima de él para liberar la entrada. Los pantalones cortos revierten la desigualdad.
  • Filtro MACD: la línea principal MACD (5/35/5 como en EA) debe ser positiva para posiciones largas y negativa para posiciones cortas.

Reglas de entrada

Una operación larga se ejecuta cuando:

  1. La detección de tendencias informa una tendencia alcista y la votación de la pendiente GMMA supera la mitad de las líneas disponibles.
  2. El disparador de Laguerre se armó previamente y el valor actual se cierra nuevamente por encima de LaguerreOversold.
  3. El EMA rápido está por encima del EMA lento después de haber estado anteriormente por debajo.
  4. MACD es mayor que cero.

Las entradas cortas requieren condiciones simétricas con el oscilador cruzando por debajo de LaguerreOverbought y MACD negativo. Al revertir una posición existente, el tamaño de la orden compensa automáticamente la exposición anterior para que la posición neta final sea igual a Volume.

Gestión de riesgos y salidas.

  • Paradas: elija la parada de oscilación (UseSwingStop) ubicada debajo (sobre) de la vela anterior en SwingStopPips puntos, o la parada de distancia fija (UseFixedStop) compensada en FixedStopPips puntos. Si ambos están habilitados a la vez la estrategia aborta al inicio, reproduciéndose las reglas de validación EA.
  • Módulo de salida de pivote (Salir): cuando está habilitado, el primer cierre parcial (50 % de Volume) se activa una vez que el precio cruza el pivote R1/S1 del día anterior con ganancias no realizadas. El resto se cierra tan pronto como Hull MA produce un valor válido, que coincide con la verificación del búfer hma1 de MetaTrader.
  • Módulo de salida de rango de pivote (Salir1) – El cierre parcial inicial todavía ocurre en R1/S1. El resto sale en R2/S2 una vez que la operación sigue siendo rentable.
  • Módulo de salida de canal (Salir2): el primer cierre parcial ocurre en R1/S1. La estrategia cierra el resto cuando la vela se vuelve a abrir por debajo del canal bajo SMA (ChannelPeriod) para largos o por encima del canal alto SMA para cortos, reflejando el filtro de volatilidad original.

Solo puede haber un módulo de salida activo a la vez, al igual que la validación de parámetros de EA.

Parámetros

  • Volumen: tamaño del pedido para nuevas operaciones.
  • StartGmmaPeriod / EndGmmaPeriod – Límites para los fanáticos de GMMA.
  • BandsPerGroup: número de líneas GMMA muestreadas por grupo (CountLine en MT4).
  • FastSignalLength / SlowSignalLength – EMA longitudes utilizadas para la confirmación de cruce.
  • TradeShift – Se mantiene por compatibilidad; la implementación opera en velas terminadas, por lo que se rechazan los valores distintos de 0 o 1.
  • UseSwingStop / SwingStopPips: habilita y configura la parada protectora basada en oscilación.
  • UseFixedStop/FixedStopPips: habilita la parada de distancia fija medida en puntos de precio.
  • EnablePivotExit / EnablePivotRangeExit / EnableChannelExit: módulos de salida por etapas mutuamente excluyentes.
  • LaguerreOversold / LaguerreOverbought / LaguerreGamma – Umbrales de activación de Laguerre y factor de suavizado.
  • HmaPeriod – Longitud MA del casco utilizada por el módulo de salida de pivote.
  • ChannelPeriod: longitud del canal alto/bajo SMA para Quit2.
  • CandleType: período de tiempo que impulsa los cálculos de la estrategia (predeterminado: velas de 1 hora).

Notas adicionales

  • Los niveles de pivote diarios se calculan a partir de la última vela diaria terminada proporcionada por una suscripción secundaria.
  • Los puntos de precio y las conversiones de pips dependen del valor PriceStep. Los símbolos con diferentes tamaños de tick se adaptan automáticamente.
  • La estrategia se suscribe únicamente a indicadores de alto nivel y evita lecturas directas del búfer, adhiriéndose a las pautas de alto nivel API del proyecto.
  • No se proporciona ninguna implementación de Python en este paquete.
using System;

using Ecng.Common;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Trend following strategy using EMA crossover with MACD confirmation.
/// Buys when fast EMA crosses above slow EMA and MACD histogram is positive.
/// Sells when fast EMA crosses below slow EMA and MACD histogram is negative.
/// </summary>
public class FtTrendFollowerStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;

	private decimal _prevFast;
	private decimal _prevSlow;
	private decimal _prevMacd;
	private bool _isReady;

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

	public int FastPeriod
	{
		get => _fastPeriod.Value;
		set => _fastPeriod.Value = value;
	}

	public int SlowPeriod
	{
		get => _slowPeriod.Value;
		set => _slowPeriod.Value = value;
	}

	public FtTrendFollowerStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Candle type for strategy", "General");

		_fastPeriod = Param(nameof(FastPeriod), 12)
			.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");

		_slowPeriod = Param(nameof(SlowPeriod), 26)
			.SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
	}

	/// <inheritdoc />
	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();

		_prevFast = 0;
		_prevSlow = 0;
		_prevMacd = 0;
		_isReady = false;
	}

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

		_prevFast = 0;
		_prevSlow = 0;
		_prevMacd = 0;
		_isReady = false;

		var fast = new EMA { Length = FastPeriod };
		var slow = new EMA { Length = SlowPeriod };
		var macd = new MovingAverageConvergenceDivergence();

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fast, slow, macd, OnProcess)
			.Start();

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

	private void OnProcess(ICandleMessage candle, decimal fastVal, decimal slowVal, decimal macdVal)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (!_isReady)
		{
			_prevFast = fastVal;
			_prevSlow = slowVal;
			_prevMacd = macdVal;
			_isReady = true;
			return;
		}

		// Buy: fast crosses above slow + MACD positive
		if (_prevFast <= _prevSlow && fastVal > slowVal && macdVal > 0)
		{
			if (Position < 0)
				BuyMarket();
			if (Position <= 0)
				BuyMarket();
		}
		// Sell: fast crosses below slow + MACD negative
		else if (_prevFast >= _prevSlow && fastVal < slowVal && macdVal < 0)
		{
			if (Position > 0)
				SellMarket();
			if (Position >= 0)
				SellMarket();
		}

		_prevFast = fastVal;
		_prevSlow = slowVal;
		_prevMacd = macdVal;
	}
}