Quaisquer perguntas de recém-chegados sobre MQL4 e MQL5, ajuda e discussão sobre algoritmos e códigos - página 985

 

Boa tarde.

Por favor, ajude. Ao escrever uma função personalizada, o testador dá erro 3 e não abre ordens. Favor especificar os erros.

 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:

Estranho, se em um EA, ele abre negócios um após o outro para cada par de moedas especificado. Com um intervalo de tempo. E quando você o coloca em 5 gráficos diferentes com pares de moedas diferentes (símbolo(0)), todas as 5 negociações se abrem simultaneamente e instantaneamente quando você pressiona o auto-negocio.

Você pode sugerir o que pode ser e como consertá-lo? Ter tudo em um EA e em um gráfico (para que o botão no gráfico abra todos os pares tão rápido quanto ao ativar o "autotrade" com vários EAs, como na versão original)

aqui em geral é o problema.... você e eu estamos fazendo nosso melhor para suspender o terminal, imho.... não gosto de lógica errada para escrever, aqui fiz o que você quer - jogue o EA no gráfico, pressione o botão e ele tentará abrir uma ordem em um loop infinito

#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:

aqui em geral é o problema.... você e eu estamos fazendo nosso melhor para suspender o terminal, imho.... não gosto de escrever a lógica errada, aqui fiz o que você quer - jogue a EA no gráfico, pressione o botão e ele tentará abrir uma ordem em um loop infinito

Igor, obrigado pela funcionalidade estendida! Infelizmente, nada mudou em termos de velocidade. Meus negócios também estão abrindo um após o outro. Tentei novamente colocar uma versão mínima em cada gráfico e pressionei "autotrade", todos os negócios foram abertos de uma só vez e instantaneamente. Ainda há um pequeno atraso no início.
Apesar disso, ainda quando você clica no botão do Painel de Comércio integrado, um único comércio se abre ainda mais rápido, sem um atraso inicial. Estranho. Gostaríamos de chegar a um estado em que um botão semelhante abrisse uma cesta sem demora.

No que diz respeito à velocidade de execução:
1. A maneira mais rápida é cutucar o Painel de Comércio padrão.
2. Disperse-o em vários gráficos e pressione "AutoTrade".
3. O botão que abre a cesta uma a uma

 
Ivan Butko:

Os ofícios também são abertos um após o outro.

Não há outra maneira, google informação sobre os tipos de contas de Execução de Mercado/Instant Execution

e o segundo pontohttps://www.mql5.com/ru/docs/runtime/running

Expert Advisor - Em seu próprio fio condutor, tantos EAs quantos são os fios de execução para eles

em resumo - depois que uma EA envia uma ordem, ela espera que uma ordem seja confirmada e se houver várias EA em diferentes gráficos, você obtém a independência de cada EA, ou seja, a execução multi-tarefa do código


Acho que para sua tarefa, tanto quanto entendo de negociação das notícias, a melhor solução é abrir vários gráficos, jogar os EAs configurados neles, que são loopados em um loop infinito e, após colocar uma ordem o EA tem que deixar o gráfico, iniciar todos os EAs com o botão Autotrade

 
Olá a todos! Como obter o indicador parabólico padrão em um EA para abrir um comerciante quando ele cria seu primeiro ponto (ou seja, mudanças na tendência do mercado) ????
 
ponochka:
Olá a todos! Como fazer o indicador parabólico padrão em uma EA para abrir um comerciante na criação de seu primeiro ponto (ou seja, mudança de tendência de mercado) ????

No início, os pontos para os quais as setas apontavam estavam do lado oposto do preço atual. E assim que o preço tocou esse ponto, ele pulou imediatamente para o outro lado.

Conclusão: O primeiro ponto em cima será quando o preço tocar o ponto em baixo. E vice versa...

 
Igor Makanu:

Não há outra maneira, google informação sobre os tipos de contas de Execução de Mercado/Instant Execution

E o segundo ponto éhttps://www.mql5.com/ru/docs/runtime/running

Em resumo, quando você envia uma ordem, a EA espera que uma ordem seja confirmada e se você tiver algumas EA em gráficos diferentes, então você obtém a independência de cada EA, ou seja, a execução multi-tarefa do código


Acho que para o seu problema, tanto quanto entendo de negociação das notícias, a melhor solução é abrir vários gráficos, jogar os EAs configurados neles, que são em loop infinito e, após colocar um pedido, o EA deve deixar o gráfico e iniciar todos os EAs usando o botão de auto-comércio

Uau... obrigado pelo esclarecimento. Quero dizer. De fato, somente após a abertura do atual é que se abre o próximo. Curioso.

Você sabe, por acaso, se você tentar o quarto esquema - copiadora de comércio - os negócios também serão abertos sequencialmente? Por exemplo, damos um sinal ao copiador de que 7 ordens parecem estar abertas no feiticeiro. como ele as abrirá? Ou, devemos também criar 7 copiadores e indicar a cada um deles para copiar seu par. Embora, eu possa tentar, não tenho que criar nada adicional.

Há também um quinto método - use o clicker. Mas, é muito caro, não creio que ninguém o escreva no momento. Vou tentar o que está disponível por enquanto.


UPD

Eu tentei copiar - a mesma coisa, os negócios se abrem sequencialmente. E se eu colocar a copiadora em 7 cartas e definir 1ms de atualização, o terminal junto com a UPD explodirá.

Isso deixa dois caminhos.

1. O ativo - para colocar o Expert Advisor em cada gráfico e permitir o auto-negociação.
2) O não comprovado - para usar software de terceiros - clicker.
 
Ivan Butko:

1. Acionável - colocar um EA em cada gráfico e permitir o auto-negociação.

2. Não comprovado - usar software de terceiros - clicker.

com 99% de probabilidade 1 e 2 funcionarão na mesma velocidade, o servidor ainda está processando suas solicitações comerciais uma a uma, e quando você envia 7 solicitações de 7 gráficos, você ganhou tempo esperando a resposta do servidor (até a EA receber o tíquete, ela não faz nada - ela está esperando)

sobre o clicker, com WinAPI você pode "clicar" com seu mouse em qualquer ponto da tela, eu verifiquei o código há um mês atráshttps://www.mql5.com/ru/forum/156025#comment_7552799

Você quer usar o clicker automático para enviar um pedido, e pode fazer o mesmo com o código@Koldun Zloy

 
Igor Makanu:

com 99% de probabilidade a opção 1 e 2 funcionará na mesma velocidade, o servidor ainda está processando suas solicitações comerciais uma a uma, e quando você envia 7 solicitações de 7 gráficos, você ganhou tempo para esperar pela resposta do servidor (até a EA receber o tíquete, ela não faz nada - ela está esperando)

sobre o clicker, com WinAPI você pode "clicar" com seu mouse em qualquer ponto da tela, eu verifiquei o código há um mês atráshttps://www.mql5.com/ru/forum/156025#comment_7552799

Você quer usar o clicker automático para enviar um pedido, e pode fazer o mesmo com o código @Koldun Zloy

Ótimo, vou dar uma olhada. Muito obrigado por sua ajuda e pelo trabalho que você fez

 

Olá.

Eu estou dominando o MT5. Mas não está claro como traçar as linhas-tampão. Eu baixei o indicador do site mql5 e o consertei um pouco.

Mas agora eu tenho alguns problemas com as linhas. Minha pergunta é: Por que a linha está distorcida na história e como consertá-la?

//+------------------------------------------------------------------+
//|                                                        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);
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+