EA31337 / EA31337-classes

📦📈 EA31337 framework (MQL library for writing trading Expert Advisors, indicators and scripts)
https://ea31337.github.io/EA31337-classes
GNU General Public License v3.0
178 stars 97 forks source link

Implement SAR Calculate() and OnIndicator() #710

Open kenorb opened 11 months ago

kenorb commented 11 months ago
#property indicator_separate_window

// Indicator parameters
extern double step = 0.02;
extern double maxStep = 0.20;
extern color sarColor = Lime;
extern bool showAlerts = true;
extern ENUM_ALERT_MODE alertMode = ALERT_ON_BARS;
extern ENUM_APPLIED_PRICE appliedPrice = PRICE_CLOSE;

// Indicator buffers
double sarBuffer[];
double afBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   // Set indicator buffers
   SetIndexBuffer(0, sarBuffer);
   SetIndexBuffer(1, afBuffer);

   // Set indicator label
   IndicatorShortName("Enhanced Parabolic SAR");

   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   int begin = MathMax(prev_calculated - 1, 2);

   for (int i = begin; i < rates_total; i++)
     {
      if (i == 2)
        {
         sarBuffer[i] = low[i - 1];
         afBuffer[i] = step;
        }
      else
        {
         if (sarBuffer[i - 1] < low[i - 1])
           sarBuffer[i] = sarBuffer[i - 1] + afBuffer[i - 1] * (low[i - 1] - sarBuffer[i - 1]);
         else
           sarBuffer[i] = sarBuffer[i - 1];

         if (sarBuffer[i] < low[i])
           sarBuffer[i] = low[i];

         if (sarBuffer[i] > high[i - 1])
           sarBuffer[i] = high[i - 1];

         afBuffer[i] = MathMin(afBuffer[i - 1] + step, maxStep);
        }
     }

   // Visual and sound alerts
   if (showAlerts && i > 2)
     {
      if (sarBuffer[i] > close[i] && sarBuffer[i - 1] <= close[i - 1])
        {
         string alertText = "Bearish Parabolic SAR Alert";
         if (alertMode == ALERT_ON_BARS)
           Alert(alertText);
         else if (alertMode == ALERT_ONCE_PER_BAR)
           AlertOncePerBar(alertText);
        }
      else if (sarBuffer[i] < close[i] && sarBuffer[i - 1] >= close[i - 1])
        {
         string alertText = "Bullish Parabolic SAR Alert";
         if (alertMode == ALERT_ON_BARS)
           Alert(alertText);
         else if (alertMode == ALERT_ONCE_PER_BAR)
           AlertOncePerBar(alertText);
        }
     }

   return(rates_total);
  }

//+------------------------------------------------------------------+
//| Function to show an alert once per bar                           |
//+------------------------------------------------------------------+
void AlertOncePerBar(string text)
  {
   static datetime lastAlertTime = 0;
   if (Time[0] != lastAlertTime)
     {
      Alert(text);
      lastAlertTime = Time[0];
     }
  }
//+------------------------------------------------------------------+