Вопросы от начинающих MQL5 MT5 MetaTrader 5 - страница 1501

 
ulong gcd(ulong a, ulong b) {
   ulong c;
   if(a < b) {
      c = a;
      a = b;
      b = c;
   }

   while(b > 0) {
      c = a % b;
      a = b;
      b = c;
   }

   return a;
}

ulong ArrayGcd(ulong &a[]) {
   int n = ArraySize(a);
   if(n == 1) {
      return 0;
   }
   ulong c = gcd(a[0], a[1]);

   for(int i = 2; i < n; i++) {
      c = gcd(a[i], c);
      if(c == 1) {
         break;
      }
   }
   return c;
}

int OnInit() {
   PrintFormat("gcd(35, 140) = %d", gcd(35, 140));
   PrintFormat("gcd(35, 147) = %d", gcd(35, 147));
   PrintFormat("gcd(35, 149) = %d", gcd(35, 149));
   
   ulong a1[] = {35, 140, 28, 7};
   ulong a2[] = {35, 140, 28, 6};
   ulong a3[] = {32, 140, 28, 16};
   PrintFormat("gcd(35, 140, 28, 7) = %d", ArrayGcd(a1));
   PrintFormat("gcd(35, 140, 28, 6) = %d", ArrayGcd(a2));
   PrintFormat("gcd(32, 140, 28, 16) = %d", ArrayGcd(a3));
   return(INIT_SUCCEEDED);
}
 
MrBrooklin #:

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

С уважением, Владимир.

Ок, большое спасибо за Ваше мнение. Давайте попробуем. Краткая предыстория для понимания. Функцию планирую использовать в индикаторе, основанном на Ренко, наложенном на основной график. Возникает необходимость определять текущий размер кирпичиков. На основе ренко-графика строится ЗигЗаг, он имеет, кроме всего прочего, два массива - один с верхушками и один с донышками. Теперь мне нужно определить НаибольшийОбщийДелитель расстояний между ними, чтобы подкорректировать автоматически размер кирпичиков. 

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

//+------------------------------------------------------------------+
//| Вычисляем значение НОД(НаибольшийОбщийДелитель)=размера кирпичика|
//+------------------------------------------------------------------+
int CalculateBrickSize(int &size_brick, double &Arr_PeakBuff[], double &Arr_BottomBuff[])
  {
   int    size_zigbuf = 0;
   double peak        = 0.0;
   double bottom      = 0.0;

   int zigLag   = 0.0;
   int Arr_ZigLag[];

   if(!ArrayGetAsSeries(Arr_PeakBuff))
      ArraySetAsSeries(Arr_PeakBuff,   true);
   if(!ArrayGetAsSeries(Arr_BottomBuff))
      ArraySetAsSeries(Arr_BottomBuff, true);
   ArrayInitialize(Arr_ZigLag, 0.00);

   size_zigbuf = MathMin(ArraySize(Arr_PeakBuff), ArraySize(Arr_BottomBuff));
   size_zigbuf = MathMin(size_zigbuf, ChartVisibleBars()) - 1;

   if(size_zigbuf > 0)
      ArrayResize(Arr_ZigLag, size_zigbuf);
   for(int i = 0; i < size_zigbuf; i++)
     {
      if(Arr_PeakBuff[i] != EMPTY_VALUE)
         peak = NormalizeDouble(Arr_PeakBuff[i], _Digits);
      if(Arr_BottomBuff[i] != EMPTY_VALUE)
         bottom = NormalizeDouble(Arr_BottomBuff[i], _Digits);
      if(peak == 0 || bottom == 0)
        {
         zigLag = 1;
        }
      else
         zigLag = (int)DoubleToString(MathAbs(peak - bottom)*100000, 0);
      Arr_ZigLag[i] = zigLag;
     }
//---
   int delimoe = 0;
   int delitel = 1;
   int ostatok = 1;
   ArraySort(Arr_ZigLag);

   for(int i = ArraySize(Arr_ZigLag)-1; i > 0; i--)
     {
      if(Arr_ZigLag[i] != Arr_ZigLag[i-1])
        {
         if(delimoe == 0)
            delimoe = MathMax(Arr_ZigLag[i], Arr_ZigLag[i-1]);
         if(delitel == 1)
            delitel = MathMin(Arr_ZigLag[i], Arr_ZigLag[i-1]);
         ostatok = (int)MathMod(delimoe, delitel);
         if(ostatok == 0)
           {
            delimoe = delitel;
            delitel = 1;
            ostatok = 1;
            continue;
           }
         else
            while(ostatok != 0)
              {
               ostatok = (int)MathMod(delimoe, delitel);
               delimoe = delitel;
               delitel = ostatok;
              }
        }
     }
   //Print("delimoe = ", delimoe);
   //Print("delitel = ", delitel);
   //Print("ostatok = ", ostatok);
   return(size_brick);
  }
