This strategy trades market reversals using the Parabolic SAR indicator. A position is opened when the SAR value switches sides relative to price, signalling a potential change in trend. The algorithm operates only within a specified time window and can optionally close an existing position when an opposite signal appears.
Strategy Logic
Indicator: Parabolic SAR.
Buy when SAR moves below the candle close after being above the previous candle.
Sell when SAR moves above the candle close after being below the previous candle.
Trades only during the StartHour–EndHour range.
When CloseOnOppositeSignal is enabled, a position is closed if an opposite signal occurs before opening a new one.
Risk Management
Upon entering a position the strategy sets internal take-profit and stop-loss levels. The position is closed automatically if price touches either level.
Parameters
Name
Description
CandleType
Timeframe of candles used for trading.
Step
Acceleration step of the Parabolic SAR.
Maximum
Maximum acceleration factor of the Parabolic SAR.
TakeProfit
Profit target in price units.
StopLoss
Stop loss in price units.
StartHour
Hour to start trading (0–23).
EndHour
Hour to stop trading (0–23).
CloseOnOppositeSignal
Close current position when an opposite signal appears.
Notes
This example demonstrates basic usage of the high level API with a popular trend reversal indicator. Adjust parameters and risk management according to the traded instrument and personal preferences.
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;
}
}