Ошибки, баги, вопросы - страница 3259

 
Anatoli Kazharski #:

Флаг 

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

В редакторе MetaEditor через главное меню можно открыть эту папку:


Спасибище!!!

 
Привет друг. Можно ли здесь обсуждать технические вопросы?
В настоящее время максимальное количество графиков, которые может открыть клиент MT5, составляет 100, что достаточно для обычных ручных и программных трейдеров, но для институциональных клиентов, которые используют MT5 для работы с несколькими вариантами, периодами и стратегиями. на каждом шагу есть тысячи стратегий.Хотя в настоящее время можно открыть более 100 графиков, открыв несколько клиентов, многие операции по управлению рисками необходимо обрабатывать между клиентами, что более проблематично. Есть ли способ снять это ограничение.
 
Zhang Fengqun #:
Привет друг. Можно ли здесь обсуждать технические вопросы?
В настоящее время максимальное количество графиков, которые может открыть клиент MT5, составляет 100, что достаточно для обычных ручных и программных трейдеров, но для институциональных клиентов, которые используют MT5 для работы с несколькими вариантами, периодами и стратегиями. на каждом шагу есть тысячи стратегий.Хотя в настоящее время можно открыть более 100 графиков, открыв несколько клиентов, многие операции по управлению рисками необходимо обрабатывать между клиентами, что более проблематично. Есть ли способ снять это ограничение.

Попробуем снять это ограничение

 
Скрипт при работе использует 12% мощности процессора. Можно ли увеличить эти проценты?
 
Aliaksandr Yemialyanau #:
Скрипт при работе использует 12% мощности процессора. Можно ли увеличить эти проценты?

Можно, если будите использовать в коде OpenCL.

 

Привет всем.
Подскажите пожалуйста, на основном графике есть ли способ изменить цвет определённой свечи?
Например по её индексу. То что можно отрисовать свечи в индикаторе я знаю, но не хотелось бы это делать через индикатор. 
Так как рассчитывается кастомный символ и хотелось бы в этом расчёте сразу управлять цветами (больше двух) определённой свечи.

Эти функции не подходят, так-как красят всю серию свечей основного графика.
А хотелось бы по индексно менять цвет.

ChartSetInteger(0, CHART_COLOR_CANDLE_BULL, clrOrange);
ChartSetInteger(0, CHART_COLOR_CHART_UP, clrOrange);
 

При использовании в советниках ресурсозатратной обработки фреймов в void OnTesterDeinit() получается неприятная ситуация, - тестер стратегий показывает о завершении работы оптимизации, в то время, как оптимизация в виде обработки полученных данных продолжается. Это может влиять на автоматический запуск следующей оптимизации, особенно если требуются данные от предыдущей.

Хорошо бы научить тестер стратегий ждать окончания расчетов в void OnTesterDeinit().

 

Вчера столкнулся с проблемой в последних билдах платформы (3470) - мой код перестал компилироваться.

Сегодня еще поисследовал и нашел странное поведение компилятора (на мой взгляд это баг).

Подробно описал в англоязычной ветке форума https://www.mql5.com/en/forum/ 434751 #comment_42728507


Кто может подсказать куда слать багрепорты?

MQL5 compiler issue
MQL5 compiler issue
  • 2022.10.17
  • www.mql5.com
Today I ran into a problem with MQL5 compiler. Errors appear when compiling my old code. I have written simple example to demonstrate it...
 

слови баг в мт5.

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

Файлы:
 

Решил поэкспериментировать с OpenCL, сделал скрипт - код ниже, но вот беда - если запускаешь первый раз - считает и завершает работу корректно, но если запустить второй раз, то терминал зависает, перезагружается драйвер видеокарты, а иногда и компьютер уходит в перезагрузку. Компьютер FX-8350 32ГБ ОЗУ, видеокарта HD7950.

Скрипт запускается с настройками по умолчанию.

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

Прошу помощи!

//+------------------------------------------------------------------+
//|                                                       Primer.mq5 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "-Aleks-"
#property link      "https://www.mql5.com/ru/users/-aleks-"
#property version   "1.00"
#property script_show_inputs
#property strict
//--- COpenCL class
#include <OpenCL/OpenCL.mqh>
COpenCL           m_OpenCL;
//--- исходные коды кернелов
#resource "tester.cl" as string cl_tester


