Ver en GitHub

Estrategia PSAR Trader v2

Descripción general

Esta estrategia opera reversiones del mercado usando el indicador Parabolic SAR. Se abre una posición cuando el valor del SAR cambia de lado con respecto al precio, señalando un posible cambio de tendencia. El algoritmo opera únicamente dentro de una ventana temporal especificada y puede opcionalmente cerrar una posición existente cuando aparece una señal opuesta.

Lógica de la estrategia

  • Indicador: Parabolic SAR.
  • Compra cuando el SAR se desplaza por debajo del cierre de la vela tras haber estado por encima de la vela anterior.
  • Venta cuando el SAR se desplaza por encima del cierre de la vela tras haber estado por debajo de la vela anterior.
  • Opera solo en el rango StartHourEndHour.
  • Cuando CloseOnOppositeSignal está habilitado, la posición se cierra si aparece una señal opuesta antes de abrir una nueva.

Gestión del riesgo

Al entrar en una posición, la estrategia establece niveles internos de take-profit y stop-loss. La posición se cierra automáticamente si el precio toca cualquiera de los niveles.

Parámetros

Nombre Descripción
CandleType Marco temporal de las velas utilizadas para operar.
Step Paso de aceleración del Parabolic SAR.
Maximum Factor de aceleración máximo del Parabolic SAR.
TakeProfit Objetivo de ganancia en unidades de precio.
StopLoss Stop loss en unidades de precio.
StartHour Hora de inicio de la operativa (0–23).
EndHour Hora de fin de la operativa (0–23).
CloseOnOppositeSignal Cerrar la posición actual cuando aparezca una señal opuesta.

Notas

Este ejemplo demuestra el uso básico de la API de alto nivel con un popular indicador de reversión de tendencia. Ajuste los parámetros y la gestión del riesgo según el instrumento operado y las preferencias personales.

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 trader v2 with reversal logic.
/// </summary>
public class PsarTraderV2Strategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<decimal> _step;
	private readonly StrategyParam<decimal> _maximum;

	private decimal _prevSar;
	private bool _prevPriceAboveSar;
	private bool _hasPrev;

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

	public PsarTraderV2Strategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Trading timeframe", "General");

		_step = Param(nameof(Step), 0.001m)
			.SetDisplay("PSAR Step", "Acceleration step for PSAR", "Indicators");

		_maximum = Param(nameof(Maximum), 0.2m)
			.SetDisplay("PSAR Maximum", "Maximum acceleration for PSAR", "Indicators");
	}

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

	protected override void OnReseted()
	{
		base.OnReseted();
		_prevSar = 0;
		_prevPriceAboveSar = false;
		_hasPrev = false;
	}

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

		var psar = new ParabolicSar
		{
			AccelerationStep = Step,
			AccelerationMax = Maximum
		};

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

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

		var priceAboveSar = candle.ClosePrice > sar;

		if (!_hasPrev)
		{
			_prevSar = sar;
			_prevPriceAboveSar = priceAboveSar;
			_hasPrev = true;
			return;
		}

		if (priceAboveSar != _prevPriceAboveSar)
		{
			if (priceAboveSar && Position <= 0)
			{
				if (Position < 0) BuyMarket();
				BuyMarket();
			}
			else if (!priceAboveSar && Position >= 0)
			{
				if (Position > 0) SellMarket();
				SellMarket();
			}
		}

		_prevSar = sar;
		_prevPriceAboveSar = priceAboveSar;
	}
}