Discrepancy between the value of the average Close line and the value used to generate the buy/sell signal.

 
Hello everyone I wrote this code:


//+------------------------------------------------------------------+
//| Simple_Alert.mq5                                                |
//| Copyright 2024, MetaQuotes Software Corp.                        |
//| http://www.metaquotes.net/                                       |
//+------------------------------------------------------------------+

// Indicator properties
#property version      "1.01"          // Indicator version
#property description  "Indicator with EMA Close and Buy/Sell signals"
#property indicator_chart_window     // Display indicator in the chart window

// Buffer and plot properties
#property indicator_buffers 1
#property indicator_plots   1

// Define plot for EMA Close
#property indicator_label1 "EMA Close"
#property indicator_type1  DRAW_LINE
#property indicator_color1 clrMagenta
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2     // Line thickness

// Input parameters for EMA Close
input int ema_period_close  = 28;  // Period for EMA Close
input ENUM_MA_METHOD ema_method = MODE_EMA;  // Moving average method (EMA default)

// Global variables for managing EMA Close
int ema_handle_close;  // Handle for EMA Close
double ema_buffer_close[];  // Buffer for EMA Close values
double current_price;   // Current symbol price

// Variables for managing active signal
string current_signal_type = "";

//+------------------------------------------------------------------+
//| Function to display EMA Close value as an object on the chart     |
//+------------------------------------------------------------------+
void EmaValue()
{
   // Remove previous object if it exists
   ObjectDelete(0, "EMAValue");

   // Show EMA Close value as an object on the chart
   string ema_close_comment = StringFormat("EMA Close: %.5f", ema_buffer_close[Bars(_Symbol, _Period) - 1]);
   int x = 10;
   int y = 70;
   ObjectCreate(0, "EMAValue", OBJ_LABEL, 0, 0, 0);
   ObjectSetInteger(0, "EMAValue", OBJPROP_XDISTANCE, x);
   ObjectSetInteger(0, "EMAValue", OBJPROP_YDISTANCE, y);
   ObjectSetInteger(0, "EMAValue", OBJPROP_CORNER, 0);
   ObjectSetInteger(0, "EMAValue", OBJPROP_XSIZE, 200);
   ObjectSetInteger(0, "EMAValue", OBJPROP_YSIZE, 100);
   ObjectSetInteger(0, "EMAValue", OBJPROP_COLOR, clrMagenta);
   ObjectSetInteger(0, "EMAValue", OBJPROP_FONTSIZE, 12);
   ObjectSetString(0, "EMAValue", OBJPROP_TEXT, ema_close_comment);
}

//+------------------------------------------------------------------+
//| Function to generate alert, draw signal, and comment              |
//+------------------------------------------------------------------+
void AlertAndDrawSignal(string message, color clr)
{
   // Draw current signal label on the chart
   int x = 10;
   int y = 50;
   ObjectCreate(0, "CurrentSignal", OBJ_LABEL, 0, 0, 0);
   ObjectSetInteger(0, "CurrentSignal", OBJPROP_XDISTANCE, x);
   ObjectSetInteger(0, "CurrentSignal", OBJPROP_YDISTANCE, y);
   ObjectSetInteger(0, "CurrentSignal", OBJPROP_CORNER, 0);
   ObjectSetInteger(0, "CurrentSignal", OBJPROP_XSIZE, 200);
   ObjectSetInteger(0, "CurrentSignal", OBJPROP_YSIZE, 100);
   ObjectSetInteger(0, "CurrentSignal", OBJPROP_COLOR, clr);
   ObjectSetInteger(0, "CurrentSignal", OBJPROP_FONTSIZE, 12);
   ObjectSetString(0, "CurrentSignal", OBJPROP_TEXT, message);

   // Display EMA Close value as an object on the chart
   EmaValue();
}

