#ifndef LIB_MT5API_ARRAY_TPL_MQH_INCLUDED #define LIB_MT5API_ARRAY_TPL_MQH_INCLUDED #property version "2.0"; /********************************************************************************** * Copyright (C) 2010-2022 Dominik Egert * * This file is the MQLplus MT5-API array templates include file. * * MQLplus, including this file may not be copied and/or distributed * without explecit permit by the author. * Author Dominik Egert / Freie Netze UG. ********************************************************************************** * * Version: 2.0 * State: production * * File information * ================ * * * */ #ifdef DBG_MSG_TRACE_FILE_LOADER DBG_MSG_TRACE_FILE_LOADER; #endif ///////////////////////////////////////// // // Define library mode // // Header mode #ifndef LIB_MQLPLUS_LIB_EXPORT #define LIB_MQLPLUS_LIB_EXPORT #endif // Binary mode #ifdef LIB_MQLPLUS_BINARY_LIBRARY #ifndef LIB_MQLPLUS_NO_INCLUDE #define LIB_MQLPLUS_NO_INCLUDE #endif #ifdef LIB_MQLPLUS_LIB_EXPORT #undef LIB_MQLPLUS_LIB_EXPORT #endif #ifdef LIB_DEBUG #undef LIB_DEBUG #endif #define LIB_MQLPLUS_LIB_EXPORT export #property library #endif //////////////////////////////////////////////////////////////// // // MQL4 compatibility // #ifndef LIB_MQLPLUS_NO_INCLUDE #include #endif //////////////////////////////////////////////////////////////// // // MQL4 compatibility // #ifndef LIB_MQLPLUS_NO_INCLUDE #include #include #endif ///////////////////////////////////////////////////////////////////////////////////////////////////// // // Setup function macros // #define mqp_ArrayResize LIB_NAMESPACE_ADD(LIB_NAMESPACE(mt5api, mqlplus_ArrayResize)) #define mqp_ArrayInitialize LIB_NAMESPACE_ADD(LIB_NAMESPACE(mt5api, mqlplus_ArrayInitialize)) #define mqp_ArrayFill LIB_NAMESPACE_ADD(LIB_NAMESPACE(mt5api, mqlplus_ArrayFill)) #define mqp_ArrayPrint LIB_NAMESPACE_ADD(LIB_NAMESPACE(mt5api, mqlplus_ArrayPrint)) #define mqp_ArrayUnique LIB_NAMESPACE_ADD(LIB_NAMESPACE(mt5api, mqlplus_ArrayUnique)) #define mqp_ArrayCopy LIB_NAMESPACE_ADD(LIB_NAMESPACE(mt5api, mqlplus_ArrayCopy)) /*********************************************************************************************************************************************************/ /* */ /* MQL original API system function additions */ /* */ /*********************************************************************************************************************************************************/ #ifndef __MQL4_COMPATIBILITY_CODE__ namespace LIB_MQLPLUS_LIBRARY_PREFIX { namespace mt5api { #endif //+------------------------------------------------------------------+ //| ArrayResize() | //+------------------------------------------------------------------+ template const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayResize)(T& arr_in[], const int new_size = NULL, const int _pre_alloc = NULL) { // Calculate memory geometry const int mempage = 4096 / MathRoundPow2(sizeof(T)); const int pre_alloc = (_pre_alloc == NULL) ? mempage : _pre_alloc; const int arr_size = ::ArraySize(arr_in); const int abs_size = (new_size < NULL) ? (arr_size + new_size) : (new_size + ((arr_size + 1) * (new_size == NULL))); const int _size = (abs_size > pre_alloc) ? abs_size : pre_alloc; const int _mod = mempage - (_size % mempage); // Shrink array if(new_size < NULL) { return((arr_size + new_size) * (::ArrayRemove(arr_in, arr_size + new_size))); } // Extend array return(::ArrayResize(arr_in, abs_size, ((_size << 1) < mempage) ? (_size << 1) : (_size + ((_mod < _size) ? _mod : NULL)))); } template const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayResize)(T& arr_in[][], const int new_size = NULL, const int _pre_alloc = NULL) { // Calculate memory geometry const int mempage = 4096 / MathRoundPow2(sizeof(T) * ArrayRange(arr_in, 1)); const int pre_alloc = (_pre_alloc == NULL) ? mempage : _pre_alloc; const int arr_size = ::ArraySize(arr_in); const int abs_size = (new_size < NULL) ? (arr_size + new_size) : (new_size + ((arr_size + 1) * (new_size == NULL))); const int _size = (abs_size > pre_alloc) ? abs_size : pre_alloc; const int mod = mempage - (_size % mempage); // Shrink array if(new_size < NULL) { return((arr_size + new_size) * (::ArrayRemove(arr_in, arr_size + new_size))); } // Extend array return(::ArrayResize(arr_in, abs_size, ((_size << 1) < mempage) ? (_size << 1) : (_size + mod))); } template const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayResize)(T& arr_in[][][], const int new_size = NULL, const int _pre_alloc = NULL) { // Calculate memory geometry const int mempage = 4096 / MathRoundPow2(sizeof(T) * ArrayRange(arr_in, 1) * ArrayRange(arr_in, 2)); const int pre_alloc = (_pre_alloc == NULL) ? mempage : _pre_alloc; const int arr_size = ::ArraySize(arr_in); const int abs_size = (new_size < NULL) ? (arr_size + new_size) : (new_size + ((arr_size + 1) * (new_size == NULL))); const int _size = (abs_size > pre_alloc) ? abs_size : pre_alloc; const int mod = mempage - (_size % mempage); // Shrink array if(new_size < NULL) { return((arr_size + new_size) * (::ArrayRemove(arr_in, arr_size + new_size))); } // Extend array return(::ArrayResize(arr_in, abs_size, ((_size << 1) < mempage) ? (_size << 1) : (_size + mod))); } //+------------------------------------------------------------------+ //| ArrayInitialize() | //+------------------------------------------------------------------+ template const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayInitialize)(T& arr_in[], const T value = NULL, const int new_size = NULL) { const int _size = (new_size != NULL) ? mqp_ArrayResize(arr_in, new_size): ::ArraySize(arr_in); for(int cnt = NULL; (cnt < _size) && !_StopFlag; cnt++) { arr_in[cnt] = value; } return(_size); } template const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayInitialize)(T& arr_in[][], const T value = NULL, const int new_size = NULL) { const int _size = (new_size != NULL) ? mqp_ArrayResize(arr_in, new_size): ::ArraySize(arr_in); const int d1_size = ArrayRange(arr_in, 0); const int d2_size = ArrayRange(arr_in, 1); for(int dim_1 = NULL; (dim_1 < d1_size) && !_StopFlag; dim_1++) { for(int dim_2 = NULL; (dim_2 < d2_size) && !_StopFlag; dim_2++) { arr_in[dim_1][dim_2] = value; } } return(_size); } template const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayInitialize)(T& arr_in[][][], const T value = NULL, const int new_size = NULL) { const int _size = (new_size != NULL) ? mqp_ArrayResize(arr_in, new_size): ::ArraySize(arr_in); const int d1_size = ArrayRange(arr_in, 0); const int d2_size = ArrayRange(arr_in, 1); const int d3_size = ArrayRange(arr_in, 2); for(int dim_1 = NULL; (dim_1 < d1_size) && !_StopFlag; dim_1++) { for(int dim_2 = NULL; (dim_2 < d2_size) && !_StopFlag; dim_2++) { for(int dim_3 = NULL; (dim_3 < d3_size) && !_StopFlag; dim_3++) { arr_in[dim_1][dim_2][dim_3] = value; } } } return(_size); } //+------------------------------------------------------------------+ //| ArrayFill() | //+------------------------------------------------------------------+ template void LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayFill)(T& arr_in[], const int start, const int count, const T value = NULL) { const int _size = ::ArraySize(arr_in); const int _end = start + count; for(int cnt = start; (cnt < _size) && (cnt < _end) && !_StopFlag; cnt++) { arr_in[cnt] = value; } } //+------------------------------------------------------------------+ //| ArrayFill() | //+------------------------------------------------------------------+ template void LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayFill)(T& arr_in[], const int start, const int count, const T value, const T increment_step) { const int _size = ::ArraySize(arr_in); const int _end = start + count; for(int cnt = start; (cnt < _size) && (cnt < _end) && !_StopFlag; cnt++) { arr_in[cnt] = (cnt != NULL) && increment_step != NULL) ? (arr_in[cnt - 1] + increment_step) : value; } } //+------------------------------------------------------------------+ //| ArrayPrint() | //+------------------------------------------------------------------+ void LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayPrint)(char& arr_in[], const int digits = -1, const string separator = NULL, const ulong start = 0, const ulong count = WHOLE_ARRAY, const ulong flags = ARRAYPRINT_HEADER|ARRAYPRINT_INDEX|ARRAYPRINT_LIMIT|ARRAYPRINT_ALIGN) { ArrayPrint(arr_in, (uint)((digits == -1) ? _Digits : digits), separator, start, count, flags); } void LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayPrint)(uchar& arr_in[], const int digits = -1, const string separator = NULL, const ulong start = 0, const ulong count = WHOLE_ARRAY, const ulong flags = ARRAYPRINT_HEADER|ARRAYPRINT_INDEX|ARRAYPRINT_LIMIT|ARRAYPRINT_ALIGN) { ArrayPrint(arr_in, (uint)((digits == -1) ? _Digits : digits), separator, start, count, flags); } void LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayPrint)(short& arr_in[], const int digits = -1, const string separator = NULL, const ulong start = 0, const ulong count = WHOLE_ARRAY, const ulong flags = ARRAYPRINT_HEADER|ARRAYPRINT_INDEX|ARRAYPRINT_LIMIT|ARRAYPRINT_ALIGN) { ArrayPrint(arr_in, (uint)((digits == -1) ? _Digits : digits), separator, start, count, flags); } void LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayPrint)(ushort& arr_in[], const int digits = -1, const string separator = NULL, const ulong start = 0, const ulong count = WHOLE_ARRAY, const ulong flags = ARRAYPRINT_HEADER|ARRAYPRINT_INDEX|ARRAYPRINT_LIMIT|ARRAYPRINT_ALIGN) { ArrayPrint(arr_in, (uint)((digits == -1) ? _Digits : digits), separator, start, count, flags); } void LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayPrint)(int& arr_in[], const int digits = -1, const string separator = NULL, const ulong start = 0, const ulong count = WHOLE_ARRAY, const ulong flags = ARRAYPRINT_HEADER|ARRAYPRINT_INDEX|ARRAYPRINT_LIMIT|ARRAYPRINT_ALIGN) { ArrayPrint(arr_in, (uint)((digits == -1) ? _Digits : digits), separator, start, count, flags); } void LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayPrint)(uint& arr_in[], const int digits = -1, const string separator = NULL, const ulong start = 0, const ulong count = WHOLE_ARRAY, const ulong flags = ARRAYPRINT_HEADER|ARRAYPRINT_INDEX|ARRAYPRINT_LIMIT|ARRAYPRINT_ALIGN) { ArrayPrint(arr_in, (uint)((digits == -1) ? _Digits : digits), separator, start, count, flags); } void LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayPrint)(long& arr_in[], const int digits = -1, const string separator = NULL, const ulong start = 0, const ulong count = WHOLE_ARRAY, const ulong flags = ARRAYPRINT_HEADER|ARRAYPRINT_INDEX|ARRAYPRINT_LIMIT|ARRAYPRINT_ALIGN) { ArrayPrint(arr_in, (uint)((digits == -1) ? _Digits : digits), separator, start, count, flags); } void LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayPrint)(ulong& arr_in[], const int digits = -1, const string separator = NULL, const ulong start = 0, const ulong count = WHOLE_ARRAY, const ulong flags = ARRAYPRINT_HEADER|ARRAYPRINT_INDEX|ARRAYPRINT_LIMIT|ARRAYPRINT_ALIGN) { ArrayPrint(arr_in, (uint)((digits == -1) ? _Digits : digits), separator, start, count, flags); } void LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayPrint)(datetime& arr_in[], const int digits = -1, const string separator = NULL, const ulong start = 0, const ulong count = WHOLE_ARRAY, const ulong flags = ARRAYPRINT_HEADER|ARRAYPRINT_INDEX|ARRAYPRINT_LIMIT|ARRAYPRINT_ALIGN) { ArrayPrint(arr_in, (uint)((digits == -1) ? _Digits : digits), separator, start, count, flags); } void LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayPrint)(float& arr_in[], const int digits = -1, const string separator = NULL, const ulong start = 0, const ulong count = WHOLE_ARRAY, const ulong flags = ARRAYPRINT_HEADER|ARRAYPRINT_INDEX|ARRAYPRINT_LIMIT|ARRAYPRINT_ALIGN) { ArrayPrint(arr_in, (uint)((digits == -1) ? _Digits : digits), separator, start, count, flags); } void LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayPrint)(double& arr_in[], const int digits = -1, const string separator = NULL, const ulong start = 0, const ulong count = WHOLE_ARRAY, const ulong flags = ARRAYPRINT_HEADER|ARRAYPRINT_INDEX|ARRAYPRINT_LIMIT|ARRAYPRINT_ALIGN) { ArrayPrint(arr_in, (uint)((digits == -1) ? _Digits : digits), separator, start, count, flags); } void LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayPrint)(string& arr_in[], const int digits = -1, const string separator = NULL, const ulong start = 0, const ulong count = WHOLE_ARRAY, const ulong flags = ARRAYPRINT_HEADER|ARRAYPRINT_INDEX|ARRAYPRINT_LIMIT|ARRAYPRINT_ALIGN) { ArrayPrint(arr_in, (uint)((digits == -1) ? _Digits : digits), separator, start, count, flags); } template void LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayPrint)(T& arr_in[]) { const int _size = ::ArraySize(arr_in); for(int cnt = NULL; (cnt < _size) && !_StopFlag; cnt++) { printf("[%i] %s", cnt, arr_in[cnt].to_string()); } } //+------------------------------------------------------------------+ //| ArrayUnique() | //+------------------------------------------------------------------+ template const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayUnique)(T& array[], const bool last_occurence = false, const int start = NULL, const int count = WHOLE_ARRAY) { // Local init const int size = ::ArraySize(array); const int end = (count == WHOLE_ARRAY) ? (size - start) : start + ((count == WHOLE_ARRAY) ? (size - start) : size); int idx = (last_occurence) ? (end -1) : start; int cnt = NULL; int map[]; T ref; // Init map ::ArrayResize(map, end - start); ::ArrayInitialize(map, -1); // Fill map while( (idx < end) && (idx >= start) && (!_StopFlag) ) { // Inner loop ref = array[idx]; cnt = idx; while( (cnt < end) && (cnt >= start) && (!_StopFlag) ) { map[cnt] = (ref == array[cnt]) ? idx : map[cnt]; cnt += (last_occurence) ? -1 : 1; } // Find next (Outer loop skip elements) while( (idx < end) && (idx >= start) && (map[idx] != -1) && (!_StopFlag) ) { idx += (last_occurence) ? -1 : 1; } } // Substitute map idx = start; cnt = NULL; while( (cnt < end) && (!_StopFlag) ) { array[idx] = array[cnt]; idx += (map[cnt] == cnt); cnt++; } // Resize result array ::ArrayResize(array, idx); // Return return(idx); } //+------------------------------------------------------------------+ //| ArrayCopy() | //+------------------------------------------------------------------+ const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayCopy)(double& dst[], const double& src[], const int dst_start = NULL, const int src_start = NULL, const int count = WHOLE_ARRAY) { return(::ArrayCopy(dst, src, dst_start, src_start, count)); } const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayCopy)(float& dst[], const float& src[], const int dst_start = NULL, const int src_start = NULL, const int count = WHOLE_ARRAY) { return(::ArrayCopy(dst, src, dst_start, src_start, count)); } const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayCopy)(long& dst[], const ulong& src[], const int dst_start = NULL, const int src_start = NULL, const int count = WHOLE_ARRAY) { return(::ArrayCopy(dst, src, dst_start, src_start, count)); } const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayCopy)(int& dst[], const uint& src[], const int dst_start = NULL, const int src_start = NULL, const int count = WHOLE_ARRAY) { return(::ArrayCopy(dst, src, dst_start, src_start, count)); } const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayCopy)(short& dst[], const ushort& src[], const int dst_start = NULL, const int src_start = NULL, const int count = WHOLE_ARRAY) { return(::ArrayCopy(dst, src, dst_start, src_start, count)); } const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayCopy)(char& dst[], const uchar& src[], const int dst_start = NULL, const int src_start = NULL, const int count = WHOLE_ARRAY) { return(::ArrayCopy(dst, src, dst_start, src_start, count)); } const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayCopy)(ulong& dst[], const long& src[], const int dst_start = NULL, const int src_start = NULL, const int count = WHOLE_ARRAY) { return(::ArrayCopy(dst, src, dst_start, src_start, count)); } const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayCopy)(uint& dst[], const int& src[], const int dst_start = NULL, const int src_start = NULL, const int count = WHOLE_ARRAY) { return(::ArrayCopy(dst, src, dst_start, src_start, count)); } const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayCopy)(ushort& dst[], const short& src[], const int dst_start = NULL, const int src_start = NULL, const int count = WHOLE_ARRAY) { return(::ArrayCopy(dst, src, dst_start, src_start, count)); } const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayCopy)(uchar& dst[], const char& src[], const int dst_start = NULL, const int src_start = NULL, const int count = WHOLE_ARRAY) { return(::ArrayCopy(dst, src, dst_start, src_start, count)); } const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayCopy)(long& dst[], const long& src[], const int dst_start = NULL, const int src_start = NULL, const int count = WHOLE_ARRAY) { return(::ArrayCopy(dst, src, dst_start, src_start, count)); } const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayCopy)(int& dst[], const int& src[], const int dst_start = NULL, const int src_start = NULL, const int count = WHOLE_ARRAY) { return(::ArrayCopy(dst, src, dst_start, src_start, count)); } const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayCopy)(short& dst[], const short& src[], const int dst_start = NULL, const int src_start = NULL, const int count = WHOLE_ARRAY) { return(::ArrayCopy(dst, src, dst_start, src_start, count)); } const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayCopy)(char& dst[], const char& src[], const int dst_start = NULL, const int src_start = NULL, const int count = WHOLE_ARRAY) { return(::ArrayCopy(dst, src, dst_start, src_start, count)); } const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayCopy)(ulong& dst[], const ulong& src[], const int dst_start = NULL, const int src_start = NULL, const int count = WHOLE_ARRAY) { return(::ArrayCopy(dst, src, dst_start, src_start, count)); } const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayCopy)(uint& dst[], const uint& src[], const int dst_start = NULL, const int src_start = NULL, const int count = WHOLE_ARRAY) { return(::ArrayCopy(dst, src, dst_start, src_start, count)); } const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayCopy)(ushort& dst[], const ushort& src[], const int dst_start = NULL, const int src_start = NULL, const int count = WHOLE_ARRAY) { return(::ArrayCopy(dst, src, dst_start, src_start, count)); } const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayCopy)(uchar& dst[], const uchar& src[], const int dst_start = NULL, const int src_start = NULL, const int count = WHOLE_ARRAY) { return(::ArrayCopy(dst, src, dst_start, src_start, count)); } const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayCopy)(datetime& dst[], const datetime& src[], const int dst_start = NULL, const int src_start = NULL, const int count = WHOLE_ARRAY) { return(::ArrayCopy(dst, src, dst_start, src_start, count)); } const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayCopy)(color& dst[], const color& src[], const int dst_start = NULL, const int src_start = NULL, const int count = WHOLE_ARRAY) { return(::ArrayCopy(dst, src, dst_start, src_start, count)); } const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayCopy)(string& dst[], const string& src[], const int dst_start = NULL, const int src_start = NULL, const int count = WHOLE_ARRAY) { return(::ArrayCopy(dst, src, dst_start, src_start, count)); } template const int LIB_NAMESPACE_DEF(mt5api, mqlplus_ArrayCopy)(T& dst[], const T& src[], const int dst_start = NULL, const int src_start = NULL, const int count = WHOLE_ARRAY) { // Local init const MQLPLUS_ENUM_DATATYPE_ID data_type = mqp_DatatypeID(dst); const int dst_size = ArraySize(dst); const int src_size = ArraySize(src); const int element_count = (count < 1) ? (src_size - src_start) : MathMin(count, src_size); const int max = (dst_size < (dst_start + element_count)) ? ArrayResize(dst, dst_start + element_count) : (dst_start + element_count); // Switch copy type switch(data_type) { case BASIC_DATATYPE_VECTOR: case BASIC_DATATYPE_MATRIX: case CMPLX_DATATYPE_UNION: case CMPLX_DATATYPE_CLASS: case CMPLX_DATATYPE_CLASS_OBJECT: case CMPLX_DATATYPE_CLASS_POINTER: case CMPLX_DATATYPE_STRUCTURE: case CMPLX_DATATYPE_INTERFACE: for(int dst_ptr = dst_start, src_ptr = src_start; (dst_ptr < max) && !_StopFlag; dst_ptr++, src_ptr++) { dst[dst_ptr] = src[src_ptr]; } return(element_count); }; // Return return(NULL); } #ifndef __MQL4_COMPATIBILITY_CODE__ }; // Namespece mt5api:: }; // Namespece LIB_MQLPLUS_LIBRARY_PREFIX:: #endif // // END MQL addon functions */ //*********************************************************************************************************************************************************/ #endif // LIB_MT5API_ARRAY_TPL_MQH_INCLUDED