Questions from Beginners MQL5 MT5 MetaTrader 5 - page 763

 
Vitaly Muzichenko:

It seems so in cycles, and you can dispense with the function

Thank you.

However, removed the function - the brakes remain.... damn.

 
Aleksey Vyazmikin:

Thanks.

However, removed the function - the brakes remain.... Damn.

I once started to rewrite the program from 4=>5, then in 4, I replaced all constructions like Low[1], Time[0] and others with modern ones, i.e.CopyLow,CopyTime, the program became faster even in 4. I do not use old constructs now, only new ones. So the code is easily portable to the 5-th platform, you just need to change the trading functions

 
Vitaly Muzichenko:

Once I started to rewrite the program from 4=>5 and then I replaced all constructions like Low[1], Time[0] and others with modern ones, i.e.CopyLow,CopyTime, the program became faster even in 4. I do not use old constructs now, only new ones. So the code is easily portable to the 5-th platform, you just need to change the trading functions

Isn'tfilling the array on every sneeze a resource consumption?

Maybe it makes sense to copy the information into the array at the bar opening, and then take it from there as the code unfolds? I trade on bar opening.


 
Aleksey Vyazmikin:

Doesn'tfilling an array with every sneeze consume resources?

Maybe it makes sense to copy the information into the array when the bar opens and then take it from there as the code progresses? I trade on bar opening.

The array can be filled on a new bar, it will consume less resources. If you work with iLow[1] in several places, you should store it in a variable once and read it instead of the array.

Suppose this

// Инициализация TIME[0] TIME[1]
  ArraySetAsSeries(TM,true);
  if(CopyTime(dSymbol,Period(),0,2,TM)<0) return;
  TIME_0=TM[0];
  TIME_1=TM[1];
Then we work with variableTIME_0 andTIME_1 instead ofTM[0] andTM[1].
 
Vitaly Muzichenko:

Array can be filled on a new bar, it will take less resources. If you work with iLow[1] in several places, for example, it is desirable to write it once to a variable, and read the variable instead of the array.

Suppose so

But still, MT4 is much faster - I'm disappointed.

 

Forum on trading, automated trading systems and trading strategy testing

Bugs, bugs, questions

Aleksey Vyazmikin, 2017.07.21 15:07

Why are you fantasizing? I understood your idea, and confirmed that it works, and will have an effect if the request is made once and if it is known how many bars are needed for the EA to work.

Or maybe you suggested using the structure in a different way? Then please explain, but do not be offended!


No fantasies. If you need to get 2 or more parameters of one candlestick, then using the functions from your messages/questions we will need to call these functions separately for each parameter of the candlestick. That is 2 or more times to produce Copy***(), but using CopyRates() you need only one call of Copy.

As for the number to copy, that's another question. Maybe we should first calculate the bar containing the required indicator value and then copy it. If I remember correctly, we were talking about an unknown quantity to copy. What kind of fantasy are we talking about?

In extreme cases, we can copy, say, 10 bars and search among them. If it is not found, we copy another 10 bars. Copying is a time consuming operation, it's cheaper to copy an array.

In general, there are a lot of variations. You can't write all that into the documentation and it won't be documentation at all. They teach this at programming lessons. But, unfortunately, not all the teachers are able to do it and not all the students want to understand it at lessons. And the very beginning is at arithmetic lessons in grades 2-5, when the teacher requires a detailed explanation of the problem. But here the problems are the same.

 
Alexey Viktorov:

No fancy stuff. If you need to get 2 or more parameters of one candlestick, then using functions from your messages/questions you should call these functions separately for each candlestick parameter. That is 2 or more times to produce Copy***(), but using CopyRates() you'll need only one call of Copy.

As for the number to copy, that's another question. Maybe, we should first calculate on which bar the required value of the indicator is available, and then copy it. If I remember correctly, it was said about an unknown quantity to copy. What kind of fantasy are we talking about?