//+------------------------------------------------------------------+
//| Initialization function for the indicator                        |
//+------------------------------------------------------------------+
int OnInit()
{
   // Calculate EMA Close and initialize buffer
   ema_handle_close = iMA(_Symbol, _Period, ema_period_close, 0, ema_method, PRICE_CLOSE);

   int bars = Bars(_Symbol, _Period);
   ArrayResize(ema_buffer_close, bars);
   SetIndexBuffer(0, ema_buffer_close);

   return INIT_SUCCEEDED;
}

//+------------------------------------------------------------------+
//| Calculation function for the indicator                           |
//+------------------------------------------------------------------+
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[])
{
   // Calculate EMA Close and fill buffer
   ArraySetAsSeries(ema_buffer_close, true);
   ema_handle_close = iMA(_Symbol, _Period, ema_period_close, 0, ema_method, PRICE_CLOSE);
   CopyBuffer(ema_handle_close, 0, 0, rates_total, ema_buffer_close);

   // Calculate current closing price
   current_price = SymbolInfoDouble(_Symbol, SYMBOL_LAST);

   // Remove current signal label if no active signal
   ObjectDelete(0, "CurrentSignal");

   // Remove previous EMA value object
   ObjectDelete(0, "EMAValue");

   // Generate Buy signal when current price is above EMA Close
   if (current_price > ema_buffer_close[rates_total-1])
   {
      current_signal_type = "Buy Signal!";
      AlertAndDrawSignal(current_signal_type, clrGreen);  // Draw Buy signal label
   }
   // Generate Sell signal when current price is below EMA Close
   else if (current_price < ema_buffer_close[rates_total-1])
   {
      current_signal_type = "Sell Signal!";
      AlertAndDrawSignal(current_signal_type, clrRed);  // Draw Sell signal label
   }

   // Display EMA Close value as an object on the chart
   EmaValue();

   return rates_total;
}

//+------------------------------------------------------------------+
//| Deinitialization function for the indicator                      |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // Remove current signal label and EMA value object on deinitialization
   ObjectDelete(0, "CurrentSignal");
   ObjectDelete(0, "EMAValue");
}

It's simple yet I noticed a discrepancy between the Close line, which reports the correct average value, and the Ema_value on the screen which is the average that is used by the program to indentify the condition and gives the input signal.
I cannot understand where the error is, can anyone help me?
MetaQuotes — the developer of trading platforms for brokers, banks, exchanges and hedge funds
MetaQuotes — the developer of trading platforms for brokers, banks, exchanges and hedge funds
  • www.metaquotes.net
MetaTrader 5 trading platform is a free Forex and stock trading tool
 
  1.    int bars = Bars(_Symbol, _Period);
       ArrayResize(ema_buffer_close, bars);

    Buffers are automatically resized. Don't try to use any price (or indicator) or server related functions in OnInit (or on load or in OnTimer before you've received a tick), as there may be no connection/chart yet:

    1. Terminal starts.
    2. Indicators/EAs are loaded. Static and globally declared variables are initialized. (Do not depend on a specific order.)
    3. OnInit is called.
    4. For indicators OnCalculate is called with any existing history.
    5. Human may have to enter password, connection to server begins.
    6. New history is received, OnCalculate called again.
    7. A new tick is received, OnCalculate/OnTick is called. Now TickValue, TimeCurrent, account information and prices are valid.

  2.    ArraySetAsSeries(ema_buffer_close, true);
       ema_handle_close = iMA(_Symbol, _Period, ema_period_close, 0, ema_method, PRICE_CLOSE);
    

    Perhaps you should read the manual, especially the examples.
       How To Ask Questions The Smart Way. (2004)
          How To Interpret Answers.
             RTFM and STFW: How To Tell You've Seriously Screwed Up.

    They all (including iCustom) return a handle (an int). You get that in OnInit. In OnTick/OnCalculate (after the indicator has updated its buffers), you use the handle, shift and count to get the data.
              Technical Indicators - Reference on algorithmic/automated trading language for MetaTrader 5
              Timeseries and Indicators Access / CopyBuffer - Reference on algorithmic/automated trading language for MetaTrader 5
              How to start with MQL5 - General - MQL5 programming forum - Page 3 #22 (2020)
              How to start with MQL5 - MetaTrader 5 - General - MQL5 programming forum - Page 7 #61 (2020)
              MQL5 for Newbies: Guide to Using Technical Indicators in Expert Advisors - MQL5 Articles (2010)
              How to call indicators in MQL5 - MQL5 Articles (2010)

  3.    string ema_close_comment = StringFormat("EMA Close: %.5f", ema_buffer_close[Bars(_Symbol, _Period) - 1]);
    
       ArraySetAsSeries(ema_buffer_close, true);
    The forming bar is index zero. You are reading the oldest one.
 
