Toute question des nouveaux arrivants sur MQL4 et MQL5, aide et discussion sur les algorithmes et les codes. - page 985

 

Bon après-midi.

Aidez-moi, s'il vous plaît. Lors de l'écriture d'une fonction personnalisée, le testeur donne l'erreur 3 et n'ouvre pas les ordres. Veuillez préciser les erreurs.

 ticket=OrderSend(Symbol(),OP_SELLSTOP,Lots,Prices_install(),3,0,0,NULL,MAGICNUMBER,0,clrGreen);
               if(ticket>0)//проверка отрытия позиции
                 {
                  if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
                     Print("SELL ордер открыт:",OrderOpenPrice());
                 }
               else
                  Print("Ошибка открытия ордера SELL:",GetLastError());
              }
            return;
           }
        }
 //+---------------------------------------------------------------------------+
      //|                     Условия модификации ордеров                           |
      //+---------------------------------------------------------------------------+

      if(ticket>0)
        {
         if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
           {
            //--- длинная позиция открыта
            switch(OrderType())
              {
               case OP_BUYSTOP:
                  if(NormalizeDouble(OrderOpenPrice()-Prices_install(),Digits)>0 && NormalizeDouble(Prices_install()-Bid,Digits)>0)
                    {
                     if(OrderModify(ticket,Prices_install(),0,0,0,clrBlue))
                        Print("Цена Price_BUY ордера успешно модифицирована.");
                     else
                        Print("Ошибка модификации ордера BUYStop. Код ошибки=",GetLastError());
                    }
                  else
                     Print("Цена модификации выше цены ордера");
                  break;
               case OP_SELLSTOP:
                  if(NormalizeDouble(Prices_install()-OrderOpenPrice(),Digits)>0 && NormalizeDouble(Ask-Prices_install(),Digits)>0)
                    {
                     if(OrderModify(ticket,Prices_install(),0,0,0,clrGreen))
                        Print("Цена Price_SELL ордера успешно модифицирована.");
                     else
                        Print("Ошибка модификации ордера SELLStop. Код ошибки=",GetLastError());
                    }
                  else
                     Print("Цена модификации выше цены ордера");
                  break;
               case OP_BUY:
                  if(NormalizeDouble(StopLosse_install()-OrderStopLoss(),Digits)>0 && NormalizeDouble(Ask-StopLosse_install(),Digits)>0)
                    {
                     if(OrderModify(ticket,OrderOpenPrice(),StopLosse_install(),0,0,clrBlue))
                        Print("Цена Price_BUY ордера успешно модифицирована.");
                     else
                        Print("Ошибка модификации ордера BUY. Код ошибки=",GetLastError());
                    }
                  else
                     Print("Цена модификации выше цены ордера");
                  break;
               case OP_SELL:
                  if(NormalizeDouble(OrderStopLoss()-StopLosse_install(),Digits)>0 && NormalizeDouble(StopLosse_install()-Bid,Digits)>0)
                    {
                     if(OrderModify(ticket,OrderOpenPrice(),StopLosse_install(),0,0,clrGreen))
                        Print("Цена Price_SELL ордера успешно модифицирована.");
                     else
                        Print("Ошибка модификации ордера SELL. Код ошибки=",GetLastError());
                    }
                  else
                     Print("Цена модификации выше цены ордера");
                  break;
              }
           }
        }
      Sleep(5);
     }
   return;
  }
//+------------------------------------------------------------------+
double StopLosse_install()
  {
   double StopLoss=iSAR(NULL,PERIODs_short_term,Step,Maximum,1);
   double StopLoss_install;
   int StopLevel=(int)MarketInfo(Symbol(),MODE_STOPLEVEL); // Минимально допустимый уровень стоп-лосса/тейк-профита в пунктах
   int FreezeLevel=(int)MarketInfo(Symbol(),MODE_FREEZELEVEL);//Уровень заморозки ордеров в пунктах
   switch(OrderType())
     {
      case 0:
         if(Bid-StopLoss>FreezeLevel)
           {
            if(Bid-StopLoss>=StopLevel)
               StopLoss_install=NormalizeDouble(StopLoss,Digits);
            if(Bid-StopLoss<StopLevel)
               StopLoss_install=NormalizeDouble(StopLoss-StopLevel*MarketInfo(Symbol(),MODE_DIGITS),Digits);
           }
         else
            Print("Цена открытия ордера находится в дистанции заморозки:",GetLastError());
         break;
      case 1:
         if(StopLoss-Ask>FreezeLevel)
           {
            if(StopLoss-Ask>=StopLevel)
               StopLoss_install=NormalizeDouble(StopLoss,Digits);
            if(StopLoss-Ask<StopLevel)
               StopLoss_install=NormalizeDouble(StopLoss+StopLevel*MarketInfo(Symbol(),MODE_DIGITS),Digits);
           }
         else
            Print("Цена открытия ордера находится в дистанции заморозки:",GetLastError());
         break;
     }
     return(StopLoss_install);
  }
