Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 817

 
Seric29:

Ну разве что наклепать много мелких функций, которые будут проверять одно выражения например на равентство, вычитание, сложение, неравенство, умножение и т.д.

Для сравнений  и так в загашнике должна быть функция типа CompareDoublesWithEpsilon(double d1,d2,epsilon) - так и используйте её.


PS/ что такое "проверить выражение на вычитание,сложение,умножение" так и не понял :-(

 

Как со старшего таймфрейма увидеть время открытия баров на М1?

Если с младшего увидеть старший то так

   int limit=rates_total-prev_calculated;
   if(limit>1)
     {
      limit=rates_total-2;
      ArrayInitialize(BufferUP,EMPTY_VALUE);
      ArrayInitialize(BufferDN,EMPTY_VALUE);
     }
   for(int i=limit; i>=0; i--)
     {
   int yy=  iBarShift(Symbol(),PERIOD_H1,time[i]);
     Print("iTime: ", iTime(Symbol(),PERIOD_H1,yy));
     }
 
yiduwi:

Как со старшего таймфрейма увидеть время открытия баров на М1?

Если с младшего увидеть старший то так

если я правильно понял, то:

datetime time_h1=iTime(_Symbol,PERIOD_H1,1);  // время открытия прошлого бара H1

int bar_m1=iBarShift(_Symbol,PERIOD_M1,time_h1); // соотв. ему бар периода M1

datetime time_m1=iTime(_Symbol,PERIOD_M1,bar_m1); // время его открытия

//PS - разница может быть только от h2 и только в понедельник утром :-)

 
Maxim Kuznetsov:

если я правильно понял, то:

datetime time_h1=iTime(_Symbol,PERIOD_H1,1);  // время открытия прошлого бара H1

int bar_m1=iBarShift(_Symbol,PERIOD_M1,time_h1); // соотв. ему бар периода M1

datetime time_m1=iTime(_Symbol,PERIOD_M1,bar_m1); // время его открытия

//PS - разница может быть только от h2 и только в понедельник утром :-)

Предположим время открытия прошлого бара H1 - 01:00:00 как в переменную time_m1 получить время с бара М1 который открылся в 01:01:00?

 
yiduwi:

Предположим время открытия прошлого бара H1 - 01:00:00 как в переменную time_m1 получить время с бара М1 который открылся в 01:01:00?

time_m1_plus_1=time_h1 + 1 * PeriodSeconds(PERIOD_M1); // внезапно :-) просто добавить к времени 1 минуту = 60 секунд

но если у вас есть риск попасть на перемену дня/сессии/недели или экзотические валюты/индексы/фонд то для полной уверенности ещё раз прокатить через iBarShift, iTime - потому как в порядочных местах бар образуется с первой сделкой (баров без объёмов не бывает) а нет сделок - будет "бырка"

 
Maxim Kuznetsov:

time_m1_plus_1=time_h1 + 1 * PeriodSeconds(PERIOD_M1); // внезапно :-) просто добавить к времени 1 минуту = 60 секунд

Вот это ценно, то что нужно) Чтобы узнать что заданное время находится внутри бара любого таймфрейма нужно сделать так

   for(int i=limit; i>=0; i--)
     {
      if(time[i]<=StringToTime("2019.04.23 01:01:00") && time[i]+Period()*PeriodSeconds(PERIOD_M1)>=StringToTime("2019.04.23 01:01:00")
        {
         BufferUP[i]=low[i]-10*Point;//
         }
        }

но если время ровно, без минут "2019.04.23 01:00:00" то стрелки на двух барах, на баре в 01:00:00 и на предыдущем в 00:00:00 Как не ставить лишнюю?

 


Доброго всех частей суток и сезонов))

Написал индюка. Работает, но настойчиво пишет ошибку в разделе Эксперты.

Попытки решить проблему... пока "каком к верху"..)))

Подскажите, плиз, где я начудачил по неопытности....

Проблемное место кода выделил красным... или зеленкой было бы лучше !?)))

PS Вариант хэндла отрицаю в принципе, из-за условий работы  хэндла на МТ5

Готов осуществить некоторую оплату труда, если код имеет радикальные ошибки. 

НО ХОЧЕТСЯ ВНИКНУТЬ В СУТЬ ПРОБЛЕМЫ!!!!