Alecxander:
   current_price = SymbolInfoDouble(_Symbol, SYMBOL_LAST);

Besides all comments from William SYMBOL_LAST returns the latest deal price on the symbol not the current close price.

For close price you can use:

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[])
{...
 
William Roeder #:
  1. Buffers are automatically resized. Don't try to use any price (or indicator) or server related functions in OnInit (or on load or in OnTimer before you've received a tick), as there may be no connection/chart yet:

    1. Terminal starts.
    2. Indicators/EAs are loaded. Static and globally declared variables are initialized. (Do not depend on a specific order.)
    3. OnInit is called.
    4. For indicators OnCalculate is called with any existing history.
    5. Human may have to enter password, connection to server begins.
    6. New history is received, OnCalculate called again.
    7. A new tick is received, OnCalculate/OnTick is called. Now TickValue, TimeCurrent, account information and prices are valid.

  2. Perhaps you should read the manual, especially the examples.
       How To Ask Questions The Smart Way. (2004)
          How To Interpret Answers.
             RTFM and STFW: How To Tell You've Seriously Screwed Up.

    They all (including iCustom) return a handle (an int). You get that in OnInit. In OnTick/OnCalculate (after the indicator has updated its buffers), you use the handle, shift and count to get the data.
              Technical Indicators - Reference on algorithmic/automated trading language for MetaTrader 5
              Timeseries and Indicators Access / CopyBuffer - Reference on algorithmic/automated trading language for MetaTrader 5
              How to start with MQL5 - General - MQL5 programming forum - Page 3 #22 (2020)
              How to start with MQL5 - MetaTrader 5 - General - MQL5 programming forum - Page 7 #61 (2020)
              MQL5 for Newbies: Guide to Using Technical Indicators in Expert Advisors - MQL5 Articles (2010)
              How to call indicators in MQL5 - MQL5 Articles (2010)

  3. The forming bar is index zero. You are reading the oldest one.

Thank you William Roeder, I solved the problem of Ema_value but I still need to understand why the Signal is wrong with respect to the condition I put. 

Everything looks correct to me! Yet the Seganle is wrong it gives me Sell when it should give me Buy.

//+------------------------------------------------------------------+
//| Medie_allarme.mq5                                                |
//| Copyright 2024, MetaQuotes Software Corp.                        |
//| http://www.metaquotes.net/                                       |
//+------------------------------------------------------------------+

// Indicator properties
#property version      "1.01"          // Indicator version
#property description  "Indicator with EMA Close and Buy/Sell signals"

#property indicator_chart_window     // Display indicator in the chart window

// Buffer and plot properties
#property indicator_buffers 1
#property indicator_plots   1

// Define plot for EMA Close
#property indicator_label1 "EMA Close"
#property indicator_type1  DRAW_LINE
#property indicator_color1 clrMagenta
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2     // Line thickness

// Input parameters for EMA Close
input int ema_period_close  = 28;  // Period for EMA Close
input ENUM_MA_METHOD ema_method = MODE_EMA;  // Moving average method (EMA default)

// Global variables for managing EMA Close
int ema_handle_close;  // Handle for EMA Close
double ema_buffer_close[];  // Buffer for EMA Close values
double current_price;   // Current symbol price

// Variables for managing active signal
string current_signal_type = "";

//+------------------------------------------------------------------+
//| Function to display EMA Close value as an object on the chart     |
//+------------------------------------------------------------------+
void EmaValue()
{
   // Remove previous object if it exists
   ObjectDelete(0, "EMAValue");

   // Show EMA Close value as an object on the chart
   string ema_close_comment = StringFormat("EMA Close: %.5f", ema_buffer_close[0]);  // 0 index is the current bar
   int x = 10;
   int y = 70;
   ObjectCreate(0, "EMAValue", OBJ_LABEL, 0, 0, 0);
   ObjectSetInteger(0, "EMAValue", OBJPROP_XDISTANCE, x);
   ObjectSetInteger(0, "EMAValue", OBJPROP_YDISTANCE, y);
   ObjectSetInteger(0, "EMAValue", OBJPROP_CORNER, 0);
   ObjectSetInteger(0, "EMAValue", OBJPROP_XSIZE, 200);
   ObjectSetInteger(0, "EMAValue", OBJPROP_YSIZE, 100);
   ObjectSetInteger(0, "EMAValue", OBJPROP_COLOR, clrMagenta);
   ObjectSetInteger(0, "EMAValue", OBJPROP_FONTSIZE, 12);
   ObjectSetString(0, "EMAValue", OBJPROP_TEXT, ema_close_comment);
}

//+------------------------------------------------------------------+
//| Function to generate alert, draw signal, and comment              |
//+------------------------------------------------------------------+
void AlertAndDrawSignal(string message, color clr)
{
   // Remove current signal label if no active signal
   ObjectDelete(0, "CurrentSignal");

   // Draw current signal label on the chart
   int x = 10;
   int y = 50;
   ObjectCreate(0, "CurrentSignal", OBJ_LABEL, 0, 0, 0);
   ObjectSetInteger(0, "CurrentSignal", OBJPROP_XDISTANCE, x);
   ObjectSetInteger(0, "CurrentSignal", OBJPROP_YDISTANCE, y);
   ObjectSetInteger(0, "CurrentSignal", OBJPROP_CORNER, 0);
   ObjectSetInteger(0, "CurrentSignal", OBJPROP_XSIZE, 200);
   ObjectSetInteger(0, "CurrentSignal", OBJPROP_YSIZE, 100);
   ObjectSetInteger(0, "CurrentSignal", OBJPROP_COLOR, clr);
   ObjectSetInteger(0, "CurrentSignal", OBJPROP_FONTSIZE, 12);
   ObjectSetString(0, "CurrentSignal", OBJPROP_TEXT, message);

   // Display EMA Close value as an object on the chart
   EmaValue();
}

//+------------------------------------------------------------------+
//| Initialization function for the indicator                        |
//+------------------------------------------------------------------+
int OnInit()
{
   // Calculate EMA Close and initialize buffer
   ema_handle_close = iMA(_Symbol, _Period, ema_period_close, 0, ema_method, PRICE_CLOSE);

   int bars = Bars(_Symbol, _Period);
   ArrayResize(ema_buffer_close, bars);
   SetIndexBuffer(0, ema_buffer_close);

   return INIT_SUCCEEDED;
}

//+------------------------------------------------------------------+
//| Calculation function for the indicator                           |
//+------------------------------------------------------------------+
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[])
{
   // Check for bars count and buffer size
   if (Bars(_Symbol, _Period) != ArraySize(ema_buffer_close))
   {
      int bars = Bars(_Symbol, _Period);
      ArrayResize(ema_buffer_close, bars);
   }

   // Calculate EMA Close and fill buffer
   ArraySetAsSeries(ema_buffer_close, true);
   ema_handle_close = iMA(_Symbol, _Period, ema_period_close, 0, ema_method, PRICE_CLOSE);
   CopyBuffer(ema_handle_close, 0, 0, rates_total, ema_buffer_close);

   // Calculate current closing price
   current_price = SymbolInfoDouble(_Symbol, SYMBOL_LAST);

   // Remove current signal label if no active signal
   ObjectDelete(0, "CurrentSignal");

   // Remove previous EMA value object
   ObjectDelete(0, "EMAValue");

   // Generate Buy signal when current price is above EMA Close
   if (current_price > ema_buffer_close[0])
   {
      current_signal_type = "Buy Signal!";
      AlertAndDrawSignal(current_signal_type, clrGreen);  // Draw Buy signal label
   }
   // Generate Sell signal when current price is below EMA Close
   else if (current_price < ema_buffer_close[0])
   {
      current_signal_type = "Sell Signal!";
      AlertAndDrawSignal(current_signal_type, clrRed);  // Draw Sell signal label
   }

   // Display EMA Close value as an object on the chart
   EmaValue();

   return rates_total;
}

