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

 
Roman Sharanov:

вот еще нашел серьезный недочет, очень много вызовов CopyClose()

Не подскажете, как можно в цикле скопировать из массива валютных пар их котировки?

Это получается двойной массив должен быть, а MQL такое не поддерживает, типа%

MQL4 вроде работает с двухмерными динамичсекими массивами, первое измерение массива сами измените через ArayResize(), а второе передавайте в CopyClose() 

ну или универсальное решение от разработчиков ибо в MQL5 не работают 2-хмерные динамические массивы, оберните одномерный массив в структуру и создайте массив таких структур.... разберетесь считайте, что почти класс написали, и это более оптимальнее - класс у которого метод сам подгружает данные и хранит в свойствах(полях) класса
 
Igor Makanu:

MQL4 вроде работает с двухмерными динамичсекими массивами, первое измерение массива сами измените через ArayResize(), а второе передавайте в CopyClose() 

ну или универсальное решение от разработчиков ибо в MQL5 не работают 2-хмерные динамические массивы, оберните одномерный массив в структуру и создайте массив таких структур.... разберетесь считайте, что почти класс написали, и это более оптимальнее - класс у которого метод сам подгружает данные и хранит в свойствах(полях) класса

Спасибо попробую

 

Еще вопрос по поводу индикатора, не знаю что еще тут делать

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

По итогу выводится просто разница, без МА, в чем проблема?

#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_plots 2
#property indicator_type1 DRAW_COLOR_LINE
#property indicator_style1 STYLE_SOLID
#property indicator_type2 DRAW_LINE
#property indicator_style2 STYLE_SOLID
#property indicator_width1 1
#include <MovingAverages.mqh>

input string active_1 = "EURUSD";
input string active_2 = "USDJPY";
input ENUM_TIMEFRAMES timeframe = PERIOD_H1;
input int ma_period = 30;

double firstBuffer[], secondBuffer[], dataBuffer[], maBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0, dataBuffer, INDICATOR_DATA);
   SetIndexBuffer(1, maBuffer, INDICATOR_DATA);
   SetIndexBuffer(2, firstBuffer, INDICATOR_CALCULATIONS);
   SetIndexBuffer(3, secondBuffer, INDICATOR_CALCULATIONS);
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
//---

   CopyClose(active_1,timeframe,0,rates_total,firstBuffer);
   CopyClose(active_2,timeframe,0,rates_total,secondBuffer);

   int first, bar;
   if(prev_calculated == 0) first = begin; else first = prev_calculated - 1;

   for(bar = first; bar<rates_total; bar++){
      dataBuffer[bar] = firstBuffer[bar]-secondBuffer[bar];
   }

   ExponentialMAOnBuffer(rates_total,prev_calculated,begin,ma_period,dataBuffer,maBuffer);
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
 
Igor Makanu:

перебирать ордера нужно в цикле. а не на каждом тике... если точнее, то пришел тик и посчитали все свои ордера в цикле: for(j=0;j<OrderTotal;j++)

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

нумерация ордеров как в массивах, от 0 до OrdersTotal()-1 - это последний ордер, а у Вас, наверное, вывод в журнал на каждом тике несуществующий тикет № [OrdersTotal()] или еще какая то информация, которую сложно угадать

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

Я всегда считал, что если советник вошёл в тело функции, то она уже не должна реагировать на другие тики,пока не выйдет из цикла, но, похоже это не так. Как  обойти эту ситуацию?

int test()
{       
   int total;  
   total = OrdersTotal();
   log("total = " + total +"; ");
  
   for (int j = 0; j < total; j++)
   {       
      log("j = " + j +"; ");       
   }   
    return(0);
}

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

Проблема даже не в том, что мне нужна информация на каждый тик, а в том, что, если я понимаю правильно, цикл не успевает закончиться до прихода нового тика и новый тик каким то образом нарушает счет. Вот ещё раз приложу скриншот, чтобы Вам не искать предыдущий. Из него видно, советник досчитал до 52 и потом прыгнул на 93. Мне было трудно поверить, что это происходит из-за прихода новых тиков, но, пока, я не могу найти другую причину, т.к. при редком появлении тиков, счет заканчивается нормально, также как и последний цикл, после удаления советника с графика.

Код уже максимально упростил:

int test()
{       
   int total;  
   total = OrdersTotal();
   log("total = " + total +"; ");
  
   for (int j = 0; j < total; j++)
   {       
      log("j = " + j +"; ");       
   }   
    return(0);
}

Файлы:
test.jpg  82 kb
 
Artyom Trishkin:

Откуда вы такое знаете? Это не так.

Пока не будут завершены все вычисления, начавшиеся с приходом тика, все последующие тики пропускаются.

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

Я тоже всегда верил, что "Пока не будут завершены все вычисления, начавшиеся с приходом тика, все последующие тики пропускаются". Хотелось бы, чтобы оно так и было, но другую, кроме новых тиков, причину найти, пока, не могу.

 
Artyom Trishkin:

Без кода никто не скажет.

Вот предельно упрощённый код, который имеет туже проблему  - новые тики сбивают последовательный вывод номеров ордеров.

int test()
{       
   int total;  
   total = OrdersTotal();
   log("total = " + total +"; ");
  
   for (int j = 0; j < total; j++)
   {       
      log("j = " + j +"; ");       
   }   
    return(0);
}

 
Algotrader18:

Вот предельно упрощённый код, который имеет туже проблему  - новые тики сбивают последовательный вывод номеров ордеров.

int test()
{       
   int total;  
   total = OrdersTotal();
   log("total = " + total +"; ");
  
   for (int j = 0; j < total; j++)
   {       
      log("j = " + j +"; ");       
   }   
    return(0);
}

Неужели этот код откомпилируется без ошибок??? НЕ верю...
 
Roman Sharanov:

Еще вопрос по поводу индикатора, не знаю что еще тут делать

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

По итогу выводится просто разница, без МА, в чем проблема?

Это круто!

Роман!

Я  вот, например, успешный  трейдер с 20-летним стажем.

Я вот не пойму, зачем Вам нужна "разница между закрытиями введенных пар, и скользящая средняя по ним".

Более того, а скользящую среднюю по этим разницам Вы умеете строить? - Фантастика!

А просто скользящую среднюю по котировкам  строить умеете? - Тоже нет?

Так в чем проблема?

 
Algotrader18:

Вот предельно упрощённый код, который имеет туже проблему  - новые тики сбивают последовательный вывод номеров ордеров.

int test()
{       
   int total;  
   total = OrdersTotal();
   log("total = " + total +"; ");
  
   for (int j = 0; j < total; j++)
   {       
      log("j = " + j +"; ");       
   }   
    return(0);
}

вот этот код работает, сделайте по аналогии:

int NumberOfOrders(int magic_)
  {
   int i,res=0,k=OrdersTotal(); string sy=Symbol();
   for(i=0; i<k; i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if((OrderMagicNumber()==magic_) && (OrderSymbol()==sy)) res++;
        }
     }
   return(res);
  }
Причина обращения: