Ваши вопросы по языку MQL4

AlexeyVik

Программист mql4 mql5
AlexeyVik
Ну да, я там все в буфера натолкал, отому что не понимаю, что вообще происходит.
А как надо-то?
Да и я тоже городской, но всё-же, по логике, в индикаторах массивы динамические и соответственно при появлении нового бара и время и цена твоих вил поменяется.
Я-бы лучше в переменную глобального уровня datetime записал время и от него всё рисовал. Ну или поиск начальной точки перебором можно сделать.
 

ansol

Местный знаток
Да и я тоже городской, но всё-же, по логике, в индикаторах массивы динамические и соответственно при появлении нового бара и время и цена твоих вил поменяется.
Я-бы лучше в переменную глобального уровня datetime записал время и от него всё рисовал. Ну или поиск начальной точки перебором можно сделать.

Вот этого как раз и хочется. В принципе, есть готовые, но под мою систему их все равно править надо, я и решил свой написать, заодно поучиться.
 

AlexeyVik

Программист mql4 mql5
Ну тогда тщательно проверь что в твоих массивах пишется.
А потом подумай и замени свой массив с временем на Time[]
А в общем-то из твоего вопроса не понятно что не получается. Если направление не то, значит надо поменять вторую координату с третьей местами. Т.е. координаты второй точки назначить третьей и наоборот, координаты третьей точки назначить второй. А для этого должно быть какое-то условие.
 

ansol

Местный знаток
Ну тогда тщательно проверь что в твоих массивах пишется.
А потом подумай и замени свой массив с временем на Time[]
А в общем-то из твоего вопроса не понятно что не получается. Если направление не то, значит надо поменять вторую координату с третьей местами. Т.е. координаты второй точки назначить третьей и наоборот, координаты третьей точки назначить второй. А для этого должно быть какое-то условие.

Вроде бы нет зависимости от того, как расположены вторая и третья координаты, но я решил уточнить у знающих людей :)

Насчет Time[] все правильно, просто я хотел поумничать и сделать массив из трех элементов(раз всего три координаты), но проклятый mql4 почему-то так не работает.
Как размер массива указать кроме как через ArrayResize?
В любом нормальном языке int MyArray() хватило бы, а тут - хрен.
Поэтому я тупо взял индексы - они сразу инициализированы и "бесконечны".
 

AlexeyVik

Программист mql4 mql5
Вроде бы нет зависимости от того, как расположены вторая и третья координаты, но я решил уточнить у знающих людей :)

Насчет Time[] все правильно, просто я хотел поумничать и сделать массив из трех элементов(раз всего три координаты), но проклятый mql4 почему-то так не работает.
Как размер массива указать кроме как через ArrayResize?
В любом нормальном языке int MyArray() хватило бы, а тут - хрен.
Поэтому я тупо взял индексы - они сразу инициализированы и "бесконечны".
Всего-лишь написать не MyArray[] a MyArray[3] или ты хотел 3х мерный массив??? Только к чему он тебе?
И ты туда-же, при чём тут язык? Что за привычка на зеркало пенять, когда рожа крива???
 
Последнее редактирование:

ansol

Местный знаток
Всего-лишь написать не MyArray[] a MyArray[3] или ты хотел 3х мерный массив??? Только а чему он тебе?
И ты туда-же, при чём тут язык? Что за привычка на зеркало пенять, когда рожа крива???

Если размер не указан (обычно, не в mql4), то он может быть любой длины. Я его обычно и не указывал и в примерах хелпа написано просто "double f[]".
Начинаю присваивать f[3] = Time[x], а туда ничего не присваивается оО
Зашибись, бочарик!©
Оскорбления насчет рож прошу придержать при себе.
 

AlexeyVik

Программист mql4 mql5
Если размер не указан (обычно, не в mql4), то он может быть любой длины. Я его обычно и не указывал и в примерах хелпа написано просто "double f[]".
Начинаю присваивать f[3] = Time[x], а туда ничего не присваивается оО
Зашибись, бочарик!©
Оскорбления насчет рож прошу придержать при себе.
Это не оскорбление, это поговорка такая.
Ну не может такого быть. Если в массив что-то записано, то оно там будет даже если массив объявлен в теле функции. Потому и говорят о массивах, что они все статические. Т.е. если для сохранения переменной после выхода из функции надо её объявить как static double f; то массив просто double m[];
Но если это индикаторный массив, то его индексация на каждом баре сдвигается. Соответственно если ты сейчас пишешь в f[3] то на следующем баре надо читать из f[4] а на следующем из 5.
 

ansol

