Ver en GitHub

Estrategia de Seguimiento del Alligator

Implementación de la estrategia Ride Alligator. El método utiliza tres medias móviles conocidas como el indicador Alligator. Se abre una posición larga cuando la línea Lips cruza por encima de la línea Jaws mientras la línea Teeth está por debajo de Jaws. Se abre una posición corta cuando Lips cruza por debajo de Jaws y la línea Teeth está por encima de Jaws. La posición abierta está protegida por un stop en la línea Jaws que sigue el movimiento de la línea.

Detalles

  • Criterios de entrada:
    • Largo: Lips > Jaws && Teeth < Jaws && previous Lips < previous Jaws
    • Corto: Lips < Jaws && Teeth > Jaws && previous Lips > previous Jaws
  • Largo/Corto: Ambos
  • Criterios de salida:
    • Largo: price <= Jaws
    • Corto: price >= Jaws
  • Stops: Trailing stop en Alligator Jaws
  • Valores predeterminados:
    • AlligatorPeriod = 5
    • MaType = MovingAverageTypeEnum.Weighted
    • CandleType = TimeSpan.FromMinutes(1).TimeFrame()
  • Filtros:
    • Categoría: Seguimiento de tendencia
    • Dirección: Ambos
    • Indicadores: Alligator
    • Stops: Sí
    • Complejidad: Básico
    • Marco temporal: Intradía
    • Estacionalidad: No
    • Redes neuronales: No
    • Divergencia: No
    • Nivel de riesgo: Medio
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>
/// Ride Alligator strategy using SMMA jaw/teeth/lips crossover.
/// </summary>
public class RideAlligatorStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevJaw;
	private decimal _prevLips;
	private bool _hasPrev;

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

	public RideAlligatorStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Type of candles", "General");
	}

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

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

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

		var jaw = new SmoothedMovingAverage { Length = 13 };
		var teeth = new SmoothedMovingAverage { Length = 8 };
		var lips = new SmoothedMovingAverage { Length = 5 };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(jaw, teeth, lips, ProcessCandle)
			.Start();
	}

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

		if (!_hasPrev)
		{
			_prevJaw = jaw;
			_prevLips = lips;
			_hasPrev = true;
			return;
		}

		// Lips crosses above jaw -> buy
		if (_prevLips <= _prevJaw && lips > jaw && teeth < jaw)
		{
			if (Position < 0)
				BuyMarket();
			if (Position <= 0)
				BuyMarket();
		}
		// Lips crosses below jaw -> sell
		else if (_prevLips >= _prevJaw && lips < jaw && teeth > jaw)
		{
			if (Position > 0)
				SellMarket();
			if (Position >= 0)
				SellMarket();
		}

		// Exit on price crossing jaw
		if (Position > 0 && candle.ClosePrice < jaw)
			SellMarket();
		else if (Position < 0 && candle.ClosePrice > jaw)
			BuyMarket();

		_prevJaw = jaw;
		_prevLips = lips;
	}
}