//+------------------------------------------------------------------+
//|                                   Ind Sliding Line Level MT5.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 1
#property indicator_plots   1
//+----------------------------------------------+
//|  Параметры отрисовки индикатора 1            |
//+----------------------------------------------+
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_width1  1   
//----
enum method
  {
   Simple=MODE_SMA,
   Exponential=MODE_EMA,
  };
//----
enum applied
  {
   CLOSE=PRICE_CLOSE,
   OPEN=PRICE_OPEN,
   HIGH=PRICE_HIGH,
   LOW=PRICE_LOW
  };
//--- входные параметры
input int    InpMAPeriod = 10;                      // Период мультитаймфреймовой линии
input int    InpBars = 50;                          // Расчитать баров (Период линии х 5)
input int    InpMAShift = 0;                        // Сдвиг линии
//--- параметры для выбранного таймфрема
input string TimeBar = "2019.04.19 00:00";          //Дата начала отсчета
input bool DataBars = false;                        //Считать по дате (true)
input int MAShift = 2;                              //Сдвиг бара таймфрема 
input ENUM_TIMEFRAMES Timeframes = PERIOD_D1;       //Таймфрейм скользящей
input method  MethodLine = Simple;                  //Метод  расчета скользящей
input applied AppliedPrice = CLOSE;                 //Расчет цены скользящей
input ENUM_LINE_STYLE MAStyle = STYLE_DASH;         //Стиль всех скользящих линий
input color ColorLine = clrRed;                     //Цвет скользящей и таймфрейма
input int maWidthAll = 0;                           //Толщина всех скользящих линий
input bool Ray = true;                              //Сдвиг тренда вправо до шкалы
input bool LineTrend = true;                        //Выбор Линия(true) Отрезок(false)
input bool HLines = false;                       //Выключатель горизонтального уровня 
//----
int    i,period_ma,beginbar,nn,BigPeriod;
double ExtLineBuffer[],ArrayPrice[];
double SMA=0.0,EMA=0.0;
double bp,bp1,bp2,bp3;
datetime time_1,time_2;
string smaname="",emaname="";
string tooltipsma="",tooltipema="";
string type_ma="",pr="";
bool   sma=false,ema=false,ok;
//+------------------------------------------------------------------+
//|   simple moving average multytimeframes                          |
//+------------------------------------------------------------------+
void CalculateSimpleMA(int rates_total,int prev_calculated,int begin,const double &price[])
  {
   int j,limit;
//--- first calculation or number of bars was changed
   if(prev_calculated==0)// first calculation
     {
      limit=period_ma+begin;
      //--- set empty value for first limit bars
      for(j=0;j<limit-1;j++) ExtLineBuffer[j]=0.0;
      //--- calculate first visible value
      double fvalue=0;
      for(j=begin;j<limit;j++)
         fvalue+=price[j];
      fvalue/=period_ma;
      ExtLineBuffer[limit-1]=fvalue;
     }
   else limit=prev_calculated-1;
//--- main loop
   for(j=limit;j<rates_total && !IsStopped();j++)
      ExtLineBuffer[j]=ExtLineBuffer[j-1]+(price[j]-price[j-period_ma])/period_ma;
//---
  }
//+------------------------------------------------------------------+
//|  exponential moving average multytimeframes                      |
//+------------------------------------------------------------------+
void CalculateExponentialMA(int rates_total,int prev_calculated,int begin,const double &price[])
  {
   int    q,limit;
   double SmoothFactor=2.0/(1.0+period_ma);
//--- first calculation or number of bars was changed
   if(prev_calculated==0)
     {
      limit=period_ma+begin;
      ExtLineBuffer[begin]=price[begin];
   for(q=begin+1;q<limit;q++)
         ExtLineBuffer[q]=price[q]*SmoothFactor+ExtLineBuffer[q-1]*(1.0-SmoothFactor);
     }
   else limit=prev_calculated-1;
//--- main loop
   for(q=limit;q<rates_total && !IsStopped();q++)
      ExtLineBuffer[q]=price[q]*SmoothFactor+ExtLineBuffer[q-1]*(1.0-SmoothFactor);
  }
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
  period_ma=int(InpMAPeriod<1 ? 1 : InpMAPeriod);
  smaname="Ind SMA "+string(InpMAPeriod);
  emaname="Ind EMA "+string(InpMAPeriod);
