No signals generated from iSAR cross

 

Hello, I'm sorry if the question sounds a bit dumb. I sought ways to improve my strategy and decided to add Parabolic SAR signals.

So I wrote this small class to handle that:

class ParabolicSARSignal
  {
private:
   int               handle;        // Indicator handle
   double            sarBuffer[];   // Buffer for SAR values
   MqlRates          rates[];       // Buffer for price data
   ENUM_TIMEFRAMES   timeframe;     // Timeframe for the indicator

public:
   // Constructor: Initializes the Parabolic SAR indicator
                     ParabolicSARSignal(double step, double maximum, ENUM_TIMEFRAMES tf = PERIOD_M1)
     {
      timeframe = tf;
      handle = iSAR(_Symbol, tf, step, maximum);
      ArraySetAsSeries(sarBuffer, true);
      ArraySetAsSeries(rates, true);
     }

   // Releases the indicator handle
                    ~ParabolicSARSignal()
     {
      IndicatorRelease(handle);
     }

   // Detects when SAR switches sides relative to price
   int               CheckSignal(int shift = 0)  //Shifts reference candle backwards. 0 --> bar 0
     {
      if(handle == INVALID_HANDLE)
         return 0;
      int refCandle = 0  + shift;//If not candle 0, then move back shift units
      int prefCandle = 1  + shift;//If not candle 1, then move back shift units
      // Copy SAR values for the last 2 bars
      if(CopyBuffer(handle, 0, 0, 3 + shift, sarBuffer) < 3)
         return 0;

      // Copy price data for the last 2 bars
      if(CopyRates(_Symbol, timeframe, 0, 3 + shift, rates) < 3)
         return 0;
      // Downtrend to uptrend
      if(sarBuffer[prefCandle] > rates[prefCandle].high && sarBuffer[refCandle] < rates[refCandle].low)
         return -1; // Bullish signal

      // Uptrend to downtrend
      if(sarBuffer[prefCandle] < rates[prefCandle].low && sarBuffer[refCandle] > rates[refCandle].high)
         return 1;  // Bearish signal

      return 0; // No signal
     }

   //Retrieves the SAR value for a specific bar shift
   double            GetSAR(int shift = 0)
     {
      if(CopyBuffer(handle, 0, shift, 1, sarBuffer) == 1)
         return sarBuffer[0];
      return 0; // Return 0 if copy fails
     }

   //Determines the current trend direction based on last closed bar
   int               GetTrendDirection()
     {
      if(handle == INVALID_HANDLE)
         return 0;

      double sar[1];
      if(CopyBuffer(handle, 0, 1, 1, sar) < 1)
         return 0;

      double close = iClose(_Symbol, timeframe, 1);
      if(close == 0)
         return 0; // If close is not available

      if(close > sar[0])
         return -1; // Bullish trend
      else
         return 1;  // Bearish trend
     }
  };

However when I try to test it, at first i didn't see any signals. When I left the test to run to the end, I realized it only registered a few signals compared to a whole lot more missed.

Here is the ontick code:

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(!isNewBar())
      return;
   int signal = mySignal.CheckSignal(0);
   int trend = mySignal.GetTrendDirection();

   Print("Signal: ", signal, " || trend: ",trend);
   if(signal != 0)
      Print("Signal on Trend Switch");
  }

And it is expected that a signal will fire after the PSAR switches to the other side of the price. I have looked at a lot of examples and videos I can't find where I get wrong. In all the videos I watched, this seemed to work well.

2025.04.29 11:15:58.611 2025.01.17 20:59:00   Signal: 0 || trend: -1
2025.04.29 11:15:58.611 2025.01.17 21:00:00   Signal: 0 || trend: -1
2025.04.29 11:15:58.611 2025.01.17 21:01:00   Signal: 0 || trend: 1
2025.04.29 11:15:58.611 2025.01.17 21:02:00   Signal: 0 || trend: 1


//---> Expected the "Signal on Trend Switch" at this trend change moment




UPDATE:

I called the signal method with a shift = 1 and it worked. The downside is that I have to wait for full candle closure after to make trade decision.

int signal = mySignal.CheckSignal(
1 );
2025.04.29 11:21:18.460 2025.01.17 14:30:00   Signal: 0 || trend: 1
2025.04.29 11:21:18.460 2025.01.17 14:31:00   Signal: -1 || trend: -1
2025.04.29 11:21:18.460 2025.01.17 14:31:00   Signal on Trend Switch
2025.04.29 11:21:18.460 2025.01.17 14:32:00   Signal: 0 || trend: -1

//--->This is what I was looking for

It seems the parabolic Sar indicator repaints on index 0 and maybe that's why I dont get signals when I use indices 0 and 1 but I get the results on 1 and 2. But why does it work on the others? Every video and tutorial I watched used the current candle and they were getting signals.

Parabolic SAR - Trend Indicators - Technical Indicators - Price Charts, Technical and Fundamental Analysis - MetaTrader 5 Help
Parabolic SAR - Trend Indicators - Technical Indicators - Price Charts, Technical and Fundamental Analysis - MetaTrader 5 Help
  • www.metatrader5.com
Parabolic SAR Technical Indicator was developed for analyzing the trending markets. The indicator is constructed on the price chart. This indicator...
 