And, as a last resort, we can copy, say, 10 bars and search through them and, if we fail to find it, we copy another 10 bars. Copying is a rather expensive operation; it would be cheaper to search through the array.

There are a lot of variants in this case. All this cannot be written into the documentation; actually, it won't be documentation any more. They teach this at programming lessons. But, unfortunately, not all the teachers know how to do it and not all the students want to understand it at the lessons. And the very beginning is at arithmetic lessons in grades 2-5, when the teacher requires a detailed explanation of the problem. But here the problems are the same.

About fantasy - was a response to your statement "Instead of trying to understand what was said, to figure out what you get, you make some incredible objections", and not to the fact that the version you offered is from the fantasy field.

I understand your concept perfectly, and it was embedded in the response to you.

However, I don't quite understand how you propose to work with unknown amount of data - can you give me an example in the form of code?


 

Please help in auditing and optimizing the indicator using this link https://www.mql5.com/ru/code/16805 - the trouble is that the indicator starts to slow down a lot when a large number of bars appear - it shows up when testing.

I want to know how to make it work so it will not be calculated on every tick, but only on bar opening? The method from the Expert Advisor is not suitable - after the first tick all values disappear and appear only on the next bar...

Donchian Channel MTF
Donchian Channel MTF
  • votes: 13
  • 2016.12.13
  • Mladen Rakic
  • www.mql5.com
Мультитаймфреймовая версия канала Дончиана.
 
Aleksey Vyazmikin:

About fantasy - it was a response to your statement "Instead of trying to understand what was said, to figure out what would work, some incredible objections are rolled out.", and not that the option you proposed is from the realm of fantasy.

I understand your concept perfectly, and it was embedded in the response to you.

However, I don't quite understand how you propose to deal with an unknown amount of data - can you give me an example in the form of code?


The answer was given before...

Alexey Viktorov:

As a last resort, you can copy, say, 10 bars at a time and search for it. If you don't find it, you copy another 10 bars at a time. The copying is a costly operation, it is cheaper to search through the array.

But we'd better not try to get the maximum number of bars from the array, but try to do with one copy.

I'm not going to write a code sample. A normal programmer just needs a hint. Here is a sample algorithm:

  1. Determine the approximate number of bars at which the channel is crossed. Let it be 15.
  2. Copy both buffers of the indicator.
  3. Copy the values of bars using CopyRates()
  4. In the loop, we start comparing the values of the upper limit of the channel and high bars simultaneously with comparing low bars with the lower limit of the channel. If one of these crossings is found, the bar index is stored in a variable, and we continue to look for the second crossing. We exit the loop when both variables of intersection bars have values.

Thus, it is possible to find two intersections in one copy and one cycle, if necessary. There is even no need in ArraySetAsSeries() because when finding the crossing it is possible and, in my opinion, better to remember the time of bar, not its number. Although, knowing the time of the bar, there is no difficulty in determining its number.

Question: What is faster, a cycle with copying of the indicator buffer by 1 value and copying of high bar by 1 and comparing those values or a single copy of a certain amount and comparing the values of the two arrays with each other?

 

Just wrote this yesterday:

Task:

on each tick get "InpCountCopy" elements open, high, low, close and time.

Implementation:

  1. loop from "0" to "InpCountCopy-1" - the loop gets one open, high, low, close and time at a time.
  2. At one time we get "InpCountCopy" elements into MqlRates structure and then loop through the structure.

Features:

You can choose how to check: in OnTick or in OnTimer (1 second).

//+------------------------------------------------------------------+
//|                                      Copy OHLC vc Copy Rates.mq5 |
//|                              Copyright © 2017, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2017, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.001"
//--- input parameter
input int InpCountCopy=1000;
input bool OnTickOnTimer=false; // OnTickOnTimer: false -> OnTick, true -> OnTimer 1 second
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   if(OnTickOnTimer)
      EventSetTimer(1);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(OnTickOnTimer)
      return;
   Testing();
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   if(!OnTickOnTimer)
      return;
   Testing();
  }