//+------------------------------------------------------------------+
double Prices_install()
  {
   double Price=iSAR(NULL,PERIODs_short_term,Step,Maximum,1);
   double Price_install;
   int StopLevel=(int)MarketInfo(Symbol(),MODE_STOPLEVEL); // Минимально допустимый уровень стоп-лосса/тейк-профита в пунктах
   int FreezeLevel=(int)MarketInfo(Symbol(),MODE_FREEZELEVEL);//Уровень заморозки ордеров в пунктах
   switch(OrderType())
     {
      case 4:
         if(Price-Ask>FreezeLevel)
           {
            if(Price - Ask>=StopLevel)
               Price_install=NormalizeDouble(Price,Digits);
            if(Price - Ask<StopLevel)
               Price_install=NormalizeDouble(Price+StopLevel*MarketInfo(Symbol(),MODE_DIGITS),Digits);
           }
         else
            Print("Цена открытия ордера находится в дистанции заморозки:",GetLastError());
         break;
      case 5:
         if(Bid-Price>FreezeLevel)
           {
            if(Bid-Price>=StopLevel)
               Price_install=NormalizeDouble(Price,Digits);
            if(Bid-Price<StopLevel)
               Price_install=NormalizeDouble(Price+StopLevel*MarketInfo(Symbol(),MODE_DIGITS),Digits);
           }
         else
            Print("Цена открытия ордера находится в дистанции заморозки:",GetLastError());
         break;
     }
     return(Price_install);
  }
//+------------------------------------------------------------------+
 
Ivan Butko:

Étrange, si dans un EA, il ouvre des trades l'un après l'autre pour chaque paire de devises spécifiée.... Avec un décalage dans le temps. Et lorsque vous le placez sur 5 graphiques différents avec différentes paires de devises (symbole(0)), les 5 transactions s'ouvrent simultanément et instantanément lorsque vous appuyez sur autotrade.