Местный знаток
Это не оскорбление, это поговорка такая.
Ну не может такого быть. Если в массив что-то записано, то оно там будет даже если массив объявлен в теле функции. Потому и говорят о массивах, что они все статические. Т.е. если для сохранения переменной после выхода из функции надо её объявить как static double f; то массив просто double m[];
Но если это индикаторный массив, то его индексация на каждом баре сдвигается. Соответственно если ты сейчас пишешь в f[3] то на следующем баре надо читать из f[4] а на следующем из 5.

"Рожа" бывает у уродов и пьяниц, так что оскорбление. У меня - лицо. Прошу принять к сведению.

Насчет "не может быть" - не принимается возражение. Массив объявлен сразу за переменными типа extern:
extern int StartZ=13;
double ExtMapBuffer0[];
и используется в функции start() безо всяких вызовов подпрограмм и т.п.
Т.е. в цикле перебираются значения и если попадается нужное по условию, то идет присвоение
ExtMapBuffer0[iLastZ] = iZCountLast;

Если его сразу же следующей строчкой напечатать, то выдает "0", хотя этого "не может быть" :)
Как только я его сделал индексным, сразу все заработало.
Видимо, надо было написать
double ExtMapBuffer0[3];
Но в дальнейшем предполагалось иметь 6 и, возможно, 9 значений, поэтому у меня в мыслях как-то не возникло заморачиваться с размером.
На нужную мысль меня могла бы навести функция
int ArrayResize(object&array[], int new_size)
Сразу ясно, что разработчики замыслили что-то нехорошее :laugh:
Так оно и оказалось :facepalm:
 
Последнее редактирование:

AlexeyVik

Программист mql4 mql5
"Рожа" бывает у уродов и пьяниц, так что оскорбление. У меня - лицо. Прошу принять к сведению.

Насчет "не может быть" - не принимается возражение. Массив объявлен сразу за переменными типа extern:
extern int StartZ=13;
double ExtMapBuffer0[];
и используется в функции start() безо всяких вызовов подпрограмм и т.п.
Т.е. в цикле перебираются значения и если попадается нужное по условию, то идет присвоение
ExtMapBuffer0[iLastZ] = iZCountLast;

Если его сразу же следующей строчкой напечатать, то выдает "0", хотя этого "не может быть" :)
Как только я его сделал индексным, сразу все заработало.
Видимо, надо было написать
double ExtMapBuffer0[3];
Но в дальнейшем предполагалось иметь 6 и, возможно, 9 значений, поэтому у меня в мыслях как-то не возникло заморачиваться с размером.
На нужную мысль меня могла бы навести функция
int ArrayResize(object&array[], int new_size)
Сразу ясно, что разработчики замыслили что-то нехорошее :laugh:
Так оно и оказалось :facepalm:
Я тебе ещё раз повторяю, это просто поговорка и к твоему лицу прямого отношения не имеет.
И ещё раз повторяю, что-то где-то ты не правильно записываешь. Я пользуюсь массивами везде где только нужно помнить значений больше двух и не известно сколько их будет вообще. Например в массиве храню количество открытых ордеров по типам раздельно и их тикеты так-же. Ну если твой код имеет гриф "Совершенно секретно" то помочь тебе вряд-ли представляется возможным.
 

AlexeyVik

Программист mql4 mql5
Т.е. в цикле перебираются значения и если попадается нужное по условию, то идет присвоение
ExtMapBuffer0[iLastZ] = iZCountLast;

Если его сразу же следующей строчкой напечатать, то выдает "0", хотя это
Пока я обедал пришла мысль тебе ещё дать один совет:
В цикле перед присваиванием значения массива поставь ещё один Print()
Получится так:

Код:
if(условие для заполнения массива ExtMapBuffer0[])
{
Print("iZCountLast = ", iZCountLast);
ExtMapBuffer0[iLastZ] = iZCountLast;
Print("ExtMapBuffer0[iLastZ] = ", ExtMapBuffer0[iLastZ]);
}
 

ansol

Местный знаток
Пока я обедал пришла мысль тебе ещё дать один совет:
В цикле перед присваиванием значения массива поставь ещё один Print()
Получится так:

Код:
if(условие для заполнения массива ExtMapBuffer0[])
{
Print("iZCountLast = ", iZCountLast);
ExtMapBuffer0[iLastZ] = iZCountLast;
Print("ExtMapBuffer0[iLastZ] = ", ExtMapBuffer0[iLastZ]);
}
Переменная правильная - это число колен зигзага, так что я ее на графике могу пальцами посчитать(для проверки, так сказать), значение элемента массива - ноль, если размер массива не задан. Я ХЗ почему так. Отсюда и все дальнейшее обсуждение возникло
 

