Ver en GitHub

Estrategia Parabolic SAR Bug

La estrategia Parabolic SAR Bug opera reversiones de tendencia utilizando el indicador Parabolic SAR. Cuando el SAR gira por debajo del precio, la estrategia entra largo, y cuando el SAR gira por encima del precio entra corto. El modo reverse opcional invierte las señales. El stop loss protector, take profit y trailing stop son compatibles a través del módulo de protección de posición integrado.

Detalles

  • Criterios de entrada: Cambio de dirección del Parabolic SAR.
  • Largo/Corto: Ambas direcciones.
  • Criterios de salida: Señal SAR opuesta o stop protector.
  • Stops: Stop loss, take profit, trailing stop opcional.
  • Valores predeterminados:
    • Step = 0.02
    • MaxStep = 0.2
    • StopLossPercent = 2
    • TakeProfitPercent = 1
    • UseTrailingStop = false
    • Reverse = false
    • CloseOnSar = true
    • CandleType = TimeSpan.FromMinutes(5)
  • Filtros:
    • Categoría: Tendencia
    • Dirección: Ambos
    • Indicadores: Parabolic SAR
    • Stops: Stop loss, take profit
    • Complejidad: Básico
    • Marco temporal: Intradía (5m)
    • 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>
/// Parabolic SAR crossover strategy.
/// Buys when price crosses above SAR, sells when price crosses below.
/// </summary>
public class ParabolicSarBugStrategy : Strategy
{
	private readonly StrategyParam<decimal> _step;
	private readonly StrategyParam<decimal> _maxStep;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevSar;
	private decimal _prevClose;
	private bool _initialized;

	public decimal Step { get => _step.Value; set => _step.Value = value; }
	public decimal MaxStep { get => _maxStep.Value; set => _maxStep.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public ParabolicSarBugStrategy()
	{
		_step = Param(nameof(Step), 0.02m)
			.SetDisplay("Step", "Acceleration factor", "Indicator");

		_maxStep = Param(nameof(MaxStep), 0.2m)
			.SetDisplay("Max Step", "Maximum acceleration", "Indicator");

		_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();
		_prevSar = 0;
		_prevClose = 0;
		_initialized = false;
	}

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

		var sar = new ParabolicSar
		{
			Acceleration = Step,
			AccelerationMax = MaxStep
		};

		SubscribeCandles(CandleType).Bind(sar, ProcessCandle).Start();
	}

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

		var close = candle.ClosePrice;

		if (!_initialized)
		{
			_prevSar = sarValue;
			_prevClose = close;
			_initialized = true;
			return;
		}

		var crossUp = close > sarValue && _prevClose <= _prevSar;
		var crossDown = close < sarValue && _prevClose >= _prevSar;

		if (crossUp && Position <= 0)
		{
			if (Position < 0) BuyMarket();
			BuyMarket();
		}
		else if (crossDown && Position >= 0)
		{
			if (Position > 0) SellMarket();
			SellMarket();
		}

		_prevSar = sarValue;
		_prevClose = close;
	}
}