Pouvez-vous suggérer ce que cela peut être et comment le réparer ? Tout avoir dans un seul EA et sur un seul graphique (de sorte que le bouton sur le graphique ouvre toutes les paires aussi rapidement qu'en activant "autotrade" avec plusieurs EAs, comme dans la version originale)

voici en général le problème.... vous et moi faisons de notre mieux pour suspendre le terminal, imho.... Je n'aime pas écrire une logique erronée, ici j'ai fait ce que vous voulez - j'ai lancé l'EA sur le graphique, j'ai appuyé sur le bouton et il va essayer d'ouvrir un ordre dans une boucle sans fin.

#property copyright "IgorM"
#property link      "https://www.mql5.com/ru/users/igorm"
#property version   "1.00"
#property strict
input string   sym1 = "EURUSD";
input double   lot1 = 0.01;
input string   sym2 = "GBPUSD";
input double   lot2 = 0.01;
input string   sym3 = "USDCAD";
input double   lot3 = 0.01;
input string   sym4 = "USDJPY";
input double   lot4 = 0.01;
input string   sym5 = "AUDUSD";
input double   lot5 = 0.01;
#include <Controls\Button.mqh>
CButton ButtonSend;

string sym[5];
double lot[5];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+

int OnInit()
  {
   sym[0] = sym1;
   sym[1] = sym2;
   sym[2] = sym3;
   sym[3] = sym4;
   sym[4] = sym5;
   lot[0] = lot1;
   lot[1] = lot2;
   lot[2] = lot3;
   lot[3] = lot4;
   lot[4] = lot5;
   ButtonSend.Create(0, "ButtonSend" + _Symbol, 0, 10, 50, 100, 90);
   ButtonSend.Color(clrRed);
   ButtonSend.Text("Kill Forex!");
   OnTick();
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   static int ticket[5] = {-1, -1, -1, -1, -1 };
   if(ticket[0] > 0 && ticket[1] > 0 && ticket[2] > 0 && ticket[3] > 0 && ticket[4] > 0)
   {
    ButtonSend.Text("EA Stop");
    return;
    }
   while(!IsStopped())
   {
   if(ButtonSend.Pressed())
     {
      ButtonSend.Text("Sending...");
         if(TerminalInfoInteger(TERMINAL_CONNECTED) && TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && !IsTradeContextBusy())
           {
            RefreshRates();
            for(int i = 0; i < 5; i++)
              {
               if(sym[i] == "") ticket[i] = INT_MAX;
               if(ticket[i] > 0) continue;
               double vol = NormalizeLot(lot[i],sym[i]);
               ticket[i] = OrderSend(sym[i], OP_SELL, vol, SymbolInfoDouble(sym[i],SYMBOL_BID), 3, 0, 0, "", 0, 0, clrRed);
              }
           }
        }
     if(ticket[0] > 0 && ticket[1] > 0 && ticket[2] > 0 && ticket[3] > 0 && ticket[4] > 0) break;        
     ChartRedraw();      
     Sleep(123);
     }
  }
//+------------------------------------------------------------------+
double NormalizeLot(const double value,const string sym_,bool up=false)
  {
   double res,sizetable[9]={1.0,0.1,0.01,0.001,0.0001,0.00001,0.000001,0.0000001,0.00000001};
   double lotStep=SymbolInfoDouble(sym_,  SYMBOL_VOLUME_STEP);
   int lotdigits;
   for(lotdigits=8; lotdigits>=0; lotdigits--) if(lotStep<=sizetable[lotdigits]) break;
   if(up) res=NormalizeDouble(MathCeil(MathMin(MathMax(value,SymbolInfoDouble(sym_,SYMBOL_VOLUME_MIN)),SymbolInfoDouble(sym_,SYMBOL_VOLUME_MAX))/lotStep)*lotStep,lotdigits);
   else res=NormalizeDouble(MathFloor(MathMin(MathMax(value,SymbolInfoDouble(sym_,SYMBOL_VOLUME_MIN)),SymbolInfoDouble(sym_,SYMBOL_VOLUME_MAX))/lotStep)*lotStep,lotdigits);
   return(res);
  }
//+------------------------------------------------------------------+
 
Igor Makanu:

voici en général le problème.... vous et moi faisons de notre mieux pour suspendre le terminal, imho.... Je n'aime pas écrire la mauvaise logique, ici j'ai fait ce que vous voulez - lancer l'EA sur le graphique, appuyer sur le bouton et il va essayer d'ouvrir un ordre dans une boucle sans fin.

Igor, merci pour cette fonctionnalité étendue ! Malheureusement, rien n'a changé en ce qui concerne la vitesse. Mes transactions s'ouvrent également les unes après les autres. J'ai essayé à nouveau de mettre la version minimale sur chaque graphique et j'ai appuyé sur "autotrade", toutes les transactions se sont ouvertes en même temps et instantanément. Il y a encore un léger retard au début.
Malgré cela, lorsque vous cliquez sur le bouton du panneau commercial intégré, une transaction unique s'ouvre encore plus rapidement, sans retard initial. Bizarre. Nous aimerions arriver à un stade où un bouton similaire ouvrirait un panier sans délai.

En ce qui concerne la vitesse d'exécution:
1. Le moyen le plus rapide est d'utiliser le panneau commercial standard.
2. Répartissez-le sur plusieurs graphiques et appuyez sur le bouton "autotrade".
3. Le bouton qui ouvre le panier un par un

 
Ivan Butko:

Les transactions sont également ouvertes l'une après l'autre.

Il n'y a pas d'autre moyen, informations google sur les types de comptes Market Execution/Instant Execution.

et le deuxième pointhttps://www.mql5.com/ru/docs/runtime/running

Conseiller expert - Dans son propre fil de discussion, autant de conseillers experts qu'il y a de fils d'exécution pour eux.

en bref - après qu'un EA envoie un ordre, il attend qu'il soit confirmé et s'il y a plusieurs EA sur des graphiques différents, vous obtenez l'indépendance de chaque EA, c'est-à-dire l'exécution multithread du code


Je pense que pour votre problème, pour autant que je comprenne le trading des news, la meilleure solution est d'ouvrir plusieurs graphiques, de lancer les EAs configurés sur eux, qui sont bouclés dans une boucle infinie et, après avoir placé un ordre l'EA doit quitter le graphique, de démarrer tous les EAs avec le bouton Autotrade

 
Bonjour à tous, Comment faire pour que l'indicateur Parabolique standard dans un EA ouvre un trader lorsqu'il crée son premier point (c'est-à-dire lorsqu'il y a des changements dans la tendance du marché) ? ???.
 
ponochka:
Bonjour à tous, Comment faire pour que l'indicateur standard Parabolique dans un EA ouvre un trader à la création de son premier point (i.e. changement de tendance du marché) ? ???

Au début, les points vers lesquels pointent les flèches se trouvaient à l'opposé du prix actuel. Et dès que le prix a touché ce point, il a immédiatement sauté de l'autre côté.

Conclusion : le premier point en haut sera celui où le prix touchera le point en bas. Et vice versa...

 
Igor Makanu:

Il n'y a pas d'autre moyen, informations google sur les types de comptes Market Execution/Instant Execution.

Et le deuxième point esthttps://www.mql5.com/ru/docs/runtime/running

En bref, lorsque vous envoyez un ordre, l'EA attend qu'il soit confirmé et si vous avez plusieurs EA sur des graphiques différents, vous bénéficiez de l'indépendance de chaque EA, c'est-à-dire de l'exécution multithread du code.


Je pense que pour votre problème, pour autant que je comprenne le trading des news, la meilleure solution est d'ouvrir plusieurs graphiques, de lancer les EAs configurés sur ceux-ci, qui sont mis en boucle dans une boucle infinie et, après avoir placé un ordre, l'EA devrait quitter le graphique et lancer tous les EAs en utilisant le bouton auto-trade

Wow... Merci pour la clarification. Je veux dire. En effet, ce n'est qu'après l'ouverture de celle en cours que la suivante s'ouvre. Curieux.

Savez-vous si, par hasard, si vous essayez le quatrième schéma - le copieur de transaction - les transactions s'ouvriront également de manière séquentielle ? Par exemple, nous donnons un signal au copieur que 7 ordres semblent être ouverts sur l'assistant... comment va-t-il les ouvrir ? Ou bien, nous devrions également mettre en place 7 copieurs et indiquer à chacun d'eux de copier sa paire. Bien que je puisse l'essayer, je n'ai pas besoin de créer quelque chose de plus.

Il existe également une cinquième méthode : l'utilisation du clicker. Mais, il est trop cher, je ne pense pas que quelqu'un l'écrira pour le moment. Je vais essayer ce qui est disponible pour le moment.


UPD

J'ai essayé le copieur - même chose, les transactions s'ouvrent de manière séquentielle. Et si je mets le copieur sur 7 cartes et que je règle la mise à jour sur 1ms, le terminal ainsi que l'UPD vont exploser.

Cela laisse deux possibilités.

1. L'actif - pour placer le conseiller expert sur chaque graphique et activer l'auto-trading.
2) Le clicker, qui n'a pas fait ses preuves - pour utiliser un logiciel tiers.
 