//---
   SetIndexBuffer(0,ExtLineBuffer,INDICATOR_DATA);
   switch(Timeframes)
     {
      case PERIOD_MN1: BigPeriod=PERIOD_MN1; ok=true;  pr="MN1";  break;
      case PERIOD_W1:  BigPeriod=PERIOD_MN1; ok=true;  pr="W1";   break;
      case PERIOD_D1:  BigPeriod=PERIOD_W1;  ok=true;  pr="D1";   break;
      case PERIOD_H12: BigPeriod=PERIOD_D1;  ok=true;  pr="H12";  break;
      case PERIOD_H8:  BigPeriod=PERIOD_D1;  ok=true;  pr="H8";   break;
      case PERIOD_H4:  BigPeriod=PERIOD_D1;  ok=true;  pr="H4";   break;
      case PERIOD_H3:  BigPeriod=PERIOD_H4;  ok=true;  pr="H3";   break;
      case PERIOD_H2:  BigPeriod=PERIOD_H4;  ok=true;  pr="H2";   break;
      case PERIOD_H1:  BigPeriod=PERIOD_H4;  ok=true;  pr="H1";   break;
      case PERIOD_M30: BigPeriod=PERIOD_H1;  ok=true;  pr="M30";  break;
      case PERIOD_M20: BigPeriod=PERIOD_H1;  ok=true;  pr="M20";  break;
      case PERIOD_M15: BigPeriod=PERIOD_M30; ok=true;  pr="M15";  break;
      case PERIOD_M12: BigPeriod=PERIOD_M15; ok=true;  pr="M12";  break;
      case PERIOD_M10: BigPeriod=PERIOD_M15; ok=true;  pr="M10";  break;
      case PERIOD_M6:  BigPeriod=PERIOD_M15; ok=true;  pr="M6";   break;
      case PERIOD_M5:  BigPeriod=PERIOD_M15; ok=true;  pr="M5";   break;
      case PERIOD_M4:  BigPeriod=PERIOD_M15; ok=true;  pr="M4";   break;
      case PERIOD_M3:  BigPeriod=PERIOD_M15; ok=true;  pr="M3";   break;
      case PERIOD_M2:  BigPeriod=PERIOD_M15; ok=true;  pr="M2";   break;
      case PERIOD_M1:  BigPeriod=PERIOD_M15; ok=true;  pr="M1";   break;
     }
   switch(MethodLine)
     {
      case Simple:       sma=true;  type_ma="SMA ";   break;
      case Exponential:  ema=true;  type_ma="EMA ";   break;
     }
//--- set accuracy
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//--- sets first bar from what index will be drawn
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,period_ma);
//---- line shifts when drawing
   PlotIndexSetInteger(0,PLOT_SHIFT,InpMAShift);
//---
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,ColorLine);
//---
   IndicatorSetString(INDICATOR_SHORTNAME,type_ma+" "+string(period_ma));
//---- sets drawing line empty value--
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
//----
   ChartRedraw(0);
//---- initialization done
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 | 
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
  ObjectsDeleteAll(0,smaname);
  ObjectsDeleteAll(0,emaname);
  ObjectsDeleteAll(0,"No Period ");
  Comment(""); 
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
//--- минимальное количество баров
   if(rates_total<period_ma-1+begin)
  return(0);
//--- Количество начальных баров без отрисовки и значений 
      PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,period_ma-1+begin);
   if(prev_calculated==0)
     {
      ArrayInitialize(ExtLineBuffer,0);
      ArrayInitialize(ArrayPrice,0);
     }
//--- calculation
   switch(MethodLine)
     {
      case Simple:       CalculateSimpleMA(rates_total,prev_calculated,begin,price);       break;
      case Exponential:  CalculateExponentialMA(rates_total,prev_calculated,begin,price);  break;
     }
//считаем количество элементов буфера
int size=ArraySize(ExtLineBuffer);
         ArrayResize(ArrayPrice,size,100000);