All indicators repaints on current candle if they use high, low or close prices to calculate. Only if using open price you will have static value for current bar.

Anyway the need of checking last closed candle is not only a downside, you can build more solid and less tick sensitive strategies, plus possibility to backtest using faster methods rather than real ticks (but to be reliable this depends also on other aspect of your strategy).
 
      // Downtrend to uptrend
      if(sarBuffer[prefCandle] > rates[prefCandle].high && sarBuffer[refCandle] < rates[refCandle].low)
         return -1; // Bullish signal

      // Uptrend to downtrend
      if(sarBuffer[prefCandle] < rates[prefCandle].low && sarBuffer[refCandle] > rates[refCandle].high)
         return 1;  // Bearish signal

this logic is wrong


it should be like this (as an example):

    // Downtrend to uptrend
      if(sarBuffer[0] < rates[0].close && sarBuffer[1] > rates[1].close)
         return -1; // Bullish signal

      // Uptrend to downtrend
      if(sarBuffer[0] > rates[0].close && sarBuffer[1] < rates[1].close)
         return 1;  // Bearish signal

using close price has its benefits (won't miss the entry), and the open price might help with false signals...but you might miss entries as well

 
Fabio Cavalloni #:
All indicators repaints on current candle if they use high, low or close prices to calculate. Only if using open price you will have static value for current bar.

Anyway the need of checking last closed candle is not only a downside, you can build more solid and less tick sensitive strategies, plus possibility to backtest using faster methods rather than real ticks (but to be reliable this depends also on other aspect of your strategy).

I just wanted to add this as an alternative signal source and filter. On the chat, I always see a dot printed on the current bar. I don't know if it does it on open or a few ticks in. But when I tried to wait for the signal midbar, I got a signal almost every tick, even though there was none. I'd prefer if it worked on the current bar because my strategy is quick in and out but I will research more and adapt.

 
Kevin Onsongo #:

I just wanted to add this as an alternative signal source and filter. On the chat, I always see a dot printed on the current bar. I don't know if it does it on open or a few ticks in. But when I tried to wait for the signal midbar, I got a signal almost every tick, even though there was none. I'd prefer if it worked on the current bar because my strategy is quick in and out but I will research more and adapt.

If you need it to work "as a filter", you can only check a single candle, better if the last closed one, so values are sticky and not changes.

If you are planning to use "as a signal" you should use something like the crossover, using 2 candles, like the current and the previous one, or better, the last closed and the previous one (for the same reason of what I explained before).

You should compare indicator value with high/low of the candle.

 
Conor Mcnamara #:

this logic is wrong


it should be like this (as an example):

using close price has its benefits (won't miss the entry), and the open price might help with false signals...but you might miss entries as well

Thank you. I will use this and test it out. Weirdly, many of the tutorials I watched before and articles here used high and low prices. It seems to work for them, but I can't reproduce the same behavior. This is one of the articles. https://www.mql5.com/en/articles/10920

Learn how to design a trading system by Parabolic SAR
Learn how to design a trading system by Parabolic SAR
  • www.mql5.com
In this article, we will continue our series about how to design a trading system using the most popular indicators. In this article, we will learn about the Parabolic SAR indicator in detail and how we can design a trading system to be used in MetaTrader 5 using some simple strategies.
 
Fabio Cavalloni #:

If you need it to work "as a filter", you can only check a single candle, better if the last closed one, so values are sticky and not changes.

If you are planning to use "as a signal" you should use something like the crossover, using 2 candles, like the current and the previous one, or better, the last closed and the previous one (for the same reason of what I explained before).

You should compare indicator value with high/low of the candle.

Thank you. As I mentioned, the signals work on the last closed candle and the previous one. I shifted the index by 1, and it worked. I'll try to figure out how to use these signals to work well with my strategy. If it doesn't, I'll use it only as a filter, which already works well.

 
Kevin Onsongo:

Hello, I'm sorry if the question sounds a bit dumb. I sought ways to improve my strategy and decided to add Parabolic SAR signals.

So I wrote this small class to handle that:

However when I try to test it, at first i didn't see any signals. When I left the test to run to the end, I realized it only registered a few signals compared to a whole lot more missed.

Here is the ontick code:

And it is expected that a signal will fire after the PSAR switches to the other side of the price. I have looked at a lot of examples and videos I can't find where I get wrong. In all the videos I watched, this seemed to work well.




UPDATE:

I called the signal method with a shift = 1 and it worked. The downside is that I have to wait for full candle closure after to make trade decision.

It seems the parabolic Sar indicator repaints on index 0 and maybe that's why I dont get signals when I use indices 0 and 1 but I get the results on 1 and 2. But why does it work on the others? Every video and tutorial I watched used the current candle and they were getting signals.

Parabolic SAR on bar 0 repaints because the candle is still forming, so signals from shift = 0 are unreliable. When you use shift = 1 , you're checking the last fully closed candle — the SAR value is stable and final. That’s why signals appear correctly with shift = 1 . Stick with that for consistent and valid results.

 
Arda Kaya #:

Parabolic SAR on bar 0 repaints because the candle is still forming, so signals from shift = 0 are unreliable. When you use shift = 1 , you're checking the last fully closed candle — the SAR value is stable and final. That’s why signals appear correctly with shift = 1 . Stick with that for consistent and valid results.

Thanks