//+------------------------------------------------------------------+
//| Deinitialization function for the indicator                      |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // Remove current signal label and EMA value object on deinitialization
   ObjectDelete(0, "CurrentSignal");
   ObjectDelete(0, "EMAValue");
}

 
Yashar Seyyedin #:

Besides all comments from William SYMBOL_LAST returns the latest deal price on the symbol not the current close price.

For close price you can use:

Hi Yashar Seyyedin, no I really want the current price, I don't want Close. The current price, the one moving now has to compare it with the EmaClose. 

If the price is above the EmaClose he has to "Buy," if it is below he has to "Sell."

And a simple code, only I was trying to figure out why the emaValue was calculated the wrong way. William Roeder clarified the problem but now I don't understand one thing:

the emaClose value is correct and yet with the product I am obsrving now where the current price is above the emaClose gives me an Alert Sell. 

There is another error that I cannot see.

 
//+------------------------------------------------------------------+
//| Medie_allarme.mq5                                                |
//| Copyright 2024, MetaQuotes Software Corp.                        |
//| http://www.metaquotes.net/&nbsp;                                      |
//+------------------------------------------------------------------+

// Indicator properties
#property version      "1.01"          // Indicator version
#property description  "Indicator with EMA Close and Buy/Sell signals"

#property indicator_chart_window     // Display indicator in the chart window

// Buffer and plot properties
#property indicator_buffers 1
#property indicator_plots   1

// Define plot for EMA Close
#property indicator_label1 "EMA Close"
#property indicator_type1  DRAW_LINE
#property indicator_color1 clrMagenta
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2     // Line thickness

// Input parameters for EMA Close
input int ema_period_close  = 28;  // Period for EMA Close
input ENUM_MA_METHOD ema_method = MODE_EMA;  // Moving average method (EMA default)

// Global variables for managing EMA Close
int ema_handle_close;  // Handle for EMA Close
double ema_buffer_close[];  // Buffer for EMA Close values
double current_price;   // Current symbol price

// Variables for managing active signal
string current_signal_type = "";

//+------------------------------------------------------------------+
//| Function to display EMA Close value as an object on the chart     |
//+------------------------------------------------------------------+
void EmaValue()
{
   // Remove previous object if it exists
   ObjectDelete(0, "EMAValue");

   // Show EMA Close value as an object on the chart
   string ema_close_comment = StringFormat("EMA Close: %.5f", ema_buffer_close[0]);  // 0 index is the current bar
   int x = 10;
   int y = 70;
   ObjectCreate(0, "EMAValue", OBJ_LABEL, 0, 0, 0);
   ObjectSetInteger(0, "EMAValue", OBJPROP_XDISTANCE, x);
   ObjectSetInteger(0, "EMAValue", OBJPROP_YDISTANCE, y);
   ObjectSetInteger(0, "EMAValue", OBJPROP_CORNER, 0);
   ObjectSetInteger(0, "EMAValue", OBJPROP_XSIZE, 200);
   ObjectSetInteger(0, "EMAValue", OBJPROP_YSIZE, 100);
   ObjectSetInteger(0, "EMAValue", OBJPROP_COLOR, clrMagenta);
   ObjectSetInteger(0, "EMAValue", OBJPROP_FONTSIZE, 12);
   ObjectSetString(0, "EMAValue", OBJPROP_TEXT, ema_close_comment);
}

