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
186 stars 98 forks source link

Trade: Add calculation of support and resistance #52

Open kenorb opened 5 years ago

kenorb commented 5 years ago

For example:

// See: http://forum.mql4.com/49780
void CalculateSupRes() {
   int commonPoint;
   int minLevel, maxLevel;
   double highest, lowest, stepIncrement, tolerance, high;
   double storeLevel[];
   ///ArrayResize(storeLevel, loopback);

   minLevel = iLowest(Symbol(), Period(), MODE_LOW, loopback, 0);
   maxLevel = iHighest(Symbol(), Period(), MODE_HIGH, loopback, 0);
   highest = iHigh(Symbol(), Period(), maxLevel);
   lowest = iLow(Symbol(), Period(), minLevel);

   //Print("max: " + highest + " min: " + lowest);
   stepIncrement = 0.0005;
   tolerance = 0.0002;
   static double tmp;
   tmp = 0.0;

   for (double actPrice = lowest; actPrice <= highest; actPrice += stepIncrement) {
      for (int i = 1; i <= loopback; i++) {
         //do some stuff here...
         high = iHigh(Symbol(), Period(), i);
         double topRange, bottomRange;
         // if is the first value tmp stores the first high encountered until that moment
         if (tmp == 0) {
            tmp = high;
         } else {
            //define a buffer adding a subtracting from tmp to check if the new high is within that value
            topRange = tmp + tolerance;
            bottomRange = tmp - tolerance;

            if (high <= topRange && high >= bottomRange) {
               commonPoint++;
            }
         }
         //if has been touched at least three times reset common point
         //tmp goes to the new high value to keep looping
         if (commonPoint == 3) {
            commonPoint = 0;
            tmp = high;
            ///Print("valore tmp: " + tmp);
            storeLevel[i] = tmp;
         }
      }
   }
}

Refs: https://www.mql5.com/en/forum/140136

kenorb commented 1 year ago

Indicator:

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 Blue
#property indicator_color2 Red

//--- input parameters
input int period = 20; // Number of bars to use for support/resistance line calculation

//--- indicator buffers
double SupportBuffer[];
double ResistanceBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   // Set indicator short name
   IndicatorShortName("Support & Resistance Lines");

   // Set indicator buffers
   SetIndexBuffer(0, SupportBuffer);
   SetIndexBuffer(1, ResistanceBuffer);

   // Plot the indicator on a separate window
   IndicatorDigits(4);
   IndicatorSetInteger(INDICATOR_DIGITS, 4);
   IndicatorSetInteger(INDICATOR_WIDTH1, 2);
   IndicatorSetInteger(INDICATOR_WIDTH2, 2);

   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 startIdx = MathMax(0, rates_total - period);
   int limit = rates_total - startIdx;

   // Calculate the least squares regression line (support line) and resistance line
   double sumX = 0, sumYLow = 0, sumYHigh = 0, sumXYLow = 0, sumXYHigh = 0, sumXX = 0;
   for (int i = startIdx; i < rates_total; i++)
   {
      double x = i - startIdx;
      double yLow = low[i];
      double yHigh = high[i];

      sumX += x;
      sumYLow += yLow;
      sumYHigh += yHigh;
      sumXYLow += x * yLow;
      sumXYHigh += x * yHigh;
      sumXX += x * x;
   }

   double supportSlope = (period * sumXYLow - sumX * sumYLow) / (period * sumXX - sumX * sumX);
   double supportIntercept = (sumYLow - supportSlope * sumX) / period;

   double resistanceSlope = (period * sumXYHigh - sumX * sumYHigh) / (period * sumXX - sumX * sumX);
   double resistanceIntercept = (sumYHigh - resistanceSlope * sumX) / period;

   // Calculate the support and resistance line values
   for (int i = startIdx; i < rates_total; i++)
   {
      double x = i - startIdx;
      SupportBuffer[i] = supportSlope * x + supportIntercept;
      ResistanceBuffer[i] = resistanceSlope * x + resistanceIntercept;
   }

   return (rates_total);
}

Oscillator:

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Blue

//--- input parameters
input int period = 20; // Number of bars to use for support/resistance line calculation

//--- indicator buffers
double OscillatorBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   // Set indicator short name
   IndicatorShortName("Support & Resistance Oscillator");

   // Set indicator buffers
   SetIndexBuffer(0, OscillatorBuffer);

   // Plot the indicator on a separate window
   IndicatorDigits(4);
   IndicatorSetInteger(INDICATOR_DIGITS, 4);
   IndicatorSetInteger(INDICATOR_WIDTH1, 2);

   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 startIdx = MathMax(0, rates_total - period);
   int limit = rates_total - startIdx;

   // Calculate the least squares regression line (support line) and resistance line
   double sumX = 0, sumYLow = 0, sumYHigh = 0, sumXYLow = 0, sumXYHigh = 0, sumXX = 0;
   for (int i = startIdx; i < rates_total; i++)
   {
      double x = i - startIdx;
      double yLow = low[i];
      double yHigh = high[i];

      sumX += x;
      sumYLow += yLow;
      sumYHigh += yHigh;
      sumXYLow += x * yLow;
      sumXYHigh += x * yHigh;
      sumXX += x * x;
   }

   double supportSlope = (period * sumXYLow - sumX * sumYLow) / (period * sumXX - sumX * sumX);
   double supportIntercept = (sumYLow - supportSlope * sumX) / period;

   double resistanceSlope = (period * sumXYHigh - sumX * sumYHigh) / (period * sumXX - sumX * sumX);
   double resistanceIntercept = (sumYHigh - resistanceSlope * sumX) / period;

   // Calculate the oscillator values
   for (int i = startIdx; i < rates_total; i++)
   {
      double x = i - startIdx;
      double supportValue = supportSlope * x + supportIntercept;
      double resistanceValue = resistanceSlope * x + resistanceIntercept;

      // Calculate the oscillator value as the distance between the current price and the support/resistance lines
      OscillatorBuffer[i] = close[i] - (supportValue + resistanceValue) / 2;
   }

   return (rates_total);
}
kenorb commented 1 year ago
// Define input parameters
input int loopback = 10; // Number of candles to consider
input double stepIncrement = 0.0005; // Price step increment
input double tolerance = 0.0002; // Tolerance range

// Declare variables
double highest = iHigh(Symbol(), Period(), 0);
double lowest = iLow(Symbol(), Period(), 0);
double storeLevel[];
int commonPoint;

// Calculate highest and lowest levels
for (int i = 1; i <= loopback; i++) {
    double high = iHigh(Symbol(), Period(), i);
    double low = iLow(Symbol(), Period(), i);

    if (high > highest) highest = high;
    if (low < lowest) lowest = low;
}

// Initialize tmp with the first high encountered
double tmp = iHigh(Symbol(), Period(), loopback);

// Loop through the price range
for (double actPrice = lowest; actPrice <= highest; actPrice += stepIncrement) {
    int touchedCount = 0;

    for (int i = 1; i <= loopback; i++) {
        double high = iHigh(Symbol(), Period(), i);
        double topRange = tmp + tolerance;
        double bottomRange = tmp - tolerance;

        // Check if the high is within the tolerance range
        if (high <= topRange && high >= bottomRange) {
            touchedCount++;
        }

        // Update tmp if touchedCount reaches 3
        if (touchedCount == 3) {
            storeLevel[i] = tmp;
            touchedCount = 0;
        }
    }

    // Update tmp with the current actPrice
    tmp = actPrice;
}