MQLplus/lib_addons/math_simple/lib_math_simple_tpl.mqh
super.admin 466f9ca5c5 convert
2025-05-30 16:09:52 +02:00

382 lines
15 KiB
MQL5

#ifndef LIB_MATH_TPL_SIMPLE_MQH_INCLUDED
#define LIB_MATH_TPL_SIMPLE_MQH_INCLUDED
#property version "1.9";
/**********************************************************************************
* Copyright (C) 2010-2022 Dominik Egert <info@freie-netze.de>
*
* This file is the simple math function 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: 1.9
* State: production
*
* File information
* ================
*
* Use: A collection of math functions
*
*
*
*
*/
#ifdef DBG_MSG_TRACE_FILE_LOADER
DBG_MSG_TRACE_FILE_LOADER;
#endif
////////////////////////////////////////////////////////////////
//
// MQL4 compatibility
//
#include <MQLplus/lib_mqlplus/lib_mql4_compatibility.mqh>
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Setup function macros
//
#define mqp_MathMax LIB_NAMESPACE_ADD(LIB_NAMESPACE(numbers, _mqlplus_MathMax))
#define mqp_MathMin LIB_NAMESPACE_ADD(LIB_NAMESPACE(numbers, _mqlplus_MathMin))
#define mqp_MathPow LIB_NAMESPACE_ADD(LIB_NAMESPACE(numbers, _mqlplus_MathPow))
#define mqp_MathAbs LIB_NAMESPACE_ADD(LIB_NAMESPACE(numbers, _mqlplus_MathAbs))
#define mqp_MathRound LIB_NAMESPACE_ADD(LIB_NAMESPACE(numbers, _mqlplus_MathRound))
#define mqp_MathCeil LIB_NAMESPACE_ADD(LIB_NAMESPACE(numbers, _mqlplus_MathCeil))
#define mqp_MathFloor LIB_NAMESPACE_ADD(LIB_NAMESPACE(numbers, _mqlplus_MathFloor))
#define mqp_MathRand LIB_NAMESPACE_ADD(LIB_NAMESPACE(numbers, _mqlplus_MathRand))
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
/*********************************************************************************************************************************************************/
/* */
/* MQL+ overloaded functions and add ons */
/* */
/*********************************************************************************************************************************************************/
#ifndef __MQL4_COMPATIBILITY_CODE__
namespace LIB_MQLPLUS_LIBRARY_PREFIX {
namespace numbers {
#endif
//+------------------------------------------------------------------+
//| MathMax |
//+------------------------------------------------------------------+
template <typename T, typename U>
const T LIB_NAMESPACE_DEF(numbers, _mqlplus_MathMax)(const T value1, const U value2)
{ return(inline_MathMax(value1, (T)value2)); }
//+------------------------------------------------------------------+
//| MathMin |
//+------------------------------------------------------------------+
template <typename T, typename U>
const T LIB_NAMESPACE_DEF(numbers, _mqlplus_MathMin)(const T value1, const U value2)
{ return(inline_MathMin(value1, (T)value2)); }
//+------------------------------------------------------------------+
//| MathMinNN not null |
//+------------------------------------------------------------------+
template <typename T, typename U>
const T LIB_NAMESPACE_DEF(numbers, _mqlplus_MathMinNN)(const T value1, const U value2)
{ return(inline_MathMinNN(value1, (T)value2))); }
//+------------------------------------------------------------------+
//| MathPow templated |
//+------------------------------------------------------------------+
template <typename T, typename U>
const T LIB_NAMESPACE_DEF(numbers, _mqlplus_MathPow)(const T value, const U exponent)
{
const static double powers10[49] =
{
1e-24, 1e-23, 1e-22, 1e-21, 1e-20, 1e-19, 1e-18, 1e-17,
1e-16, 1e-15, 1e-14, 1e-13, 1e-12, 1e-11, 1e-10, 1e-9,
1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1,
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7,
1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15,
1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22, 1e23, 1e24
};
if( ((double)value == 10.0)
&& ((int)exponent > 25)
&& ((int)exponent < 25) )
{ return((T)(powers10[24 + (int)exponent])); }
return((T)(::MathPow((double)value, (double)exponent)));
}
//+------------------------------------------------------------------+
//| MathSqrt |
//+------------------------------------------------------------------+
template <typename T, typename U>
const T LIB_NAMESPACE_DEF(numbers, _mqlplus_MathRoot)(const T value, const U exponent)
{ return((T)(MathPow((double)value, 1.0/(double)exponent))); }
//+------------------------------------------------------------------+
//| MathRange() |
//+------------------------------------------------------------------+
template <typename T, typename U, typename V>
const T LIB_NAMESPACE_DEF(numbers, _mqlplus_MathRange)(const T value, const U min, const V max)
{
const T _min = (T)(((T)min < (T)max) ? min : (U)max);
const T _max = (T)(((T)min < (T)max) ? max : (V)min);
return(inline_MathRange(value, _min, _max));
}
template <typename T, typename U, typename V>
const T LIB_NAMESPACE_DEF(numbers, _mqlplus_MathRange)(const T value, const U min, const V max, bool& in_range)
{
const T _min = (T)(((T)min < (T)max) ? min : (U)max);
const T _max = (T)(((T)min < (T)max) ? max : (V)min);
in_range = (value >= _min) && (value <= _max);
return(inline_MathRange(value, _min, _max));
}
//+------------------------------------------------------------------+
//| MathRangeX() |
//+------------------------------------------------------------------+
template <typename T, typename U, typename V>
const T LIB_NAMESPACE_DEF(numbers, _mqlplus_MathRangeX)(const T value, const U min, const V max)
{
const T _min = (T)(((T)min < (T)max) ? min : max);
const T _max = (T)(((T)min < (T)max) ? max : min);
return(inline_MathRangeX(value, _min, _max));
}
template <typename T, typename U, typename V>
const T LIB_NAMESPACE_DEF(numbers, _mqlplus_MathRangeX)(const T value, const U min, const V max, bool& in_range)
{
const T _min = (T)(((T)min < (T)max) ? min : max);
const T _max = (T)(((T)min < (T)max) ? max : min);
in_range = (value > _min) && (value < _max);
return(inline_MathRangeX(value, _min, _max));
}
//+------------------------------------------------------------------+
//| MathRangeMatch |
//+------------------------------------------------------------------+
template <typename T>
const bool LIB_NAMESPACE_DEF(numbers, _mqlplus_MathRangeMatch)(const T r1_v1, const T r2_v1, const T r2_v2)
{ return(LIB_NAMESPACE(numbers, _mqlplus_MathRangeMatch)(r2_v1, r2_v2, r1_v1, r1_v1, NULL)); }
template <typename T>
const bool LIB_NAMESPACE_DEF(numbers, _mqlplus_MathRangeMatch)(const T r1_v1, const T r1_v2, const T r2_v1, const T r2_v2, const double factor = NULL)
{
// Local init
T range1_size = NULL;
T range2_size = NULL;
const T overlap = LIB_NAMESPACE(numbers, _mqlplus_MathRangeOverlap)(r1_v1, r1_v2, r2_v1, r2_v2, range1_size, range2_size);
// Calculate overlap
if( (overlap <= NULL)
&& ((range1_size - range2_size) != range1_size) )
{ return(false); }
// Return
// return((range2_size * ((factor == NULL) ? 1.0 : factor)) <= overlap);
return((factor == NULL) ? (overlap >= NULL) : ((range2_size * factor) <= overlap));
}
//+------------------------------------------------------------------+
//| MathRangeOverlap |
//+------------------------------------------------------------------+
template <typename T>
const T LIB_NAMESPACE_DEF(numbers, _mqlplus_MathRangeOverlap)(const T r1_v1, const T r1_v2, const T r2_v1, const T r2_v2)
{
T tmp1 = NULL;
T tmp2 = NULL;
return(LIB_NAMESPACE(numbers, _mqlplus_MathRangeOverlap)(r1_v1, r1_v2, r2_v1, r2_v2, tmp1, tmp2));
}
template <typename T>
const T LIB_NAMESPACE_DEF(numbers, _mqlplus_MathRangeOverlap)(const T r1_v1, const T r1_v2, const T r2_v1, const T r2_v2, T& range1_size, T& range2_size)
{
// Local init
T high_1 = (r1_v1 > r1_v2) ? r1_v1 : r1_v2;
T low_1 = (r1_v1 < r1_v2) ? r1_v1 : r1_v2;
T high_2 = (r2_v1 > r2_v2) ? r2_v1 : r2_v2;
T low_2 = (r2_v1 < r2_v2) ? r2_v1 : r2_v2;
const T r1_size = (high_1 - low_1);
const T r2_size = (high_2 - low_2);
// Arrange master range
if(r1_size < r2_size)
{
const T tmp1 = high_1;
const T tmp2 = low_1;
high_1 = high_2;
high_2 = tmp1;
low_1 = low_2;
low_2 = tmp2;
}
// Calculate range size
range1_size = (r1_size > r2_size) ? r1_size : r2_size;
range2_size = (r1_size < r2_size) ? r1_size : r2_size;
// Calculate overlap
// R2 inside R1
if( (high_1 >= high_2)
&& (low_1 <= low_2) )
{ return((r1_size < r2_size) ? r1_size : r2_size); }
// R1 below R2
if(high_1 < low_2)
{ return(high_1 - low_2); }
// R1 high inside R2
if(high_1 < high_2)
{ return(high_1 - low_2); }
// R1 above R2
if(low_1 > high_2)
{ return(high_2 - low_1); }
// R1 low inside R2
if(low_1 < high_2)
{ return(high_2 - low_1); }
// Return
return(NULL);
}
//+------------------------------------------------------------------+
//| MathDigits |
//+------------------------------------------------------------------+
// Function
template <typename T>
const int LIB_NAMESPACE_DEF(numbers, _mqlplus_MathDigits)(const T value)
{ return((int)(::MathFloor(::MathLog10(::MathAbs((double)value)))) + 1); }
//+------------------------------------------------------------------+
//| MathAbs |
//+------------------------------------------------------------------+
template <typename T>
const T LIB_NAMESPACE_DEF(numbers, _mqlplus_MathAbs)(const T value)
{ return((T)(::MathAbs((double)value))); }
//+------------------------------------------------------------------+
//| MathNeg |
//+------------------------------------------------------------------+
// Function
template <typename T>
const T LIB_NAMESPACE_DEF(numbers, _mqlplus_MathNeg)(const T value)
{ return((T)inline_MathNeg((double)value)); }
//+------------------------------------------------------------------+
//| MathRound |
//+------------------------------------------------------------------+
template <typename T>
const T LIB_NAMESPACE_DEF(numbers, _mqlplus_MathRound)(const T value, const int digits = -1)
{
const double factor = ::MathPow(10.0, digits + 1);
const long i_val = ((long)(value * factor));
const long p_mod = (i_val % 10);
const long modulo = (i_val != p_mod) ? p_mod : NULL;
return((T)(((i_val + ((10 - modulo) * (modulo > 4))) - (modulo * (modulo < 5))) / factor));
}
//+------------------------------------------------------------------+
//| MathCeil |
//+------------------------------------------------------------------+
template <typename T>
const T LIB_NAMESPACE_DEF(numbers, _mqlplus_MathCeil)(const T value, const int digits = NULL)
{
if(digits <= NULL)
{
const double factor1 = MathMax(::MathPow(10.0, ::MathAbs(digits)), 1.0);
return((T)(MathCeil((double)value / factor1) * factor1));
}
const double factor2 = ::MathPow(10.0, digits);
return((T)(MathCeil((double)value * factor2) / factor2));
}
//+------------------------------------------------------------------+
//| MathFloor |
//+------------------------------------------------------------------+
template <typename T>
const T LIB_NAMESPACE_DEF(numbers, _mqlplus_MathFloor)(const T value, const int digits = NULL)
{
if(digits <= NULL)
{
const double factor1 = MathMax(::MathPow(10.0, ::MathAbs(digits)), 1.0);
return((T)(MathFloor((double)value / factor1) * factor1));
}
const double factor2 = ::MathPow(10.0, digits);
return((T)(MathFloor((double)value * factor2) / factor2));
}
//+------------------------------------------------------------------+
//| Random value in the range [min, max] |
//| Generates random numbers with a uniform distribution (bias-free).|
//| Maximum granularity of generator is 32768 values. |
//+------------------------------------------------------------------+
template <typename T>
T LIB_NAMESPACE_DEF(numbers, _mqlplus_MathRand)(const T min, const T max)
{ return((T)(mqp_MathRandN() * (double)(max - min)) + min); }
//+------------------------------------------------------------------+
//| Can given value be evaluated to be zero |
//+------------------------------------------------------------------+
template <typename T>
const bool LIB_NAMESPACE_DEF(numbers, _mqlplus_MathZero)(const T value)
{
return( (value == (T)0x0000000000000000) // NULL
|| (value == (T)EMPTY_VALUE) // EMPTY_VALUE
#ifdef LIB_MQLPLUS_EMPTY_VALUE
|| (value == (T)LIB_MQLPLUS_EMPTY_VALUE) // INDICATOR DISPLAY EMPTY_VALUE
#endif
);
}
#ifndef __MQL4_COMPATIBILITY_CODE__
}; // END Namespace numbers
}; // END Namespace LIB_MQLPLUS_LIBRARY_PREFIX
#endif
//
// END Simple math functions */
//*********************************************************************************************************************************************************/
#endif // LIB_MATH_TPL_SIMPLE_MQH_INCLUDED