Any questions from newcomers on MQL4 and MQL5, help and discussion on algorithms and codes - page 1899

 
Vitaly Muzichenko #:

How to use this, can you show me?

Here's the task.

Here's the finished code, but the loop is a little scary

---

Again, there is a loop inside ArrayCopy() and maybe more than one. So the code will hardly become simpler and faster due to this replacement.

In this code, you should specify one array

int  ArrayCopy(
   void&        dst_array[],         // куда копируем
   const void&  src_array[],         // откуда копируем
   int          dst_start=0,         // с какого индекса пишем в приемник
   int          src_start=0,         // с какого индекса копируем из источника
   int          count=WHOLE_ARRAY    // сколько элементов
   );

from which index to write and from which to copy depends on the direction of the array shift. Thus, if we want index 0 to always contain fresh, new data, we should copy from 0 and write from 1. Thus, values in index 0 and 1 will be identical, and afterwards a fresh value will be copied to 0.

And I doubt very much that ArrayCopy() has the same loop inside as the user one. Thus, having some array with a certain size, it is shifted by 1 on every tick and then copied into the indicator buffer that is displayed as a line...

 
Please tell me the breakdown function for the daily factals.
//+----------------------------------------------------------------------------+
//|Определение пробоя дневного фрактала вверх                                  |
//+----------------------------------------------------------------------------+
int BreakdownSignalUpD1()
  {
   int sig=-1;
   double resistD1 = GetNearestUpFractal(PERIOD_D1);
   if (resistD1 < Ask)
     sig=0;
   if (resistD1 >= Ask)
     sig=1;  
   return(sig);
  }

And here is the function that shows the breakdown on the screen

ObjectCreate("signal100",OBJ_LABEL,0,0,0,0,0);
   ObjectSet("signal100",OBJPROP_XDISTANCE,600);
   ObjectSet("signal00",OBJPROP_YDISTANCE, 40);
   ObjectSetText("signal100",DoubleToString(BreakdownSignalUpD1(),0),18,"Times New Roman", clrRed);

Can you please tell me how to make the screen show not 0 or 1 but 0 is "YES" 1 is "NO".

Thank you

 
EVGENII SHELIPOV #:
Please tell me the breakdown function for the daily factals.

And here is the function that shows the breakdown on the screen

Can you please tell me how to make the screen show not 0 or 1 but 0 is "YES" 1 is "NO".

Thank you

string boolToStr(bool value) { return ((value) ? "true" : "false"); }
 
EVGENII SHELIPOV #:
Please tell me what the breakdown function of the daytime factal is.

And here is the function that shows the breakdown on the screen

Can you please tell me how to make the screen show not 0 or 1 but 0 is "YES" 1 is "NO".

Thank you

ObjectSetText("signal100",BreakdownSignalUpD1()==0?"Да":"Нет",18,"Times New Roman", clrRed);

Something like this.

 
JRandomTrader #:

Something like that.

Thank you

 
Alexey Viktorov #:

In this code, you need to specify one array

Which index to write from and which index to copy depends on the array offset direction. I.e. if index 0 should always contain fresh, new data, then copy from 0 and write from 1. Thus, values in index 0 and 1 will be identical, and afterwards a fresh value will be copied to 0.

And I doubt very much that ArrayCopy() has the same loop inside as the user one. Thus, having some array with a certain size, it is shifted by 1 on every tick and then copied into the indicator buffer that is displayed as a line...

I will try.

---

All in all, my code works successfully, it's been more than an hour


 
Vitaly Muzichenko #:


Here's the best way to do it.
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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 H=100;
  double b, a;
  if(prev_calculated==0) {
    ArrayInitialize(Buffer1,EMPTY_VALUE);
    ArrayInitialize(Buffer2,EMPTY_VALUE);
  }

  b=SymbolInfoDouble(Symbol(),SYMBOL_BID);
  a=SymbolInfoDouble(Symbol(),SYMBOL_ASK);

  if(rates_total-prev_calculated==1) {
    Buffer1[H+1]=EMPTY_VALUE;
    Buffer2[H+1]=EMPTY_VALUE;
  }
  else if (rates_total == prev_calculated) { // сдвигаем данные только когда количество баров не поменялось (в случае появления нового бара они сдвигаются системой терминала)
    for(int j=H; j>0; j--) { 
      Buffer1[j]=Buffer1[j-1];
      Buffer2[j]=Buffer2[j-1];
    }
  }
  // записываем новые данные
  Buffer1[0]=b;
  Buffer2[0]=a;
  return(rates_total);
}
 
JRandomTrader a circular buffer, remembering the current position of the first element?

What a brilliant idea! Who came up with it and what is its practical application? I doubt it is used exclusively for sliding window charts...

 
Mihail Matkovskij #:

What a brilliant idea! Who came up with it and what is its practical application? I doubt it's used exclusively for sliding window charts...

True, it's not unreasonable to know how much data you can roll back. Because this circular buffer is "stepping on its own toes", due to its limited length...

 
Mihail Matkovskij #:
Here's the best way to do it.

Checked it out, yes it's a good solution - I'm keeping it.

But I would still like to check ifArrayCopy works

---

I decided to do it this way, because it's not nice to tear off the graph:

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrDodgerBlue
#property indicator_label1  "Bid"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrRed
#property indicator_label2  "Ask"

double Buffer1[];
double Buffer2[];
int H;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnInit()
{
  SetIndexBuffer(0,Buffer1);
  ArraySetAsSeries(Buffer1,true);
  SetIndexBuffer(1,Buffer2);
  ArraySetAsSeries(Buffer2,true);
  ArrayInitialize(Buffer1,EMPTY_VALUE);
  ArrayInitialize(Buffer2,EMPTY_VALUE);
  IndicatorSetInteger(INDICATOR_DIGITS,Digits());
  IndicatorSetString(INDICATOR_SHORTNAME,"Tick:");
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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[])
{
  H=(int)ChartGetInteger(0,CHART_FIRST_VISIBLE_BAR);
  if(prev_calculated==0) {
    ArrayInitialize(Buffer1,EMPTY_VALUE);
    ArrayInitialize(Buffer2,EMPTY_VALUE);
  }

  double b=SymbolInfoDouble(Symbol(),SYMBOL_BID);
  double a=SymbolInfoDouble(Symbol(),SYMBOL_ASK);

  if(rates_total-prev_calculated==1) {
    Buffer1[H+1]=EMPTY_VALUE;
    Buffer2[H+1]=EMPTY_VALUE;
  } else if(rates_total == prev_calculated) { // сдвигаем данные только когда количество баров не поменялось (в случае появления нового бара они сдвигаются системой терминала)
    for(int j=H; j>0; j--) {
      Buffer1[j]=Buffer1[j-1];
      Buffer2[j]=Buffer2[j-1];
    }
  }
// записываем новые данные
  Buffer1[0]=b;
  Buffer2[0]=a;
  return(rates_total);
}
//+------------------------------------------------------------------+
void OnChartEvent(const int id,         // идентификатор события
                  const long& lparam,   // параметр события типа long
                  const double& dparam, // параметр события типа double
                  const string& sparam  // параметр события типа string
                 )
{
  if(id==CHARTEVENT_CHART_CHANGE) {
    H=(int)ChartGetInteger(0,CHART_FIRST_VISIBLE_BAR);
    int B=Bars(Symbol(),0);
    for(int j=H; j<B; j++) {
      Buffer1[j]=EMPTY_VALUE;
      Buffer2[j]=EMPTY_VALUE;
    }
  }
}
//+------------------------------------------------------------------+
Reason: