admin管理员组

文章数量:1134249

I have an indicator. But I want to convert it into an expert advisor. EAs do not have OnCalculate function and using SetIndexBuffer function might interfere with other indicators buffers. My indicator has a few buffers inside OnInit function, like this:

   SetIndexBuffer(0, SuperTrendIndicatorValue, INDICATOR_DATA);
   SetIndexBuffer(1, SuperTrendIndicatorColor, INDICATOR_COLOR_INDEX);
   SetIndexBuffer(2, SuperTrend, INDICATOR_CALCULATIONS);
   SetIndexBuffer(3, FinalUpperBand, INDICATOR_CALCULATIONS);
   SetIndexBuffer(4, FinalLowerBand, INDICATOR_CALCULATIONS);
   SetIndexBuffer(5, SuperTrendUpperBand, INDICATOR_CALCULATIONS);
   SetIndexBuffer(6, SuperTrendLowerBand, INDICATOR_CALCULATIONS);
   SetIndexBuffer(7, ATRBuffer, INDICATOR_CALCULATIONS);

And default variables inside OnCalculate function. Let me give you the rest of the code plus those function of OnCalculate:

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[])
{
   if (!CopyBuffer(ATRHandler, 0, 0, last_trend_rates, ATRBuffer))
   {
      Print("Error: ", GetLastError());
   }
   
   //--- calculate values of mtm and |mtm|
   int start;

   if(prev_calculated == 0)
     {
      start = 2;  // start filling from the 1st index
      PreviousTime = time[0];
      FinalLowerBand[0] = 0;
      FinalUpperBand[0] = 0;
      SuperTrendIndicatorValue[0] = 0;
      SuperTrend[0] = 0;
      
      PreviousTime = time[1];
      FinalLowerBand[1] = 0;
      FinalUpperBand[1] = 0;
      SuperTrendIndicatorValue[1] = 0;
      SuperTrend[0] = 0;
     }
   else
     {
      start = prev_calculated - 1;
     }

   for(int i = start; i <= last_trend_rates; i++)
   {
      if (prev_calculated == 0 || PreviousTime != time[i])
      {
         SuperTrendUpperBand[i] = getBasicUpperBand(high[i], low[i], Multiplier, ATRBuffer[i]);
         SuperTrendLowerBand[i] = getBasicLowerBand(high[i], low[i], Multiplier, ATRBuffer[i]);
         FinalUpperBand[i] = getFinalUpperBand(SuperTrendUpperBand[i], FinalUpperBand[i - 1], close[i]);
         FinalLowerBand[i] = getFinalLowerBand(SuperTrendLowerBand[i], FinalLowerBand[i - 1], close[i]);
         
         if(FinalUpperBand[i] != 0 && FinalLowerBand[i] != 0 && FinalUpperBand[i - 1] != 0 && FinalLowerBand[i - 1] != 0)
         {
            if(close[i] > FinalUpperBand[i - 1])
            {
               IsUpTrend = true;
            }
            
            if(close[i] < FinalLowerBand[i - 1])
            {
               IsUpTrend = false;
            }
         }
         
         if (IsUpTrend == true)
         {
            SuperTrendIndicatorValue[i] = FinalLowerBand[i];
            SuperTrendIndicatorColor[i] = 1;
            SuperTrend[i] = 1;
         }
         
         if (IsUpTrend == false)
         {
            SuperTrendIndicatorValue[i] = FinalUpperBand[i];
            SuperTrendIndicatorColor[i] = 0;
            SuperTrend[i] = -1;
         }
         
         
         Print(SuperTrend[i - 1]);
         Print(SuperTrend[i]);
         
         PreviousTime = time[i];
      }
   }
   
  
   
   return rates_total;
}


double getBasicUpperBand(
   double _high,
   double _low,
   int _MULTIPLIER,
   double _averageTrueRange)
  {
   double _highLowAverage = (_high + _low) / 2;
   double _basicBand = _highLowAverage + (_MULTIPLIER * _averageTrueRange);

   return _basicBand;
  }


double getBasicLowerBand(
   double _high,
   double _low,
   int _MULTIPLIER,
   double _averageTrueRange)
  {
   double _highLowAverage = (_high + _low) / 2;
   double _basicBand = _highLowAverage - (_MULTIPLIER * _averageTrueRange);

   return _basicBand;
  }


double getFinalLowerBand(double _currentbasicLowerBand,
                         double _previousFinalLowerBand,
                         double _previousClose)
  {
   double _currentBand;

   if(_currentbasicLowerBand > _previousFinalLowerBand ||
      _previousClose < _previousFinalLowerBand)
     {
      _currentBand = _currentbasicLowerBand;
     }
   else
     {
      _currentBand = _previousFinalLowerBand;
     }

   return _currentBand;
  }



double getFinalUpperBand(double _currentbasicUpperBand,
                         double _previousFinalUpperBand,
                         double _previousClose)
  {
   double _currentBand;

   if(_currentbasicUpperBand < _previousFinalUpperBand || _previousClose > _previousFinalUpperBand)
     {
      _currentBand = _currentbasicUpperBand;
     }
   else
     {
      _currentBand = _previousFinalUpperBand;
     }

   return _currentBand;
  }

Perhaps I should define those 7 buffers inside OnTick function. It might be the first lines of the EA:

#property copyright "Copyright 2024, MetaQuotes Ltd."
#property link      ";
#property version   "1.00"
#property indicator_chart_window

#property indicator_type1   DRAW_COLOR_LINE
#property indicator_color1  clrRed,clrGreen

//-- Input Variables
int      ATR_Period = 14;
input int      Multiplier = 2;

//-- Global Varibles
int            ATRHandler;

datetime       PreviousTime;

bool           IsUpTrend = NULL;

int last_trend_rates = 16;
   
//-- Buffers
double ATRBuffer[];
double SuperTrendLowerBand[];
double SuperTrendUpperBand[];
double FinalUpperBand[];
double FinalLowerBand[];
double SuperTrendIndicatorValue[];
double SuperTrendIndicatorColor[];
double SuperTrend[];

// Initialization
int OnInit()
{
   ATRHandler = iATR(_Symbol, PERIOD_M1, ATR_Period);
   if (ATRHandler == INVALID_HANDLE)
   {
      Print("Failed to get ATR handle");
      return INIT_FAILED;
   }
   ArraySetAsSeries(ATRBuffer, true);
//I removed the buffers!!!
   return INIT_SUCCEEDED;
}

// I wrote the first lines of OnTick function, like this:
void OnTick()
{
   if (!CopyBuffer(ATRHandler, 0, 0, last_trend_rates, ATRBuffer))
   {
      Print("Error copying ATR buffer: ", GetLastError());
      return;
   }
   // I wrote the high and low and close of OnCalculate function for OnTick function:
   double high = iHigh(_Symbol, PERIOD_M1, 0);
   double low = iLow(_Symbol, PERIOD_M1, 0);
   double close = iClose(_Symbol, PERIOD_M1, 0);
   
   int start;

Now I should write the prev_calculated of the OnCalculate function for the OnTick function, like this: if(prev_calculated == 0), and the rest of the functions... But I'm confused.

Is it a hard job to convert the other functions?

本文标签: Converting an indicator to an EAmql5 programmingStack Overflow