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

 
Кто-нибудь видел индикатор, который бы рисовал свечи заданного временного периода? Квартальные, годовые и т.д.?
 
Alexey Viktorov #:

Ну проверил… И что? 

Где ошибка-то?

У меня тогда почему ошибка?


 
Alexandr Nikolaev #:

У меня тогда почему ошибка?


ArrayResize() не срабатывает


P.S. Покажите первые 9 строк программы.

 
PapaYozh #:

ArrayResize() не срабатывает


P.S. Покажите первые 9 строк программы.

Это я понимаю, что не срабатывает. Вопрос почему..

В первых 9 строках ничего особенного.

Вот весь код скрипта:

//+------------------------------------------------------------------+
//|                                                         TEST.mq4 |
//|                     https://www.mql5.com/ru/users/alexnik90/news |
//|                                             sashanik90@gmail.com |
//+------------------------------------------------------------------+
#property copyright "https://www.mql5.com/ru/users/alexnik90/news"
#property link      "sashanik90@gmail.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   double array[];
   int arraySize = 10;
   ArrayResize(array, arraySize);
   //--- присваиваем значения массива равные индексу
   for (int i = 0; i < arraySize; i++)
      array[i] = i; // если не закомментировать строку ниже, то тут вылазит ошибка: array out of range in 'TEST.mq4' (21,12)
   //--- высчитываем среднее значение
   double result = -1;
   result = iMAOnArray(array, 0, 5, 0, MODE_SMA, 0); // если закомментировать эту строку, то там ошибка пропадает, почему так?
   Print(result);
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
 

Да, подтверждаю, после попытки изменения размера, размер всё равно равен 0, а сама функция ArrayResize возвращает -1, это значит, что она не отработала:

При успешном выполнении функция возвращает количество всех элементов, содержащихся в массиве после изменения размера; в противном случае возвращает -1 и массив не меняет размеры.

Возможно, существует зависимость массива от функции iMAOnArray, на подобие этого:

При этом необходимо иметь ввиду, что нельзя изменять размер для динамических массивов, назначенных в качестве индикаторных буферов функцией SetIndexBuffer(). Для индикаторных буферов все операции по изменению размера производит исполняющая подсистема терминала.

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

 
Aleksei Stepanenko #:

Да, подтверждаю, после попытки изменения размера, размер всё равно равен 0, а сама функция ArrayResize возвращает -1, это значит, что она не отработала:

Возможно, существует зависимость массива от функции iMAOnArray, на подобие этого:

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

Попробуйте объявить массив в глобальной области

 
Alekseu Fedotov #:

Попробуйте объявить массив в глобальной области

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

 
Alexandr Nikolaev #:

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

Эту ветку вряд-ли разработчики читают.
Надо писать сюда: https://www.mql5.com/ru/forum/168449
 
Подскажите, пожалуйста, где здесь входные данные и фактические? 

Как сюда вставить Close[0]-Close[1] в фактические данные и  Close[1]-Close[2]  в тренировочную выборку?

То есть, это нейросетевик. В шаблоне из справочника этот советник выполняет одну конкретную задачу: найти правила по какому-то математическому уравнению. Как его перепрофилировать под цены? Эти матрицы, векторы... намного сложней ориентироваться, чем в обычном mql4 советнике. 

Шаблон из справочника работы с матрицами
matrix weights1weights2weights3;               // матрицы весовых коэффициентов
matrix output1output2result;                   // матрицы выходов нейронных слоев
input int layer1 = 200;                            // размер 1-го скрытого слоя
input int layer2 = 200;                            // размер 2-го скрытого слоя
input int Epochs = 20000;                          // количество эпох обучения
input double lr = 3e-6;                            // коэффициент скорости обучения
input ENUM_ACTIVATION_FUNCTION ac_func = AF_SWISH// функция активации
//+------------------------------------------------------------------+
//| Функция запуска скрипта                                          |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   int train = 1000;    // размер обучающей выборки
   int test = 10;       // размер тестовой выборки
   matrix m_datam_target;
//--- генерируем обучающую выборку
   if(!CreateData(m_datam_targettrain))  
      return;
//--- обучаем модель
   if(!Train(m_datam_targetEpochs))      
      return;
//--- генерируем тестовую выборку
   if(!CreateData(m_datam_targettest))   
      return;
//--- тестирование модели
   Test(m_datam_target);                   
  }
//+------------------------------------------------------------------+
//| Метод генерации выборки                                          |
//+------------------------------------------------------------------+
bool CreateData(matrix &datamatrix &targetconst int count)
  {
//--- инициализируем матрицы исходных данных и результатов
   if(!data.Init(count3) || !target.Init(count1))
      return false;
//--- заполняем матрицу исходных данных случайными значениями
   data.Random(-1010);                     
//--- рассчитываем целевые значения для обучающей выборки
   vector X1 = MathPow(data.Col(0) + data.Col(1) + data.Col(1), 2);
   vector X2 = MathPow(data.Col(0), 2) + MathPow(data.Col(1), 2) + MathPow(data.Col(2), 2);
   if(!target.Col(X1 / X20))
      return false;
//--- возвращаем результат
   return true;
  }
//+------------------------------------------------------------------+
//| Метод обучения модели                                            |
//+------------------------------------------------------------------+
bool Train(matrix &datamatrix &targetconst int epochs = 10000)
  {
//--- создаем модель
   if(!CreateNet())
      return false;
//--- обучаем модель
   for(int ep = 0ep < epochsep++)
     {
      //--- прямой проход
      if(!FeedForward(data))
         return false;
      PrintFormat("Epoch %d, loss %.5f"epresult.Loss(targetLOSS_MSE));
      //--- обратный проход и обновление матриц весов
      if(!Backprop(datatarget))
         return false;
     }
//--- возвращаем результат
   return true;
  }