//+------------------------------------------------------------------+
 
Это конечно просто еще заготовка, не судите строго. Мне кажется я вообще куда-то не туда пошел, все как-то каряво, нужно найти более простое и понятное решение, но в голове не укладывается пока....
 
Sergey Voytsekhovsky #:
Это конечно просто еще заготовка, не судите строго. Мне кажется я вообще куда-то не туда пошел, все как-то каряво, нужно найти более простое и понятное решение, но в голове не укладывается пока....
Сергей, сформируйте массив чисел, для которых вы хотите найти НОД и передайте его в функцию ArrayGcd() из моего предыдущего поста. 

Только вот не уверен, что вам получится использовать НОД в данном случае. Похоже, что вы хотите считать его для чисел, которые не имеют между собой каких-то жёстких связей, обеспечивающих наличие нетривиального общего делителя.
Тогда с высокой вероятностью вы всегда будете получать НОД = 1. 
 
Yuriy Bykov #:
Сергей, сформируйте массив чисел, для которых вы хотите найти НОД и передайте его в функцию ArrayGcd() из моего предыдущего поста. 

Спасибо, увидел Ваше сообщение уже после того, как отправил свое крайнее, сейчас пробую приладить.

 
Sergey Voytsekhovsky #:

Спасибо, увидел Ваше сообщение уже после того, как отправил свое крайнее, сейчас пробую приладить.

Можно заменит в коде везде ulong на int, но тогда надо быть уверенным, что числа в массиве все положительные 
 
Yuriy Bykov #:
Сергей, сформируйте массив чисел, для которых вы хотите найти НОД и передайте его в функцию ArrayGcd() из моего предыдущего поста. 

Только вот не уверен, что вам получится использовать НОД в данном случае. Похоже, что вы хотите считать его для чисел, которые не имеют между собой каких-то жёстких связей, обеспечивающих наличие нетривиального общего делителя.
Тогда с высокой вероятностью вы всегда будете получать НОД = 1. 

Возможно, нужно проверять, а это только после кодирования алгоритма. Спасибо за отзывчивость.

 

Всем привет, подскажите, возможно ли как-то сделать импорт функции из одного советника в другой?

К примеру, есть советник который открывает ордера, а есть советник который следит за состоянием счета, где указаны параметры просадка и т.д.,

нужно чтобы по достижению просадки второго советника, первый советник не открывал ордера...

Как к примеру это сделать?

 
psihodelit #:

Всем привет, подскажите, возможно ли как-то сделать импорт функции из одного советника в другой?

К примеру, есть советник который открывает ордера, а есть советник который следит за состоянием счета, где указаны параметры просадка и т.д.,

нужно чтобы по достижению просадки второго советника, первый советник не открывал ордера...

Как к примеру это сделать?

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

 
psihodelit #:

Всем привет, подскажите, возможно ли как-то сделать импорт функции из одного советника в другой?

К примеру, есть советник который открывает ордера, а есть советник который следит за состоянием счета, где указаны параметры просадка и т.д.,

нужно чтобы по достижению просадки второго советника, первый советник не открывал ордера...

Как к примеру это сделать?

Вариантов несколько.

Можно воспользоваться советом выше. Вполне рабочий вариант.

Можно использовать  Глобальные переменные терминала.

Можно наладить обмен между советниками с помощью записи/чтения файла.

Как говорится на вкус и цвет все фломастеры разные)))

Причина обращения: