Auf GitHub ansehen

PSAR Trader Ticks-Strategie

Strategie basierend auf dem Parabolic SAR-Indikator. PSAR Trader Ticks folgt den Punkten des Parabolic SAR-Indikators und reagiert, wenn der Preis von einer Seite zur anderen kreuzt. Es eröffnet eine Long-Position, wenn der Preis über den SAR steigt, und eine Short-Position, wenn der Preis unter ihn fällt. Der Handel kann auf einen bestimmten Zeitbereich beschränkt werden, und bestehende Positionen können optional geschlossen werden, wenn ein gegenteiliges Signal erscheint. Die Strategie wendet auch Take-Profit- und Stop-Loss-Niveaus an, die in Ticks gemessen werden.

Details

  • Einstiegskriterien: Preis, der den Parabolic SAR-Indikator kreuzt.
  • Long/Short: Beide Richtungen.
  • Ausstiegskriterien: Entgegengesetztes Signal (optional), Stop-Loss oder Take-Profit.
  • Stops: Take-Profit und Stop-Loss in Ticks.
  • Standardwerte:
    • Step = 0.001m
    • Maximum = 0.2m
    • TakeProfitTicks = 50
    • StopLossTicks = 50
    • StartHour = 0
    • EndHour = 23
    • CloseOnOpposite = true
    • CandleType = TimeSpan.FromMinutes(5)
  • Filter:
    • Kategorie: Trend
    • Richtung: Beide
    • Indikatoren: Parabolic SAR
    • Stops: Take-Profit, Stop-Loss
    • Komplexität: Grundlegend
    • Zeitrahmen: Intraday (5m)
    • Saisonalität: Nein
    • Neuronale Netze: Nein
    • Divergenz: Nein
    • Risikolevel: Mittel
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>
/// PSAR Trader strategy - opens long when price crosses above SAR
/// and short when price crosses below SAR.
/// </summary>
public class PsarTraderTicksStrategy : Strategy
{
	private readonly StrategyParam<decimal> _step;
	private readonly StrategyParam<decimal> _maximum;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevSar;
	private decimal _prevPrice;
	private bool _hasPrev;

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

	public PsarTraderTicksStrategy()
	{
		_step = Param(nameof(Step), 0.001m)
			.SetDisplay("SAR Step", "Acceleration factor step", "Indicators");
		_maximum = Param(nameof(Maximum), 0.2m)
			.SetDisplay("SAR Maximum", "Maximum acceleration factor", "Indicators");
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Type of candles to use", "General");
	}

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

	protected override void OnReseted()
	{
		base.OnReseted();
		_prevSar = 0;
		_prevPrice = 0;
		_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 sarValue)
	{
		if (candle.State != CandleStates.Finished) return;

		if (!_hasPrev)
		{
			_prevSar = sarValue;
			_prevPrice = candle.ClosePrice;
			_hasPrev = true;
			return;
		}

		var prevAbove = _prevPrice > _prevSar;
		var currAbove = candle.ClosePrice > sarValue;

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

		_prevSar = sarValue;
		_prevPrice = candle.ClosePrice;
	}
}