//+------------------------------------------------------------------+
//| Метод создания модели                                            |
//+------------------------------------------------------------------+
bool CreateNet()
  {
//--- инициализируем матрицы весов
   if(!weights1.Init(4layer1) || !weights2.Init(layer1 + 1layer2) || !weights3.Init(layer2 + 11))
      return false;
//--- заполняем матрицы весов случайными значениями
   weights1.Random(-0.10.1);
   weights2.Random(-0.10.1);
   weights3.Random(-0.10.1);
//--- возвращаем результат
   return true;
  }
//+------------------------------------------------------------------+
//| Метод прямого прохода                                            |
//+------------------------------------------------------------------+
bool FeedForward(matrix &data)
  {
//--- проверяем размер исходных данных
   if(data.Cols() != weights1.Rows() - 1)
      return false;
//--- вычисляем первый нейронный слой
   matrix temp = data;
   if(!temp.Resize(temp.Rows(), weights1.Rows()) ||
      !temp.Col(vector::Ones(temp.Rows()), weights1.Rows() - 1))
      return false;
   output1 = temp.MatMul(weights1);
//--- вычисяем функцию активации
   if(!output1.Activation(tempac_func))
      return false;
//--- вычисляем второй нейронный слой
   if(!temp.Resize(temp.Rows(), weights2.Rows()) ||
      !temp.Col(vector::Ones(temp.Rows()), weights2.Rows() - 1))
      return false;
   output2 = temp.MatMul(weights2);
//--- вычисляем функцию активации
   if(!output2.Activation(tempac_func))
      return false;
//--- вычисляем третий нейронный слой
   if(!temp.Resize(temp.Rows(), weights3.Rows()) ||
      !temp.Col(vector::Ones(temp.Rows()), weights3.Rows() - 1))
      return false;
   result = temp.MatMul(weights3);
//--- возвращаем результат
   return true;
  }
//+------------------------------------------------------------------+
//| Метод обратного прохода                                          |
//+------------------------------------------------------------------+
bool Backprop(matrix &datamatrix &target)
  {
//--- проверяем размерность матрицы целевых значений
   if(target.Rows() != result.Rows() ||
      target.Cols() != result.Cols())
      return false;
//--- определяем отклонение расчетных значений от целевых
   matrix loss = (target - result) * 2;
//--- проводим градиент до предыдущего слоя
   matrix gradient = loss.MatMul(weights3.Transpose());
//--- обновляем матрицу весов последнего слоя
   matrix temp;
   if(!output2.Activation(tempac_func))
      return false;
   if(!temp.Resize(temp.Rows(), weights3.Rows()) ||
      !temp.Col(vector::Ones(temp.Rows()), weights3.Rows() - 1))
      return false;
   weights3 = weights3 + temp.Transpose().MatMul(loss) * lr;
//--- корректируем градиент ошибки на производную функции активации
   if(!output2.Derivative(tempac_func))
      return false;
   if(!gradient.Resize(gradient.Rows(), gradient.Cols() - 1))
      return false;
   loss = gradient * temp;
//--- опускаем градиент на слой ниже
   gradient = loss.MatMul(weights2.Transpose());
//--- обновляем матрицу весов 2-го скрытого слоя
   if(!output1.Activation(tempac_func))
      return false;
   if(!temp.Resize(temp.Rows(), weights2.Rows()) ||
      !temp.Col(vector::Ones(temp.Rows()), weights2.Rows() - 1))
      return false;
   weights2 = weights2 + temp.Transpose().MatMul(loss) * lr;
//--- корректируем градиент ошибки на производную функции активации
   if(!output1.Derivative(tempac_func))
      return false;
   if(!gradient.Resize(gradient.Rows(), gradient.Cols() - 1))
      return false;
   loss = gradient * temp;
//--- обновляем матрицу весов 1-го скрытого слоя
   temp = data;
   if(!temp.Resize(temp.Rows(), weights1.Rows()) ||
      !temp.Col(vector::Ones(temp.Rows()), weights1.Rows() - 1))
      return false;
   weights1 = weights1 + temp.Transpose().MatMul(loss) * lr;
//--- возвращаем результат
   return true;
  }
//+------------------------------------------------------------------+
//| Метод тестирования модели                                        |
//+------------------------------------------------------------------+
bool Test(matrix &datamatrix &target)
  {
//--- прямой проход на тестовых данных
   if(!FeedForward(data))
      return false;
//--- выводим в лог результаты расчета модели и истинные значения
   PrintFormat("Test loss %.5f"result.Loss(targetLOSS_MSE));
   ulong total = data.Rows();
   for(ulong i = 0i < totali++)
      PrintFormat("(%.2f + %.2f + %.2f)^2 / (%.2f^2 + %.2f^2 + %.2f^2) =  Net %.2f, Target %.2f"data[i0], data[i1], data[i2],
                  data[i0], data[i1], data[i2], result[i0], target[i0]);
//--- возвращаем результат
   return true;
  }
//+------------------------------------------------------------------+

 
Alexandr Nikolaev #:

Это я понимаю, что не срабатывает. Вопрос почему..

В первых 9 строках ничего особенного.

Вот весь код скрипта:

Уважаемый Александр Николаев, та блин... Перенесите   double array[]; в глобальную область, и всё)))

И нет никаких ошибок, принтует 7,0

  

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