Terminal
MetaTrader 5 Web Terminal
Terminal
MQL5
//+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { complex a=1+1i; complex b=a.Conjugate(); Print(a, " ", b); /* (1,1) (1,-1) */ vectorc va= {0.1+0.1i, 0.2+0.2i, 0.3+0.3i}; vectorc vb=va.Conjugate(); Print(va, " ", vb); /* [(0.1,0.1),(0.2,0.2),(0.3,0.3)] [(0.1,-0.1),(0.2,-0.2),(0.3,-0.3)] */ matrixc ma(2, 3); ma.Row(va, 0); ma.Row(vb, 1); matrixc mb=ma.Conjugate(); Print(ma); Print(mb); /* [[(0.1,0.1),(0.2,0.2),(0.3,0.3)] [(0.1,-0.1),(0.2,-0.2),(0.3,-0.3)]] [[(0.1,-0.1),(0.2,-0.2),(0.3,-0.3)] [(0.1,0.1),(0.2,0.2),(0.3,0.3)]] */ ma=mb.Transpose().Conjugate(); Print(ma); /* [[(0.1,0.1),(0.1,-0.1)] [(0.2,0.2),(0.2,-0.2)] [(0.3,0.3),(0.3,-0.3)]] */ }
from sys import argv data_path=argv[0] last_index=data_path.rfind("\\")+1 data_path=data_path[0:last_index] from sklearn.datasets import load_iris iris_dataset = load_iris() from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(iris_dataset['data'], iris_dataset['target'], random_state=0) from sklearn.neighbors import KNeighborsClassifier knn = KNeighborsClassifier(n_neighbors=1) knn.fit(X_train, y_train) # Convert into ONNX format from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType initial_type = [('float_input', FloatTensorType([None, 4]))] onx = convert_sklearn(knn, initial_types=initial_type) path = data_path+"iris.onnx" with open(path, "wb") as f: f.write(onx.SerializeToString())Откройте созданный onnx-файл в MetaEditor:
struct MyMap { long key[]; float value[]; };Здесь мы использовали динамические массивы с соответствующими типами. В данном случае можно использовать фиксированные массивы, поскольку для данной модели Map всегда содержит 3 пары ключ+значение.
//--- объявим массив для приема данных с выходного слоя output_probability MyMap output_probability[]; ... //--- выполнение модели OnnxRun(model,ONNX_DEBUG_LOGS,float_input,output_label,output_probability);
MetaEditor
Web Terminal
Отчет поделен на четыре вкладки, каждая из которых содержит агрегированную информацию в своем разрезе:
Terminal MetaTrader 5 x64 build 3914 started for MetaQuotes Software Corp.
Terminal Windows 10 build 19045, 20 x Intel Xeon E5-2630 v4 @ 2.20GHz, AVX, 41 / 63 Gb memory, 58 / 280 Gb disk, UAC, GMT+2
VPS Hosting
MQL5
#define MACRO1 /* #define MACRO2 */ void OnStart() { #ifdef MACRO2 Print( 2 ); #else Print( 1 ); #endif }
void OnStart() { Print("CPU name: ",TerminalInfoString(TERMINAL_CPU_NAME)); Print("CPU cores: ",TerminalInfoInteger(TERMINAL_CPU_CORES)); Print("CPU architecture: ",TerminalInfoString(TERMINAL_CPU_ARCHITECTURE)); Print(""); Print("EX5 architecture: ",__CPU_ARCHITECTURE__); } CPU name: 12th Gen Intel Core i9-12900K CPU cores: 24 CPU architecture: AVX2 + FMA3 EX5 architecture: AVX
extern int X=0; void OnStart() { }
extern int X; void OnStart() { }
extern int X; int Y=X; void OnStart(void) { Print("Y=",Y," X=",X); } int X=_Digits;
MetaEditor
Tester
Обновлены переводы пользовательского интерфейса.
Исправления по крешлогам.
MetaTrader 5 Web Terminal build 3950
Terminal
MQL5
double vector::RegressionMetric( const vector& vector_true, // истинные значения const ENUM_REGRESSION_METRIC metric // метрика ); double matrix::RegressionMetric( const matrix& matrix_true, // истинные значения const ENUM_REGRESSION_METRIC metric // метрика ); vector matrix::RegressionMetric( const matrix& matrix_true, // истинные значения const ENUM_REGRESSION_METRIC metric, // метрика const int axis // ось );
vector vector::LinearRegression(); matrix matrix::LinearRegression( ENUM_MATRIX_AXIS axis=AXIS_NONE // ось, вдоль которой считается регрессия );Пример:
vector vector_a; //--- заполним вектор ценами vector_a.CopyRates(_Symbol,_Period,COPY_RATES_CLOSE,1,100); //--- получим линейную регрессию vector vector_r=vector_a.LinearRegression();Визуализация результата в виде графика:
ulong vector::HasNan(); ulong matrix::HasNan();Методы Compare и CompareByDigits при сравнении соответствующей пары элементов, имеющих значения NaN, считают эти элементы равными, тогда как при обычном сравнении чисел с плавающей точкой NaN != NaN.
Изменена структура OnnxTypeInfo, используемая для работы с моделями ONNX (Open Neural Network Exchange):
struct OnnxTypeInfo { ENUM_ONNX_TYPE type; // тип параметра OnnxTensorTypeInfo tensor; // описание тензора OnnxMapTypeInfo map; // описание карты OnnxSequenceTypeInfo sequence; // описание последовательности };
Теперь тип данных в ней указывается при помощи новых подструктур:
struct OnnxTensorTypeInfo { ENUM_ONNX_DATATYPE data_type; // тип данных в тензоре long dimensions[]; // количество элементов }; struct OnnxMapTypeInfo { ENUM_ONNX_DATA_TYPE key_type; // тип ключа OnnxTypeInfo type_info; // тип значения }; struct OnnxSequenceTypeInfo { OnnxTypeInfo type_info; // тип данных в последовательности };В зависимости от OnnxTypeInfo::type (ONNX_TYPE_TENSOR, ONNX_TYPE_MAP или ONNX_TYPE_SEQUENCE) заполняется соответствующая подструктура.
bool vector<T>::CopyIndicatorBuffer(long indicator_handle,ulong buffer_index,ulong start_pos,ulong count); bool vector<T>::CopyIndicatorBuffer(long indicator_handle,ulong buffer_index,datetime start_time,ulong count); bool vector<T>::CopyIndicatorBuffer(long indicator_handle,ulong buffer_index,datetime start_time,datetime stop_time);
MetaEditor
Tester
Исправления по крешлогам.
Web Terminal
MQL5.community
Обновление будет доступно через систему Live Update.
Terminal
MQL5
Web Terminal
Web Terminal
MQL5
MQL5: Добавлены флаги COPY_TICKS_VERTICAL и COPY_RATES_VERTICAL для методов CopyTicks, CopyTicksRange и CopyRates соответственно.
По умолчанию копирование тиков и серий в матрицу производится вдоль горизонтальной оси, то есть данные добавляются справа в конец строки. В задачах запуска обученной ONNX модели такую матрицу приходится транспонировать для подачи входных данных:
const long ExtOutputShape[] = {1,1}; // форма выходных данных модели const long ExtInputShape [] = {1,10,4}; // форма входных данных модели #resource "Python/model.onnx" as uchar ExtModel[]// модель в виде ресурса //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { matrix rates; //--- получаем 10 баров if(!rates.CopyRates("EURUSD",PERIOD_H1,COPY_RATES_OHLC,2,10)) return(-1); //--- подаем на вход набор векторов OHLC matrix x_norm=rates.Transpose(); vector m=x_norm.Mean(0); vector s=x_norm.Std(0); matrix mm(10,4); matrix ms(10,4);
Теперь достаточно при вызове метода указать дополнительный флаг COPY_RATES_VERTICAL (COPY_TICKS_VERTICAL для тиков), чтобы избавиться от лишней операции трансформации данных:
//+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { matrix rates; //--- получаем 10 баров if(!rates.CopyRates("EURUSD",PERIOD_H1,COPY_RATES_OHLC|COPY_RATES_VERTICAL,2,10)) return(-1); //--- подаем на вход набор векторов OHLC
MetaEditor
Terminal
Terminal
MQL5
Скомпилируйте проект и запустите его на EURUSD H1, чтобы посмотреть результат.
Помимо
готовой модели и MQL5-кода для ее запуска, в проекте также доступен
Python скрипт PricePredictionTraining.py. Он показывает, как
самостоятельно создать модель ONNX. Для работы скрипта установите на
свой компьютер Python, а также необходимые модули из командной строки:
#import "mmlib.dll" bool sgemm(uint flags,matrix<float> &C,const matrix<float> &A,const matrix<float> &B,ulong M,ulong N,ulong K,float alpha,float beta); #importC++
extern "C" __declspec(dllexport) bool sgemm(UINT flags,float *C,const float *A,const float *B,UINT64 M,UINT64 N,UINT64 K,float alpha,float beta)Для правильной обработки матриц и векторов, кроме их буферов, следует передавать их размеры.
Добавлена новая функция CopySeries для копирования синхронизированных таймсерий из MqlRates в отдельные массивы.
Функция CopySeries позволяет за один раз получать только нужные таймсерии в разные указанные массивы, при этом они все синхронизированы между собой. Это означает, что все значения в полученных массивах по конкретному индексу N будут принадлежать одному и тому же бару на указанной паре символ/таймфрейм. В этом случае не требуется заботиться о том, чтобы все полученные таймсерии были синхронизированы по времени открытия бара.
В отличие от CopyRates, которая возвращает полный набор таймсерий в виде массива MQLRates, функция CopySeries позволяет программисту получать только нужные таймсерии на основе комбинации флагов, указывающих тип запрашиваемых таймсерий. При этом порядок массивов, передаваемых в функцию, должен соответствовать порядку полей в структуре MqlRates:
struct MqlRates { datetime time; // время начала периода double open; // цена открытия double high; // наивысшая цена за период double low; // наименьшая цена за период double close; // цена закрытия long tick_volume; // тиковый объем int spread; // спред long real_volume; // биржевой объем }
Таким образом, если необходимо получить значения таймсерий time, close и real_volume для последних 100 баров текущего символа/таймфрейма, вызов должен быть следующим:
datetime time[]; double close[]; long volume[]; CopySeries(NULL,0,0,100,COPY_RATES_TIME|COPY_RATES_CLOSE|COPY_RATES_VOLUME_REAL,time,close,volume);
При этом важен порядок массивов "time, close, volume" — он должен соответствовать порядку полей в структуре MqlRates. А вот порядок значений в маске rates_mask значения не имеет, маска могла быть такой :
COPY_RATES_VOLUME_REAL|COPY_RATES_TIME|COPY_RATES_CLOSE
Пример
//--- input parameters input datetime InpDateFrom=D'2022.01.01 00:00:00'; input datetime InpDateTo =D'2023.01.01 00:00:00'; input uint InpCount =20; //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart(void) { //--- массивы для получения таймсерий из ценовой структуры Rates double open[]; double close[]; float closef[]; datetime time1[], time2[]; //---запросим цены закрытия в массив типа double ResetLastError(); int res1=CopySeries(NULL, PERIOD_CURRENT, 0, InpCount, COPY_RATES_TIME|COPY_RATES_CLOSE, time1, close); PrintFormat("1. CopySeries returns %d values. Error code=%d", res1, GetLastError()); ArrayPrint(close); //--- теперь запросим еще цены открытия, а цены закрытия в массив типа float ResetLastError(); int res2=CopySeries(NULL, PERIOD_CURRENT, 0, InpCount, COPY_RATES_TIME|COPY_RATES_CLOSE|COPY_RATES_OPEN, time2, open, closef); PrintFormat("2. CopySeries returns %d values. Error code=%d", res2, GetLastError()); ArrayPrint(closef); //--- сравним полученные данные if((res1==res2) && (time1[0]==time2[0])) { Print(" | Time | Open | Close double | Close float |"); for(int i=0; i<10; i++) { PrintFormat("%d | %s | %.5f | %.5f | %.5f |", i, TimeToString(time1[i]), open[i], close[i], closef[i]); } } /* Результат 1. CopySeries returns 0 values. Error code=0 [ 0] 1.06722 1.06733 1.06653 1.06520 1.06573 1.06649 1.06694 1.06675 1.06684 1.06604 [10] 1.06514 1.06557 1.06456 1.06481 1.06414 1.06394 1.06364 1.06386 1.06239 1.06247 2. CopySeries returns 0 values. Error code=0 [ 0] 1.06722 1.06733 1.06653 1.06520 1.06573 1.06649 1.06694 1.06675 1.06684 1.06604 [10] 1.06514 1.06557 1.06456 1.06481 1.06414 1.06394 1.06364 1.06386 1.06239 1.06247 | Time | Open | Close double | Close float | 0 | 2023.03.01 17:00 | 1.06660 | 1.06722 | 1.06722 | 1 | 2023.03.01 18:00 | 1.06722 | 1.06733 | 1.06733 | 2 | 2023.03.01 19:00 | 1.06734 | 1.06653 | 1.06653 | 3 | 2023.03.01 20:00 | 1.06654 | 1.06520 | 1.06520 | 4 | 2023.03.01 21:00 | 1.06520 | 1.06573 | 1.06573 | 5 | 2023.03.01 22:00 | 1.06572 | 1.06649 | 1.06649 | 6 | 2023.03.01 23:00 | 1.06649 | 1.06694 | 1.06694 | 7 | 2023.03.02 00:00 | 1.06683 | 1.06675 | 1.06675 | 8 | 2023.03.02 01:00 | 1.06675 | 1.06684 | 1.06684 | 9 | 2023.03.02 02:00 | 1.06687 | 1.06604 | 1.06604 | */ }
MetaEditor
Tester
MetaTrader 5 Web Terminal build 3620
Terminal
Web Terminal
Web Terminal
Terminal
MQL5
long preferred_workgroup_size_multiple=OpenCL.GetDeviceInfo(0x1067);
void OnStart() { string cpu,os; //--- cpu=TerminalInfoString(TERMINAL_CPU_NAME); os=TerminalInfoString(TERMINAL_OS_VERSION); PrintFormat("CPU: %s, OS: %s",cpu,os); }Результат:
MetaEditor
Terminal
MQL5
//--- первый параметр handle игнорируется при получении кода последней ошибки int code = (int)CLGetInfoInteger(0,CL_LAST_ERROR);
//--- получить код последней OpenCL ошибки int code = (int)CLGetInfoInteger(0,CL_LAST_ERROR); string desc; // для получения текстового описания ошибки //--- используем код ошибки для получения текстового описания ошибки if(!CLGetInfoString(code,CL_ERROR_DESCRIPTION,desc)) desc = "cannot get OpenCL error description, " + (string)GetLastError(); Print(desc); //--- чтобы получить описание последней OpenCL ошибки без предварительного получения кода, нужно передать CL_LAST_ERROR if(!CLGetInfoString(CL_LAST_ERROR,CL_ERROR_DESCRIPTION, desc)) desc = "cannot get OpenCL error description, " + (string)GetLastError(); Print(desc);Пока в качестве описания ошибки отдаётся имя внутреннего перечисления, расшифровку которого можно посмотреть на странице https://registry.khronos.org/OpenCL/specs/3.0-unified/html/OpenCL_API.html#CL_SUCCESS. Например, если получено значение CL_INVALID_KERNEL_ARGS, описание для него "Returned when enqueuing a kernel when some kernel arguments have not been set or are invalid."
MetaTrader 5 WebTerminal
Terminal
MQL5
class A { }; void OnStart(void) { const A *const arr[][2][3]={}; Print(typename(arr)); }Результат:
"class A const * const [][2][3]"
Terminal
MQL5
Исправления по крешлогам.
MetaTrader 5 WebTerminal build 3500
Мобильная версия веб-терминала
В новой версии веб-терминала добавлена полноценная поддержка мобильных устройств. Теперь его интерфейс автоматически адаптируется по размеру экрана, позволяя пользователям удобно работать в платформе на телефонах и планшетах с iOS и Android:
Помимо этого, в веб-терминал внесено множество исправлений и улучшений.
Новый веб-терминал MetaTrader 5 поддерживает все функции, которые нужны современному трейдеру. Приложение позволяет:
Terminal
MQL5
bool matrix::CopyTicks(string symbol,uint flags,ulong from_msc,uint count); bool vector::CopyTicks(string symbol,uint flags,ulong from_msc,uint count); bool matrix::CopyTicksRange(string symbol,uint flags,ulong from_msc,ulong to_msc); bool matrix::CopyTicksRange(string symbol,uint flags,ulong from_msc,ulong to_msc);Тип копируемых данных указывается в параметре flags при помощи перечисления ENUM_COPY_TICKS. Доступны следующие значения:
COPY_TICKS_INFO = 1, // тики, вызванные изменениями Bid и/или Ask COPY_TICKS_TRADE = 2, // тики, вызванные изменениями Last и Volume COPY_TICKS_ALL = 3, // все тики, в которых есть изменения COPY_TICKS_TIME_MS = 1<<8, // время в миллисекундах COPY_TICKS_BID = 1<<9, // цена Bid COPY_TICKS_ASK = 1<<10, // цена Ask COPY_TICKS_LAST = 1<<11, // цена Last COPY_TICKS_VOLUME = 1<<12, // объем COPY_TICKS_FLAGS = 1<<13, // флаги тикаПри выборе нескольких типов данных (доступно только для матриц) порядок строк в матрице будет соответствовать порядку значений в перечислении.
bool matrix::Assign(const vector &vec);Результатом будет однострочная матрица.
bool vector::Assign(const matrix &mat);
bool vector::Swap(vector &vec); bool vector::Swap(matrix &vec); bool vector::Swap(double &arr[]); bool matrix::Swap(vector &vec); bool matrix::Swap(matrix &vec); bool matrix::Swap(double &arr[]);Каждый массив, вектор или матрица ссылаются на буфер памяти, который содержит элементы данного объекта. Метод Swap фактически меняет местами указатели на данные буферы, не проводя записи элементов в памяти. Поэтому матрица остается матрицей, а вектор вектором. При обмене матрицы и вектора вы получите однострочную матрицу с элементами вектора и вектор с элементами матрицы в плоском представлении (смотрите метод Flat).
//+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- matrix a= {{1, 2, 3}, {4, 5, 6}}; Print("a before Swap: \n", a); matrix b= {{5, 10, 15, 20}, {25, 30, 35, 40}, {45, 50, 55, 60}}; Print("b before Swap: \n", b); //--- обменяем указатели на матрицы местами a.Swap(b); Print("a after Swap: \n", a); Print("b after Swap: \n", b); /* a before Swap: [[1,2,3] [4,5,6]] b before Swap: [[5,10,15,20] [25,30,35,40] [45,50,55,60]] a after Swap: [[5,10,15,20] [25,30,35,40] [45,50,55,60]] b after Swap: [[1,2,3] [4,5,6]] */ vector v=vector::Full(10, 7); Print("v before Swap: \n", v); Print("b before Swap: \n", b); v.Swap(b); Print("v after Swap: \n", v); Print("b after Swap: \n", b); /* v before Swap: [7,7,7,7,7,7,7,7,7,7] b before Swap: [[1,2,3] [4,5,6]] v after Swap: [1,2,3,4,5,6] b after Swap: [[7,7,7,7,7,7,7,7,7,7]] */ }Метод Swap также позволяет работать с динамическими массивами (массив фиксированного размера в качестве параметра передавать нельзя). При этом массив может быть любой размерности, но согласованного размера. Это означает, что общий размер матрицы или вектора должен быть кратен нулевой размерности массива. Нулевой размерностью массива называется количество элементов, которые содержатся по первому индексу массива. Например, для динамического трехмерного массива double array[][2][3] нулевой размерностью будет произведение размеров второго и третьего измерения, то есть 2x3=6. Значит, такой массив можно использовать в методе Swap только с матрицами и векторами, общий размер которых кратен 6: 6, 12, 18, 24 и т.д.
//+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- заполним матрицу 1x10 значением 7.0 matrix m= matrix::Full(1, 10, 7.0); Print("matrix before Swap:\n", m); //--- попробуем провести обмен между матрицей и массивом double array_small[2][5]= {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}}; Print("array_small before Swap:"); ArrayPrint(array_small); if(m.Swap(array_small)) { Print("array_small after Swap:"); ArrayPrint(array_small); Print("matrix after Swap: \n", m); } else // размер матрицы не кратен размеру первого измерения массива { Print("m.Swap(array_small) failed. Error ", GetLastError()); } /* matrix before Swap: [[7,7,7,7,7,7,7,7,7,7]] array_small before Swap: [,0] [,1] [,2] [,3] [,4] [0,] 1.00000 2.00000 3.00000 4.00000 5.00000 [1,] 6.00000 7.00000 8.00000 9.00000 10.00000 m.Swap(array_small) failed. Error 4006 */ //--- возьмем матрицу побольше и снова попробуем провести обмен double array_static[3][10]= {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, {2, 4, 6, 8, 10, 12, 14, 16, 18, 20}, {3, 6, 9, 12, 15, 18, 21, 24, 27, 30} }; Print("array_static before Swap:"); ArrayPrint(array_static); if(m.Swap(array_static)) { Print("array_static after Swap:"); ArrayPrint(array_static); Print("matrix after Swap: \n", m); } else // статический массив нельзя использовать для обмена с матрицей { Print("m.Swap(array_static) failed. Error ", GetLastError()); } /* array_static before Swap: [,0] [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [0,] 1.00000 2.00000 3.00000 4.00000 5.00000 6.00000 7.00000 8.00000 9.00000 10.00000 [1,] 2.00000 4.00000 6.00000 8.00000 10.00000 12.00000 14.00000 16.00000 18.00000 20.00000 [2,] 3.00000 6.00000 9.00000 12.00000 15.00000 18.00000 21.00000 24.00000 27.00000 30.00000 m.Swap(array_static) failed. Error 4006 */ //--- еще одна попытка обменять массив и матрицу double array_dynamic[][10]; // динамический массив ArrayResize(array_dynamic, 3); // выставим размер первого измерения ArrayCopy(array_dynamic, array_static); //--- теперь для обмена используем динамический массив if(m.Swap(array_dynamic)) { Print("array_dynamic after Swap:"); ArrayPrint(array_dynamic); Print("matrix after Swap: \n", m); } else // нет ошибки { Print("m.Swap(array_dynamic) failed. Error ", GetLastError()); } /* array_dynamic after Swap: [,0] [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [0,] 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000 matrix after Swap: [[1,2,3,4,5,6,7,8,9,10,2,4,6,8,10,12,14,16,18,20,3,6,9,12,15,18,21,24,27,30]] */ }
vector vector::LossGradient(const vector &expected,ENUM_LOSS_FUNCTION loss) const; matrix matrix::LossGradient(const matrix &expected,ENUM_LOSS_FUNCTION loss) const;
CREATE TABLE artist( artistid INTEGER PRIMARY KEY, artistname TEXT ); CREATE TABLE track( trackid INTEGER, trackname TEXT, trackartist INTEGER, FOREIGN KEY(trackartist) REFERENCES artist(artistid) );
MetaEditor
MetaTester
Исправления по крешлогам.
Terminal
MQL5
bool vector<TDst>::Assign(const vector<TSrc> &assign); bool matrix<TDst>::Assign(const matrix<TSrc> &assign);Пример:
//--- копирование матриц matrix b={}; matrix a=b; a.Assign(b); //--- копирование массива в матрицу double arr[5][5]={{1,2},{3,4},{5,6}}; Print("array arr"); ArrayPrint(arr); b.Assign(arr); Print("matrix b \n",b); /* array arr [,0] [,1] [,2] [,3] [,4] [0,] 1.00000 2.00000 0.00000 0.00000 0.00000 [1,] 3.00000 4.00000 0.00000 0.00000 0.00000 [2,] 5.00000 6.00000 0.00000 0.00000 0.00000 [3,] 0.00000 0.00000 0.00000 0.00000 0.00000 [4,] 0.00000 0.00000 0.00000 0.00000 0.00000 matrix b [[1,2,0,0,0] [3,4,0,0,0] [5,6,0,0,0] [0,0,0,0,0] [0,0,0,0,0]] */
bool matrix::CopyRates(string symbol,ENUM_TIMEFRAMES period,ulong rates_mask,ulong from,ulong count); bool vector::CopyRates(string symbol,ENUM_TIMEFRAMES period,ulong rates_mask,ulong from,ulong count);Тип копируемых данных указывается в параметре rates_mask при помощи перечисления ENUM_COPY_RATES. Доступны следующие значения:
Исправлена ошибка изменения константного параметра, переданного в функцию в виде ссылки на указатель объекта.
Напомним, что спецификатор const объявляет переменную константой и не позволяет изменять значение этой переменной в процессе выполнения программы. Допускается только однократная инициализация переменной при ее объявлении. Пример константных переменных в функции OnCalculate:
int OnCalculate (const int rates_total, // размер массива price[] const int prev_calculated, // обработано баров на предыдущем вызове const int begin, // откуда начинаются значимые данные const double& price[] // массив для расчета );
Но в примере ниже обнаружилась ошибка компилятора, который позволял неявное приведение указателей для параметров-ссылок:
class A {}; const A *a = new A; void foo( const A*& b ) { b = a; } void OnStart() { A *b; foo(b); // недопустимо Print( a,":",b ); }Теперь данная недопустимая операция будет детектироваться компилятором и выдавать ошибку.
MetaEditor
Новый веб-терминал MetaTrader 5
Представляем
абсолютно новый веб-терминал для MetaTrader 5. Мы сделали его
современным и быстрым, обновив не только внешний вид, но и полностью
переписав ядро. В плане интерфейса веб-терминал стал похож на уже
привычную версию платформы для iPad:
По сравнению со старой версии в нем появилось множество новых функций:
Terminal
MQL5
//--- matrix a= {{1, 4}, {9, 16}}; Print("matrix a=\n",a); a=MathSqrt(a); Print("MatrSqrt(a)=\n",a); /* matrix a= [[1,4] [9,16]] MatrSqrt(a)= [[1,2] [3,4]] */В случае MathMod и MathPow в качестве второго параметра может быть использован как скаляр, так и матрица или вектор соответствующего размера.
//+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- используем инициализирующую функцию для заполнения вектора vector r(10, ArrayRandom); // массив случайных чисел от 0 до 1 //--- вычислим среднее значение double avr=r.Mean(); // среднее значение массива vector d=r-avr; // вычислим массив отклонений от среднего значения Print("avr(r)=", avr); Print("r=", r); Print("d=", d); vector s2=MathPow(d, 2); // массив квадратов отклонений double sum=s2.Sum(); // сумма квадратов отклонений //--- вычислим стандартное отклонение 2-мя способами double std=MathSqrt(sum/r.Size()); Print(" std(r)=", std); Print("r.Std()=", r.Std()); } /* avr(r)=0.5300302133243813 r=[0.8346201971495713,0.8031556138798182,0.6696676534318063,0.05386516922513505,0.5491195410016175,0.8224433118686484,... d=[0.30458998382519,0.2731254005554369,0.1396374401074251,-0.4761650440992462,0.01908932767723626,0.2924130985442671, ... std(r)=0.2838269732183663 r.Std()=0.2838269732183663 */ //+------------------------------------------------------------------+ //| Заполняет вектор случайными значениями | //+------------------------------------------------------------------+ void ArrayRandom(vector& v) { for(ulong i=0; i<v.Size(); i++) v[i]=double(MathRand())/32767.; }
Доработаны математические функции для работы с типом float.
В связи с появившейся возможностью применения математических функций к
матрицам и векторам типа float, были также доработаны соответствующие
функции, применяемые к скалярам типа float. Раньше параметры этих
функций безусловно приводились к типу double, вызывалась соответствующая
реализация математической функции, и затем результат приводился к типу
float. Теперь в случае типа float параметры и результаты не подвергаются
приведению, так как вызываются реализации математических функций,
соответствующих типу float.
Разница в вычислениях на примере математического синуса:
//+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- массив случайных чисел от 0 до 1 vector d(10, ArrayRandom); for(ulong i=0; i<d.Size(); i++) { double delta=MathSin(d[i])-MathSin((float)d[i]); Print(i,". delta=",delta); } } /* 0. delta=5.198186103783087e-09 1. delta=8.927621308885136e-09 2. delta=2.131878673594656e-09 3. delta=1.0228555918923021e-09 4. delta=2.0585739779477308e-09 5. delta=-4.199390279957527e-09 6. delta=-1.3221741035351897e-08 7. delta=-1.742922250969059e-09 8. delta=-8.770715820283215e-10 9. delta=-1.2543186267421902e-08 */ //+------------------------------------------------------------------+ //| Заполняет вектор случайными значениями | //+------------------------------------------------------------------+ void ArrayRandom(vector& v) { for(ulong i=0; i<v.Size(); i++) v[i]=double(MathRand())/32767.; }
Функция активации в нейронной сети определяет, как взвешенная сумма входного сигнала преобразуется в выходной сигнал узла или узлов на уровне сети. Выбор функции активации имеет большое влияние на возможности и производительность нейронной сети. В разных частях модели могут использоваться разные функции активации. В MQL5 реализованы не только все известные функции активации, но и производные активационной функции. Производные функции нужны для быстрого вычисления поправки на основании полученной ошибки во время обучения нейронной сети.
AF_ELU Exponential Linear Unit AF_EXP Exponential AF_GELU Gaussian Error Linear Unit AF_HARD_SIGMOID Hard Sigmoid AF_LINEAR Linear AF_LRELU Leaky REctified Linear Unit AF_RELU REctified Linear Unit AF_SELU Scaled Exponential Linear Unit AF_SIGMOID Sigmoid AF_SOFTMAX Softmax AF_SOFTPLUS Softplus AF_SOFTSIGN Softsign AF_SWISH Swish AF_TANH Hyperbolic Tangent AF_TRELU Thresholded REctified Linear Unit
LOSS_MSE Mean Squared Error LOSS_MAE Mean Absolute Error LOSS_CCE Categorical Crossentropy LOSS_BCE Binary Crossentropy LOSS_MAPE Mean Absolute Percentage Error LOSS_MSLE Mean Squared Logarithmic Error LOSS_KLD Kullback-Leibler Divergence LOSS_COSINE Cosine similarity/proximity LOSS_POISSON Poisson LOSS_HINGE Hinge LOSS_SQ_HINGE Squared Hinge LOSS_CAT_HINGE Categorical Hinge LOSS_LOG_COSH Logarithm of the Hyperbolic Cosine LOSS_HUBER Huber
int cl_ctx; //--- инициализация OpenCL контекста if((cl_ctx=CLContextCreate(CL_USE_GPU_DOUBLE_ONLY))==INVALID_HANDLE) { Print("OpenCL not found"); return; }
CalendarValueLast(change, result, "", "EUR")
MetaEditor
'levels.bmp' as 'uint levels[18990]'
Terminal
MQL5
MetaTester
MetaEditor
Исправления по крешлогам.
Terminal
MQL5
double vector.RegressionError(const enum lr_error); double matrix.RegressionError(const enum lr_error); vector matrix.RegressionError(const enum lr_error,const int axis);В качестве метрик могут использоваться:
enum REGRESSION_ERROR { REGRESSION_MAE, // Средняя абсолютная ошибка REGRESSION_MSE, // Средняя квадратичная ошибка REGRESSION_RMSE, // Корень из средней квадратичной ошибки REGRESSION_R2, // R в квадрате REGRESSION_MAPE, // Средняя абсолютная ошибка в процентах REGRESSION_MSPE, // Среднеквадратичная ошибка в процентах REGRESSION_RMSLE // Среднеквадратичная логарифмическая ошибка };
MetaEditor
Tester
Terminal
Terminal