ansol

Местный знаток
Вообще, если интересно, давайте обсудим простейший генератор вил Эндрюса
PHP:
//+------------------------------------------------------------------+
//|                                                     1Pitchok.mq4 |
//|                        Copyright 2014, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"

#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Red
#property indicator_color2 Red
//--- input parameters
extern int       ExtDepth=12;
extern int       StartZ=13;
//--- buffers
double ExtMapBuffer0[];
double ExtMapBuffer1[];

int ExtDeviation = 5;
int ExtBackStep = 3;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   SetIndexStyle(0,DRAW_NONE);
   SetIndexBuffer(0,ExtMapBuffer0);
   SetIndexStyle(1,DRAW_NONE);
   SetIndexBuffer(1,ExtMapBuffer1);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   ObjectDelete("Bily");
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int    counted_bars=IndicatorCounted();
   int    iLastZ, iZCountLast, ZHigh, ZLow;
   double dLastZ;
//----
      if(counted_bars >= Bars) return(0);
      RefreshRates();
      ObjectDelete("Bily");
      while(iLastZ <= StartZ)
         {
            iLastZ++;
            while(!dLastZ)
               {
                  iZCountLast++;
                  dLastZ = iCustom(NULL, 0, "1ZigZag", ExtDepth, ExtDeviation, ExtBackStep, 0, iZCountLast);
                }
            ExtMapBuffer0[iLastZ] = Time[iZCountLast];
            ExtMapBuffer1[iLastZ] = dLastZ;
            dLastZ = 0;
          }
   if(Bid - ExtMapBuffer1[StartZ] > 0) 
      {
         ZHigh = ArrayMaximum(ExtMapBuffer1, StartZ, 1);
         ZLow = ArrayMinimum(ExtMapBuffer1, StartZ-ZHigh, 1); 
       }
   if(ExtMapBuffer1[StartZ] - Bid > 0)
      {
         ZLow = ArrayMinimum(ExtMapBuffer1, StartZ, 1);
         ZHigh = ArrayMaximum(ExtMapBuffer1, StartZ-ZLow, 1);
       }
Comment(ExtMapBuffer1[StartZ],"_S_",StartZ," ",
   ExtMapBuffer1[ZHigh],"_H_",ZHigh," ",
   ExtMapBuffer1[ZLow],"_L_",ZLow);
ObjectCreate("Bily", OBJ_PITCHFORK, 0, ExtMapBuffer0[StartZ], ExtMapBuffer1[StartZ], ExtMapBuffer0[ZHigh],
       ExtMapBuffer1[ZHigh], ExtMapBuffer0[ZLow], ExtMapBuffer1[ZLow]);
//----
   return(0);
  }
//+------------------------------------------------------------------+
Ну, типа, я вот так написал, а можно же проще или экономнее в смысле ресурсов и памяти.
Я этим еще не занимался, но конечный код точно будет другим. Вот и польза для всех в обсуждении моментов "как?"
 
Последнее редактирование:

AlexeyVik

Программист mql4 mql5
Вообще, если интересно, давайте обсудим простейший генератор вил Эндрюса
PHP:
//+------------------------------------------------------------------+
//|                                                     1Pitchok.mq4 |
//|                        Copyright 2014, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"

#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Red
#property indicator_color2 Red
//--- input parameters
extern int       ExtDepth=12;
extern int       StartZ=13;
//--- buffers
double ExtMapBuffer0[];
double ExtMapBuffer1[];

int ExtDeviation = 5;
int ExtBackStep = 3;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   SetIndexStyle(0,DRAW_NONE);
   SetIndexBuffer(0,ExtMapBuffer0);
   SetIndexStyle(1,DRAW_NONE);
   SetIndexBuffer(1,ExtMapBuffer1);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   ObjectDelete("Bily");
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int    counted_bars=IndicatorCounted();
   int    iLastZ, iZCountLast, ZHigh, ZLow;
   double dLastZ;
//----
      if(counted_bars >= Bars) return(0);
      RefreshRates();
      ObjectDelete("Bily");
      while(iLastZ <= StartZ)
         {
            iLastZ++;
            while(!dLastZ)
               {
                  iZCountLast++;
                  dLastZ = iCustom(NULL, 0, "1ZigZag", ExtDepth, ExtDeviation, ExtBackStep, 0, iZCountLast);
                }
            ExtMapBuffer0[iLastZ] = Time[iZCountLast];
            ExtMapBuffer1[iLastZ] = dLastZ;
            dLastZ = 0;
          }
   if(Bid - ExtMapBuffer1[StartZ] > 0) 
      {
         ZHigh = ArrayMaximum(ExtMapBuffer1, StartZ, 1);
         ZLow = ArrayMinimum(ExtMapBuffer1, StartZ-ZHigh, 1); 
       }
   if(ExtMapBuffer1[StartZ] - Bid > 0)
      {
         ZLow = ArrayMinimum(ExtMapBuffer1, StartZ, 1);
         ZHigh = ArrayMaximum(ExtMapBuffer1, StartZ-ZLow, 1);
       }
Comment(ExtMapBuffer1[StartZ],"_S_",StartZ," ",
   ExtMapBuffer1[ZHigh],"_H_",ZHigh," ",
   ExtMapBuffer1[ZLow],"_L_",ZLow);
ObjectCreate("Bily", OBJ_PITCHFORK, 0, ExtMapBuffer0[StartZ], ExtMapBuffer1[StartZ], ExtMapBuffer0[ZHigh],
       ExtMapBuffer1[ZHigh], ExtMapBuffer0[ZLow], ExtMapBuffer1[ZLow]);
//----
   return(0);
  }
//+------------------------------------------------------------------+
Ну, типа, я вот так написал, а можно же проще или экономнее в смысле ресурсов и памяти.
Я этим еще не занимался, но конечный код точно будет другим. Вот и польза для всех в обсуждении моментов "как?"
Первая ошибка в том что ты сделал динамические, индикаторные массивы
Код:
   SetIndexStyle(0,DRAW_NONE);
   SetIndexBuffer(0,ExtMapBuffer0);
   SetIndexStyle(1,DRAW_NONE);
   SetIndexBuffer(1,ExtMapBuffer1);
А вторая, наверное, в том, что ты пытаешься нарисовать вилы по всем пикам зиг-зага? Хотя может и надо, для анализа. Тогда не надо объект удалять на каждом тике. Да и если нужен только последний то его не обязательно удалять и создавать вновь. Достаточно назначить новые координаты.
 

ansol

Местный знаток
Первая ошибка в том что ты сделал динамические, индикаторные массивы
Код:
   SetIndexStyle(0,DRAW_NONE);
   SetIndexBuffer(0,ExtMapBuffer0);
   SetIndexStyle(1,DRAW_NONE);
   SetIndexBuffer(1,ExtMapBuffer1);
А вторая, наверное, в том, что ты пытаешься нарисовать вилы по всем пикам зиг-зага? Хотя может и надо, для анализа. Тогда не надо объект удалять на каждом тике. Да и если нужен только последний то его не обязательно удалять и создавать вновь. Достаточно назначить новые координаты.
Не по всем! Я беру 13 колен из.. эмм... ну, стратегия такая, не будем об этом, ибо это вынесено во внешние переменные.
Насчет "удаления" я не знаю - ни разу не писал индикаторы, побоялся, что там на графике нарисуется много "вил Эндрюса", а мне нужны... Ну, это опять стратегия, не здесь обсуждать.
Счас удаление уберу и посмотрю, что будет, но... Если есть CreateObject, то старый объект с этим именем автоматом удаляется? Или крейтобъект вынести в init(), а потом только set для него делать? А как?
 

ansol

Местный знаток
Еще добавлю насчет "по всем пикам":
А как по вашему рисуются вилы? Надо выбрать некие пики зигзага по определенному алгоритму. Этот алгоритм надо сгрузить программе, чтобы она рисовала. Я выбрал элементарный пока что.
1. Если тренд вниз, то ищем минимум
2. От этого минимума до 13 колена ищем максимум
3. Готово
Или наоборот, ищем максимум для тренда вверх. Тренд определяется, как отношение начала "вил" к текущему моменту.
 

AlexeyVik

Программист mql4 mql5
Ты знаешь, я ведь тебе сказал, что я тоже городской и с вилами не дружил никогда.
Просто построение объектов абсолютно одинаково не зависимо от типа объекта.
Я-бы для начала написал так, чтобы рисовался ПРАВИЛЬНО один объект, по ближайшим точкам, а потом уже попытался-бы сделать повтор в цикле.
Для того чтобы было несколько одинаковых объектов им надо дать разные имена. Чаще применяется метод включения в имя времени создания или даты.
string name;
Потом перед созданием объекта
name = StringConcatenate("Bily", Time);
if(ObjectFind(name) < 0)
ObjectCreate(name, ....
А дальше назначаются свойства объекта
ObjectSet(name, ....
Столько раз сколько надо изменить свойств.
 
Последнее редактирование:
Верх