Ver en GitHub

Estrategia Maximus vX Lite

Esta estrategia intenta operar rupturas de zonas de consolidación a corto plazo. Busca rangos de precios compactos en el gráfico de 15 minutos y abre operaciones cuando el precio se aleja de estos rangos una distancia especificada.

Lógica de la estrategia

  1. Para cada vela de 15 minutos finalizada, se calculan el máximo más alto y el mínimo más bajo de las últimas 40 velas.
  2. Si la distancia entre estos extremos es inferior al parámetro Range, se asume una zona de consolidación.
  3. Tras esperar el período Delay Open sin nuevas operaciones, una ruptura por encima del límite superior más Distance puntos activa una posición larga, mientras que una ruptura por debajo del límite inferior menos Distance puntos activa una posición corta.
  4. Se aplica un Stop Loss fijo y un trailing stop de Trail puntos una vez abierta la posición.
  5. Los límites de consolidación se reinician tras transcurrir las horas de Period.

Parámetros

  • DelayOpen – Horas de espera antes de abrir una nueva operación.
  • Distance – Distancia de ruptura desde el límite de consolidación en puntos.
  • Period – Horas tras las cuales se recalculan los niveles de consolidación.
  • Range – Tamaño máximo de la zona de consolidación en puntos.
  • StopLoss – Stop loss inicial en puntos.
  • Trail – Distancia del trailing stop en puntos.

Notas

La estrategia usa solo la API de alto nivel: las velas se reciben mediante SubscribeCandles y los valores de indicadores se vinculan con Bind. Las órdenes se envían con los métodos BuyMarket y SellMarket. Los comentarios en el código fuente están escritos en inglés.

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>
/// Breakout strategy based on consolidation zones.
/// </summary>
public class MaximusVxLiteStrategy : Strategy
{
	private readonly StrategyParam<int> _lookback;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevHigh;
	private decimal _prevLow;
	private bool _hasPrev;

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

	public MaximusVxLiteStrategy()
	{
		_lookback = Param(nameof(Lookback), 20)
			.SetDisplay("Lookback", "Highest/Lowest lookback period", "General");

		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Time frame for candles", "General");
	}

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

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

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

		var highest = new Highest { Length = Lookback };
		var lowest = new Lowest { Length = Lookback };

		SubscribeCandles(CandleType).Bind(highest, lowest, ProcessCandle).Start();
	}

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

		if (!_hasPrev)
		{
			_prevHigh = highest;
			_prevLow = lowest;
			_hasPrev = true;
			return;
		}

		var close = candle.ClosePrice;

		// Breakout above previous highest
		if (close > _prevHigh && Position <= 0)
		{
			if (Position < 0) BuyMarket();
			BuyMarket();
		}
		// Breakout below previous lowest
		else if (close < _prevLow && Position >= 0)
		{
			if (Position > 0) SellMarket();
			SellMarket();
		}

		_prevHigh = highest;
		_prevLow = lowest;
	}
}