//+------------------------------------------------------------------+
//| Main function                                                    |
//+------------------------------------------------------------------+
void Testing()
  {
//--- for once one element
   ulong start=GetMicrosecondCount();
   for(int i=0;i<InpCountCopy;i++) // in one operation we get one element.
     {
      double open=iOpen(i);
      double high=iHigh(i);
      double low=iLow(i);
      double close=iClose(i);
      datetime time=iTime(i);
     }
   ulong end=GetMicrosecondCount()-start;
   string text=(OnTickOnTimer)?"OnTimer":"OnTick";
   text=text+"\n"+"OHLC: "+IntegerToString(end);

//--- for one operation we get "InpCountCopy" elements.
   start=GetMicrosecondCount();
   MqlRates Rates[];
   if(!iRates(Rates,0,InpCountCopy))
      return;
   for(int i=0;i<InpCountCopy;i++)
     {
      double open=Rates[i].open;
      double high=Rates[i].high;
      double low=Rates[i].low;
      double close=Rates[i].close;
      datetime time=Rates[i].time;
     }
   end=GetMicrosecondCount()-start;
   text=text+"\n"+"Rates: "+IntegerToString(end);

   Comment(text);
  }
//+------------------------------------------------------------------+ 
//| Get Open for specified bar index                                 | 
//+------------------------------------------------------------------+ 
double iOpen(const int index,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)
  {
   if(symbol==NULL)
      symbol=Symbol();
   if(timeframe==0)
      timeframe=Period();
   double Open[1];
   double open=0;
   int copied=CopyOpen(symbol,timeframe,index,1,Open);
   if(copied==1)
      open=Open[0];
   return(open);
  }
//+------------------------------------------------------------------+ 
//| Get the High for specified bar index                             | 
//+------------------------------------------------------------------+ 
double iHigh(const int index,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)
  {
   if(symbol==NULL)
      symbol=Symbol();
   if(timeframe==0)
      timeframe=Period();
   double High[1];
   double high=0;
   int copied=CopyHigh(symbol,timeframe,index,1,High);
   if(copied==1)
      high=High[0];
   return(high);
  }
//+------------------------------------------------------------------+ 
//| Get Low for specified bar index                                  | 
//+------------------------------------------------------------------+ 
double iLow(const int index,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)
  {
   if(symbol==NULL)
      symbol=Symbol();
   if(timeframe==0)
      timeframe=Period();
   double Low[1];
   double low=0;
   int copied=CopyLow(symbol,timeframe,index,1,Low);
   if(copied==1)
      low=Low[0];
   return(low);
  }
//+------------------------------------------------------------------+ 
//| Get Close for specified bar index                                | 
//+------------------------------------------------------------------+ 
double iClose(const int index,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)
  {
   if(symbol==NULL)
      symbol=Symbol();
   if(timeframe==0)
      timeframe=Period();
   double Close[1];
   double close=0;
   int copied=CopyClose(symbol,timeframe,index,1,Close);
   if(copied==1)
      close=Close[0];
   return(close);
  }
//+------------------------------------------------------------------+ 
//| Get Time for specified bar index                                 | 
//+------------------------------------------------------------------+ 
datetime iTime(const int index,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)
  {
   if(symbol==NULL)
      symbol=Symbol();
   if(timeframe==0)
      timeframe=Period();
   datetime Time[1];
   datetime time=0;
   int copied=CopyTime(symbol,timeframe,index,1,Time);
   if(copied==1)
      time=Time[0];
   return(time);
  }
//+------------------------------------------------------------------+ 
//| Get Rates for specified bar index                                | 
//+------------------------------------------------------------------+ 
bool iRates(MqlRates  &Rates[],const int index,int count,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)
  {
   if(symbol==NULL)
      symbol=Symbol();
   if(timeframe==0)
      timeframe=Period();
   int copied=CopyRates(symbol,timeframe,index,count,Rates);
   if(copied!=count)
      return(false);
//---
   return(true);
  }
//+------------------------------------------------------------------+


Reason: