537 lines
39 KiB
MQL5
537 lines
39 KiB
MQL5
#ifndef LIB_MQLPLUS_STRUCTURE_LIFETIME_MQH_INCLUDED
|
|
#define LIB_MQLPLUS_STRUCTURE_LIFETIME_MQH_INCLUDED
|
|
#property version "1.2";
|
|
/**********************************************************************************
|
|
* Copyright (C) 2010-2022 Dominik Egert <info@freie-netze.de>
|
|
*
|
|
* This file is the smart objects 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: 1.2
|
|
* State: production
|
|
*
|
|
* File information
|
|
* ================
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
#ifdef DBG_MSG_TRACE_FILE_LOADER
|
|
DBG_MSG_TRACE_FILE_LOADER;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*********************************************************************************************************************************************************/
|
|
/* */
|
|
/* MQLplus auto destructing handlers */
|
|
/* */
|
|
/*********************************************************************************************************************************************************/
|
|
|
|
|
|
/////////////////////////////////////////////////////
|
|
//
|
|
// Main handle and pointer structure
|
|
//
|
|
|
|
// Primary abstract template class
|
|
template <typename T>
|
|
class _smart_object
|
|
{
|
|
protected:
|
|
|
|
// Close message
|
|
string _identifyer;
|
|
string _close_msg;
|
|
|
|
// Object handle
|
|
T obj;
|
|
|
|
|
|
public:
|
|
|
|
// Constructors
|
|
_smart_object() :
|
|
obj(NULL),
|
|
_close_msg(NULL),
|
|
_identifyer(NULL)
|
|
{ };
|
|
|
|
_smart_object(_smart_object& p_in) :
|
|
obj(operator=(p_in)),
|
|
_close_msg(NULL),
|
|
_identifyer(NULL)
|
|
{ };
|
|
|
|
_smart_object(const T p_in) :
|
|
obj(p_in),
|
|
_close_msg(NULL),
|
|
_identifyer(NULL)
|
|
{ };
|
|
|
|
// Assignment operator
|
|
const T operator=(const T p_in) { if(is_valid() && (obj != p_in)) { obj_free(); _identifyer = NULL; _close_msg = NULL; } obj = p_in; return(obj); }
|
|
const T operator=(_smart_object& p_in) { return(obj_assign(p_in)); }
|
|
|
|
// Compare handle
|
|
const bool operator==(const _smart_object& p_in) const { return(obj == p_in.obj); }
|
|
const bool operator!=(const _smart_object& p_in) const { return(obj != p_in.obj); }
|
|
const bool operator==(const T p_in) const { return(obj == p_in); }
|
|
const bool operator!=(const T p_in) const { return(obj != p_in); }
|
|
|
|
// Set closing message
|
|
void set_close_message(const string p_in) { _close_msg = p_in; }
|
|
|
|
// Check handle
|
|
virtual bool is_valid() = 0;
|
|
|
|
// Get handle
|
|
const T get() { return(obj); }
|
|
|
|
// Get/Set identifyer
|
|
const string get_identifyer() { return(_identifyer); }
|
|
void set_identifyer(const string p_in) { _identifyer = p_in; }
|
|
|
|
protected:
|
|
|
|
// Assign smart object
|
|
const T obj_assign(_smart_object& p_in) { if(is_valid() && (obj != p_in.obj)) { obj_free(); } _identifyer = p_in._identifyer; _close_msg = p_in._close_msg; obj = p_in.obj_extract(); return(obj); }
|
|
|
|
// Release handle
|
|
virtual void obj_free() = 0;
|
|
|
|
// Extract handle
|
|
virtual T obj_extract() = 0;
|
|
};
|
|
|
|
|
|
// General 32 bit integer handle
|
|
class __smo_handle : public _smart_object<int>
|
|
{
|
|
public:
|
|
|
|
// Constructor
|
|
__smo_handle() : _smart_object(INVALID_HANDLE) { };
|
|
__smo_handle(const int p_in): _smart_object(p_in) { };
|
|
|
|
// Destructor
|
|
~__smo_handle() { if(is_valid()) { obj_free(); } };
|
|
|
|
// Check handle
|
|
virtual bool is_valid() { return(obj != INVALID_HANDLE); };
|
|
|
|
|
|
protected:
|
|
|
|
// Release handle
|
|
virtual void obj_free() = 0;
|
|
virtual int obj_extract() = 0;
|
|
};
|
|
|
|
|
|
// Object pointer instance class
|
|
template <typename T>
|
|
class smart_ptr : public _smart_object<T*>
|
|
{
|
|
public:
|
|
|
|
// Constructor
|
|
smart_ptr() : _smart_object(NULL) { };
|
|
smart_ptr(const T& p_in) : _smart_object(::GetPointer(p_in)) { };
|
|
|
|
// Destructor
|
|
~smart_ptr() { if(is_valid()) { obj_free(); } };
|
|
|
|
// Assignment operator
|
|
T* operator=(smart_ptr& p_in) { return(obj_assign(p_in)); };
|
|
|
|
// Handle Identifyer
|
|
const string get_identifyer() { if(!is_valid()) { return(NULL); } return(::StringLen(_identifyer) > 0) _identifyer : typename(*obj)); };
|
|
|
|
// Check handle
|
|
virtual bool is_valid() { return((obj != NULL) && ::CheckPointer(obj) != POINTER_INVALID)); };
|
|
|
|
|
|
protected:
|
|
|
|
// Release handle
|
|
virtual void obj_free() { if(!is_valid()) { return; }
|
|
if(_close_msg != NULL) { printf("Deleting object by pointer: %s; Object name: %s", _close_msg, typename(obj)); }
|
|
delete(obj); obj = NULL;
|
|
};
|
|
virtual T obj_extract() { const T tmp = obj; obj = NULL; return(tmp); };
|
|
};
|
|
|
|
|
|
// General string type object identifyer handle
|
|
class str_handle : public _smart_object<string>
|
|
{
|
|
public:
|
|
|
|
// Constructor
|
|
str_handle() : _smart_object(NULL) { };
|
|
str_handle(const string p_in) : _smart_object(p_in) { };
|
|
|
|
// Destructor
|
|
~str_handle() { if(is_valid()) { obj_free(); } };
|
|
|
|
// Assignment operator
|
|
const string operator=(str_handle& p_in) { return(obj_assign(p_in)); };
|
|
|
|
// Handle Identifyer
|
|
const string get_identifyer() { if(!is_valid()) { return(NULL); } return((::StringLen(_identifyer) > 0) ? _identifyer : obj); };
|
|
|
|
// Check handle
|
|
virtual bool is_valid() { return((obj != NULL) && (obj != "")); };
|
|
|
|
|
|
protected:
|
|
|
|
// Release handle
|
|
virtual void obj_free() { if(!is_valid()) { return; }
|
|
if(_close_msg != NULL) { printf("%s; String handle: %s", _close_msg, obj); }
|
|
obj = NULL;
|
|
};
|
|
};
|
|
|
|
|
|
// Resource handler
|
|
class resource_handle : public str_handle
|
|
{
|
|
public:
|
|
|
|
// Constructor
|
|
resource_handle() : str_handle(NULL) { };
|
|
resource_handle(const string p_in) : str_handle(p_in) { };
|
|
|
|
// Destructor
|
|
~resource_handle() { if(is_valid()) { obj_free(); } };
|
|
|
|
// Assignment operator
|
|
const string operator=(resource_handle& p_in) { return(obj_assign(p_in)); };
|
|
|
|
// Handle Identifyer
|
|
const string get_identifyer() { if(!is_valid()) { return(NULL); } return((::StringLen(_identifyer) > 0) ? _identifyer : obj); };
|
|
|
|
// Check handle
|
|
virtual bool is_valid() { return((obj != NULL) && (obj != "")); };
|
|
|
|
|
|
protected:
|
|
|
|
// Release handle
|
|
virtual void obj_free() { if(!is_valid()) { return; }
|
|
if(_close_msg != NULL) { printf("Closing Resource handle: %s; Resource name: %s", _close_msg, obj); }
|
|
::ResetLastError(); ::ResourceFree(obj); obj = NULL;
|
|
if(_LastError != ERR_SUCCESS) { printf("Error closing resource: %i", _LastError); }
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////
|
|
//
|
|
// Specific handle implementations
|
|
//
|
|
|
|
|
|
// File handle
|
|
class file_handle : public __smo_handle
|
|
{
|
|
public:
|
|
|
|
// Destructor
|
|
~file_handle() { if(is_valid()) { obj_free(); } };
|
|
|
|
// Assignment operator
|
|
const int operator=(file_handle& p_in) { return(obj_assign(p_in)); };
|
|
|
|
// Handle Identifyer
|
|
const string get_identifyer() { if(!is_valid()) { return(NULL); }
|
|
if(::StringLen(_identifyer) > 0) { return(_identifyer); }
|
|
if(::FileGetInteger(obj, FILE_EXISTS) != 1) { return(NULL); }
|
|
return(::TerminalInfoString((::FileGetInteger(obj, FILE_IS_COMMON)) ? TERMINAL_COMMONDATA_PATH : TERMINAL_DATA_PATH));
|
|
};
|
|
const int get_type() { if(!is_valid()) { return(-1); }
|
|
return(
|
|
(::FileGetInteger(obj, FILE_IS_COMMON) ? FILE_COMMON : NULL)
|
|
| (::FileGetInteger(obj, FILE_IS_TEXT) ? FILE_TXT : NULL)
|
|
| (::FileGetInteger(obj, FILE_IS_BINARY) ? FILE_BIN : NULL)
|
|
| (::FileGetInteger(obj, FILE_IS_CSV) ? FILE_CSV : NULL)
|
|
| (::FileGetInteger(obj, FILE_IS_ANSI) ? FILE_ANSI : FILE_UNICODE)
|
|
| (::FileGetInteger(obj, FILE_IS_READABLE) ? FILE_READ : NULL)
|
|
| (::FileGetInteger(obj, FILE_IS_WRITABLE) ? FILE_WRITE : NULL)
|
|
);
|
|
};
|
|
|
|
protected:
|
|
|
|
// Release handle
|
|
virtual void obj_free() { if(!is_valid()) { return; }
|
|
if(_close_msg != NULL) { printf("Closing File handle: %s; File location: %s", _close_msg, ::TerminalInfoString((::FileGetInteger(obj, FILE_IS_COMMON)) ? TERMINAL_COMMONDATA_PATH : TERMINAL_DATA_PATH)); }
|
|
::ResetLastError(); ::FileClose(obj); obj = INVALID_HANDLE;
|
|
if(_LastError != ERR_SUCCESS) { printf("Error closing file: %i", _LastError); }
|
|
if(_StopFlag) { Sleep(10); }
|
|
};
|
|
virtual int obj_extract() { const int tmp = obj; obj = INVALID_HANDLE; return(tmp); };
|
|
};
|
|
|
|
|
|
#ifndef __MQL4_COMPATIBILITY_CODE__
|
|
// Indicator handle
|
|
class indicator_handle : public __smo_handle
|
|
{
|
|
public:
|
|
|
|
// Destructor
|
|
~indicator_handle() { if(is_valid()) { obj_free(); } };
|
|
|
|
// Assignment operator
|
|
const int operator=(indicator_handle& p_in) { return(obj_assign(p_in)); };
|
|
|
|
// Handle Identifyer
|
|
const string get_identifyer() { if(!is_valid()) { return(NULL); }
|
|
if(::StringLen(_identifyer) > 0) { return(_identifyer); }
|
|
string short_name = __find_indicator_short_name(::ChartID(), obj);
|
|
long chart_id = ::ChartFirst();
|
|
while( (short_name == NULL) && (chart_id != -1) )
|
|
{
|
|
short_name = __find_indicator_short_name(chart_id, obj);
|
|
chart_id = ::ChartNext(chart_id);
|
|
}
|
|
if(short_name != NULL) {return(short_name); }
|
|
ENUM_INDICATOR ind_type;
|
|
MqlParam params[];
|
|
if(::IndicatorParameters(obj, ind_type, params) == -1) { ind_type = -1; }
|
|
return(::EnumToString(ind_type));
|
|
};
|
|
const ENUM_INDICATOR get_type() { if(!is_valid()) { return(-1); }
|
|
ENUM_INDICATOR ind_type;
|
|
MqlParam params[];
|
|
if(::IndicatorParameters(obj, ind_type, params) == -1) { return(-1); }
|
|
return(ind_type);
|
|
}
|
|
|
|
|
|
protected:
|
|
|
|
// Release handle
|
|
virtual void obj_free() { if(!is_valid()) { return; }
|
|
if(_close_msg != NULL)
|
|
{
|
|
ENUM_INDICATOR ind_type;
|
|
MqlParam params[];
|
|
const int param_cnt = (!_StopFlag) ? ::IndicatorParameters(obj, ind_type, params) : NULL;
|
|
string params_out = NULL;
|
|
for(int cnt = NULL; (cnt < param_cnt) && !_StopFlag; cnt++)
|
|
{
|
|
switch(params[cnt].type)
|
|
{
|
|
case TYPE_BOOL: params_out += " " + ::StringFormat("%s\n", (params[cnt].integer_value) ? "True" : "False"); break;
|
|
case TYPE_CHAR:
|
|
case TYPE_SHORT:
|
|
case TYPE_INT:
|
|
case TYPE_LONG: params_out += " " + ::StringFormat("%lli\n", params[cnt].integer_value); break;
|
|
case TYPE_UCHAR:
|
|
case TYPE_USHORT:
|
|
case TYPE_UINT:
|
|
case TYPE_ULONG: params_out += " " + ::StringFormat("%llu\n", (ulong)params[cnt].integer_value); break;
|
|
case TYPE_COLOR: params_out += " " + ::ColorToString((color)params[cnt].integer_value, true); break;
|
|
case TYPE_DATETIME: params_out += " " + ::TimeToString((datetime)params[cnt].integer_value, TIME_DATE|TIME_MINUTES); break;
|
|
case TYPE_FLOAT:
|
|
case TYPE_DOUBLE: params_out += " " + ::StringFormat("%.*f", 12, params[cnt].double_value); break;
|
|
case TYPE_STRING: params_out += " " + ::StringFormat("%s\n", params[cnt].string_value); break;
|
|
}
|
|
}
|
|
printf("Closing Indicator handle: %s; Indicator type: %s\n%s", _close_msg, ::EnumToString(ind_type), params_out);
|
|
}
|
|
::ResetLastError(); ::IndicatorRelease(obj); obj = INVALID_HANDLE;
|
|
if(_LastError != ERR_SUCCESS) { printf("Error closing indicator: %i", _LastError); }
|
|
if(_StopFlag) { ::Sleep(25); }
|
|
};
|
|
virtual int obj_extract() { const int tmp = obj; obj = INVALID_HANDLE; return(tmp); };
|
|
|
|
|
|
private:
|
|
|
|
// Find indicator on charts
|
|
const string __find_indicator_short_name(const long chart_id, const int h_ind) { for(int wnd = (int)::ChartGetInteger(chart_id, CHART_WINDOWS_TOTAL) - 1; (wnd >= NULL); wnd--)
|
|
{
|
|
for(int ind = (int)::ChartIndicatorsTotal(chart_id, wnd) - 1; (ind >= NULL); ind--)
|
|
{
|
|
const string ind_name = ::ChartIndicatorName(chart_id, wnd, ind);
|
|
if(::ChartIndicatorGet(chart_id, wnd, ind_name) == h_ind) { return(ind_name); }
|
|
}
|
|
}
|
|
return(NULL);
|
|
};
|
|
|
|
};
|
|
|
|
|
|
// Open CL handle
|
|
#ifndef __MQL4_COMPATIBILITY_CODE__
|
|
class opencl_handle : public __smo_handle
|
|
{
|
|
public:
|
|
|
|
// Constructor
|
|
opencl_handle() : __smo_handle(OPENCL_INVALID) { };
|
|
|
|
// Destructor
|
|
~opencl_handle() { if(is_valid()) { obj_free(); } };
|
|
|
|
// Assignment operator
|
|
const int operator=(opencl_handle& p_in) { return(obj_assign(p_in)); };
|
|
|
|
// Handle Identifyer
|
|
const string get_identifyer() { if(!is_valid()) { return(NULL); } return((::StringLen(_identifyer) > 0) ? _identifyer : ::EnumToString(::CLHandleType(obj))); };
|
|
const ENUM_OPENCL_HANDLE_TYPE get_type() { if(!is_valid()) { return(OPENCL_INVALID); } return(::CLHandleType(obj)); };
|
|
|
|
// Check handle
|
|
virtual bool is_valid() { return(obj != OPENCL_INVALID); };
|
|
|
|
|
|
protected:
|
|
|
|
// Release handle
|
|
virtual void obj_free() { if(!is_valid()) { return; }
|
|
if(_close_msg != NULL) { printf("Closing OpenCL handle: %s; OpenCL handle type: %s", _close_msg, ::EnumToString(::CLHandleType(obj))); }
|
|
::ResetLastError();
|
|
switch(::CLHandleType(obj))
|
|
{
|
|
case OPENCL_CONTEXT: ::CLContextFree(obj); obj = OPENCL_INVALID; break;
|
|
case OPENCL_PROGRAM: ::CLProgramFree(obj); obj = OPENCL_INVALID; break;
|
|
case OPENCL_KERNEL: ::CLKernelFree(obj); obj = OPENCL_INVALID; break;
|
|
case OPENCL_BUFFER: ::CLBufferFree(obj); obj = OPENCL_INVALID; break;
|
|
}
|
|
if(_LastError != ERR_SUCCESS) { printf("Error closing ocl-handle: %i", _LastError); }
|
|
if(_StopFlag) { ::Sleep(25); }
|
|
};
|
|
virtual int obj_extract() { const int tmp = obj; obj = OPENCL_INVALID; return(tmp); };
|
|
};
|
|
|
|
|
|
// DirectX handle
|
|
class dx_handle : public __smo_handle
|
|
{
|
|
public:
|
|
|
|
// Constructor
|
|
dx_handle() : __smo_handle(DX_HANDLE_INVALID) { };
|
|
|
|
// Destructor
|
|
~dx_handle() { if(is_valid()) { obj_free(); } };
|
|
|
|
// Assignment operator
|
|
const int operator=(dx_handle& p_in) { return(obj_assign(p_in)); };
|
|
|
|
// Handle Identifyer
|
|
const string get_identifyer() { if(!is_valid()) { return(NULL); } return((::StringLen(_identifyer) > 0) ? _identifyer : ::EnumToString(DXHandleType(obj))); };
|
|
const ENUM_DX_HANDLE_TYPE get_type() { if(!is_valid()) { return(-1); } return(::DXHandleType(obj)); };
|
|
|
|
// Check handle
|
|
virtual bool is_valid() { return(obj != DX_HANDLE_INVALID); };
|
|
|
|
|
|
protected:
|
|
|
|
// Release handle
|
|
virtual void obj_free() { if(!is_valid()) { return; }
|
|
if(_close_msg != NULL) { printf("Closing DirectX handle: %s; DirectX handle type: %s", _close_msg, ::EnumToString(::DXHandleType(obj))); }
|
|
::ResetLastError(); ::DXRelease(obj); obj = DX_HANDLE_INVALID;
|
|
if(_LastError != ERR_SUCCESS) { printf("Error closing dx-handle: %i", _LastError); }
|
|
if(_StopFlag) { Sleep(25); }
|
|
};
|
|
virtual int obj_extract() { const int tmp = obj; obj = DX_HANDLE_INVALID; return(tmp); };
|
|
};
|
|
|
|
|
|
// Database handle
|
|
class db_handle : public __smo_handle
|
|
{
|
|
public:
|
|
|
|
// Destructor
|
|
~db_handle() { if(is_valid()) { obj_free(); } };
|
|
|
|
// Assignment operator
|
|
const int operator=(db_handle& p_in) { return(obj_assign(p_in)); };
|
|
|
|
// Handle Identifyer
|
|
const string get_identifyer() { if(!is_valid()) { return(NULL); }
|
|
if(::StringLen(_identifyer) > 0) { return(_identifyer); }
|
|
const int h_request = ::DatabasePrepare(obj, "SELECT file FROM pragma_database_list WHERE name = 'main';");
|
|
string file = NULL;
|
|
bool err = !::DatabaseRead(h_request);
|
|
err |= (!err) && !::DatabaseColumnText(h_request, 0, file);
|
|
::DatabaseFinalize(h_request);
|
|
return((err) ? NULL : ((file == "") ? ":memory:" : file));
|
|
};
|
|
|
|
protected:
|
|
|
|
// Release handle
|
|
virtual void obj_free() { if(!is_valid()) { return; }
|
|
if(_close_msg != NULL) { printf("Closing Database handle: %s", _close_msg); }
|
|
::ResetLastError(); ::DatabaseClose(obj); obj = INVALID_HANDLE;
|
|
if(_LastError != ERR_SUCCESS) { printf("Error closing database: %i", _LastError); }
|
|
if(_StopFlag) { Sleep(100); }
|
|
};
|
|
virtual int obj_extract() { const int tmp = obj; obj = INVALID_HANDLE; return(tmp); };
|
|
};
|
|
|
|
|
|
// Socket handle
|
|
class socket_handle : public __smo_handle
|
|
{
|
|
public:
|
|
|
|
// Destructor
|
|
~socket_handle() { if(is_valid()) { obj_free(); } };
|
|
|
|
// Assignment operator
|
|
const int operator=(socket_handle& p_in) { return(obj_assign(p_in)); };
|
|
|
|
// Handle Identifyer
|
|
const string get_identifyer() { if(!is_valid() || !::SocketIsConnected(obj)) { return(NULL); }
|
|
if(::StringLen(_identifyer) > 0) { return(_identifyer); }
|
|
if(!::SocketIsConnected(obj)) { return(NULL); }
|
|
::ResetLastError();
|
|
string subject = NULL, issuer = NULL, serial = NULL, thumbprint = NULL;
|
|
datetime expiration = NULL;
|
|
bool err = !::SocketTlsCertificate(obj, subject, issuer, serial, thumbprint, expiration);
|
|
if(_LastError == ERR_NETSOCKET_NO_CERTIFICATE) { ::ResetLastError(); return(""); }
|
|
if(err) { return(NULL); }
|
|
return(subject + ";" + issuer + ";" + ::TimeToString(expiration));
|
|
};
|
|
|
|
|
|
protected:
|
|
|
|
// Release handle
|
|
virtual void obj_free() { if(!is_valid()) { return; }
|
|
if(_close_msg != NULL) { printf("Closing Socket handle: %s", _close_msg); }
|
|
::ResetLastError(); ::SocketClose(obj); obj = INVALID_HANDLE;
|
|
if(_LastError != ERR_SUCCESS) { printf("Error closing socket: %i", _LastError); }
|
|
if(_StopFlag) { ::Sleep(25); }
|
|
};
|
|
virtual int obj_extract() { const int tmp = obj; obj = INVALID_HANDLE; return(tmp); };
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//
|
|
// END MQL data structures */
|
|
//*********************************************************************************************************************************************************/
|
|
#endif // LIB_MQLPLUS_STRUCTURE_UNIONS_MQH_INCLUDED
|