sinput bool Random_Data=false;//Генерировать таблицу с данными?
input group "Параметры генерируемой таблицы"
sinput      int Strok_Total_Data_Random=1000;//Всего строк
sinput      int Stolb_Total_Data_Random=1000;//Всего столбцов
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
float arr_Data[];//Массив для первичных данных - выборка
float arr_Quant[];//Массив с таблицами неравенств (сплитов)
char arr_Target[];//Массив с целевыми
float arr_MiniData[]=//Массив для проверки логики с малым числом примеров - первичные данные
{
   7,0,1,
   8,1,2,
   9,0,3,
   10,1,1,
   11,0,2,
   12,1,3,
   13,0,1,
   14,1,2,
   15,0,3,
   16,1,1
};
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
float arr_MiniQuant[]=//Массив для проверки логики с малым числом примеров - таблицы неравенств (сплитов)
{
   0,10.5,
   0,14.5,
   0,15.5,
   1,0.5,
   2,0.5,
   2,1.5
};
char arr_MiniTarget[]=//Массив с целевыми
{
   0,
   1,
   0,
   1,
   0,
   1,
   0,
   1,
   0,
   1
};

int Strok_Total_Data=10;//Количество строк в таблице Data
int Stolb_Total_Data=3;//Количество столбцов в таблице Data