//---- Расчет и построение горизонтального уровня выбранного таймфрейма
 if(DataBars==false)
    beginbar=MAShift;
 if(DataBars==true)
    beginbar=iBarShift(_Symbol,Timeframes,StringToTime(TimeBar));
    time_1=iTime(_Symbol,Timeframes,beginbar);
    time_2=iTime(_Symbol,Timeframes,0);

 if(HLines==true)
  {
//+------------------------------------------------------------------+
//|   Simple Moving Average                                          |
//+------------------------------------------------------------------+
 if(sma==true && ok==true && Period()<=BigPeriod)   //SMA
   {
int  lim=period_ma+beginbar;
double firstValue=0.0;
   for(i=beginbar;i<lim;i++)
   switch(AppliedPrice)
     {
      case 1: firstValue+=iClose(_Symbol,Timeframes,i); break;
      case 2: firstValue+=iOpen(_Symbol,Timeframes,i);  break;
      case 3: firstValue+=iHigh(_Symbol,Timeframes,i);  break;
      case 4: firstValue+=iLow(_Symbol,Timeframes,i);   break;
   default :  firstValue+=iClose(_Symbol,Timeframes,i); break;
     }
      firstValue/=period_ma;
//-----
      SMA=NormalizeDouble(firstValue,_Digits);
   if(LineTrend==true)
      tooltipsma="Line "+type_ma+string(InpMAPeriod)+"  "+pr+"\n"+TimeToString(iTime(_Symbol,Timeframes,beginbar),TIME_DATE|TIME_MINUTES)+"\n"+DoubleToString(SMA,_Digits);
   else
      tooltipsma="Trend "+type_ma+string(InpMAPeriod)+"  "+pr+"\n"+TimeToString(iTime(_Symbol,Timeframes,beginbar),TIME_DATE|TIME_MINUTES)+"\n"+"Original Price: "+DoubleToString(SMA,_Digits);
   if(LineTrend==true)
      HLine(0,smaname,tooltipsma,time_1,SMA,MAStyle,maWidthAll,ColorLine);
   else
      PlotTrend(0,smaname,tooltipsma,0,time_1,SMA,time_2,SMA,ColorLine,MAStyle,maWidthAll,true,false,false,true);
//----
   } //sma==true
//----------------------------------------------------------------------------------------------------------------
//+------------------------------------------------------------------+
//|  Exponential Moving Average                                      |
//+------------------------------------------------------------------+
 if(ema==true && ok==true && Period()<=BigPeriod)   //EMA
   {
int p,lmt;
double   SmoothFactor=2.0/(1.0+period_ma);
  if(prev_calculated==0)
       lmt=0;
  else 
       lmt=InpBars;
   for(p=lmt;p>=beginbar;p--)
     {
   switch(AppliedPrice)
     {
      case 1: ArrayPrice[lmt]=iClose(_Symbol,Timeframes,lmt); break;
      case 2: ArrayPrice[lmt]=iOpen(_Symbol,Timeframes,lmt); break;
      case 3: ArrayPrice[lmt]=iHigh(_Symbol,Timeframes,lmt); break;
      case 4: ArrayPrice[lmt]=iLow(_Symbol,Timeframes,lmt); break;
   default :  ArrayPrice[lmt]=iClose(_Symbol,Timeframes,lmt); break;
     }
   switch(AppliedPrice)
     {
      case 1: ArrayPrice[p]=iClose(_Symbol,Timeframes,p)*SmoothFactor+ArrayPrice[p+1]*(1.0-SmoothFactor); break;
      case 2: ArrayPrice[p]=iOpen(_Symbol,Timeframes,p)*SmoothFactor+ArrayPrice[p+1]*(1.0-SmoothFactor);  break;
      case 3: ArrayPrice[p]=iHigh(_Symbol,Timeframes,p)*SmoothFactor+ArrayPrice[p+1]*(1.0-SmoothFactor);  break;
      case 4: ArrayPrice[p]=iLow(_Symbol,Timeframes,p)*SmoothFactor+ArrayPrice[p+1]*(1.0-SmoothFactor);   break;
   default :  ArrayPrice[p]=iClose(_Symbol,Timeframes,p)*SmoothFactor+ArrayPrice[p+1]*(1.0-SmoothFactor); break;
     }
     } //for
//------------------------------------------------------------------------------------------------------------- 
      EMA=NormalizeDouble(ArrayPrice[beginbar],_Digits);
   if(LineTrend==true)
      tooltipema="Line "+type_ma+string(InpMAPeriod)+"  "+pr+"\n"+TimeToString(iTime(_Symbol,Timeframes,beginbar),TIME_DATE|TIME_MINUTES)+"\n"+DoubleToString(EMA,_Digits);
   else
      tooltipema="Trend "+type_ma+string(InpMAPeriod)+"  "+pr+"\n"+TimeToString(iTime(_Symbol,Timeframes,beginbar),TIME_DATE|TIME_MINUTES)+"\n"+"Original Price: "+DoubleToString(EMA,_Digits);
   if(LineTrend==true)
      HLine(0,smaname,tooltipema,time_1,EMA,MAStyle,maWidthAll,ColorLine);
   else
      PlotTrend(0,smaname,tooltipema,0,time_1,EMA,time_2,EMA,ColorLine,MAStyle,maWidthAll,true,false,false,true);
      ArrayFree(ArrayPrice);
//----
   }  //ema==true
   }  //if(HLines==true)
      
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Вывод горизонтальной линии на график                             |
//+------------------------------------------------------------------+
bool HLine(const long              chart_ID=0,
           string                  name="",
           string                  tooltip="",
           datetime                time=0,
           double                  price=0,
           int                     style=STYLE_SOLID,
           int                     width=1,
           color                   clr=clrBlack)
  {
//--- сбросим значение ошибки 
   ResetLastError(); 
//---
 if(!ObjectCreate(chart_ID,name,OBJ_HLINE,0,0,price)) 
     { 
      Print(__FUNCTION__,": не удалось создать горизонтальную линию! Код ошибки = ",GetLastError()); 
  return(false); 
     }       
      ObjectSetInteger(chart_ID,name,OBJPROP_STYLE, style);
      ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH, width);
      ObjectSetInteger(chart_ID,name,OBJPROP_COLOR, clr);
//--- скроем (true) или отобразим (false) имя графического объекта в списке объектов 
      ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,true); 
      ObjectSetString(chart_ID,name,OBJPROP_TOOLTIP,tooltip);
//----
  return(true);
  }
//+------------------------------------------------------------------+
//|  Построение трендовой линии на графике                           |
//+------------------------------------------------------------------+
bool PlotTrend(const long              chart_ID=0,
               string                  name="",
               string                  tooltip="",
               const int               subwindow=0,
               datetime                time1=0,
               double                  price1=0,
               datetime                time2=0,
               double                  price2=0,
               const color             clr=clrBlack,
               const ENUM_LINE_STYLE   style=STYLE_SOLID,
               const int               width=2,
               const bool              back=true,
               const bool              selection=false,
               const bool              ray=false,
               const bool              hidden=true)
  {
//----
   ResetLastError();
 if(ObjectFind(chart_ID,name)!=subwindow)
   {
 if(!ObjectCreate(chart_ID,name,OBJ_TREND,subwindow,time1,price1,time2,price2))
   {
   Print(__FUNCTION__,": не удалось создать трендовую линию! Код ошибки = ",GetLastError()); 
  return(false);
   }
   }
 else
   {
   ObjectMove(chart_ID,name,0,time1,price1);
   ObjectMove(chart_ID,name,1,time2,price2);
   }
   ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
   ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
   ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
   ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
   ObjectSetInteger(chart_ID,name,OBJPROP_RAY,ray);
   ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
   ObjectSetString(chart_ID,name,OBJPROP_TOOLTIP,tooltip);
//----
  return(true);
  }
//+------------------------------------------------------------------+
 
kopeyka2:

Написал индюка. Работает, но настойчиво пишет ошибку в разделе Эксперты.

У меня лог чистый, попереключал режимы произвольно (ЕМА тоже потестил). Дайте вариант настроек, при которых может появиться ошибка.

Было интересно, как может работать и выдавать ошибку одновременно.

 
yiduwi:

Вот это ценно, то что нужно) Чтобы узнать что заданное время находится внутри бара любого таймфрейма нужно сделать так

но если время ровно, без минут "2019.04.23 01:00:00" то стрелки на двух барах, на баре в 01:00:00 и на предыдущем в 00:00:00 Как не ставить лишнюю?

if (time[i]>=time_m1 && time[i]<time_m1+PeriodSeconds(PERIOD_M1) {

  // время time[i] попало внутрь бара открытого в time_m1

}

 
Igor Zakharov:

У меня лог чистый, попереключал режимы произвольно (ЕМА тоже потестил). Дайте вариант настроек, при которых может появиться ошибка.

Было интересно, как может работать и выдавать ошибку одновременно.

EMA20 23.04.2019 10:00


Линия ЕМА 20 23.04.2019 00:00 

При включении МТ5, БЕЗ онлайн подключения, СРАЗУ ЖЕ появляется сообщение "array out...."

Ошибки меняются, но присутствуют всегда. Могут размножаться в онлайне, но чаще присутствуют при включении МТ.


Вот такая вот загадка "бермудского параллепипеда"