//+------------------------------------------------------------------+
//| Function to generate alert, draw signal, and comment              |
//+------------------------------------------------------------------+
void AlertAndDrawSignal(string message, color clr)
{
   // Remove current signal label if no active signal
   ObjectDelete(0, "CurrentSignal");

   // Draw current signal label on the chart
   int x = 10;
   int y = 50;
   ObjectCreate(0, "CurrentSignal", OBJ_LABEL, 0, 0, 0);
   ObjectSetInteger(0, "CurrentSignal", OBJPROP_XDISTANCE, x);
   ObjectSetInteger(0, "CurrentSignal", OBJPROP_YDISTANCE, y);
   ObjectSetInteger(0, "CurrentSignal", OBJPROP_CORNER, 0);
   ObjectSetInteger(0, "CurrentSignal", OBJPROP_XSIZE, 200);
   ObjectSetInteger(0, "CurrentSignal", OBJPROP_YSIZE, 100);
   ObjectSetInteger(0, "CurrentSignal", OBJPROP_COLOR, clr);
   ObjectSetInteger(0, "CurrentSignal", OBJPROP_FONTSIZE, 12);
   ObjectSetString(0, "CurrentSignal", OBJPROP_TEXT, message);

   // Display EMA Close value as an object on the chart
   EmaValue();
}

//+------------------------------------------------------------------+
//| Initialization function for the indicator                        |
//+------------------------------------------------------------------+
int OnInit()
{
   // Calculate EMA Close and initialize buffer
   ema_handle_close = iMA(_Symbol, _Period, ema_period_close, 0, ema_method, PRICE_CLOSE);
   SetIndexBuffer(0, ema_buffer_close);
   ArraySetAsSeries(ema_buffer_close, true);

   return INIT_SUCCEEDED;
}

//+------------------------------------------------------------------+
//| Calculation function for the indicator                           |
//+------------------------------------------------------------------+
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[])
{
   // Calculate EMA Close and fill buffer
   CopyBuffer(ema_handle_close, 0, 0, rates_total, ema_buffer_close);
   ArraySetAsSeries(close, true);
   // Calculate current closing price
   current_price = close[0];

   // Remove current signal label if no active signal
   ObjectDelete(0, "CurrentSignal");

   // Remove previous EMA value object
   ObjectDelete(0, "EMAValue");

   // Generate Buy signal when current price is above EMA Close
   if (current_price > ema_buffer_close[0])
   {
      current_signal_type = "Buy Signal!";
      AlertAndDrawSignal(current_signal_type, clrGreen);  // Draw Buy signal label
   }
   // Generate Sell signal when current price is below EMA Close
   else if (current_price < ema_buffer_close[0])
   {
      current_signal_type = "Sell Signal!";
      AlertAndDrawSignal(current_signal_type, clrRed);  // Draw Sell signal label
   }

   // Display EMA Close value as an object on the chart
   EmaValue();

   return rates_total;
}

//+------------------------------------------------------------------+
//| Deinitialization function for the indicator                      |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // Remove current signal label and EMA value object on deinitialization
   ObjectDelete(0, "CurrentSignal");
   ObjectDelete(0, "EMAValue");
}
 
Yashar Seyyedin #:
Yashar Seyyedin #:

Hi Yashar yes it is true so the code works me explain, why do you use close[0]. I understand that close[0] actually hasn't been realized yet until it closes the bar, but I don't understand why " current_price = SymbolInfoDouble(_Symbol, SYMBOL_LAST);" is not good when in the documentation (https://www.mql5.com/en/docs/constants/environment_state/marketinfoconstants) it says it is the last price. Sorry but this is a personal curiosity.

Thank you if you can answer me

Documentation on MQL5: Constants, Enumerations and Structures / Environment State / Symbol Properties
Documentation on MQL5: Constants, Enumerations and Structures / Environment State / Symbol Properties
  • www.mql5.com
To obtain the current market information there are several functions: SymbolInfoInteger() , SymbolInfoDouble() and SymbolInfoString() . The first...
 
Alecxander #:
SYMBOL_LAST

This returns the price of latest deal executed on your specific trading account. In order to access the current price on chart it is best to use close[0].