int Strok_Total_Quant=6;//Количество строк в таблице Quant
int Stolb_Total_Quant=2;//Количество столбцов в таблице Quant


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
{
   if(Random_Data==true)//Сгенерируем данные для оценки времени работы алгоритма
   {
      MathSrand(GetTickCount());
      float N_Random=0.0;//Переменная для сохранения случайного числа
      int Strok_Total_Quant_Random=0;

      int Size_Arr_RandomData=Strok_Total_Data_Random*Stolb_Total_Data_Random;
      float arr_RandomData[];
      float arr_RandomQuant[];
      int arr_RandomTarget[];

      ArrayResize(arr_RandomData,Size_Arr_RandomData);
      ArrayResize(arr_RandomTarget,Strok_Total_Data_Random);


      for(int i=0; i<Size_Arr_RandomData; i++) //Выберем комбинации
      {
         N_Random=RandomFloat(20);//Определяем число случайным образом
         arr_RandomData[i]=N_Random;
      }

      for(int i=0; i<Strok_Total_Data_Random; i++) //Выберем комбинации
      {
         N_Random=RandomFloat(2);//Определяем число случайным образом
         arr_RandomTarget[i]=(int)N_Random;
      }

      for(int i=0; i<Stolb_Total_Data_Random; i++) //Выберем комбинации для квантовой таблицы
      {
         N_Random=RandomFloat(20);//Определяем число сплитов
         if(N_Random<1)
            N_Random=1;
         int Size_arr_RandomQuant=ArraySize(arr_RandomQuant);
         ArrayResize(arr_RandomQuant,Size_arr_RandomQuant+(int)N_Random*2);
         Size_arr_RandomQuant=ArraySize(arr_RandomQuant);
         float arr_N_Random[];
         ArrayResize(arr_N_Random,(int)N_Random);
         for(int n=0; n<(int)N_Random; n++) //Выберем комбинации
         {
            arr_N_Random[n]=RandomFloat(20);//Определяем значение сплитов
         }
         ArraySort(arr_N_Random);
         for(int n=0; n<(int)N_Random; n++) //Выберем комбинации
         {
            arr_RandomQuant[Size_arr_RandomQuant-(int)N_Random*2+2*n]=(float)i;//Номер столбца
            arr_RandomQuant[Size_arr_RandomQuant-(int)N_Random*2+2*n+1]=arr_N_Random[n];//Значение сплита
         }
      }

      ArrayCopy(arr_Data,arr_RandomData,0,0,WHOLE_ARRAY);
      ArrayCopy(arr_Quant,arr_RandomQuant,0,0,WHOLE_ARRAY);
      ArrayCopy(arr_Target,arr_RandomTarget,0,0,WHOLE_ARRAY);

      Strok_Total_Data=Strok_Total_Data_Random;
      Stolb_Total_Data=Stolb_Total_Data_Random;
      Strok_Total_Quant_Random=ArraySize(arr_RandomQuant)/2;
      Strok_Total_Quant=Strok_Total_Quant_Random;
   }
   else
   {
      ArrayCopy(arr_Data,arr_MiniData,0,0,WHOLE_ARRAY);
      ArrayCopy(arr_Quant,arr_MiniQuant,0,0,WHOLE_ARRAY);
      ArrayCopy(arr_Target,arr_MiniTarget,0,0,WHOLE_ARRAY);
   }

   int arr_N_Quant[];//Массив в котором будем хранить число сплитов квантовой таблицы для каждого предиктора
   ArrayResize(arr_N_Quant,Stolb_Total_Data);
   ArrayInitialize(arr_N_Quant,-1);

   int New_Size=0;//Для установки размера массива
   int N_Calc=1;//Счетчик
   int N_Pred=0;//Счетчик столбцов (//Номер предиктора)

   for(int i=1; i<Strok_Total_Quant; i++)//Найдем число сплитов для каждого предиктора
   {
      //Print("2*i=",2*i," 2*(i-1)=",2*(i-1));
      if(arr_Quant[2*i]>arr_Quant[2*(i-1)])
      {
         arr_N_Quant[N_Pred++]=N_Calc;
         if(New_Size<N_Calc)
         {
            New_Size=N_Calc;
         }
         N_Calc=1;
      }
      else
         N_Calc++;
      if(i+1==Strok_Total_Quant)
         arr_N_Quant[N_Pred++]=N_Calc;//Если последний индекс столбца, то сохраним его
   }

   int arr_Max_Calc[];//Массив в котором будем искать максимум после сортировки
   ArrayCopy(arr_Max_Calc,arr_N_Quant);//Скопируем массив
   ArraySort(arr_Max_Calc);//Отсортируем массив
   int Max_Ind=ArrayMaximum(arr_Max_Calc,0,WHOLE_ARRAY);//Присвоем индекс максимального значения массива
   int Max_N=arr_Max_Calc[Max_Ind];//Присвоем максимальное значение массива
   int Size_arr_Quant_Trans=(Max_N+1)*Stolb_Total_Data;//Размер массива транспонированной квантовой таблицы

   float arr_Quant_Trans[];//Массив, куда запишем преобразованную таблицу с неравенствами
   ArrayResize(arr_Quant_Trans,Size_arr_Quant_Trans);
   ArrayInitialize(arr_Quant_Trans,0);
   Print("New_Size=",New_Size," Max_N=",Max_N);
   int Index=0;
   New_Size=0;
   N_Calc=1;//Счетчик числа сплитов предиктора
   N_Pred=0;
   double Split=0.0;//Значение сплита
   for(int i=1; i<Strok_Total_Quant; i++)//Транспонируем квантовую таблицу и записывем число сплитов
   {
      Index=(int)arr_Quant[2*(i-1)];
      arr_Quant_Trans[Stolb_Total_Data*(N_Calc)+Index]=arr_Quant[2*i-1];//Значение сплита

      if(arr_Quant[2*i]>arr_Quant[2*(i-1)])//Новый сплит
      {
         arr_Quant_Trans[Index]=(float)N_Calc;//Число сплитов в предикторе / столбца
         if(New_Size<N_Calc)
         {
            New_Size=N_Calc;
         }
         N_Calc=1;
      }
      else
         N_Calc++;
      if(i+1==Strok_Total_Quant)//Если последний индекс столбца, то сохраним число сплитов в предикторе / столбца
      {
         Index=(int)arr_Quant[2*i];
         arr_Quant_Trans[Index]=(float)N_Calc;//Число сплитов в предикторе / столбце
         arr_Quant_Trans[Stolb_Total_Data*(N_Calc)+Index]=arr_Quant[2*i+1];//Значение сплита -1 так как это последнее значение, а счетчик N_Calc ранее по коду учел новое
      }
   }


   ushort arr_Data_Q[];//Таблица №3 с результатами классификации(квантования) выборки.
   ArrayResize(arr_Data_Q,Strok_Total_Data*Stolb_Total_Data);
   ArrayInitialize(arr_Data_Q,0);

   float arr_Proc_Target[];//Процент принадлежности классов к целевой
   float arr_Proc_Otklik[];//Процент откликов классов ко всей таблице (выборке).
   ArrayResize(arr_Proc_Target,((Max_N+1)*Stolb_Total_Data)*2);//Делаем по размеру квантовой таблицы, умноженной на число разных значений (типов) целевых
   ArrayResize(arr_Proc_Otklik,((Max_N+1)*Stolb_Total_Data));//Делаем по размеру квантовой таблицы
   ArrayInitialize(arr_Proc_Target,0);
   ArrayInitialize(arr_Proc_Otklik,0);

   ushort arr_N_Class_Target[];//Считаем число целевых по их типам для каждого условного класса после квантования
   ushort arr_N_Class_Otklik[];//Считаем число откликов для каждого условного класса после квантования в выборке
   //ArrayResize(arr_N_Class_Target,((int)arr_Quant_Trans[p]+1)*2);//Умножаем на количество разных целевых ("0" и "1")
   //ArrayResize(arr_N_Class_Otklik,((int)arr_Quant_Trans[p]+1));//
   ArrayResize(arr_N_Class_Target,(Max_N+1)*2);//Умножаем на количество разных целевых ("0" и "1")
   ArrayResize(arr_N_Class_Otklik,Max_N+1);//

   ArrayInitialize(arr_N_Class_Target,0);
   ArrayInitialize(arr_N_Class_Otklik,0);

   /*
   __kernel void CalcPred(
   __global int *arr_Data,
   __global int *arr_Quant_Trans,
   __global int *arr_Target,
   __global int *arr_Data_Q,
   __global int *arr_N_Class_Target,
   __global int *arr_N_Class_Otklik,
     int p,
     int Stolb_Total_Data
    )
   */

   int index_kernel=0;
   int Handle_Context=0;
//---Инициализация файла с кернелами
   Print("Initialize=",m_OpenCL.Initialize(cl_tester,true));
   //CLProgramCreate(Handle_Context,cl_tester);
//--- установка количества кернелов
   Print("SetKernelsCount=",m_OpenCL.SetKernelsCount(1));
//--- создание кернелов
   Print("KernelCreate=",m_OpenCL.KernelCreate(index_kernel,"CalcPred"));
//--- создание буферов - указать количество буферов
   Print("SetBuffersCount=",m_OpenCL.SetBuffersCount(6));
//--- копирование буфера на видеокарту
   Print("BufferFromArray=",m_OpenCL.BufferFromArray(0,arr_Data,0,Stolb_Total_Data*Strok_Total_Data,CL_MEM_READ_ONLY));
   Print("BufferFromArray=",m_OpenCL.BufferFromArray(1,arr_Quant_Trans,0,Size_arr_Quant_Trans,CL_MEM_READ_ONLY));
   Print("BufferFromArray=",m_OpenCL.BufferFromArray(2,arr_Target,0,Strok_Total_Data,CL_MEM_READ_ONLY));
   Print("BufferFromArray=",m_OpenCL.BufferFromArray(3,arr_Data_Q,0,Stolb_Total_Data*Strok_Total_Data,CL_MEM_READ_WRITE));
   Print("BufferFromArray=",m_OpenCL.BufferFromArray(4,arr_N_Class_Target,0,(Max_N+1)*2,CL_MEM_READ_WRITE));
   Print("BufferFromArray=",m_OpenCL.BufferFromArray(5,arr_N_Class_Otklik,0,Max_N+1,CL_MEM_READ_WRITE));
//---привязка буфера к аргументу кернела
   Print("SetArgumentBuffer=",m_OpenCL.SetArgumentBuffer(index_kernel,0,0));
   Print("SetArgumentBuffer=",m_OpenCL.SetArgumentBuffer(index_kernel,1,1));
   Print("SetArgumentBuffer=",m_OpenCL.SetArgumentBuffer(index_kernel,2,2));
   Print("SetArgumentBuffer=",m_OpenCL.SetArgumentBuffer(index_kernel,3,3));
   Print("SetArgumentBuffer=",m_OpenCL.SetArgumentBuffer(index_kernel,4,4));
   Print("SetArgumentBuffer=",m_OpenCL.SetArgumentBuffer(index_kernel,5,5));
//---привязка параметра фукнкции к кернелу
   int p=0;
   Print("SetArgument=",m_OpenCL.SetArgument(index_kernel,6,p));
   Print("SetArgument=",m_OpenCL.SetArgument(index_kernel,7,Stolb_Total_Data));

//--- пространство задач для кернела - одномерное
   uint global_work_size[1];
//--- 1-е измерение
   global_work_size[0]=Strok_Total_Data;
//--- начальное смещение в пространстве задач для обоих измерений равно нулю
   uint global_work_offset[1]= {0};

   for(/*int*/ p=0; p<Stolb_Total_Data; p++)
   {

      Print("Execute=",m_OpenCL.Execute(index_kernel,1,global_work_offset,global_work_size));

      Print("BufferRead=",m_OpenCL.BufferRead(4,arr_N_Class_Target,0,0,(Max_N+1)*2));
      Print("BufferRead=",m_OpenCL.BufferRead(5,arr_N_Class_Otklik,0,0,Max_N+1));
      
      for(ushort q=0; q<arr_Quant_Trans[p]+1; q++)//Посчитаем проценты
      {
         int Summ=arr_N_Class_Target[2*q]+arr_N_Class_Target[2*q+1];
         //Print("Summ=",Summ);
         if (Summ>0)
         {
            arr_Proc_Target[Stolb_Total_Data*2*q+p*2]=float((double)arr_N_Class_Target[2*q]/(double)Summ*100.0);//Целевая "0"
            arr_Proc_Target[Stolb_Total_Data*2*q+p*2+1]=float((double)arr_N_Class_Target[2*q+1]/(double)Summ*100.0);//Целевая "1"
         }
         arr_Proc_Otklik[Stolb_Total_Data*q+p]=float((double)arr_N_Class_Otklik[q]/(double)Strok_Total_Data*100.0);

      }
   }
   Print("BufferRead=",m_OpenCL.BufferRead(3,arr_Data_Q,0,0,Stolb_Total_Data*Strok_Total_Data));
   Print("Задача №1 Таблица №3 с результатами классификации выборки.");
   ArrayPrint(arr_Data_Q);
   Print("Таблица №5 с результатами вычислений процента принадлежности классов к целевой.");
   ArrayPrint(arr_Proc_Target);
   Print("Таблица №6 с  результатами вычислений процента откликов классов ко всей таблице (выборке).");
   ArrayPrint(arr_Proc_Otklik);

   m_OpenCL.KernelFree(index_kernel);
   m_OpenCL.Shutdown();
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//|Определяем комбинацию случайным образом
//+------------------------------------------------------------------+
float RandomFloat(float max_vl)
{
   return (float)MathFloor((MathRand()+MathRand()*32767.0)/1073741824.0*max_vl);  //случайное Int от 0 до  1073741824
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+

Ну и сам кернел

//+------------------------------------------------------------------+
//|                                                        tester.cl |
//+------------------------------------------------------------------+
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable
#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable
#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable
#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable
#pragma OPENCL EXTENSION cl_khr_int64_base_atomics : enable
#pragma OPENCL EXTENSION cl_khr_int64_base_atomics : enable

//+------------------------------------------------------------------+
//| Расчет
//+------------------------------------------------------------------+
__kernel void CalcPred(
__global int *arr_Data,
__global int *arr_Quant_Trans,
__global int *arr_Target,
__global int *arr_Data_Q,
__global int *arr_N_Class_Target,
__global int *arr_N_Class_Otklik,
 int p,
 int Stolb_Total_Data
 
 )
  {
  
   int Index_Data=0;//Индекс массива arr_Data и arr_Data_Q
   int Index_Quant_A=0;//Индекс массива arr_Quant_Trans для границы А
   int Index_Quant_B=0;//Индекс массива arr_Quant_Trans для границы Б  
//--- работает в одном измерении    
   size_t i=get_global_id(0);

         Index_Data=Stolb_Total_Data*i+p;
         for(ushort q=0; q<arr_Quant_Trans[p]+1; q++)
         {
            if(arr_Quant_Trans[p]<1)
            {
               arr_Data_Q[Index_Data]=0;//Обнуляем значение предиктора, так как нет информации о сплитах
               break;
            }
            else
            {
               if(q==0)//Первый сплит
               {
                  Index_Quant_A=Stolb_Total_Data*(q+1)+p;//Рассчитаем индекс первой границы
                  if(arr_Data[Index_Data]<=arr_Quant_Trans[Index_Quant_A])
                  {
                     arr_Data_Q[Index_Data]=q+1;
                     break;
                  }
               }
               else
               {
                  Index_Quant_A=Stolb_Total_Data*(q+1-1)+p;//Рассчитаем индекс первой границы
                  Index_Quant_B=Stolb_Total_Data*(q+1)+p;//Рассчитаем индекс последней границы
                  if(q==arr_Quant_Trans[p])//Последний сплит "q" будет равно arr_Quant_Trans[p] при выходе за пределы массива)
                  {
                     if(arr_Data[Index_Data]>arr_Quant_Trans[Index_Quant_A])
                     {
                        arr_Data_Q[Index_Data]=q+1;
                        break;

                     }
                  }
                  else//Средние сплиты
                  {
                     if(arr_Data[Index_Data]>arr_Quant_Trans[Index_Quant_A] && arr_Data[Index_Data]<=arr_Quant_Trans[Index_Quant_B])
                     {
                        arr_Data_Q[Index_Data]=q+1;
                        break;
                     }
                  }
               }
            }
         }
         int Calc_Index=0;
         switch(arr_Target[i])
         {
         case 0:
            Calc_Index=((int)arr_Data_Q[Index_Data]-1)*2;
            break;
         case 1:
            Calc_Index=((int)arr_Data_Q[Index_Data]-1)*2+1;
            break;
         }
         arr_N_Class_Target[Calc_Index]++;//Прибавим 1 для подсчета целевой
         Calc_Index=((int)arr_Data_Q[Index_Data]-1);//Индекс для массива arr_N_Class_Otklik
         arr_N_Class_Otklik[Calc_Index]++;//Прибавим 1 для подсчета откликов
  }
Причина обращения: