Ver en GitHub

Estrategia SuperTrend de Reversión de Pivot Mejorada

Combina la dirección del SuperTrend con rupturas de máximos/mínimos de pivot. Se coloca un stop de compra por encima de un máximo de pivot reciente cuando el SuperTrend es bajista. Se coloca un stop de venta por debajo de un mínimo de pivot cuando el SuperTrend es alcista. Las posiciones están protegidas con un stop-loss porcentual desde el pivot.

Detalles

  • Criterios de entrada:
    • Largo: Formado un máximo de pivot, SuperTrend bajista → stop de compra por encima del pivot.
    • Corto: Formado un mínimo de pivot, SuperTrend alcista → stop de venta por debajo del pivot.
  • Dirección: Configurable.
  • Criterios de salida: Stop-loss porcentual o dirección opuesta para el modo unilateral.
  • Indicadores: SuperTrend, máximos/mínimos de pivot.
  • Valores predeterminados:
    • LeftBars = 6
    • RightBars = 3
    • AtrLength = 5
    • Factor = 2.618
    • StopLossPercent = 20
    • TradeDirection = Both
    • CandleType = 5 minute
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>
/// SuperTrend Enhanced Pivot Reversal strategy using EMA crossover.
/// </summary>
public class SuperTrendEnhancedPivotReversalStrategy : Strategy
{
	private readonly StrategyParam<int> _slowLength;
	private readonly StrategyParam<DataType> _candleType;

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

	public SuperTrendEnhancedPivotReversalStrategy()
	{
		_slowLength = Param(nameof(SlowLength), 40)
			.SetGreaterThanZero()
			.SetDisplay("Slow Length", "Slow EMA period", "General");

		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Candle type", "General");
	}

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

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		var fast = new ExponentialMovingAverage { Length = 14 };
		var slow = new ExponentialMovingAverage { Length = SlowLength };
		var prevF = 0m; var prevS = 0m; var init = false;
		var lastSignal = DateTimeOffset.MinValue;
		var cooldown = TimeSpan.FromMinutes(360);
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(fast, slow, (candle, f, s) =>
		{
			if (candle.State != CandleStates.Finished) return;
			if (!fast.IsFormed || !slow.IsFormed) return;
			if (!init) { prevF = f; prevS = s; init = true; return; }
			if (candle.OpenTime - lastSignal >= cooldown)
			{
				if (prevF <= prevS && f > s && Position <= 0) { BuyMarket(); lastSignal = candle.OpenTime; }
				else if (prevF >= prevS && f < s && Position >= 0) { SellMarket(); lastSignal = candle.OpenTime; }
			}
			prevF = f; prevS = s;
		}).Start();
		var area = CreateChartArea();
		if (area != null) { DrawCandles(area, subscription); DrawIndicator(area, fast); DrawIndicator(area, slow); DrawOwnTrades(area); }
	}
}