Ivan Butko:

1. Actionnable - mettez un EA sur chaque graphique et activez l'auto-trading.

2. Non éprouvé - utiliser un logiciel tiers - clicker.

avec 99% de probabilité, 1 et 2 fonctionneront à la même vitesse, le serveur traite toujours vos demandes de transaction une par une, et lorsque vous envoyez 7 demandes depuis 7 graphiques, vous avez gagné du temps en attendant la réponse du serveur (jusqu'à ce que l'EA reçoive le ticket, il ne fait rien - il attend).

à propos du clicker, avec WinAPI vous pouvez "cliquer" avec votre souris sur n'importe quel point de l'écran, j'ai vérifié le code il y a un moishttps://www.mql5.com/ru/forum/156025#comment_7552799.

Vous voulez utiliser l'auto clicker pour envoyer une commande, vous pouvez donc faire de même avec le code de @Koldun Zloy

 
Igor Makanu:

avec 99% de probabilité, les options 1 et 2 fonctionneront à la même vitesse, le serveur traite toujours vos demandes de transaction une par une, et lorsque vous envoyez 7 demandes à partir de 7 graphiques, vous avez gagné du temps pour attendre la réponse du serveur (jusqu'à ce que l'EA reçoive le ticket, il ne fait rien - il attend).

à propos du clicker, avec WinAPI vous pouvez "cliquer" avec votre souris sur n'importe quel point de l'écran, j'ai vérifié le code il y a un moishttps://www.mql5.com/ru/forum/156025#comment_7552799.

Vous voulez utiliser l'auto clicker pour envoyer une commande, vous pouvez donc faire de même avec le code de @Koldun Zloy

Super, je vais vérifier. Merci beaucoup pour votre aide et le travail que vous avez accompli.

 

Bonjour.

Je maîtrise MT5. Mais la manière de tracer les lignes tampons n'est pas claire. J'ai téléchargé l'indicateur du site mql5 et je l'ai un peu corrigé.

Mais maintenant, j'ai des problèmes avec les lignes. Ma question est la suivante : pourquoi la ligne est-elle faussée dans l'histoire et comment y remédier ?

//+------------------------------------------------------------------+
//|                                                        Proba.mq5 |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
//---- для расчета и отрисовки индикатора использовано пятнадцать буферов
#property indicator_buffers 4
//---- использовано пятнадцать графических построений
#property indicator_plots   4
//+----------------------------------------------+
//|  Параметры отрисовки уровня                  |
//+----------------------------------------------+
//---- отрисовка индикатора в виде значка
#property indicator_type1   DRAW_LINE
//---- в качестве цвета линии индикатора цвет MediumSeaGreen
#property indicator_color1 clrGold
//---- толщина линии индикатора равна
#property indicator_width1  1
//---- отображение метки индикатора
#property indicator_label1  "OPEN"
//+----------------------------------------------+
//|  Параметры отрисовки уровня                  |
//+----------------------------------------------+
//---- отрисовка индикатора в виде значка
#property indicator_type2   DRAW_LINE
//---- в качестве цвета индикатора использован цвет MediumSeaGreen
#property indicator_color2 clrRed
//---- толщина линии индикатора равна
#property indicator_width2  1
//---- отображение лэйбы индикатора
#property indicator_label2  "CLOSE"
//+----------------------------------------------+
//|  Параметры отрисовки уровня                  |
//+----------------------------------------------+
//---- отрисовка индикатора в виде значка
#property indicator_type3   DRAW_LINE
//---- в качестве цвета индикатора использован цвет Lime
#property indicator_color3 clrYellow
//---- толщина линии индикатора равна
#property indicator_width3  2
//---- отображение метки индикатора
#property indicator_label3  "HIGH"
//+----------------------------------------------+
//|  Параметры отрисовки уровня                  |
//+----------------------------------------------+
//---- отрисовка индикатора в виде значка
#property indicator_type4   DRAW_LINE
//---- в качестве цвета индикатора использован цвет MediumSeaGreen
#property indicator_color4 clrYellow
//---- толщина индикатора равна
#property indicator_width4  1
//---- отображение метки индикатора
#property indicator_label4  "LOW"
//+----------------------------------------------+
//| Входные параметры индикатора                 |
//+----------------------------------------------+
input int  ExtHowManyDays=10; //Количество Дней истории
input ENUM_TIMEFRAMES Timeframes = PERIOD_D1; //Период расчетов
//+----------------------------------------------+
//---- объявление динамических массивов, которые в дальнейшем
//---- будут использованы в качестве индикаторных буферов
double BufferLow[],BufferHigh[],BufferClose[],BufferOpen[];
//+------------------------------------------------------------------+
//| iBarShift() function                                             |
//+------------------------------------------------------------------+
int iBarShift(string symbol,ENUM_TIMEFRAMES timeframe,datetime time)
  {
//----
   if(time<0)
      return(-1);
   datetime Arr[],time1;

   time1=(datetime)SeriesInfoInteger(symbol,timeframe,SERIES_LASTBAR_DATE);

   if(CopyTime(symbol,timeframe,time,time1,Arr)>0)
     {
      int size=ArraySize(Arr);
      return(size-1);
     }
   else
      return(-1);
//----
  }
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
//---
   int draw_begin;
   if(ExtHowManyDays < 1)
      draw_begin=0;
   else
      draw_begin=ExtHowManyDays;

//---- превращение динамических массивов в индикаторные буферы
   SetIndexBuffer(0,BufferOpen,INDICATOR_DATA);
   SetIndexBuffer(1,BufferClose,INDICATOR_DATA);
   SetIndexBuffer(2,BufferHigh,INDICATOR_DATA);
   SetIndexBuffer(3,BufferLow,INDICATOR_DATA);
//---- создание метки для отображения в DataWindow
   PlotIndexSetString(0,PLOT_LABEL,"Price OPEEN");
   PlotIndexSetString(1,PLOT_LABEL,"Price CLOSE");
   PlotIndexSetString(2,PLOT_LABEL,"Price HIGH");
   PlotIndexSetString(3,PLOT_LABEL,"Price LOW");
//---- индексация элементов в буферах как в таймсериях
   ArraySetAsSeries(BufferOpen,true);
   ArraySetAsSeries(BufferClose,true);
   ArraySetAsSeries(BufferHigh,true);
   ArraySetAsSeries(BufferLow,true);
//---- определение точности отображения значений индикатора
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//--- установим номер бара, с которого будет идти отрисовка
   for(int q=0; q<=4; q++)
      PlotIndexSetInteger(q,PLOT_DRAW_BEGIN,draw_begin); //ПРОБЛЕМА ТУТ!!!!!
      //PlotIndexSetInteger(q,PLOT_SHIFT,0);
      //PlotIndexSetDouble(q,PLOT_EMPTY_VALUE,EMPTY_VALUE);
//----
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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    begin_bar,first_bar,last_bar,cnt,copy;
   double High_=0.0,Low_=0.0,Close_=0.0,Open_=0.0;
   double iClose[],iOpen[],iHigh[],iLow[];
   datetime iTime[];
//---
   if(_Period>=Timeframes)
      return(0);
//---- проверка и установка начального бара
   if(ExtHowManyDays < 1)
      begin_bar=Bars(NULL,Timeframes)-2;
   else
      begin_bar=ExtHowManyDays-1;

//---- индексация элементов в массивах как в таймсериях
   ArraySetAsSeries(time,true);
   ArraySetAsSeries(iTime,true);
   ArraySetAsSeries(iOpen,true);
   ArraySetAsSeries(iClose,true);
   ArraySetAsSeries(iHigh,true);
   ArraySetAsSeries(iLow,true);

   copy=begin_bar+2;

   if(CopyTime(NULL,Timeframes,0,copy,iTime)<copy)
      return(0);
   if(CopyOpen(NULL,Timeframes,0,copy,iOpen)<copy)
      return(0);
   if(CopyClose(NULL,Timeframes,0,copy,iClose)<copy)
      return(0);
   if(CopyHigh(NULL,Timeframes,0,copy,iHigh)<copy)
      return(0);
   if(CopyLow(NULL,Timeframes,0,copy,iLow)<copy)
      return(0);

//----
   /*cnt=0;
   while(true)
     {
      if(iTime[0]>=(time[0]-Timeframes*60))
         break;
      cnt++;
      if(cnt>5)
         return(0);
      Sleep(300); //1000
     }*/
//----
   if(prev_calculated!=0)
     {
      begin_bar=0;
      BufferOpen[cnt]=0.0;
      BufferClose[cnt]=0.0;
      BufferHigh[cnt]=0.0;
      BufferLow[cnt]=0.0;
     }
//----
   for(cnt=begin_bar; cnt>=0; cnt--)
     {
      if(cnt<rates_total)
        {
         Open_=iOpen[cnt];
         Close_=iClose[cnt+1];
         High_=iHigh[cnt+1];
         Low_=iLow[cnt+1];
        }
      first_bar=iBarShift(NULL,_Period,iTime[cnt]);

      if(cnt>0)
         last_bar=iBarShift(NULL,_Period,iTime[cnt-1]);
      else
         last_bar=0;

      while(first_bar>=last_bar)
        {
         if((first_bar==last_bar && last_bar>0) || first_bar<0)
            break;

         BufferOpen[first_bar]=Open_;
         BufferClose[first_bar]=Close_;
         BufferHigh[first_bar]=High_;
         BufferLow[first_bar]=Low_;
         if(BufferOpen[first_bar]!=BufferOpen[first_bar+1])
            BufferOpen[first_bar+1]=EMPTY_VALUE;
         if(BufferClose[first_bar]!=BufferClose[first_bar+1])
            BufferClose[first_bar+1]=EMPTY_VALUE;
         if(BufferHigh[first_bar]!=BufferHigh[first_bar+1])
            BufferHigh[first_bar+1]=EMPTY_VALUE;
         if(BufferLow[first_bar]!=BufferLow[first_bar+1])
            BufferLow[first_bar+1]=EMPTY_VALUE;

         first_bar--;
        }
     }
//----
   ChartRedraw(0);
//----
   return(rates_total);
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+



Raison: