Fragen von Neueinsteigern zu MQL4 und MQL5, Hilfe und Diskussion über Algorithmen und Codes - Seite 985

 

Guten Tag.

Bitte um Hilfe. Wenn ich eine benutzerdefinierte Funktion schreibe, gibt der Tester den Fehler 3 aus und öffnet keine Aufträge. Bitte geben Sie die Fehler an.

 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:

Seltsam, wenn in einem EA für jedes angegebene Währungspaar ein Handel nach dem anderen eröffnet wird... Mit einer zeitlichen Verzögerung. Und wenn Sie es auf 5 verschiedene Charts mit verschiedenen Währungspaaren (Symbol(0)) setzen, öffnen sich alle 5 Trades gleichzeitig und sofort, wenn Sie Autotrade drücken.

Können Sie mir sagen, woran das liegen könnte und wie man es beheben kann? Alles in einem EA und auf einem Diagramm zu haben (so dass die Schaltfläche auf dem Diagramm alle Paare so schnell öffnet, wie bei der Aktivierung von "autotrade" mit mehreren EAs, wie in der ursprünglichen Version)

hier ist im Allgemeinen das Problem.... Sie und ich tun unser Bestes, um das Terminal auszusetzen, imho.... Ich mag keine falsche Logik zu schreiben, hier habe ich getan, wie Sie wollen - warf die EA auf dem Chart, drückte die Taste und es wird versuchen, eine Bestellung in einer Endlosschleife zu öffnen

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

hier ist im Allgemeinen das Problem.... Sie und ich tun unser Bestes, um das Terminal auszusetzen, imho.... Ich mag nicht die falsche Logik zu schreiben, hier habe ich getan, wie Sie wollen - werfen Sie die EA auf dem Chart, drücken Sie die Taste und es wird versuchen, eine Bestellung in einer Endlosschleife zu öffnen

Igor, vielen Dank für die erweiterte Funktionalität! Leider hat sich in Bezug auf die Geschwindigkeit nichts geändert. Auch meine Geschäfte werden nach und nach eröffnet. Ich habe wieder versucht, minimale Version auf jedem Diagramm zu setzen und drückte "autotrade", alle Geschäfte auf einmal und sofort geöffnet. Es gibt immer noch eine leichte Verzögerung am Anfang.
Trotzdem, wenn Sie auf die integrierte Schaltfläche des Handelspanels klicken, öffnet sich ein einzelner Handel noch schneller, ohne eine anfängliche Verzögerung. Seltsam. Wir würden gerne einen Zustand erreichen, in dem eine ähnliche Schaltfläche ohne Verzögerung einen Warenkorb öffnet.

Was die Ausführungsgeschwindigkeit anbelangt:
1. Am schnellsten geht es, wenn Sie die Standard-Handelstafel anklicken.
2. Verteilen Sie sie auf mehrere Charts und drücken Sie die Schaltfläche "Autotrade".
3. Die Schaltfläche, die den Korb nacheinander öffnet

 
Ivan Butko:

Die Geschäfte werden ebenfalls nacheinander eröffnet.

Es gibt keine andere Möglichkeit, Informationen zu den Kontotypen Market Execution/Instant Execution zu googeln

und der zweite Punkthttps://www.mql5.com/ru/docs/runtime/running

Expert Advisor - In einem eigenen Thread, so viele EAs wie es Ausführungs-Threads für sie gibt

Kurz gesagt: Nachdem ein EA einen Auftrag gesendet hat, wartet er auf eine Auftragsbestätigung, und wenn es mehrere EAs auf verschiedenen Charts gibt, erhalten Sie die Unabhängigkeit jedes EAs, d. h. die Ausführung des Codes in mehreren Threads


Ich denke, für Ihre Aufgabe, so weit ich verstehe, den Handel mit den Nachrichten, die beste Lösung ist es, mehrere Charts zu öffnen, werfen die EAs auf sie konfiguriert, die in einer Endlosschleife und, nach der Platzierung einer Bestellung der EA hat, um den Chart zu verlassen, starten Sie alle EAs mit dem Autotrade-Taste

 
Hallo zusammen, wie bringe ich den Standard-Parabolic-Indikator in einem EA dazu, einen Trader zu öffnen, wenn er seinen ersten Punkt erzeugt (d.h. wenn sich der Markttrend ändert) ????
 
ponochka:
Hallo zusammen, wie kann man den Standard-Parabolic-Indikator in einem EA so einstellen, dass er bei der Erstellung seines ersten Punktes (d.h. bei einem Trendwechsel des Marktes) einen Trader öffnet ????

Zunächst befanden sich die Punkte, auf die die Pfeile zeigten, auf der gegenüberliegenden Seite des aktuellen Kurses. Und sobald der Preis diesen Punkt erreicht hatte, sprang er sofort auf die andere Seite.

