question about speed and much more

 

Hi i have this code

//+------------------------------------------------------------------+
//|                                                         6pip.mq4 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 clrWhite
extern int PipRequest = 9;            // QUANTI PUNTI PER EVIDENZIARE
double Buffer[];
// Dichiarazione globale della variabile di stato
bool alertShown = false;

int OnInit()
{
    SetIndexBuffer(0, Buffer);
    SetIndexStyle(0, DRAW_ARROW);
    SetIndexArrow(0, 233);
    
    return(INIT_SUCCEEDED);
}




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 start = prev_calculated;
    if (start == 0)
        start = 1;

    for (int i = start; i < rates_total; i++)
    {
    
        double bodySize = MathAbs(NormalizeDouble(open[i],4) - NormalizeDouble(close[i],4));
        double pipSize = MarketInfo(Symbol(), MODE_POINT) * PipRequest; // calcola i punti
        //if (bodySize <= PipRequest)
        if (bodySize <= pipSize)
        {
        
            Buffer[i] = high[i]; // Disegna un punto in alto sulla candela
            // Mostra l'allert solo se non è stato già mostrato in precedenza
              if (!alertShown)
              {
                  Alert("C'e' una candela interessante "+Symbol(), pipSize, " punti");
                  alertShown = true; // Imposta il flag per evitare ulteriori alert
              }
        }
        else
        {
            Buffer[i] = 0; // Non disegnare nulla sulla candela
        }
    }
    
    return (rates_total);
}

i have two question about  it :

1. try to run with start profiling on real data  i notice  that  have problem when try to run on calculate  in this part

  double bodySize = MathAbs(NormalizeDouble(open[i],4) - NormalizeDouble(close[i],4));
        double pipSize = MarketInfo(Symbol(), MODE_POINT) * PipRequest; // calcola i punti

exist a mode for increase performance ??

2. is normal  on calculate  work only one  time  when  attach it ?   and  when chart create a candel <= 8 point not  do nothing  but if i reload  it  work !!  why ??

anyone  can explain me  thanks

 
faustf:

Hi i have this code

i have two question about  it :

1. try to run with start profiling on real data  i notice  that  have problem when try to run on calculate  in this part

  double bodySize = MathAbs(NormalizeDouble(open[i],4) - NormalizeDouble(close[i],4));
        double pipSize = MarketInfo(Symbol(), MODE_POINT) * PipRequest; // calcola i punti

exist a mode for increase performance ??

2. is normal  on calculate  work only one  time  when  attach it ?   and  when chart create a candel <= 8 point not  do nothing  but if i reload  it  work !!  why ??

anyone  can explain me  thanks


To 1:

double bodySize = MathAbs(long(open[i] * factor) - long(close[i] * factor)) * _Point;

Prepare a variable outside the forloop called factor:

double factor = MathPow(10, _Digits -1);
Do the same for your MarketInfo:

double point = MarketInfo(_Symbol, MODE_POINT);


To 2:

    int start = prev_calculated - 1;
    if (start <= 0)

EDIT:

Somewhere in your code, you need to do this as well:

alertShown = false;
 
  1. faustf: 2. is normal  on calculate  work only one  time  when  attach it ?   a
        for (int i = start; i < rates_total; i++)

    After the first run start equals prev_calculated equals rates_total. Your loop will never run until a new bar forms.
              How to do your lookbacks correctly #9 - #14 & #19 (2016)

  2. Your loop is processing bars non-series. Buffers default to as-series, and your arrays (open[], close[]) have no default.

    In MT4, buffers and MT4 predefined arrays are all ordered AsSeries. There is a difference between the arrays passed to OnCalculate (e.g. low[]) and the MT4 predefined variables (e.g. Low[].) The passed arrays have no default direction, just like MT5.

    To determine the indexing direction of time[], open[], high[], low[], close[], tick_volume[], volume[] and spread[], call ArrayGetAsSeries(). In order not to depend on default values, you should unconditionally call the ArraySetAsSeries() function for those arrays, which are expected to work with.
              Event Handling Functions - Functions - Language Basics - MQL4 Reference

  3.         double bodySize = MathAbs(NormalizeDouble(open[i],4) - NormalizeDouble(close[i],4));

    You used NormalizeDouble, It's use is usually wrong, as it is in your case.

    1. Floating point has an infinite number of decimals, it's you were not understanding floating point and that some numbers can't be represented exactly. (like 1/10.)
                Double-precision floating-point format - Wikipedia, the free encyclopedia

      See also The == operand. - MQL4 programming forum (2013)

    2. Print out your values to the precision you want with DoubleToString - Conversion Functions - MQL4 Reference.

    3. SL/TP (stops) need to be normalized to tick size (not Point) — code fails on non-currencies.
                On 5Digit Broker Stops are only allowed to be placed on full pip values. How to find out in mql? - MQL4 programming forum #10 (2011)

      And abide by the limits Requirements and Limitations in Making Trades - Appendixes - MQL4 Tutorial and that requires understanding floating point equality Can price != price ? - MQL4 programming forum (2012)

    4. Open price for pending orders need to be adjusted. On Currencies, Point == TickSize, so you will get the same answer, but it won't work on non-currencies. So do it right.
                Trailing Bar Entry EA - MQL4 programming forum (2013)
                Bid/Ask: (No Need) to use NormalizeDouble in OrderSend - MQL4 programming forum (2012)

    5. Lot size must also be adjusted to a multiple of LotStep and check against min and max. If that is not a power of 1/10 then NormalizeDouble is wrong. Do it right.
                (MT4 2013)) (MT5 2022))

    6. MathRound() and NormalizeDouble() are rounding in a different way. Make it explicit.
                MT4:NormalizeDouble - MQL5 programming forum (2017)
                How to Normalize - Expert Advisors and Automated Trading - MQL5 programming forum (2017)

    7. Prices you get from the terminal are already correct (normalized).

    8. PIP, Point, or Tick are all different in general.
                What is a TICK? - MQL4 programming forum (2014)

  4.         double pipSize = MarketInfo(Symbol(), MODE_POINT) * PipRequest; // calcola i punti

    What of this is changing inside the loop. Nothing. Move it outside.

  5. A Point is not a PIP. PIP, Point, or Tick are all different in general.
              Ticks, PIPs or points in the GUI. Make up your mind. - MQL4 programming forum #1 (2014)
              Percentage in point - Wikipedia

    Unless you manually adjust your SL/TP for each separate symbol, using Point means code breaks on 4 digit brokers, exotics (e.g. USDZAR where spread is over 500 points), and metals. Compute what a PIP is and use it, not points.
              How to manage JPY pairs with parameters? - MQL4 programming forum (2017)
              Slippage defined in index points - Expert Advisors and Automated Trading - MQL5 programming forum (2018)

  6.               if (!alertShown)
                  {
                      Alert("C'e' una candela interessante "+Symbol(), pipSize, " punti");
                      alertShown = true; // Imposta il flag per evitare ulteriori alert
                  }
    Why are you alerting (once) on the oldest small bar, instead of the newest?
 

i have  modify in this mode a code 

//+------------------------------------------------------------------+
//|                                                         6pip.mq4 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 clrWhite
extern int PipRequest = 10;            // QUANTI PUNTI PER EVIDENZIARE
double Buffer[];
// Dichiarazione globale della variabile di stato
bool alertShown = false;

int OnInit()
{
    SetIndexBuffer(0, Buffer);
    SetIndexStyle(0, DRAW_ARROW);
    SetIndexArrow(0, 233);
    
    return(INIT_SUCCEEDED);
}
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 Go = prev_calculated;
    if (Go == 0){Go = 1;}

    double point = MarketInfo(Symbol(), MODE_POINT);

    for (int i = Go; i < rates_total; i++)
    {
        double bodySize = MathAbs(open[i] - close[i]);
        double pipSize = point * PipRequest; // calcola i punti
        
        if (bodySize <= pipSize || MathAbs(bodySize - pipSize) < 0.00001)
        {
            Buffer[i] = high[i]; // Disegna un punto in alto sulla candela
        }
        else
        {
            Buffer[i] = 0; // Non disegnare nulla sulla candela
        }
    }
but  also in this mode not  work 
 
William Roeder #:
Why are you alerting (once) on the oldest small bar, instead of the newest?
because  without allertshow , start allert  in infinity loop
 
faustf #:

i have  modify in this mode a code 

but  also in this mode not  work 
Because you need to add this as well:

 Go -= (prev_calculated == rates_total);

As William stated, you only process data as a new bar forms. Look up what has been posted as answer to your question.