Schlussfolgerung: Der erste Punkt auf der Oberseite wird sein, wenn der Preis den Punkt auf der Unterseite berührt. Und andersherum...

 
Igor Makanu:

Es gibt keinen anderen Weg, googeln Sie Informationen zu den Kontotypen Market Execution/Instant Execution

Und der zweite Punkt isthttps://www.mql5.com/ru/docs/runtime/running

Kurz gesagt, wenn Sie einen Auftrag senden, wartet der EA auf eine Auftragsbestätigung, und wenn Sie mehrere EAs auf verschiedenen Charts haben, erhalten Sie die Unabhängigkeit jedes EAs, d. h. die Ausführung von Code in mehreren Threads


Ich denke, für Ihr Problem, so weit ich verstehe, den Handel mit den Nachrichten, die beste Lösung ist es, mehrere Charts zu öffnen, werfen die EAs auf sie konfiguriert, die in einer Endlosschleife und nach der Platzierung einer Bestellung, die EA sollte das Diagramm verlassen und starten Sie alle EAs mit dem Auto-Trade-Taste

Wow... danke für die Klarstellung. Ich meine. Denn erst nach dem Öffnen des aktuellen öffnet sich das nächste. Neugierig.

Wissen Sie zufällig, dass die Geschäfte auch nacheinander geöffnet werden, wenn Sie das vierte Schema - Trade Copier - ausprobieren? Zum Beispiel geben wir dem Kopierer ein Signal, dass 7 Aufträge im Assistenten offen zu sein scheinen... wie wird er sie öffnen? Oder wir sollten auch 7 Kopierer aufstellen und jeden von ihnen auffordern, sein Paar zu kopieren. Ich kann es zwar versuchen, aber ich muss nichts zusätzlich erstellen.

Es gibt auch noch eine fünfte Methode: den Clicker. Aber es ist zu teuer, ich glaube nicht, dass es derzeit jemand schreiben wird. Ich werde versuchen, was für den Moment verfügbar ist.


UPD

Ich habe es mit dem Kopierer versucht - dasselbe, die Angebote werden nacheinander geöffnet. Und wenn ich den Kopierer auf 7 Charts stelle und 1ms Update einstelle, explodiert das Terminal zusammen mit UPD.

Damit bleiben zwei Möglichkeiten.

1. Die aktive - um den Expert Advisor auf jedem Chart zu platzieren und den automatischen Handel zu aktivieren.
2) Der unbewährte - zu verwendende Software von Drittanbietern - Clicker.
 
Ivan Butko:

1. Actionable - setzen Sie einen EA auf jeden Chart und aktivieren Sie den automatischen Handel.

2. Unbewährt - Software von Drittanbietern verwenden - Clicker.

mit 99%iger Wahrscheinlichkeit werden 1 und 2 gleich schnell arbeiten, der Server bearbeitet Ihre Handelsanfragen immer noch eine nach der anderen, und wenn Sie 7 Anfragen von 7 Charts senden, haben Sie Zeit gewonnen, indem Sie auf die Antwort vom Server warten (bis der EA das Ticket erhält, tut er nichts - er wartet)

über den Clicker, mit WinAPI kann man mit der Maus auf jeden Punkt des Bildschirms "klicken", ich habe den Code vor einem Monat überprüfthttps://www.mql5.com/ru/forum/156025#comment_7552799

Wenn Sie den Autoklicker verwenden möchten, um eine Bestellung abzuschicken, können Sie dies mit dem Code von @Koldun Zloy tun

 
Igor Makanu:

mit 99%iger Wahrscheinlichkeit werden Option 1 und 2 gleich schnell funktionieren, der Server bearbeitet Ihre Handelsanfragen immer noch eine nach der anderen, und wenn Sie 7 Anfragen von 7 Charts senden, haben Sie Zeit gewonnen, um auf die Antwort des Servers zu warten (bis der EA das Ticket erhält, tut er nichts - er wartet)

über den Clicker, mit WinAPI kann man mit der Maus auf jeden Punkt des Bildschirms "klicken", ich habe den Code vor einem Monat überprüfthttps://www.mql5.com/ru/forum/156025#comment_7552799

Wenn Sie den Autoklicker verwenden möchten, um eine Bestellung abzuschicken, können Sie dies mit dem Code von @Koldun Zloy tun

Gut, ich werde es mir ansehen. Vielen Dank für Ihre Hilfe und die von Ihnen geleistete Arbeit

 

Hallo.

Ich bin dabei, MT5 zu meistern. Aber es ist nicht klar, wie die Pufferlinien gezeichnet werden sollen. Ich habe den Indikator von der mql5-Website heruntergeladen und ihn ein wenig korrigiert.

Aber jetzt habe ich einige Probleme mit Linien. Meine Frage ist: Warum ist die Linie in der Geschichte verzerrt und wie kann man das beheben?

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