From 56b382609fe17b99d492a2597a550e7e48f9648a Mon Sep 17 00:00:00 2001 From: amirghadiri1987 <144431373+amirghadiri1987@users.noreply.github.com> Date: Fri, 7 Feb 2025 19:12:13 +0330 Subject: [PATCH] Add files via upload --- Graphics/Axis.mqh | 260 + Graphics/ColorGenerator.mqh | 74 + Graphics/Curve.mqh | 700 + Graphics/Graphic.mqh | Bin 0 -> 174806 bytes Indicators/BillWilliams.mqh | 761 + Indicators/Custom.mqh | 194 + Indicators/Indicator.mqh | 516 + Indicators/Indicators.mqh | 385 + Indicators/Oscilators.mqh | 1722 + Indicators/Series.mqh | 299 + Indicators/TimeSeries.mqh | 1551 + Indicators/Trend.mqh | 1717 + Indicators/Volumes.mqh | 424 + Layouts/Box.mqh | 385 + Layouts/ComboBoxResizable.mqh | 66 + Layouts/Grid.mqh | 153 + Layouts/GridTk.mqh | 154 + Layouts/MaximizableAppDialog.mqh | 337 + Layouts/SpinEditResizable.mqh | 27 + Layouts/res/Expand2.bmp | Bin 0 -> 1078 bytes Layouts/res/size10.bmp | Bin 0 -> 1078 bytes Layouts/res/size6.bmp | Bin 0 -> 1078 bytes MT4Bridge/MT4Orders.mqh | Bin 0 -> 182558 bytes MT4Bridge/MT4Time.mqh | Bin 0 -> 4222 bytes Marketeer/CSVReader.mqh | Bin 0 -> 6138 bytes Marketeer/CSVcolumns.mqh | Bin 0 -> 764 bytes Marketeer/Converter.mqh | Bin 0 -> 1430 bytes Marketeer/GroupSettings.mqh | Bin 0 -> 50 bytes Marketeer/HTMLcolumns.mqh | Bin 0 -> 716 bytes Marketeer/IndexMap.mqh | Bin 0 -> 17274 bytes Marketeer/RubbArray.mqh | Bin 0 -> 7580 bytes Marketeer/WebDataExtractor.mqh | Bin 0 -> 84488 bytes Marketeer/empty_strings.h | 20 + Math/Alglib/alglib.mqh | 38345 ++++++++++++ Math/Alglib/alglibinternal.mqh | 15934 +++++ Math/Alglib/alglibmisc.mqh | 2575 + Math/Alglib/ap.mqh | 2549 + Math/Alglib/arrayresize.mqh | 104 + Math/Alglib/bitconvert.mqh | 411 + Math/Alglib/dataanalysis.mqh | 26387 ++++++++ Math/Alglib/delegatefunctions.mqh | 444 + Math/Alglib/diffequations.mqh | 849 + Math/Alglib/fasttransforms.mqh | 2657 + Math/Alglib/integration.mqh | 2980 + Math/Alglib/interpolation.mqh | 34261 ++++++++++ Math/Alglib/linalg.mqh | 37629 +++++++++++ Math/Alglib/matrix.mqh | 1025 + Math/Alglib/optimization.mqh | 51766 ++++++++++++++++ Math/Alglib/solvers.mqh | 7154 +++ Math/Alglib/specialfunctions.mqh | 6534 ++ Math/Alglib/statistics.mqh | 13650 ++++ Math/Fuzzy/dictionary.mqh | 197 + Math/Fuzzy/fuzzyrule.mqh | 371 + Math/Fuzzy/fuzzyterm.mqh | 69 + Math/Fuzzy/fuzzyvariable.mqh | 113 + Math/Fuzzy/genericfuzzysystem.mqh | 333 + Math/Fuzzy/helper.mqh | 158 + Math/Fuzzy/inferencemethod.mqh | 125 + Math/Fuzzy/mamdanifuzzysystem.mqh | 556 + Math/Fuzzy/membershipfunction.mqh | 1008 + Math/Fuzzy/ruleparser.mqh | 1019 + Math/Fuzzy/sugenofuzzysystem.mqh | 327 + Math/Fuzzy/sugenovariable.mqh | 254 + Math/Stat/Beta.mqh | 772 + Math/Stat/Binomial.mqh | 874 + Math/Stat/Cauchy.mqh | 539 + Math/Stat/ChiSquare.mqh | 531 + Math/Stat/Exponential.mqh | 520 + Math/Stat/F.mqh | 563 + Math/Stat/Gamma.mqh | 764 + Math/Stat/Geometric.mqh | 567 + Math/Stat/Hypergeometric.mqh | 754 + Math/Stat/Logistic.mqh | 592 + Math/Stat/Lognormal.mqh | 635 + Math/Stat/Math.mqh | Bin 0 -> 434790 bytes Math/Stat/NegativeBinomial.mqh | 643 + Math/Stat/NoncentralBeta.mqh | 954 + Math/Stat/NoncentralChiSquare.mqh | 912 + Math/Stat/NoncentralF.mqh | 790 + Math/Stat/NoncentralT.mqh | 1192 + Math/Stat/Normal.mqh | 914 + Math/Stat/Poisson.mqh | 791 + Math/Stat/Stat.mqh | 27 + Math/Stat/T.mqh | 654 + Math/Stat/Uniform.mqh | 539 + Math/Stat/Weibull.mqh | 574 + .../HistoryDealGetTicket.ex5 | Bin 0 -> 10864 bytes .../HistoryDealGetTicket.mq5 | Bin 0 -> 11944 bytes 88 files changed, 274630 insertions(+) create mode 100644 Graphics/Axis.mqh create mode 100644 Graphics/ColorGenerator.mqh create mode 100644 Graphics/Curve.mqh create mode 100644 Graphics/Graphic.mqh create mode 100644 Indicators/BillWilliams.mqh create mode 100644 Indicators/Custom.mqh create mode 100644 Indicators/Indicator.mqh create mode 100644 Indicators/Indicators.mqh create mode 100644 Indicators/Oscilators.mqh create mode 100644 Indicators/Series.mqh create mode 100644 Indicators/TimeSeries.mqh create mode 100644 Indicators/Trend.mqh create mode 100644 Indicators/Volumes.mqh create mode 100644 Layouts/Box.mqh create mode 100644 Layouts/ComboBoxResizable.mqh create mode 100644 Layouts/Grid.mqh create mode 100644 Layouts/GridTk.mqh create mode 100644 Layouts/MaximizableAppDialog.mqh create mode 100644 Layouts/SpinEditResizable.mqh create mode 100644 Layouts/res/Expand2.bmp create mode 100644 Layouts/res/size10.bmp create mode 100644 Layouts/res/size6.bmp create mode 100644 MT4Bridge/MT4Orders.mqh create mode 100644 MT4Bridge/MT4Time.mqh create mode 100644 Marketeer/CSVReader.mqh create mode 100644 Marketeer/CSVcolumns.mqh create mode 100644 Marketeer/Converter.mqh create mode 100644 Marketeer/GroupSettings.mqh create mode 100644 Marketeer/HTMLcolumns.mqh create mode 100644 Marketeer/IndexMap.mqh create mode 100644 Marketeer/RubbArray.mqh create mode 100644 Marketeer/WebDataExtractor.mqh create mode 100644 Marketeer/empty_strings.h create mode 100644 Math/Alglib/alglib.mqh create mode 100644 Math/Alglib/alglibinternal.mqh create mode 100644 Math/Alglib/alglibmisc.mqh create mode 100644 Math/Alglib/ap.mqh create mode 100644 Math/Alglib/arrayresize.mqh create mode 100644 Math/Alglib/bitconvert.mqh create mode 100644 Math/Alglib/dataanalysis.mqh create mode 100644 Math/Alglib/delegatefunctions.mqh create mode 100644 Math/Alglib/diffequations.mqh create mode 100644 Math/Alglib/fasttransforms.mqh create mode 100644 Math/Alglib/integration.mqh create mode 100644 Math/Alglib/interpolation.mqh create mode 100644 Math/Alglib/linalg.mqh create mode 100644 Math/Alglib/matrix.mqh create mode 100644 Math/Alglib/optimization.mqh create mode 100644 Math/Alglib/solvers.mqh create mode 100644 Math/Alglib/specialfunctions.mqh create mode 100644 Math/Alglib/statistics.mqh create mode 100644 Math/Fuzzy/dictionary.mqh create mode 100644 Math/Fuzzy/fuzzyrule.mqh create mode 100644 Math/Fuzzy/fuzzyterm.mqh create mode 100644 Math/Fuzzy/fuzzyvariable.mqh create mode 100644 Math/Fuzzy/genericfuzzysystem.mqh create mode 100644 Math/Fuzzy/helper.mqh create mode 100644 Math/Fuzzy/inferencemethod.mqh create mode 100644 Math/Fuzzy/mamdanifuzzysystem.mqh create mode 100644 Math/Fuzzy/membershipfunction.mqh create mode 100644 Math/Fuzzy/ruleparser.mqh create mode 100644 Math/Fuzzy/sugenofuzzysystem.mqh create mode 100644 Math/Fuzzy/sugenovariable.mqh create mode 100644 Math/Stat/Beta.mqh create mode 100644 Math/Stat/Binomial.mqh create mode 100644 Math/Stat/Cauchy.mqh create mode 100644 Math/Stat/ChiSquare.mqh create mode 100644 Math/Stat/Exponential.mqh create mode 100644 Math/Stat/F.mqh create mode 100644 Math/Stat/Gamma.mqh create mode 100644 Math/Stat/Geometric.mqh create mode 100644 Math/Stat/Hypergeometric.mqh create mode 100644 Math/Stat/Logistic.mqh create mode 100644 Math/Stat/Lognormal.mqh create mode 100644 Math/Stat/Math.mqh create mode 100644 Math/Stat/NegativeBinomial.mqh create mode 100644 Math/Stat/NoncentralBeta.mqh create mode 100644 Math/Stat/NoncentralChiSquare.mqh create mode 100644 Math/Stat/NoncentralF.mqh create mode 100644 Math/Stat/NoncentralT.mqh create mode 100644 Math/Stat/Normal.mqh create mode 100644 Math/Stat/Poisson.mqh create mode 100644 Math/Stat/Stat.mqh create mode 100644 Math/Stat/T.mqh create mode 100644 Math/Stat/Uniform.mqh create mode 100644 Math/Stat/Weibull.mqh create mode 100644 MyScr/HistoryDealGetXXXX/HistoryDealGetTicket.ex5 create mode 100644 MyScr/HistoryDealGetXXXX/HistoryDealGetTicket.mq5 diff --git a/Graphics/Axis.mqh b/Graphics/Axis.mqh new file mode 100644 index 0000000..b122bb9 --- /dev/null +++ b/Graphics/Axis.mqh @@ -0,0 +1,260 @@ +//+------------------------------------------------------------------+ +//| Axis.mqh | +//| Copyright 2000-2024, MetaQuotes Ltd. | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +typedef string(*DoubleToStringFunction)(double,void*); +//--- Various axis types +enum ENUM_AXIS_TYPE + { + AXIS_TYPE_DOUBLE, + AXIS_TYPE_DATETIME, + AXIS_TYPE_CUSTOM, + }; +//+------------------------------------------------------------------+ +//| Class CAxis | +//| Usage: class for create axes on a two-dimensional graphics | +//+------------------------------------------------------------------+ +class CAxis + { +private: + double m_min; + double m_max; + double m_step; + uint m_clr; + string m_name; + int m_name_size; + int m_values_size; + int m_values_width; + string m_values_format; + string m_values_fontname; + uint m_values_fontflags; + uint m_values_fontangle; + bool m_auto_scale; + double m_zero_lever; // this number is used to determine when an axis scale range should be extended to include the zero value. + double m_default_step; // length of the default step + double m_max_labels; // the maximum number of marks + double m_min_grace; // "grace" value applied to the minimum data range + double m_max_grace; // "grace" value applied to the maximum data range + int m_values_dt_mode; + DoubleToStringFunction m_values_func; + void *m_values_cbdata; + ENUM_AXIS_TYPE m_type; + +public: + CAxis(void); + ~CAxis(void); + //--- properties + double Step(void) const { return(m_step); } + double Min(void) const { return(m_min); } + void Min(const double min) { m_min=min; } + double Max(void) const { return(m_max); } + void Max(const double max) { m_max=max; } + string Name(void) const { return(m_name); } + void Name(const string name) { m_name=name; } + ENUM_AXIS_TYPE Type(void) const { return(m_type); } + void Type(ENUM_AXIS_TYPE type) { m_type=type; } + //--- default properties + uint Color(void) const { return(m_clr); } + void Color(const uint clr) { m_clr=clr; } + bool AutoScale(void) const { return(m_auto_scale); } + void AutoScale(const bool auto) { m_auto_scale=auto; } + int ValuesSize(void) const { return(m_values_size); } + void ValuesSize(const int size) { m_values_size=size; } + int ValuesWidth(void) const { return(m_values_width); } + void ValuesWidth(const int width) { m_values_width=width; } + string ValuesFormat(void) const { return(m_values_format); } + void ValuesFormat(const string format) { m_values_format=format; } + int ValuesDateTimeMode(void) const { return(m_values_dt_mode); } + void ValuesDateTimeMode(const int mode) { m_values_dt_mode=mode; } + DoubleToStringFunction ValuesFunctionFormat(void) const { return(m_values_func); } + void ValuesFunctionFormat(DoubleToStringFunction func) { m_values_func=func; } + void *ValuesFunctionFormatCBData(void) const { return(m_values_cbdata); } + void ValuesFunctionFormatCBData(void *cbdata) { m_values_cbdata=cbdata; } + string ValuesFontName(void) const { return(m_values_fontname); } + void ValuesFontName(const string fontname) { m_values_fontname=fontname; } + uint ValuesFontAngle(void) const { return(m_values_fontangle); } + void ValuesFontAngle(const uint fontangle) { m_values_fontangle=fontangle; } + uint ValuesFontFlags(void) const { return(m_values_fontflags); } + void ValuesFontFlags(const uint fontflags) { m_values_fontflags=fontflags; } + int NameSize(void) const { return(m_name_size); } + void NameSize(const int size) { m_name_size=size; } + double ZeroLever(void) const { return(m_zero_lever); } + void ZeroLever(const double value) { m_zero_lever=value; } + double DefaultStep(void) const { return(m_default_step); } + void DefaultStep(const double value) { m_default_step=value; } + double MaxLabels(void) const { return(m_max_labels); } + void MaxLabels(const double value) { m_max_labels=value; } + double MinGrace(void) const { return(m_min_grace); } + void MinGrace(const double value) { m_min_grace=value; } + double MaxGrace(void) const { return(m_max_grace); } + void MaxGrace(const double value) { m_max_grace=value; } + //--- method for auto scaling + void SelectAxisScale(void); + +private: + //--- additional methods for axis autoscaling + void ExtensionBoundaries(void); + double CalcStepSize(const double range,const double steps); + double Mod(const double x,const double y); + double CalcBoundedStepSize(const double range,const double max_steps); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CAxis::CAxis(void) : m_auto_scale(true), + m_zero_lever(0.25), + m_default_step(25.0), + m_max_labels(15), + m_min_grace(0.01), + m_max_grace(0.01), + m_clr(clrBlack), + m_name_size(0), + m_values_size(12), + m_values_fontname("arial"), + m_values_fontflags(0), + m_values_fontangle(0), + m_values_func(NULL), + m_values_cbdata(NULL), + m_values_dt_mode(TIME_MINUTES), + m_type(AXIS_TYPE_DOUBLE), + m_values_width(30) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CAxis::~CAxis(void) + { + } +//+------------------------------------------------------------------+ +//| Rounds a maximum, minimum values and defines step size. | +//+------------------------------------------------------------------+ +void CAxis::SelectAxisScale(void) + { + if(m_min>m_max) + m_max=m_min; + if(!m_auto_scale) + { + if(m_max<=m_min) + ExtensionBoundaries(); + m_step=((m_max-m_min)>m_default_step && m_default_step>0) ? m_default_step : m_max-m_min; + return; + } + ExtensionBoundaries(); +//--- test for trivial condition of range = 0 and pick a suitable default + if(m_max-m_min<1.0e-30) + { + m_max=m_max+0.2 *(m_max==0 ? 1.0 : MathAbs(m_max)); + m_min=m_min-0.2 *(m_min==0 ? 1.0 : MathAbs(m_min)); + } +//--- this is the zero-lever test. If m_min is within the zero lever fraction of the data range,then use zero. + if(m_min>0 && m_min/(m_max-m_min)0) + m_step=CalcBoundedStepSize(m_max-m_min,m_max_labels); + else + m_step=CalcBoundedStepSize(m_max-m_min,labels); +//--- calculate the scale minimum + m_min=m_min-Mod(m_min,m_step); +//--- calculate the scale maximum + m_max=Mod(m_max,m_step)==0.0 ? m_max : m_max+m_step-Mod(m_max,m_step); + } +//+------------------------------------------------------------------+ +//| Expands the boundaries to the left and right. | +//+------------------------------------------------------------------+ +void CAxis::ExtensionBoundaries(void) + { + double range=m_max-m_min; +//--- do not let the grace value extend the axis below zero when all the values were positive + if(m_min<0 || m_min-m_min_grace*range>=0.0) + m_min=m_min-m_min_grace*range; +//--- do not let the grace value extend the axis above zero when all the values were negative + if(m_max>0 || m_max+m_max_grace*range<=0.0) + m_max=m_max+m_max_grace*range; +//--- calculate new min and max values if they equal + if(m_max==m_min) + { + if(MathAbs(m_max)>1e-100) + { + m_max *= (m_min < 0 ? 0.95 : 1.05 ); + m_min *= (m_min < 0 ? 1.05 : 0.95 ); + } + else + { + m_max = 1.0; + m_min = -1.0; + } + } +//--- + } +//+------------------------------------------------------------------+ +//| Calculate a m_step size based on a data range. | +//+------------------------------------------------------------------+ +double CAxis::CalcStepSize(const double range,const double steps) + { +//--- calculate an initial guess at m_step size + double temp=range/steps; +//--- get the magnitude of the m_step size + double mag=MathFloor(MathLog10(temp)); + double magPow=MathPow(10.0,mag); +//--- calculate most significant digit of the new m_step size + double magMsd=NormalizeDouble(temp/magPow+.5,0); +//--- promote the MSD to either 1, 2, or 5 + if(magMsd>5.0) + magMsd=10.0; + else + if(magMsd>2.0) + magMsd=5.0; + else + if(magMsd>1.0) + magMsd=2.0; +//--- return step + return(magMsd * magPow); + } +//+------------------------------------------------------------------+ +//| Calculate the modulus (remainder) in a safe manner so that divide| +//| by zero errors are avoided | +//+------------------------------------------------------------------+ +double CAxis::Mod(const double x,const double y) + { +//--- check + if(y==0) + return(0); +//--- calculate modulus + return (x>0)? MathMod(x,y): MathMod(x,y)+y; + } +//+------------------------------------------------------------------+ +//| Calculate a m_step size based on a data range, limited to a max | +//| number of steps. | +//+------------------------------------------------------------------+ +double CAxis::CalcBoundedStepSize(const double range,const double max_steps) + { +//--- calculate an initial guess at m_step size + double temp=range/max_steps; +//--- get the magnitude of the m_step size + double mag=MathFloor(MathLog10(temp)); + double magPow=MathPow((double) 10.0,mag); +//--- calculate most significant digit of the new m_step size + double magMsd=MathCeil(temp/magPow); +//--- promote the MSD to either 1, 2, or 5 + if(magMsd>5.0) + magMsd=10.0; + else + if(magMsd>2.0) + magMsd=5.0; + else + if(magMsd>1.0) + magMsd=2.0; +//--- return step + return(magMsd * magPow); + } +//+------------------------------------------------------------------+ diff --git a/Graphics/ColorGenerator.mqh b/Graphics/ColorGenerator.mqh new file mode 100644 index 0000000..8a8cf25 --- /dev/null +++ b/Graphics/ColorGenerator.mqh @@ -0,0 +1,74 @@ +//+------------------------------------------------------------------+ +//| ColorGenerator.mqh | +//| Copyright 2000-2024, MetaQuotes Ltd. | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +//+------------------------------------------------------------------+ +//| Class CColorGenerator | +//| Usage: class to generate the default colors | +//+------------------------------------------------------------------+ +class CColorGenerator + { +private: + int m_index; + bool m_generate; + uint m_current_palette[20]; + const static uint s_default_palette[20]; + +public: + CColorGenerator(void); + ~CColorGenerator(void); + //--- gets the next color + uint Next(void); + //--- reset generator + void Reset(void); + }; +const uint CColorGenerator::s_default_palette[20]= + { + 0x3366CC,0xDC3912,0xFF9900,0x109618,0x990099, + 0x3B3EAC,0x0099C6,0xDD4477,0x66AA00,0xB82E2E, + 0x316395,0x994499,0x22AA99,0xAAAA11,0x6633CC, + 0xE67300,0x8B0707,0x329262,0x5574A6,0x3B3EAC + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CColorGenerator::CColorGenerator(void): m_index(0), + m_generate(false) + { + ArrayCopy(m_current_palette,s_default_palette); + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CColorGenerator::~CColorGenerator(void) + { + } +//+------------------------------------------------------------------+ +//| Gets or generates the following color from the palette | +//+------------------------------------------------------------------+ +uint CColorGenerator::Next(void) + { +//--- check the array out of range + if(m_index==20) + { + m_index=0; + if(!m_generate) + m_generate=true; + } +//--- check the default palette is over + if(m_generate) + m_current_palette[m_index]=(m_index==19 ? (m_current_palette[m_index]^m_current_palette[0]):(m_current_palette[m_index]^m_current_palette[m_index+1])); +//--- return next color + return(m_current_palette[m_index++]); + } +//+------------------------------------------------------------------+ +//| Resets all the new colors, set the index to 0 | +//+------------------------------------------------------------------+ +void CColorGenerator::Reset(void) + { + m_index=0; + m_generate=false; + ArrayCopy(m_current_palette,s_default_palette); + } +//+------------------------------------------------------------------+ diff --git a/Graphics/Curve.mqh b/Graphics/Curve.mqh new file mode 100644 index 0000000..af03eb0 --- /dev/null +++ b/Graphics/Curve.mqh @@ -0,0 +1,700 @@ +//+------------------------------------------------------------------+ +//| Curve.mqh | +//| Copyright 2000-2024, MetaQuotes Ltd. | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#include +#include +//--- forward declaration +class CGraphic; +//--- fucntion for represent custom plot method +typedef void(*PlotFucntion)(double &x[],double &y[],int size,CGraphic *graphic,CCanvas *canvas,void *cbdata); +//--- function for represent curve +typedef double(*CurveFunction)(double); +//--- drawing type +enum ENUM_CURVE_TYPE + { + CURVE_POINTS, + CURVE_LINES, + CURVE_POINTS_AND_LINES, + CURVE_STEPS, + CURVE_HISTOGRAM, + CURVE_CUSTOM, + CURVE_NONE + }; +//--- type for the various point shapes that are available +enum ENUM_POINT_TYPE + { + POINT_CIRCLE, + POINT_SQUARE, + POINT_DIAMOND, + POINT_TRIANGLE, + POINT_TRIANGLE_DOWN, + POINT_X_CROSS, + POINT_PLUS, + POINT_STAR, + POINT_HORIZONTAL_DASH, + POINT_VERTICAL_DASH + }; +//+------------------------------------------------------------------+ +//| Structure CPoint2D | +//| Usage: 2d point on graphic in Cartesian coordinates | +//+------------------------------------------------------------------+ +struct CPoint2D + { + double x; + double y; + }; +//+------------------------------------------------------------------+ +//| Class CCurve | +//| Usage: class to represent the one-dimensional curve | +//+------------------------------------------------------------------+ +class CCurve : public CObject + { +private: + uint m_clr; + double m_x[]; + double m_y[]; + double m_xmin; + double m_xmax; + double m_ymin; + double m_ymax; + int m_size; + ENUM_CURVE_TYPE m_type; + string m_name; + //--- lines + ENUM_LINE_STYLE m_lines_style; + ENUM_LINE_END m_lines_end_style; + int m_lines_width; + bool m_lines_smooth; + double m_lines_tension; + double m_lines_step; + //--- points + int m_points_size; + ENUM_POINT_TYPE m_points_type; + bool m_points_fill; + uint m_points_clr; + //--- steps + int m_steps_dimension; + //--- histogram + int m_hisogram_width; + //--- custom + PlotFucntion m_custom_plot_func; + void *m_custom_plot_cbdata; + //--- general property + bool m_visible; + //--- trend line property + uint m_trend_clr; + bool m_trend_visible; + +protected: + bool m_trend_calc; + double m_trend_coeff[]; + +public: + CCurve(const double &y[],const uint clr,ENUM_CURVE_TYPE type,const string name); + CCurve(const double &x[],const double &y[],const uint clr,ENUM_CURVE_TYPE type,const string name); + CCurve(const CPoint2D &points[],const uint clr,ENUM_CURVE_TYPE type,const string name); + CCurve(CurveFunction function,const double from,const double to,const double step,const uint clr,ENUM_CURVE_TYPE type,const string name); + ~CCurve(void); + //--- gets the general properties + void GetX(double &x[]) const { ArrayCopy(x,m_x); } + void GetY(double &y[]) const { ArrayCopy(y,m_y); } + double XMax(void) const { return(m_xmax); } + double XMin(void) const { return(m_xmin); } + double YMax(void) const { return(m_ymax); } + double YMin(void) const { return(m_ymin); } + int Size(void) const { return(m_size); } + //--- update + void Update(const double &y[]); + void Update(const double &x[],const double &y[]); + void Update(const CPoint2D &points[]); + void Update(CurveFunction function,const double from,const double to,const double step); + //--- gets or sets general options + uint Color(void) const { return(m_clr); } + int Type(void) const { return(m_type); } + string Name(void) const { return(m_name); } + bool Visible(void) const { return(m_visible); } + void Color(const uint clr) { m_clr=clr; } + void Type(const int type) { m_type=(ENUM_CURVE_TYPE)type; } + void Name(const string name) { m_name=name; } + void Visible(const bool visible) { m_visible=visible; } + //--- gets or sets the lines properties + ENUM_LINE_STYLE LinesStyle(void) const { return(m_lines_style); } + ENUM_LINE_END LinesEndStyle(void) const { return(m_lines_end_style); } + int LinesWidth(void) const { return(m_lines_width); } + bool LinesSmooth(void) const { return(m_lines_smooth); } + double LinesSmoothTension(void) const { return(m_lines_tension); } + double LinesSmoothStep(void) const { return(m_lines_step); } + void LinesStyle(ENUM_LINE_STYLE style) { m_lines_style=style; } + void LinesEndStyle(ENUM_LINE_END end_style) { m_lines_end_style=end_style; } + void LinesWidth(const int width) { m_lines_width=width; } + void LinesSmooth(const bool smooth) { m_lines_smooth=smooth; } + void LinesSmoothTension(const double tension) { m_lines_tension=tension; } + void LinesSmoothStep(const double step) { m_lines_step=step; } + //--- gets or sets the points properties + int PointsSize(void) const { return(m_points_size); } + ENUM_POINT_TYPE PointsType(void) const { return(m_points_type); } + bool PointsFill(void) const { return(m_points_fill); } + uint PointsColor(void) const { return(m_points_clr); } + void PointsSize(const int size) { m_points_size=size; } + void PointsType(ENUM_POINT_TYPE type) { m_points_type=type; } + void PointsFill(const bool fill) { m_points_fill=fill; } + void PointsColor(const uint clr) { m_points_clr=clr; } + //--- gets or sets the steps properties + int StepsDimension(void) const { return(m_steps_dimension); } + void StepsDimension(const int dimension) { m_steps_dimension=dimension; } + //--- gets or sets the histogram properties + int HistogramWidth(void) const { return(m_hisogram_width); } + void HistogramWidth(const int width) { m_hisogram_width=width; } + //--- gets or sets the custom properties + PlotFucntion CustomPlotFunction(void) const { return(m_custom_plot_func); } + void *CustomPlotCBData(void) const { return(m_custom_plot_cbdata); } + void CustomPlotFunction(PlotFucntion func) { m_custom_plot_func=func; } + void CustomPlotCBData(void *cbdata) { m_custom_plot_cbdata=cbdata; } + //--- gets or sets the trend line properties + bool TrendLineVisible(void) const { return(m_trend_visible); } + uint TrendLineColor(void) const { return(m_trend_clr); } + void TrendLineVisible(const bool visible) { m_trend_visible=visible; } + void TrendLineColor(const uint clr) { m_trend_clr=clr; } + void TrendLineCoefficients(double &coefficients[]); + +protected: + virtual void CalculateCoefficients(void); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CCurve::CCurve(const double &y[],const uint clr,ENUM_CURVE_TYPE type,const string name) + : m_name(name), + m_clr(clr), + m_type(type), + m_visible(false), + m_lines_style(STYLE_SOLID), + m_lines_end_style(LINE_END_ROUND), + m_lines_width(1), + m_lines_smooth(false), + m_lines_tension(0.5), + m_lines_step(1.0), + m_points_size(6), + m_points_type(POINT_CIRCLE), + m_points_fill(false), + m_points_clr(clr), + m_steps_dimension(0), + m_hisogram_width(1), + m_custom_plot_func(NULL), + m_custom_plot_cbdata(NULL), + m_trend_visible(false), + m_trend_clr(clr), + m_trend_calc(false) + { +//--- keep y array + m_size=ArraySize(y); + ArrayResize(m_x,m_size); + ArrayCopy(m_y,y); + m_xmax = m_size-1; + m_xmin = 0.0; + m_ymax = 0.0; + m_ymin = 0.0; + bool yvalid=false; +//--- find min and max values + for(int i=0; iy[i]) + m_ymin=y[i]; + } + } + } +//--- + } +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CCurve::CCurve(const double &x[],const double &y[],const uint clr,ENUM_CURVE_TYPE type,const string name) + : m_name(name), + m_clr(clr), + m_type(type), + m_visible(false), + m_lines_style(STYLE_SOLID), + m_lines_end_style(LINE_END_ROUND), + m_lines_width(1), + m_lines_smooth(false), + m_lines_tension(0.5), + m_lines_step(1.0), + m_points_size(6), + m_points_type(POINT_CIRCLE), + m_points_fill(false), + m_points_clr(clr), + m_steps_dimension(0), + m_hisogram_width(1), + m_custom_plot_func(NULL), + m_custom_plot_cbdata(NULL), + m_trend_visible(false), + m_trend_clr(clr), + m_trend_calc(false) + { +//--- keep x and y array + ArrayCopy(m_x,x); + ArrayCopy(m_y,y); + m_size = ArraySize(x); + m_xmax = 0.0; + m_xmin = 0.0; + m_ymax = 0.0; + m_ymin = 0.0; + bool yvalid=false; + bool xvalid=false; +//--- find min and max values + for(int i=0; ix[i]) + m_xmin=x[i]; + } + } + if(MathIsValidNumber(m_y[i])) + { + if(!yvalid) + { + m_ymax = y[i]; + m_ymin = y[i]; + yvalid=true; + } + else + { + //--- find max and min of y + if(m_ymaxy[i]) + m_ymin=y[i]; + } + } + } +//--- + } +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CCurve::CCurve(const CPoint2D &points[],const uint clr,ENUM_CURVE_TYPE type,const string name) + : m_name(name), + m_clr(clr), + m_type(type), + m_visible(false), + m_lines_style(STYLE_SOLID), + m_lines_end_style(LINE_END_ROUND), + m_lines_width(1), + m_lines_smooth(false), + m_lines_tension(0.5), + m_lines_step(1.0), + m_points_size(6), + m_points_type(POINT_CIRCLE), + m_points_fill(false), + m_points_clr(clr), + m_steps_dimension(0), + m_hisogram_width(1), + m_custom_plot_func(NULL), + m_custom_plot_cbdata(NULL), + m_trend_visible(false), + m_trend_clr(clr), + m_trend_calc(false) + { +//--- preliminary calculation + m_size=ArraySize(points); + ArrayResize(m_x,m_size); + ArrayResize(m_y,m_size); + m_xmax = 0.0; + m_xmin = 0.0; + m_ymax = 0.0; + m_ymin = 0.0; + bool xvalid=false; + bool yvalid=false; +//--- keep x and y array + for(int i=0; im_x[i]) + m_xmin=m_x[i]; + } + } + if(MathIsValidNumber(m_y[i])) + { + if(!yvalid) + { + m_ymax = m_y[i]; + m_ymin = m_y[i]; + yvalid=true; + } + else + { + //--- find max and min of y + if(m_ymaxm_y[i]) + m_ymin=m_y[i]; + } + } + } +//--- + } +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CCurve::CCurve(CurveFunction function,const double from,const double to,const double step,const uint clr,ENUM_CURVE_TYPE type,const string name) + : m_name(name), + m_clr(clr), + m_type(type), + m_visible(false), + m_lines_style(STYLE_SOLID), + m_lines_end_style(LINE_END_ROUND), + m_lines_width(1), + m_lines_smooth(false), + m_lines_tension(0.5), + m_lines_step(1.0), + m_points_size(6), + m_points_type(POINT_CIRCLE), + m_points_fill(false), + m_points_clr(clr), + m_steps_dimension(0), + m_hisogram_width(1), + m_custom_plot_func(NULL), + m_custom_plot_cbdata(NULL), + m_trend_visible(false), + m_trend_clr(clr), + m_trend_calc(false) + { +//--- preliminary calculation + m_size=(int)((to-from)/step)+1; + ArrayResize(m_x,m_size); + ArrayResize(m_y,m_size); + m_xmax = to; + m_xmin = from; + m_ymax = 0.0; + m_ymin = 0.0; + bool yvalid=false; +//--- keep x and y array + for(int i=0; im_y[i]) + m_ymin=m_y[i]; + } + } + } +//--- + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CCurve::~CCurve(void) + { + } +//+------------------------------------------------------------------+ +//| Update x and y coordinates of curve | +//+------------------------------------------------------------------+ +void CCurve::Update(const double &y[]) + { + m_trend_calc=false; + ArrayFree(m_y); + int size=ArraySize(y); +//--- keep y array + if(m_size!=size) + { + m_size=size; + ArrayResize(m_x,m_size); + } + ArrayCopy(m_y,y); + m_xmax = m_size-1; + m_xmin = 0.0; + m_ymax = 0.0; + m_ymin = 0.0; + bool yvalid=false; +//--- find min and max values + for(int i=0; iy[i]) + m_ymin=y[i]; + } + } + } +//--- + } +//+------------------------------------------------------------------+ +//| Update x and y coordinates of curve | +//+------------------------------------------------------------------+ +void CCurve::Update(const double &x[],const double &y[]) + { + m_trend_calc=false; + ArrayFree(m_x); + ArrayFree(m_y); +//--- keep x and y array + ArrayCopy(m_x,x); + ArrayCopy(m_y,y); + m_size = ArraySize(x); + m_xmax = 0.0; + m_xmin = 0.0; + m_ymax = 0.0; + m_ymin = 0.0; + bool yvalid=false; + bool xvalid=false; +//--- find min and max values + for(int i=0; ix[i]) + m_xmin=x[i]; + } + } + if(MathIsValidNumber(m_y[i])) + { + if(!yvalid) + { + m_ymax = y[i]; + m_ymin = y[i]; + yvalid=true; + } + else + { + //--- find max and min of y + if(m_ymaxy[i]) + m_ymin=y[i]; + } + } + } +//--- + } +//+------------------------------------------------------------------+ +//| Update x and y coordinates of curve | +//+------------------------------------------------------------------+ +void CCurve::Update(const CPoint2D &points[]) + { + m_trend_calc=false; + int size=ArraySize(points); +//--- preliminary calculation + if(size!=m_size) + { + m_size=size; + ArrayResize(m_x,m_size); + ArrayResize(m_y,m_size); + } + m_xmax = 0.0; + m_xmin = 0.0; + m_ymax = 0.0; + m_ymin = 0.0; + bool xvalid=false; + bool yvalid=false; +//--- keep x and y array + for(int i=0; im_x[i]) + m_xmin=m_x[i]; + } + } + if(MathIsValidNumber(m_y[i])) + { + if(!yvalid) + { + m_ymax = m_y[i]; + m_ymin = m_y[i]; + yvalid=true; + } + else + { + //--- find max and min of y + if(m_ymaxm_y[i]) + m_ymin=m_y[i]; + } + } + } +//--- + } +//+------------------------------------------------------------------+ +//| Update x and y coordinates of curve | +//+------------------------------------------------------------------+ +void CCurve::Update(CurveFunction function,const double from,const double to,const double step) + { + m_trend_calc=false; + int size=(int)((to-from)/step)+1; +//--- preliminary calculation + if(size!=m_size) + { + m_size=size; + ArrayResize(m_x,m_size); + ArrayResize(m_y,m_size); + } + m_xmax = to; + m_xmin = from; + m_ymax = 0.0; + m_ymin = 0.0; + bool yvalid=false; +//--- keep x and y array + for(int i=0; im_y[i]) + m_ymin=m_y[i]; + } + } + } +//--- + } +//+------------------------------------------------------------------+ +//| Gets the coefficients for trend line | +//+------------------------------------------------------------------+ +void CCurve::TrendLineCoefficients(double &coefficients[]) + { + if(!m_trend_calc) + { + CalculateCoefficients(); + m_trend_calc=true; + } + ArrayCopy(coefficients,m_trend_coeff); + } +//+------------------------------------------------------------------+ +//| Calculate coefficients | +//+------------------------------------------------------------------+ +void CCurve::CalculateCoefficients(void) + { +//--- simple linear resgression + ArrayResize(m_trend_coeff,2); + double xmean=0.0; + double ymean=0.0; + double sum_xy=0.0; + double sum_xx=0.0; +//--- primary calculate + for(int i=0; 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 literal 0 HcmV?d00001 diff --git a/Indicators/BillWilliams.mqh b/Indicators/BillWilliams.mqh new file mode 100644 index 0000000..64e37e8 --- /dev/null +++ b/Indicators/BillWilliams.mqh @@ -0,0 +1,761 @@ +//+------------------------------------------------------------------+ +//| BillWilliams.mqh | +//| Copyright 2000-2024, MetaQuotes Ltd. | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#include "Indicator.mqh" +//+------------------------------------------------------------------+ +//| Class CiAC. | +//| Purpose: Class of the "Accelerator Oscillator" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiAC : public CIndicator + { +public: + CiAC(void); + ~CiAC(void); + //--- method of creating + bool Create(const string symbol,const ENUM_TIMEFRAMES period); + //--- methods of access to data of indicator + double Main(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_AC); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiAC::CiAC(void) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiAC::~CiAC(void) + { + } +//+------------------------------------------------------------------+ +//| Create the "Accelerator Oscillator" indicator | +//+------------------------------------------------------------------+ +bool CiAC::Create(const string symbol,const ENUM_TIMEFRAMES period) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iAC(symbol,period); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- idicator successfully created + if(!Initialize(symbol,period)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiAC::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period)); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with special parameters | +//+------------------------------------------------------------------+ +bool CiAC::Initialize(const string symbol,const ENUM_TIMEFRAMES period) + { + if(CreateBuffers(symbol,period,1)) + { + //--- string of status of drawing + m_name ="AC"; + m_status="("+symbol+","+PeriodDescription()+") H="+IntegerToString(m_handle); + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to the buffer of "Accelerator Oscillator" | +//+------------------------------------------------------------------+ +double CiAC::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiAlligator. | +//| Purpose: Class of the "Alligator" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiAlligator : public CIndicator + { +protected: + int m_jaw_period; + int m_jaw_shift; + int m_teeth_period; + int m_teeth_shift; + int m_lips_period; + int m_lips_shift; + ENUM_MA_METHOD m_ma_method; + int m_applied; + +public: + CiAlligator(void); + ~CiAlligator(void); + //--- methods of access to protected data + int JawPeriod(void) const { return(m_jaw_period); } + int JawShift(void) const { return(m_jaw_shift); } + int TeethPeriod(void) const { return(m_teeth_period); } + int TeethShift(void) const { return(m_teeth_shift); } + int LipsPeriod(void) const { return(m_lips_period); } + int LipsShift(void) const { return(m_lips_shift); } + ENUM_MA_METHOD MaMethod(void) const { return(m_ma_method); } + int Applied(void) const { return(m_applied); } + //--- method of creating + bool Create(const string symbol,const ENUM_TIMEFRAMES period, + const int jaw_period,const int jaw_shift, + const int teeth_period,const int teeth_shift, + const int lips_period,const int lips_shift, + const ENUM_MA_METHOD ma_method,const int applied); + //--- methods of access to data of indicator + double Jaw(const int index) const; + double Teeth(const int index) const; + double Lips(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_ALLIGATOR); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int jaw_period,const int jaw_shift, + const int teeth_period,const int teeth_shift, + const int lips_period,const int lips_shift, + const ENUM_MA_METHOD ma_method,const int applied); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiAlligator::CiAlligator(void) : m_jaw_period(-1), + m_jaw_shift(-1), + m_teeth_period(-1), + m_teeth_shift(-1), + m_lips_period(-1), + m_lips_shift(-1), + m_ma_method(WRONG_VALUE), + m_applied(-1) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiAlligator::~CiAlligator(void) + { + } +//+------------------------------------------------------------------+ +//| Create the "Alligator" indicator | +//+------------------------------------------------------------------+ +bool CiAlligator::Create(const string symbol,const ENUM_TIMEFRAMES period, + const int jaw_period,const int jaw_shift, + const int teeth_period,const int teeth_shift, + const int lips_period,const int lips_shift, + const ENUM_MA_METHOD ma_method,const int applied) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iAlligator(symbol,period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- idicator successfully created + if(!Initialize(symbol,period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiAlligator::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value, + (int)params[2].integer_value,(int)params[3].integer_value, + (int)params[4].integer_value,(int)params[5].integer_value, + (ENUM_MA_METHOD)params[6].integer_value,(int)params[7].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with special parameters | +//+------------------------------------------------------------------+ +bool CiAlligator::Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int jaw_period,const int jaw_shift, + const int teeth_period,const int teeth_shift, + const int lips_period,const int lips_shift, + const ENUM_MA_METHOD ma_method,const int applied) + { + if(CreateBuffers(symbol,period,3)) + { + //--- string of status of drawing + m_name ="Alligator"; + m_status="("+symbol+","+PeriodDescription()+","+ + IntegerToString(jaw_period)+","+IntegerToString(jaw_shift)+","+ + IntegerToString(teeth_period)+","+IntegerToString(teeth_shift)+","+ + IntegerToString(lips_period)+","+IntegerToString(lips_shift)+","+ + MethodDescription(ma_method)+","+PriceDescription(applied)+") H="+IntegerToString(m_handle); + //--- save settings + m_jaw_period =jaw_period; + m_jaw_shift =jaw_shift; + m_teeth_period=teeth_period; + m_teeth_shift =teeth_shift; + m_lips_period =lips_period; + m_lips_shift =lips_shift; + m_ma_method =ma_method; + m_applied =applied; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("JAW_LINE"); + ((CIndicatorBuffer*)At(0)).Offset(jaw_shift); + ((CIndicatorBuffer*)At(1)).Name("TEETH_LINE"); + ((CIndicatorBuffer*)At(1)).Offset(teeth_shift); + ((CIndicatorBuffer*)At(2)).Name("LIPS_LINE"); + ((CIndicatorBuffer*)At(2)).Offset(lips_shift); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to Jaw buffer of "Alligator" | +//+------------------------------------------------------------------+ +double CiAlligator::Jaw(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Access to Teeth buffer of "Alligator" | +//+------------------------------------------------------------------+ +double CiAlligator::Teeth(const int index) const + { + CIndicatorBuffer *buffer=At(1); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Access to Lips buffer of "Alligator" | +//+------------------------------------------------------------------+ +double CiAlligator::Lips(const int index) const + { + CIndicatorBuffer *buffer=At(2); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiAO. | +//| Purpose: Class of the "Awesome Oscillator" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiAO : public CIndicator + { +public: + CiAO(void); + ~CiAO(void); + //--- method of creating + bool Create(const string symbol,const ENUM_TIMEFRAMES period); + //--- methods of access to data of indicator + double Main(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_AO); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiAO::CiAO(void) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiAO::~CiAO(void) + { + } +//+------------------------------------------------------------------+ +//| Create the "Awesome Oscillator" indicator | +//+------------------------------------------------------------------+ +bool CiAO::Create(const string symbol,const ENUM_TIMEFRAMES period) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iAO(symbol,period); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfullly created + if(!Initialize(symbol,period)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiAO::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period)); + } +//+------------------------------------------------------------------+ +//| Create the "Awesome Oscillator" indicator | +//+------------------------------------------------------------------+ +bool CiAO::Initialize(const string symbol,const ENUM_TIMEFRAMES period) + { + if(CreateBuffers(symbol,period,1)) + { + //--- string of status of drawing + m_status="AO("+symbol+","+PeriodDescription()+") H="+IntegerToString(m_handle); + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to buffer of "Awesome Oscillator" | +//+------------------------------------------------------------------+ +double CiAO::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiFractals. | +//| Purpose: Class of the "Fractals" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiFractals : public CIndicator + { +public: + CiFractals(void); + ~CiFractals(void); + //--- method of creating + bool Create(const string symbol,const ENUM_TIMEFRAMES period); + //--- methods of access to indicator data + double Upper(const int index) const; + double Lower(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_FRACTALS); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiFractals::CiFractals(void) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiFractals::~CiFractals(void) + { + } +//+------------------------------------------------------------------+ +//| Create the "Fractals" indicator | +//+------------------------------------------------------------------+ +bool CiFractals::Create(const string symbol,const ENUM_TIMEFRAMES period) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iFractals(symbol,period); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- idicator successfully created + if(!Initialize(symbol,period)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiFractals::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period)); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with special parameters | +//+------------------------------------------------------------------+ +bool CiFractals::Initialize(const string symbol,const ENUM_TIMEFRAMES period) + { + if(CreateBuffers(symbol,period,2)) + { + //--- string of status of drawing + m_name ="Fractals"; + m_status="("+symbol+","+PeriodDescription()+") H="+IntegerToString(m_handle); + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("UPPER_LINE"); + ((CIndicatorBuffer*)At(1)).Name("LOWER_LINE"); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to Upper buffer of "Fractals" | +//+------------------------------------------------------------------+ +double CiFractals::Upper(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Access to Lower buffer of "Fractals" | +//+------------------------------------------------------------------+ +double CiFractals::Lower(const int index) const + { + CIndicatorBuffer *buffer=At(1); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiGator. | +//| Purpose: Class of the "Gator oscillator" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiGator : public CIndicator + { +protected: + int m_jaw_period; + int m_jaw_shift; + int m_teeth_period; + int m_teeth_shift; + int m_lips_period; + int m_lips_shift; + ENUM_MA_METHOD m_ma_method; + int m_applied; + +public: + CiGator(void); + ~CiGator(void); + //--- methods of access to protected data + int JawPeriod(void) const { return(m_jaw_period); } + int JawShift(void) const { return(m_jaw_shift); } + int TeethPeriod(void) const { return(m_teeth_period); } + int TeethShift(void) const { return(m_teeth_shift); } + int LipsPeriod(void) const { return(m_lips_period); } + int LipsShift(void) const { return(m_lips_shift); } + ENUM_MA_METHOD MaMethod(void) const { return(m_ma_method); } + int Applied(void) const { return(m_applied); } + //--- method of creating + bool Create(const string symbol,const ENUM_TIMEFRAMES period, + const int jaw_period,const int jaw_shift, + const int teeth_period,const int teeth_shift, + const int lips_period,const int lips_shift, + const ENUM_MA_METHOD ma_method,const int applied); + //--- methods of access to data of indicator + double Upper(const int index) const; + double Lower(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_GATOR); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int jaw_period,const int jaw_shift, + const int teeth_period,const int teeth_shift, + const int lips_period,const int lips_shift, + const ENUM_MA_METHOD ma_method,const int applied); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiGator::CiGator(void) : m_jaw_period(-1), + m_jaw_shift(-1), + m_teeth_period(-1), + m_teeth_shift(-1), + m_lips_period(-1), + m_lips_shift(-1), + m_ma_method(WRONG_VALUE), + m_applied(-1) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiGator::~CiGator(void) + { + } +//+------------------------------------------------------------------+ +//| Create indicator "Gator oscillator" | +//+------------------------------------------------------------------+ +bool CiGator::Create(const string symbol,const ENUM_TIMEFRAMES period, + const int jaw_period,const int jaw_shift, + const int teeth_period,const int teeth_shift, + const int lips_period,const int lips_shift, + const ENUM_MA_METHOD ma_method,const int applied) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iGator(symbol,period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- idicator successfully created + if(!Initialize(symbol,period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiGator::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value, + (int)params[2].integer_value,(int)params[3].integer_value, + (int)params[4].integer_value,(int)params[5].integer_value, + (ENUM_MA_METHOD)params[6].integer_value,(int)params[7].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with special parameters | +//+------------------------------------------------------------------+ +bool CiGator::Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int jaw_period,const int jaw_shift, + const int teeth_period,const int teeth_shift, + const int lips_period,const int lips_shift, + const ENUM_MA_METHOD ma_method,const int applied) + { + if(CreateBuffers(symbol,period,2)) + { + //--- string of status drawing + m_name ="Gator"; + m_status="("+symbol+","+PeriodDescription()+","+ + IntegerToString(jaw_period)+","+IntegerToString(jaw_shift)+","+ + IntegerToString(teeth_period)+","+IntegerToString(teeth_shift)+","+ + IntegerToString(lips_period)+","+IntegerToString(lips_shift)+","+ + MethodDescription(ma_method)+","+PriceDescription(applied)+") H="+IntegerToString(m_handle); + //--- save settings + m_jaw_period =jaw_period; + m_jaw_shift =jaw_shift; + m_teeth_period=teeth_period; + m_teeth_shift =teeth_shift; + m_lips_period =lips_period; + m_lips_shift =lips_shift; + m_ma_method =ma_method; + m_applied =applied; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("UPPER_LINE"); + ((CIndicatorBuffer*)At(0)).Offset(teeth_shift); + ((CIndicatorBuffer*)At(1)).Name("LOWER_LINE"); + ((CIndicatorBuffer*)At(1)).Offset(lips_shift); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to Upper buffer of "Gator oscillator" | +//+------------------------------------------------------------------+ +double CiGator::Upper(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Access to Lower buffer of "Gator oscillator" | +//+------------------------------------------------------------------+ +double CiGator::Lower(const int index) const + { + CIndicatorBuffer *buffer=At(1); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiBWMFI. | +//| Purpose: Class of the "Market Facilitation Index" indicator | +//| by Bill Williams". | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiBWMFI : public CIndicator + { +protected: + ENUM_APPLIED_VOLUME m_applied; + +public: + CiBWMFI(void); + ~CiBWMFI(void); + //--- methods of access to protected data + ENUM_APPLIED_VOLUME Applied(void) const { return(m_applied); } + //--- method of creating + bool Create(const string symbol,const ENUM_TIMEFRAMES period,const ENUM_APPLIED_VOLUME applied); + //--- methods of access to data of indicator + double Main(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_BWMFI); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const ENUM_APPLIED_VOLUME applied); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiBWMFI::CiBWMFI(void) : m_applied(WRONG_VALUE) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiBWMFI::~CiBWMFI(void) + { + } +//+------------------------------------------------------------------+ +//| Create "Market Facilitation Index by Bill Williams" indicator | +//+------------------------------------------------------------------+ +bool CiBWMFI::Create(const string symbol,const ENUM_TIMEFRAMES period,const ENUM_APPLIED_VOLUME applied) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iBWMFI(symbol,period,applied); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- idicator successfully created + if(!Initialize(symbol,period,applied)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiBWMFI::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(ENUM_APPLIED_VOLUME)params[0].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize indicator with the special parameters | +//+------------------------------------------------------------------+ +bool CiBWMFI::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const ENUM_APPLIED_VOLUME applied) + { + if(CreateBuffers(symbol,period,1)) + { + //--- string of status of drawing + m_name ="BWMFI"; + m_status="BWMFI("+symbol+","+PeriodDescription()+","+VolumeDescription(applied)+") H="+IntegerToString(m_handle); + //--- save settings + m_applied=applied; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to buffer of "Market Facilitation Index by Bill Williams".| +//+------------------------------------------------------------------+ +double CiBWMFI::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ diff --git a/Indicators/Custom.mqh b/Indicators/Custom.mqh new file mode 100644 index 0000000..aa9c513 --- /dev/null +++ b/Indicators/Custom.mqh @@ -0,0 +1,194 @@ +//+------------------------------------------------------------------+ +//| Custom.mqh | +//| Copyright 2000-2024, MetaQuotes Ltd. | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#include "Indicator.mqh" +//+------------------------------------------------------------------+ +//| Class CiCustom. | +//| Purpose: Class of custom indicators. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiCustom : public CIndicator + { +protected: + int m_num_params; // number of creation parameters + MqlParam m_params[]; // creation parameters + +public: + CiCustom(void); + ~CiCustom(void); + //--- methods of access to protected data + bool NumBuffers(const int buffers); + int NumParams(void) const { return(m_num_params); } + ENUM_DATATYPE ParamType(const int ind) const; + long ParamLong(const int ind) const; + double ParamDouble(const int ind) const; + string ParamString(const int ind) const; + //--- method of identifying + virtual int Type(void) const { return(IND_CUSTOM); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiCustom::CiCustom(void) : m_num_params(0) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiCustom::~CiCustom(void) + { + } +//+------------------------------------------------------------------+ +//| Set number of buffers of indicator | +//+------------------------------------------------------------------+ +bool CiCustom::NumBuffers(const int buffers) + { + bool result=true; +//--- + if(m_buffers_total==0) + { + m_buffers_total=buffers; + return(true); + } + if(m_buffers_total!=buffers) + { + Shutdown(); + result=CreateBuffers(m_symbol,m_period,buffers); + if(result) + { + //--- create buffers + for(int i=0;i=m_num_params) + return(WRONG_VALUE); +//--- + return(m_params[ind].type); + } +//+------------------------------------------------------------------+ +//| Get specified parameter of creatiob as a long value | +//+------------------------------------------------------------------+ +long CiCustom::ParamLong(const int ind) const + { + if(ind>=m_num_params) + return(0); + switch(m_params[ind].type) + { + case TYPE_DOUBLE: + case TYPE_FLOAT: + case TYPE_STRING: + return(0); + } +//--- + return(m_params[ind].integer_value); + } +//+------------------------------------------------------------------+ +//| Get specified parameter of creation as a double value | +//+------------------------------------------------------------------+ +double CiCustom::ParamDouble(const int ind) const + { + if(ind>=m_num_params) + return(EMPTY_VALUE); + switch(m_params[ind].type) + { + case TYPE_DOUBLE: + case TYPE_FLOAT: + break; + default: + return(EMPTY_VALUE); + } +//--- + return(m_params[ind].double_value); + } +//+------------------------------------------------------------------+ +//| Get specified parameter of creation as a string value | +//+------------------------------------------------------------------+ +string CiCustom::ParamString(const int ind) const + { + if(ind>=m_num_params || m_params[ind].type!=TYPE_STRING) + return(""); +//--- + return(m_params[ind].string_value); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiCustom::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + int i; +//--- tune + if(m_buffers_total==0) + m_buffers_total=256; + if(CreateBuffers(symbol,period,m_buffers_total)) + { + //--- string of status of drawing + m_name ="Custom "+params[0].string_value; + m_status="("+symbol+","+PeriodDescription(); + for(i=1;i0); + } +//+------------------------------------------------------------------+ +//| Refreshing of the data in buffer | +//+------------------------------------------------------------------+ +bool CIndicatorBuffer::RefreshCurrent(const int handle,const int num) + { + double array[1]; +//--- check + if(handle==INVALID_HANDLE) + { + SetUserError(ERR_USER_INVALID_HANDLE); + return(false); + } +//--- + if(CopyBuffer(handle,num,-m_offset,1,array)>0 && m_data_total>0) + { + m_data[0]=array[0]; + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Class CIndicator. | +//| Purpose: Base class of technical indicators. | +//| Derives from class CSeries. | +//+------------------------------------------------------------------+ +class CIndicator : public CSeries + { +protected: + int m_handle; // indicator handle + string m_status; // status of creation + bool m_full_release; // flag + bool m_redrawer; // flag + +public: + CIndicator(void); + ~CIndicator(void); + //--- methods of access to protected data + int Handle(void) const { return(m_handle); } + string Status(void) const { return(m_status); } + void FullRelease(const bool flag=true) { m_full_release=flag; } + void Redrawer(const bool flag=true) { m_redrawer=flag; } + //--- method for creating + bool Create(const string symbol,const ENUM_TIMEFRAMES period, + const ENUM_INDICATOR type,const int num_params,const MqlParam ¶ms[]); + virtual bool BufferResize(const int size); + //--- methods of access to data + int BarsCalculated(void) const; + double GetData(const int buffer_num,const int index) const; + int GetData(const int start_pos,const int count,const int buffer_num,double &buffer[]) const; + int GetData(const datetime start_time,const int count,const int buffer_num,double &buffer[]) const; + int GetData(const datetime start_time,const datetime stop_time,const int buffer_num,double &buffer[]) const; + //--- methods for find extremum + int Minimum(const int buffer_num,const int start,const int count) const; + double MinValue(const int buffer_num,const int start,const int count,int &index) const; + int Maximum(const int buffer_num,const int start,const int count) const; + double MaxValue(const int buffer_num,const int start,const int count,int &index) const; + //--- method of "freshening" of the data + virtual void Refresh(const int flags=OBJ_ALL_PERIODS); + //--- methods for working with chart + bool AddToChart(const long chart,const int subwin); + bool DeleteFromChart(const long chart,const int subwin); + //--- methods of conversion of constants to strings + static string MethodDescription(const int val); + static string PriceDescription(const int val); + static string VolumeDescription(const int val); + +protected: + //--- methods of tuning + bool CreateBuffers(const string symbol,const ENUM_TIMEFRAMES period,const int buffers); + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int num_params,const MqlParam ¶ms[]) {return(false);} + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +void CIndicator::CIndicator(void) : m_handle(INVALID_HANDLE), + m_status(""), + m_full_release(false), + m_redrawer(false) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +void CIndicator::~CIndicator(void) + { +//--- indicator handle release + if(m_full_release && m_handle!=INVALID_HANDLE) + { + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + } + } +//+------------------------------------------------------------------+ +//| Creation of the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CIndicator::Create(const string symbol,const ENUM_TIMEFRAMES period, + const ENUM_INDICATOR type,const int num_params,const MqlParam ¶ms[]) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=IndicatorCreate(symbol,period,type,num_params,params); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- idicator successfully created + if(!Initialize(symbol,period,num_params,params)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Returns the amount of calculated indicator data | +//+------------------------------------------------------------------+ +int CIndicator::BarsCalculated(void) const + { + if(m_handle==INVALID_HANDLE) + return(-1); +//--- + return(::BarsCalculated(m_handle)); + } +//+------------------------------------------------------------------+ +//| API access method "Copying an element of indicator buffer | +//| by specifying number of buffer and position of element" | +//+------------------------------------------------------------------+ +double CIndicator::GetData(const int buffer_num,const int index) const + { + CIndicatorBuffer *buffer=At(buffer_num); +//--- check + if(buffer==NULL) + { + Print(__FUNCTION__,": invalid buffer"); + return(EMPTY_VALUE); + } +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| API access method "Copying the buffer of indicator by specifying | +//| a start position and number of elements" | +//+------------------------------------------------------------------+ +int CIndicator::GetData(const int start_pos,const int count,const int buffer_num,double &buffer[]) const + { +//--- check + if(m_handle==INVALID_HANDLE) + { + SetUserError(ERR_USER_INVALID_HANDLE); + return(-1); + } + if(buffer_num>=m_buffers_total) + { + SetUserError(ERR_USER_INVALID_BUFF_NUM); + return(-1); + } +//--- + return(CopyBuffer(m_handle,buffer_num,start_pos,count,buffer)); + } +//+------------------------------------------------------------------+ +//| API access method "Copying the buffer of indicator by specifying | +//| start time and number of elements" | +//+------------------------------------------------------------------+ +int CIndicator::GetData(const datetime start_time,const int count,const int buffer_num,double &buffer[]) const + { +//--- check + if(m_handle==INVALID_HANDLE) + { + SetUserError(ERR_USER_INVALID_HANDLE); + return(-1); + } + if(buffer_num>=m_buffers_total) + { + SetUserError(ERR_USER_INVALID_BUFF_NUM); + return(-1); + } +//--- + return(CopyBuffer(m_handle,buffer_num,start_time,count,buffer)); + } +//+------------------------------------------------------------------+ +//| API access method "Copying the buffer of indicator by specifying | +//| start and final time | +//+------------------------------------------------------------------+ +int CIndicator::GetData(const datetime start_time,const datetime stop_time,const int buffer_num,double &buffer[]) const + { +//--- check + if(m_handle==INVALID_HANDLE) + { + SetUserError(ERR_USER_INVALID_HANDLE); + return(-1); + } + if(buffer_num>=m_buffers_total) + { + SetUserError(ERR_USER_INVALID_BUFF_NUM); + return(-1); + } +//--- + return(CopyBuffer(m_handle,buffer_num,start_time,stop_time,buffer)); + } +//+------------------------------------------------------------------+ +//| Find minimum of a specified buffer | +//+------------------------------------------------------------------+ +int CIndicator::Minimum(const int buffer_num,const int start,const int count) const + { +//--- check + if(m_handle==INVALID_HANDLE) + { + SetUserError(ERR_USER_INVALID_HANDLE); + return(-1); + } + if(buffer_num>=m_buffers_total) + { + SetUserError(ERR_USER_INVALID_BUFF_NUM); + return(-1); + } +//--- + CIndicatorBuffer *buffer=At(buffer_num); + if(buffer==NULL) + return(-1); +//--- + return(buffer.Minimum(start,count)); + } +//+------------------------------------------------------------------+ +//| Find minimum of a specified buffer | +//+------------------------------------------------------------------+ +double CIndicator::MinValue(const int buffer_num,const int start,const int count,int &index) const + { + int idx=Minimum(buffer_num,start,count); + double res=EMPTY_VALUE; +//--- check + if(idx!=-1) + { + CIndicatorBuffer *buffer=At(buffer_num); + res=buffer.At(idx); + index=idx; + } +//--- + return(res); + } +//+------------------------------------------------------------------+ +//| Find maximum of a specified buffer | +//+------------------------------------------------------------------+ +int CIndicator::Maximum(const int buffer_num,const int start,const int count) const + { +//--- check + if(m_handle==INVALID_HANDLE) + { + SetUserError(ERR_USER_INVALID_HANDLE); + return(-1); + } + if(buffer_num>=m_buffers_total) + { + SetUserError(ERR_USER_INVALID_BUFF_NUM); + return(-1); + } +//--- + CIndicatorBuffer *buffer=At(buffer_num); + if(buffer==NULL) + return(-1); +//--- + return(buffer.Maximum(start,count)); + } +//+------------------------------------------------------------------+ +//| Find maximum of specified buffer | +//+------------------------------------------------------------------+ +double CIndicator::MaxValue(const int buffer_num,const int start,const int count,int &index) const + { + int idx=Maximum(buffer_num,start,count); + double res=EMPTY_VALUE; +//--- check + if(idx!=-1) + { + CIndicatorBuffer *buffer=At(buffer_num); + res=buffer.At(idx); + index=idx; + } +//--- + return(res); + } +//+------------------------------------------------------------------+ +//| Creating data buffers of indicator | +//+------------------------------------------------------------------+ +bool CIndicator::CreateBuffers(const string symbol,const ENUM_TIMEFRAMES period,const int buffers) + { + bool result=true; +//--- check + if(m_handle==INVALID_HANDLE) + { + SetUserError(ERR_USER_INVALID_HANDLE); + return(false); + } + if(buffers==0) + return(false); + if(!Reserve(buffers)) + return(false); +//--- + for(int i=0;im_buffer_size && !CSeries::BufferResize(size)) + return(false); +//-- history is avalible + int total=Total(); + for(int i=0;i=10) + return("AppliedHandle="+IntegerToString(val)); + //--- + break; + } +//--- wrong value + return("PriceUnknown="+IntegerToString(val)); + } +//+------------------------------------------------------------------+ +//| Converting value of ENUM_APPLIED_VOLUME into string | +//+------------------------------------------------------------------+ +string CIndicator::VolumeDescription(const int val) + { +//--- select by value + switch(val) + { + case ENUM_APPLIED_VOLUME::VOLUME_TICK: + return("Tick"); + case ENUM_APPLIED_VOLUME::VOLUME_REAL: + return("Real"); + } +//--- wrong value + return("VolumeUnknown="+IntegerToString(val)); + } +//+------------------------------------------------------------------+ diff --git a/Indicators/Indicators.mqh b/Indicators/Indicators.mqh new file mode 100644 index 0000000..0cc63fe --- /dev/null +++ b/Indicators/Indicators.mqh @@ -0,0 +1,385 @@ +//+------------------------------------------------------------------+ +//| Indicators.mqh | +//| Copyright 2000-2024, MetaQuotes Ltd. | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#include "Trend.mqh" +#include "Oscilators.mqh" +#include "Volumes.mqh" +#include "BillWilliams.mqh" +#include "Custom.mqh" +#include "TimeSeries.mqh" +//+------------------------------------------------------------------+ +//| Class CIndicators. | +//| Purpose: Class for creation of collection of instances of | +//| technical indicators. | +//+------------------------------------------------------------------+ +class CIndicators : public CArrayObj + { +protected: + MqlDateTime m_prev_time; + +public: + CIndicators(void); + ~CIndicators(void); + //--- method for creation + CIndicator *Create(const string symbol,const ENUM_TIMEFRAMES period, + const ENUM_INDICATOR type,const int count,const MqlParam ¶ms[]); + bool BufferResize(const int size); + //--- method of refreshing of the data of all indicators in the collection + int Refresh(void); +protected: + //--- method of formation of flags timeframes + int TimeframesFlags(const MqlDateTime &time); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CIndicators::CIndicators(void) + { + m_prev_time.min=-1; + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CIndicators::~CIndicators(void) + { + } +//+------------------------------------------------------------------+ +//| Indicator creation | +//+------------------------------------------------------------------+ +CIndicator *CIndicators::Create(const string symbol,const ENUM_TIMEFRAMES period, + const ENUM_INDICATOR type,const int count,const MqlParam ¶ms[]) + { + CIndicator *result=NULL; +//--- + switch(type) + { + case IND_AC: + //--- Identifier of "Accelerator Oscillator" + if(count==0) + result=new CiAC; + break; + case IND_AD: + //--- Identifier of "Accumulation/Distribution" + if(count==1) + result=new CiAD; + break; + case IND_ALLIGATOR: + //--- Identifier of "Alligator" + if(count==8) + result=new CiAlligator; + break; + case IND_ADX: + //--- Identifier of "Average Directional Index" + if(count==1) + result=new CiADX; + break; + case IND_ADXW: + //--- Identifier of "Average Directional Index by Welles Wilder" + if(count==1) + result=new CiADXWilder; + break; + case IND_ATR: + //--- Identifier of "Average True Range" + if(count==1) + result=new CiATR; + break; + case IND_AO: + //--- Identifier of "Awesome Oscillator" + if(count==0) + result=new CiAO; + break; + case IND_BEARS: + //--- Identifier of "Bears Power" + if(count==1) + result=new CiBearsPower; + break; + case IND_BANDS: + //--- Identifier of "Bollinger Bands" + if(count==4) + result=new CiBands; + break; + case IND_BULLS: + //--- Identifier of "Bulls Power" + if(count==1) + result=new CiBullsPower; + break; + case IND_CCI: + //--- Identifier of "Commodity Channel Index" + if(count==2) + result=new CiCCI; + break; + case IND_CHAIKIN: + //--- Identifier of "Chaikin Oscillator" + if(count==4) + result=new CiChaikin; + break; + case IND_DEMARKER: + //--- Identifier of "DeMarker" + if(count==1) + result=new CiDeMarker; + break; + case IND_ENVELOPES: + //--- Identifier of "Envelopes" + if(count==5) + result=new CiEnvelopes; + break; + case IND_FORCE: + //--- Identifier of "Force Index" + if(count==3) + result=new CiForce; + break; + case IND_FRACTALS: + //--- Identifier of "Fractals" + if(count==0) + result=new CiFractals; + break; + case IND_GATOR: + //--- Identifier of "Gator oscillator" + if(count==8) + result=new CiGator; + break; + case IND_ICHIMOKU: + //--- Identifier of "Ichimoku Kinko Hyo" + if(count==3) + result=new CiIchimoku; + break; + case IND_MACD: + //--- Identifier of "Moving Averages Convergence-Divergence" + if(count==4) + result=new CiMACD; + break; + case IND_BWMFI: + //--- Identifier of "Market Facilitation Index by Bill Williams" + if(count==1) + result=new CiBWMFI; + break; + case IND_MOMENTUM: + //--- Identifier of "Momentum" + if(count==2) + result=new CiMomentum; + break; + case IND_MFI: + //--- Identifier of "Money Flow Index" + if(count==2) + result=new CiMFI; + break; + case IND_MA: + //--- Identifier of "Moving Average" + if(count==4) + result=new CiMA; + break; + case IND_OSMA: + //--- Identifier of "Moving Average of Oscillator (MACD histogram)" + if(count==4) + result=new CiOsMA; + break; + case IND_OBV: + //--- Identifier of "On Balance Volume" + if(count==1) + result=new CiOBV; + break; + case IND_SAR: + //--- Identifier of "Parabolic Stop And Reverse System" + if(count==2) + result=new CiSAR; + break; + case IND_RSI: + //--- Identifier of "Relative Strength Index" + if(count==2) + result=new CiRSI; + break; + case IND_RVI: + //--- Identifier of "Relative Vigor Index" + if(count==1) + result=new CiRVI; + break; + case IND_STDDEV: + //--- Identifier of "Standard Deviation" + if(count==4) + result=new CiStdDev; + break; + case IND_STOCHASTIC: + //--- Identifier of "Stochastic Oscillator" + if(count==5) + result=new CiStochastic; + break; + case IND_WPR: + //--- Identifier of "Williams' Percent Range" + if(count==1) + result=new CiWPR; + break; + case IND_DEMA: + //--- Identifier of "Double Exponential Moving Average" + if(count==3) + result=new CiDEMA; + break; + case IND_TEMA: + //--- Identifier of "Triple Exponential Moving Average" + if(count==3) + result=new CiTEMA; + break; + case IND_TRIX: + //--- Identifier of "Triple Exponential Moving Averages Oscillator" + if(count==2) + result=new CiTriX; + break; + case IND_FRAMA: + //--- Identifier of "Fractal Adaptive Moving Average" + if(count==3) + result=new CiFrAMA; + break; + case IND_AMA: + //--- Identifier of "Adaptive Moving Average" + if(count==5) + result=new CiAMA; + break; + case IND_VIDYA: + //--- Identifier of "Variable Index DYnamic Average" + if(count==4) + result=new CiVIDyA; + break; + case IND_VOLUMES: + //--- Identifier of "Volumes" + if(count==1) + result=new CiVolumes; + break; + //--- Identifier of "Custom" + case IND_CUSTOM: + if(count>0) + result=new CiCustom; + break; + } + if(result!=NULL) + { + if(result.Create(symbol,period,type,count,params)) + Add(result); + else + { + delete result; + result=NULL; + } + } +//--- + return(result); + } +//+------------------------------------------------------------------+ +//| Set size of buffers of all indicators in the collection | +//+------------------------------------------------------------------+ +bool CIndicators::BufferResize(const int size) + { + int total=Total(); + for(int i=0;i=delta) + result^=OBJ_PERIOD_H2; + if(curr%3>=delta) + result^=OBJ_PERIOD_H3; + if(curr%4>=delta) + result^=OBJ_PERIOD_H4; + if(curr%6>=delta) + result^=OBJ_PERIOD_H6; + if(curr%8>=delta) + result^=OBJ_PERIOD_H8; + if(curr%12>=delta) + result^=OBJ_PERIOD_H12; + return(result); + } +//--- reset all flags for hour timeframes + result^=OBJ_PERIOD_H1+OBJ_PERIOD_H2+OBJ_PERIOD_H3+OBJ_PERIOD_H4+OBJ_PERIOD_H6+OBJ_PERIOD_H8+OBJ_PERIOD_H12; +//--- new minute? + curr=time.min; + delta=curr-m_prev_time.min; + if(delta!=0) + { + if(curr%2>=delta) + result^=OBJ_PERIOD_M2; + if(curr%3>=delta) + result^=OBJ_PERIOD_M3; + if(curr%4>=delta) + result^=OBJ_PERIOD_M4; + if(curr%5>=delta) + result^=OBJ_PERIOD_M5; + if(curr%6>=delta) + result^=OBJ_PERIOD_M6; + if(curr%10>=delta) + result^=OBJ_PERIOD_M10; + if(curr%12>=delta) + result^=OBJ_PERIOD_M12; + if(curr%15>=delta) + result^=OBJ_PERIOD_M15; + if(curr%20>=delta) + result^=OBJ_PERIOD_M20; + if(curr%30>=delta) + result^=OBJ_PERIOD_M30; + } +//--- + return(result); + } +//+------------------------------------------------------------------+ diff --git a/Indicators/Oscilators.mqh b/Indicators/Oscilators.mqh new file mode 100644 index 0000000..c98f623 --- /dev/null +++ b/Indicators/Oscilators.mqh @@ -0,0 +1,1722 @@ +//+------------------------------------------------------------------+ +//| Oscilators.mqh | +//| Copyright 2000-2024, MetaQuotes Ltd. | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#include "Indicator.mqh" +//+------------------------------------------------------------------+ +//| Class CiATR. | +//| Purpose: Class of the "Average True Range" idnicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiATR : public CIndicator + { +protected: + int m_ma_period; + +public: + CiATR(void); + ~CiATR(void); + //--- methods of access to protected data + int MaPeriod(void) const { return(m_ma_period); } + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period); + //--- methods of access to indicator data + double Main(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_ATR); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiATR::CiATR(void) : m_ma_period(-1) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiATR::~CiATR(void) + { + } +//+------------------------------------------------------------------+ +//| Create the "Average True Range" indicator | +//+------------------------------------------------------------------+ +bool CiATR::Create(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iATR(symbol,period,ma_period); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,ma_period)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiATR::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with special parameters | +//+------------------------------------------------------------------+ +bool CiATR::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period) + { + if(CreateBuffers(symbol,period,1)) + { + //--- string of status of drawing + m_name ="ATR"; + m_status="("+symbol+","+PeriodDescription()+","+IntegerToString(ma_period)+") H="+IntegerToString(m_handle); + //--- save settings + m_ma_period=ma_period; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to buffer of "Average True Range" | +//+------------------------------------------------------------------+ +double CiATR::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiBearsPower. | +//| Purpose: Class indicator "Bears Power". | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiBearsPower : public CIndicator + { +protected: + int m_ma_period; + +public: + CiBearsPower(void); + ~CiBearsPower(void); + //--- methods of access to protected data + int MaPeriod(void) const { return(m_ma_period); } + //--- method create + bool Create(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period); + //--- methods of access to indicator data + double Main(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_BEARS); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiBearsPower::CiBearsPower(void) : m_ma_period(-1) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiBearsPower::~CiBearsPower(void) + { + } +//+------------------------------------------------------------------+ +//| Create the "Bears Power" indicator | +//+------------------------------------------------------------------+ +bool CiBearsPower::Create(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iBearsPower(symbol,period,ma_period); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,ma_period)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiBearsPower::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with special parameters | +//+------------------------------------------------------------------+ +bool CiBearsPower::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period) + { + if(CreateBuffers(symbol,period,1)) + { + //--- string of status of drawing + m_name ="BearsPower"; + m_status="("+symbol+","+PeriodDescription()+","+IntegerToString(ma_period)+") H="+IntegerToString(m_handle); + //--- save settings + m_ma_period=ma_period; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to buffer of "Bears Power" | +//+------------------------------------------------------------------+ +double CiBearsPower::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiBullsPower. | +//| Purpose: Class of the "Bulls Power" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiBullsPower : public CIndicator + { +protected: + int m_ma_period; + +public: + CiBullsPower(void); + ~CiBullsPower(void); + //--- methods of access to protected data + int MaPeriod(void) const { return(m_ma_period); } + //--- method create + bool Create(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period); + //--- methods of access to indicator data + double Main(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_BULLS); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiBullsPower::CiBullsPower(void) : m_ma_period(-1) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiBullsPower::~CiBullsPower(void) + { + } +//+------------------------------------------------------------------+ +//| Create indicator "Bulls Power" | +//+------------------------------------------------------------------+ +bool CiBullsPower::Create(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iBullsPower(symbol,period,ma_period); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,ma_period)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiBullsPower::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with special parameters | +//+------------------------------------------------------------------+ +bool CiBullsPower::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period) + { + if(CreateBuffers(symbol,period,1)) + { + //--- string of status of drawing + m_name ="BullsPower"; + m_status="("+symbol+","+PeriodDescription()+","+IntegerToString(ma_period)+") H="+IntegerToString(m_handle); + //--- save settings + m_ma_period=ma_period; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to buffer of "Bulls Power" | +//+------------------------------------------------------------------+ +double CiBullsPower::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiCCI. | +//| Purpose: Class of the "Commodity Channel Index" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiCCI : public CIndicator + { +protected: + int m_ma_period; + int m_applied; + +public: + CiCCI(void); + ~CiCCI(void); + //--- methods of access to protected data + int MaPeriod(void) const { return(m_ma_period); } + int Applied(void) const { return(m_applied); } + //--- method create + bool Create(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period,const int applied); + //--- methods of access to indicator data + double Main(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_CCI); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period,const int applied); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiCCI::CiCCI(void) : m_ma_period(-1), + m_applied(-1) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiCCI::~CiCCI(void) + { + } +//+------------------------------------------------------------------+ +//| Create the "Commodity Channel Index" indicator | +//+------------------------------------------------------------------+ +bool CiCCI::Create(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period,const int applied) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iCCI(symbol,period,ma_period,applied); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,ma_period,applied)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiCCI::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value)); + } +//+------------------------------------------------------------------+ +//| Create the "Commodity Channel Index" indicator | +//+------------------------------------------------------------------+ +bool CiCCI::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period,const int applied) + { + if(CreateBuffers(symbol,period,1)) + { + //--- string of status of drawing + m_name ="CCI"; + m_status="("+symbol+","+PeriodDescription()+","+ + IntegerToString(ma_period)+","+PriceDescription(applied)+") H="+IntegerToString(m_handle); + //--- save settings + m_ma_period=ma_period; + m_applied =applied; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to buffer of "Commodity Channel Index" | +//+------------------------------------------------------------------+ +double CiCCI::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiChaikin. | +//| Purpose: Class of the "Chaikin Oscillator" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiChaikin : public CIndicator + { +protected: + int m_fast_ma_period; + int m_slow_ma_period; + ENUM_MA_METHOD m_ma_method; + ENUM_APPLIED_VOLUME m_applied; + +public: + CiChaikin(void); + ~CiChaikin(void); + //--- methods of access to protected data + int FastMaPeriod(void) const { return(m_fast_ma_period); } + int SlowMaPeriod(void) const { return(m_slow_ma_period); } + ENUM_MA_METHOD MaMethod(void) const { return(m_ma_method); } + ENUM_APPLIED_VOLUME Applied(void) const { return(m_applied); } + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period, + const int fast_ma_period,const int slow_ma_period, + const ENUM_MA_METHOD ma_method,const ENUM_APPLIED_VOLUME applied); + //--- methods of access to indicator data + double Main(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_CHAIKIN); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int fast_ma_period,const int slow_ma_period, + const ENUM_MA_METHOD ma_method,const ENUM_APPLIED_VOLUME applied); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiChaikin::CiChaikin(void) : m_fast_ma_period(-1), + m_slow_ma_period(-1), + m_ma_method(WRONG_VALUE), + m_applied(WRONG_VALUE) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiChaikin::~CiChaikin(void) + { + } +//+------------------------------------------------------------------+ +//| Create indicator "Chaikin Oscillator" | +//+------------------------------------------------------------------+ +bool CiChaikin::Create(const string symbol,const ENUM_TIMEFRAMES period, + const int fast_ma_period,const int slow_ma_period, + const ENUM_MA_METHOD ma_method,const ENUM_APPLIED_VOLUME applied) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iChaikin(symbol,period,fast_ma_period,slow_ma_period,ma_method,applied); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,fast_ma_period,slow_ma_period,ma_method,applied)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiChaikin::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value, + (ENUM_MA_METHOD)params[2].integer_value,(ENUM_APPLIED_VOLUME)params[3].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with special parameters | +//+------------------------------------------------------------------+ +bool CiChaikin::Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int fast_ma_period,const int slow_ma_period, + const ENUM_MA_METHOD ma_method,const ENUM_APPLIED_VOLUME applied) + { + if(CreateBuffers(symbol,period,1)) + { + //--- string of status of drawing + m_name ="Chaikin"; + m_status="("+symbol+","+PeriodDescription()+","+ + IntegerToString(fast_ma_period)+","+IntegerToString(slow_ma_period)+","+ + MethodDescription(ma_method)+","+PriceDescription(applied)+") H="+IntegerToString(m_handle); + //--- save settings + m_fast_ma_period=fast_ma_period; + m_slow_ma_period=slow_ma_period; + m_ma_method =ma_method; + m_applied =applied; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to buffer of "Chaikin Oscillator" | +//+------------------------------------------------------------------+ +double CiChaikin::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiDeMarker. | +//| Purpose: Class of the "DeMarker" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiDeMarker : public CIndicator + { +protected: + int m_ma_period; + +public: + CiDeMarker(void); + ~CiDeMarker(void); + //--- methods of access to protected data + int MaPeriod(void) const { return(m_ma_period); } + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period); + //--- methods of access to indicator data + double Main(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_DEMARKER); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiDeMarker::CiDeMarker(void) : m_ma_period(-1) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiDeMarker::~CiDeMarker(void) + { + } +//+------------------------------------------------------------------+ +//| Create indicator "DeMarker" | +//+------------------------------------------------------------------+ +bool CiDeMarker::Create(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iDeMarker(symbol,period,ma_period); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,ma_period)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiDeMarker::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with special parameters | +//+------------------------------------------------------------------+ +bool CiDeMarker::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period) + { + if(CreateBuffers(symbol,period,1)) + { + //--- string of status of drawing + m_name ="DeMarker"; + m_status="("+symbol+","+PeriodDescription()+","+IntegerToString(ma_period)+") H="+IntegerToString(m_handle); + //--- save settings + m_ma_period=ma_period; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to buffer of "DeMarker" | +//+------------------------------------------------------------------+ +double CiDeMarker::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiForce. | +//| Purpose: Class of the "Force Index" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiForce : public CIndicator + { +protected: + int m_ma_period; + ENUM_MA_METHOD m_ma_method; + ENUM_APPLIED_VOLUME m_applied; + +public: + CiForce(void); + ~CiForce(void); + //--- methods of access to protected data + int MaPeriod(void) const { return(m_ma_period); } + ENUM_MA_METHOD MaMethod(void) const { return(m_ma_method); } + ENUM_APPLIED_VOLUME Applied(void) const { return(m_applied); } + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const ENUM_MA_METHOD ma_method,const ENUM_APPLIED_VOLUME applied); + //--- methods of access to indicator data + double Main(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_FORCE); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const ENUM_MA_METHOD ma_method,const ENUM_APPLIED_VOLUME applied); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiForce::CiForce(void) : m_ma_period(-1), + m_ma_method(WRONG_VALUE), + m_applied(WRONG_VALUE) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiForce::~CiForce(void) + { + } +//+------------------------------------------------------------------+ +//| Create indicator "Force Index" | +//+------------------------------------------------------------------+ +bool CiForce::Create(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const ENUM_MA_METHOD ma_method,const ENUM_APPLIED_VOLUME applied) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iForce(symbol,period,ma_period,ma_method,applied); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,ma_period,ma_method,applied)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiForce::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value,(ENUM_MA_METHOD)params[1].integer_value, + (ENUM_APPLIED_VOLUME)params[2].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with special parameters | +//+------------------------------------------------------------------+ +bool CiForce::Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const ENUM_MA_METHOD ma_method,const ENUM_APPLIED_VOLUME applied) + { + if(CreateBuffers(symbol,period,1)) + { + //--- string of status of drawing + m_name ="Force"; + m_status="("+symbol+","+PeriodDescription()+","+ + IntegerToString(ma_period)+","+MethodDescription(ma_method)+","+ + VolumeDescription(applied)+","+") H="+IntegerToString(m_handle); + //--- save settings + m_ma_period=ma_period; + m_ma_method=ma_method; + m_applied =applied; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to buffer of "Force Index" | +//+------------------------------------------------------------------+ +double CiForce::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiMACD. | +//| Purpose: Class of the "Moving Averages | +//| Convergence-Divergence" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiMACD : public CIndicator + { +protected: + int m_fast_ema_period; + int m_slow_ema_period; + int m_signal_period; + int m_applied; + +public: + CiMACD(void); + ~CiMACD(void); + //--- methods of access to protected data + int FastEmaPeriod(void) const { return(m_fast_ema_period); } + int SlowEmaPeriod(void) const { return(m_slow_ema_period); } + int SignalPeriod(void) const { return(m_signal_period); } + int Applied(void) const { return(m_applied); } + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period, + const int fast_ema_period,const int slow_ema_period, + const int signal_period,const int applied); + //--- methods of access to indicator data + double Main(const int index) const; + double Signal(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_MACD); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int fast_ema_period,const int slow_ema_period, + const int signal_period,const int applied); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiMACD::CiMACD(void) : m_fast_ema_period(-1), + m_slow_ema_period(-1), + m_signal_period(-1), + m_applied(-1) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiMACD::~CiMACD(void) + { + } +//+------------------------------------------------------------------+ +//| Create the "Moving Averages Convergence-Divergence" indicator | +//+------------------------------------------------------------------+ +bool CiMACD::Create(const string symbol,const ENUM_TIMEFRAMES period, + const int fast_ema_period,const int slow_ema_period, + const int signal_period,const int applied) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iMACD(symbol,period,fast_ema_period,slow_ema_period,signal_period,applied); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,fast_ema_period,slow_ema_period,signal_period,applied)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiMACD::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value, + (int)params[2].integer_value,(int)params[3].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with special parameters | +//+------------------------------------------------------------------+ +bool CiMACD::Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int fast_ema_period,const int slow_ema_period, + const int signal_period,const int applied) + { + if(CreateBuffers(symbol,period,2)) + { + //--- string of status of drawing + m_name ="MACD"; + m_status="("+symbol+","+PeriodDescription()+","+ + IntegerToString(fast_ema_period)+","+IntegerToString(slow_ema_period)+","+ + IntegerToString(signal_period)+","+PriceDescription(applied)+","+") H="+IntegerToString(m_handle); + //--- save settings + m_fast_ema_period=fast_ema_period; + m_slow_ema_period=slow_ema_period; + m_signal_period =signal_period; + m_applied =applied; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + ((CIndicatorBuffer*)At(1)).Name("SIGNAL_LINE"); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to Main buffer of "Moving Averages | +//| Convergence-Divergence" | +//+------------------------------------------------------------------+ +double CiMACD::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Access to Signal buffer of "Moving Averages | +//| Convergence-Divergence" | +//+------------------------------------------------------------------+ +double CiMACD::Signal(const int index) const + { + CIndicatorBuffer *buffer=At(1); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiMomentum. | +//| Purpose: Class of the "Momentum" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiMomentum : public CIndicator + { +protected: + int m_ma_period; + int m_applied; + +public: + CiMomentum(void); + ~CiMomentum(void); + //--- methods of access to protected data + int MaPeriod(void) const { return(m_ma_period); } + int Applied(void) const { return(m_applied); } + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period,const int applied); + //--- methods of access to indicator data + double Main(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_MOMENTUM); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period,const int applied); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiMomentum::CiMomentum(void) : m_ma_period(-1), + m_applied(-1) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiMomentum::~CiMomentum(void) + { + } +//+------------------------------------------------------------------+ +//| Create the "Momentum" indicator | +//+------------------------------------------------------------------+ +bool CiMomentum::Create(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period,const int applied) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iMomentum(symbol,period,ma_period,applied); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,ma_period,applied)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiMomentum::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with special parameters | +//+------------------------------------------------------------------+ +bool CiMomentum::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period,const int applied) + { + if(CreateBuffers(symbol,period,1)) + { + //--- string of status of drawing + m_name="Momentum"; + m_status="("+symbol+","+PeriodDescription()+","+ + IntegerToString(ma_period)+","+PriceDescription(applied)+","+") H="+IntegerToString(m_handle); + //--- save settings + m_ma_period=ma_period; + m_applied =applied; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to buffer of "Momentum" | +//+------------------------------------------------------------------+ +double CiMomentum::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiOsMA. | +//| Purpose: Class of the "Moving Average of Oscillator | +//| (MACD histogram)" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiOsMA : public CIndicator + { +protected: + int m_fast_ema_period; + int m_slow_ema_period; + int m_signal_period; + int m_applied; + +public: + CiOsMA(void); + ~CiOsMA(void); + //--- methods of access to protected data + int FastEmaPeriod(void) const { return(m_fast_ema_period); } + int SlowEmaPeriod(void) const { return(m_slow_ema_period); } + int SignalPeriod(void) const { return(m_signal_period); } + int Applied(void) const { return(m_applied); } + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period, + const int fast_ema_period,const int slow_ema_period, + const int signal_period,const int applied); + //--- methods of access to indicator data + double Main(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_OSMA); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int fast_ema_period,const int slow_ema_period, + const int signal_period,const int applied); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiOsMA::CiOsMA(void) : m_fast_ema_period(-1), + m_slow_ema_period(-1), + m_signal_period(-1), + m_applied(-1) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiOsMA::~CiOsMA(void) + { + } +//+------------------------------------------------------------------+ +//| Create indicator "Moving Average of Oscillator | +//| (MACD histogram)" | +//+------------------------------------------------------------------+ +bool CiOsMA::Create(const string symbol,const ENUM_TIMEFRAMES period, + const int fast_ema_period,const int slow_ema_period, + const int signal_period,const int applied) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iOsMA(symbol,period,fast_ema_period,slow_ema_period,signal_period,applied); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,fast_ema_period,slow_ema_period,signal_period,applied)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiOsMA::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value, + (int)params[2].integer_value,(int)params[3].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with special parameters | +//+------------------------------------------------------------------+ +bool CiOsMA::Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int fast_ema_period,const int slow_ema_period, + const int signal_period,const int applied) + { + if(CreateBuffers(symbol,period,1)) + { + //--- string of status of drawing + m_name ="OsMA"; + m_status="("+symbol+","+PeriodDescription()+","+ + IntegerToString(fast_ema_period)+","+IntegerToString(slow_ema_period)+","+ + IntegerToString(signal_period)+","+PriceDescription(applied)+","+") H="+IntegerToString(m_handle); + //--- save settings + m_fast_ema_period=fast_ema_period; + m_slow_ema_period=slow_ema_period; + m_signal_period =signal_period; + m_applied =applied; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to buffer of "Moving Average of Oscillator | +//| (MACD histogram)" | +//+------------------------------------------------------------------+ +double CiOsMA::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiRSI. | +//| Purpose: Class of the "Relative Strength Index" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiRSI : public CIndicator + { +protected: + int m_ma_period; + int m_applied; + +public: + CiRSI(void); + ~CiRSI(void); + //--- methods of access to protected data + int MaPeriod(void) const { return(m_ma_period); } + int Applied(void) const { return(m_applied); } + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period,const int applied); + //--- methods of access to indicator data + double Main(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_RSI); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period,const int applied); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiRSI::CiRSI(void) : m_ma_period(-1), + m_applied(-1) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiRSI::~CiRSI(void) + { + } +//+------------------------------------------------------------------+ +//| Create indicator "Relative Strength Index" | +//+------------------------------------------------------------------+ +bool CiRSI::Create(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period,const int applied) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iRSI(symbol,period,ma_period,applied); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,ma_period,applied)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiRSI::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with special parameters | +//+------------------------------------------------------------------+ +bool CiRSI::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period,const int applied) + { + if(CreateBuffers(symbol,period,1)) + { + //--- string of status of drawing + m_name ="RSI"; + m_status="("+symbol+","+PeriodDescription()+","+ + IntegerToString(ma_period)+","+PriceDescription(applied)+","+") H="+IntegerToString(m_handle); + //--- save settings + m_ma_period=ma_period; + m_applied =applied; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to buffer of "Relative Strength Index" | +//+------------------------------------------------------------------+ +double CiRSI::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiRVI. | +//| Purpose: Class of the "Relative Vigor Index" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiRVI : public CIndicator + { +protected: + int m_ma_period; + +public: + CiRVI(void); + ~CiRVI(void); + //--- methods of access to protected data + int MaPeriod(void) const { return(m_ma_period); } + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period); + //--- methods of access to indicator data + double Main(const int index) const; + double Signal(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_RVI); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiRVI::CiRVI(void) : m_ma_period(-1) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiRVI::~CiRVI(void) + { + } +//+------------------------------------------------------------------+ +//| Create the "Relative Vigor Index" indicator | +//+------------------------------------------------------------------+ +bool CiRVI::Create(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iRVI(symbol,period,ma_period); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,ma_period)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiRVI::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with special parameters | +//+------------------------------------------------------------------+ +bool CiRVI::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period) + { + if(CreateBuffers(symbol,period,2)) + { + //--- string of status of drawing + m_name ="RVI"; + m_status="("+symbol+","+PeriodDescription()+","+ + IntegerToString(ma_period)+") H="+IntegerToString(m_handle); + //--- save settings + m_ma_period=ma_period; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + ((CIndicatorBuffer*)At(1)).Name("SIGNAL_LINE"); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to Main buffer of "Relative Vigor Index" | +//+------------------------------------------------------------------+ +double CiRVI::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Access to Signal buffer of "Relative Vigor Index" | +//+------------------------------------------------------------------+ +double CiRVI::Signal(const int index) const + { + CIndicatorBuffer *buffer=At(1); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiStochastic. | +//| Purpose: Class of the "Stochastic Oscillator" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiStochastic : public CIndicator + { +protected: + int m_Kperiod; + int m_Dperiod; + int m_slowing; + ENUM_MA_METHOD m_ma_method; + ENUM_STO_PRICE m_price_field; + +public: + CiStochastic(void); + ~CiStochastic(void); + //--- methods of access to protected data + int Kperiod(void) const { return(m_Kperiod); } + int Dperiod(void) const { return(m_Dperiod); } + int Slowing(void) const { return(m_slowing); } + ENUM_MA_METHOD MaMethod(void) const { return(m_ma_method); } + ENUM_STO_PRICE PriceField(void) const { return(m_price_field); } + //--- method create + bool Create(const string symbol,const ENUM_TIMEFRAMES period, + const int Kperiod,const int Dperiod,const int slowing, + const ENUM_MA_METHOD ma_method,const ENUM_STO_PRICE price_field); + //--- methods of access to indicator data + double Main(const int index) const; + double Signal(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_STOCHASTIC); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int Kperiod,const int Dperiod,const int slowing, + const ENUM_MA_METHOD ma_method,const ENUM_STO_PRICE price_field); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiStochastic::CiStochastic(void) : m_Kperiod(-1), + m_Dperiod(-1), + m_slowing(-1), + m_ma_method(WRONG_VALUE), + m_price_field(WRONG_VALUE) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiStochastic::~CiStochastic(void) + { + } +//+------------------------------------------------------------------+ +//| Create the "Stochastic Oscillator" indicator | +//+------------------------------------------------------------------+ +bool CiStochastic::Create(const string symbol,const ENUM_TIMEFRAMES period, + const int Kperiod,const int Dperiod,const int slowing, + const ENUM_MA_METHOD ma_method,const ENUM_STO_PRICE price_field) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iStochastic(symbol,period,Kperiod,Dperiod,slowing,ma_method,price_field); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,Kperiod,Dperiod,slowing,ma_method,price_field)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiStochastic::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value, + (int)params[2].integer_value,(ENUM_MA_METHOD)params[3].integer_value, + (ENUM_STO_PRICE)params[4].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with special parameters | +//+------------------------------------------------------------------+ +bool CiStochastic::Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int Kperiod,const int Dperiod,const int slowing, + const ENUM_MA_METHOD ma_method,const ENUM_STO_PRICE price_field) + { + if(CreateBuffers(symbol,period,2)) + { + //--- string of status of drawing + m_name ="Stochastic"; + m_status="("+symbol+","+PeriodDescription()+","+ + IntegerToString(Kperiod)+","+IntegerToString(Dperiod)+","+IntegerToString(slowing)+","+ + MethodDescription(ma_method)+","+IntegerToString(price_field)+") H="+IntegerToString(m_handle); + //--- save settings + m_Kperiod =Kperiod; + m_Dperiod =Dperiod; + m_slowing =slowing; + m_ma_method =ma_method; + m_price_field=price_field; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + ((CIndicatorBuffer*)At(1)).Name("SIGNAL_LINE"); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to Main buffer of "Stochastic Oscillator" | +//+------------------------------------------------------------------+ +double CiStochastic::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Access to Signal buffer of "Stochastic Oscillator" | +//+------------------------------------------------------------------+ +double CiStochastic::Signal(const int index) const + { + CIndicatorBuffer *buffer=At(1); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiWPR. | +//| Purpose: Class of the "Williams' Percent Range" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiWPR : public CIndicator + { +protected: + int m_calc_period; + +public: + CiWPR(void); + ~CiWPR(void); + //--- methods of access to protected data + int CalcPeriod(void) const { return(m_calc_period); } + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period,const int calc_period); + //--- methods of access to indicator data + double Main(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_WPR); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int calc_period); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiWPR::CiWPR(void) : m_calc_period(-1) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiWPR::~CiWPR(void) + { + } +//+------------------------------------------------------------------+ +//| Create the "Williams' Percent Range" indicator | +//+------------------------------------------------------------------+ +bool CiWPR::Create(const string symbol,const ENUM_TIMEFRAMES period,const int calc_period) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iWPR(symbol,period,calc_period); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,calc_period)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiWPR::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize indicator with the cpecial parameters | +//+------------------------------------------------------------------+ +bool CiWPR::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int calc_period) + { + if(CreateBuffers(symbol,period,1)) + { + //--- string of status of drawing + m_name ="WPR"; + m_status="("+symbol+","+PeriodDescription()+","+ + IntegerToString(calc_period)+") H="+IntegerToString(m_handle); + //--- save settings + m_calc_period=calc_period; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to buffer of "Williams' Percent Range" | +//+------------------------------------------------------------------+ +double CiWPR::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiTriX. | +//| Purpose: Class of the "Triple Exponential Moving Averages | +//| Oscillator" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiTriX : public CIndicator + { +protected: + int m_ma_period; + int m_applied; + +public: + CiTriX(void); + ~CiTriX(void); + //--- methods of access to protected data + int MaPeriod(void) const { return(m_ma_period); } + int Applied(void) const { return(m_applied); } + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period,const int applied); + //--- methods of access to indicator data + double Main(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_TRIX); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period,const int applied); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiTriX::CiTriX(void) : m_ma_period(-1), + m_applied(-1) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiTriX::~CiTriX(void) + { + } +//+------------------------------------------------------------------+ +//| Create the "Triple Exponential Moving Averages | +//| Oscillator" indicator | +//+------------------------------------------------------------------+ +bool CiTriX::Create(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period,const int applied) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) return(false); +//--- create + m_handle=iTriX(symbol,period,ma_period,applied); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,ma_period,applied)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiTriX::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value)); + } +//+------------------------------------------------------------------+ +//| Create the "Triple Exponential Moving Averages | +//| Oscillator" indicator | +//+------------------------------------------------------------------+ +bool CiTriX::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period,const int applied) + { + if(CreateBuffers(symbol,period,1)) + { + //--- string of status of drawing + m_name ="TriX"; + m_status="("+symbol+","+PeriodDescription()+","+ + IntegerToString(ma_period)+","+PriceDescription(applied)+") H="+IntegerToString(m_handle); + //--- save settings + m_ma_period=ma_period; + m_applied =applied; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to buffer of "Triple Exponential Moving Averages | +//| Oscillator" | +//+------------------------------------------------------------------+ +double CiTriX::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ diff --git a/Indicators/Series.mqh b/Indicators/Series.mqh new file mode 100644 index 0000000..ae52da4 --- /dev/null +++ b/Indicators/Series.mqh @@ -0,0 +1,299 @@ +//+------------------------------------------------------------------+ +//| Series.mqh | +//| Copyright 2000-2024, MetaQuotes Ltd. | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#include +#include +//+------------------------------------------------------------------+ +//| defines | +//+------------------------------------------------------------------+ +#define DEFAULT_BUFFER_SIZE 1024 +//+------------------------------------------------------------------+ +//| Class CSeries. | +//| Purpose: Base class for access to timeseries. | +//| Derives from class CArrayObj. | +//+------------------------------------------------------------------+ +class CSeries : public CArrayObj + { +protected: + string m_name; // name of series + int m_buffers_total; // number of buffers + int m_buffer_size; // buffer size + int m_timeframe_flags; // flags of timeframes (similar to "flags of visibility of objects") + string m_symbol; // symbol + ENUM_TIMEFRAMES m_period; // period + bool m_refresh_current; // flag + //--- + datetime m_first_date; + +public: + CSeries(void); + ~CSeries(void); + //--- methods of access to protected data + string Name(void) const { return(m_name); } + int BuffersTotal(void) const { return(m_buffers_total); } + int BufferSize(void) const { return(m_buffer_size); } + int Timeframe(void) const { return(m_timeframe_flags); } + string Symbol(void) const { return(m_symbol); } + ENUM_TIMEFRAMES Period(void) const { return(m_period); } + string PeriodDescription(const int val=0); + void RefreshCurrent(const bool flag) { m_refresh_current=flag; } + //--- method of tuning + virtual bool BufferResize(const int size); + //--- method of refreshing" of the data + virtual void Refresh(const int flags) { } + +protected: + //--- methods of tuning + bool SetSymbolPeriod(const string symbol,const ENUM_TIMEFRAMES period); + void PeriodToTimeframeFlag(const ENUM_TIMEFRAMES period); + //--- + bool CheckLoadHistory(const int size); + bool CheckTerminalHistory(const int size); + bool CheckServerHistory(const int size); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +void CSeries::CSeries(void) : m_name(""), + m_timeframe_flags(0), + m_buffers_total(0), + m_buffer_size(0), + m_symbol(""), + m_period(WRONG_VALUE), + m_refresh_current(true) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CSeries::~CSeries(void) + { + } +//+------------------------------------------------------------------+ +//| Set buffer size | +//+------------------------------------------------------------------+ +bool CSeries::BufferResize(const int size) + { +//--- check history + if(!CheckLoadHistory(size)) + { + printf("failed to get %d bars for %s,%s",size,m_symbol,EnumToString(m_period)); + return(false); + } +//--- history is available + m_buffer_size=size; +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Set symbol and period | +//+------------------------------------------------------------------+ +bool CSeries::SetSymbolPeriod(const string symbol,const ENUM_TIMEFRAMES period) + { + m_symbol=(symbol==NULL) ? ChartSymbol() : symbol; + m_period=(period==0) ? ChartPeriod() : period; + PeriodToTimeframeFlag(m_period); +//--- + return(true); + } +//+------------------------------------------------------------------+ +//| Convert period to timeframe flag (similar to visibility flags) | +//+------------------------------------------------------------------+ +void CSeries::PeriodToTimeframeFlag(const ENUM_TIMEFRAMES period) + { + static ENUM_TIMEFRAMES _p_int[]= + { + PERIOD_M1,PERIOD_M2,PERIOD_M3,PERIOD_M4,PERIOD_M5,PERIOD_M6, + PERIOD_M10,PERIOD_M12,PERIOD_M15,PERIOD_M20,PERIOD_M30, + PERIOD_H1,PERIOD_H2,PERIOD_H3,PERIOD_H4,PERIOD_H6,PERIOD_H8,PERIOD_H12, + PERIOD_D1,PERIOD_W1,PERIOD_MN1 + }; +//--- cycle for all timeframes + for(int i=0;iTerminalInfoInteger(TERMINAL_MAXBARS)) + { + //--- Definitely won't have such amount of data + printf(__FUNCTION__+": requested too much data (%d)",size); + return(false); + } + m_first_date=0; + if(CheckTerminalHistory(size)) + return(true); + if(CheckServerHistory(size)) + return(true); +//--- failed + return(false); + } +//+------------------------------------------------------------------+ +//| Checks data in terminal | +//+------------------------------------------------------------------+ +bool CSeries::CheckTerminalHistory(const int size) + { + datetime times[1]; + long bars=0; +//--- Enough data in timeseries? + if(Bars(m_symbol,m_period)>=size) + return(true); +//--- second attempt + if(SeriesInfoInteger(m_symbol,PERIOD_M1,SERIES_BARS_COUNT,bars)) + { + //--- there is loaded data to build timeseries + if(bars>size*PeriodSeconds(m_period)/60) + { + //--- force timeseries build + CopyTime(m_symbol,m_period,size-1,1,times); + //--- check date + if(SeriesInfoInteger(m_symbol,m_period,SERIES_BARS_COUNT,bars)) + //--- Timeseries generated using data from terminal + if(bars>size) + return(true); + } + } +//--- failed + return(false); + } +//+------------------------------------------------------------------+ +//| Downloads missing data from server | +//+------------------------------------------------------------------+ +bool CSeries::CheckServerHistory(const int size) + { +//--- load symbol history info + datetime first_server_date=0; + while(!SeriesInfoInteger(m_symbol,PERIOD_M1,SERIES_SERVER_FIRSTDATE,first_server_date) && !IsStopped()) + Sleep(5); +//--- Enough data on server? + if(first_server_date>TimeCurrent()-size*PeriodSeconds(m_period)) + return(false); +//--- load data step by step + int fail_cnt=0; + datetime times[1]; + while(!IsStopped()) + { + //--- wait for timeseries build + while(!SeriesInfoInteger(m_symbol,m_period,SERIES_SYNCHRONIZED) && !IsStopped()) + Sleep(5); + //--- ask for built bars + int bars=Bars(m_symbol,m_period); + if(bars>size) + return(true); + //--- copying of next part forces data loading + if(CopyTime(m_symbol,m_period,size-1,1,times)==1) + return(true); + //--- no more than 100 failed attempts + if(++fail_cnt>=100) + return(false); + Sleep(10); + } +//--- failed + return(false); + } +//+------------------------------------------------------------------+ +//| Class CDoubleBuffer. | +//| Purpose: Base class of buffer of data of the double type. | +//| Derives from class CArrayDouble. | +//+------------------------------------------------------------------+ +class CDoubleBuffer : public CArrayDouble + { +protected: + string m_symbol; // symbol + ENUM_TIMEFRAMES m_period; // period + int m_size; // size of used history + +public: + CDoubleBuffer(void); + ~CDoubleBuffer(void); + //--- methods of access to protected data + void Size(const int size) { m_size=size; } + //--- methods of access to data + double At(const int index) const; + //--- method of refreshing of the data buffer + virtual bool Refresh(void) { return(true); } + virtual bool RefreshCurrent(void) { return(true); } + //--- methods of tuning + void SetSymbolPeriod(const string symbol,const ENUM_TIMEFRAMES period); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CDoubleBuffer::CDoubleBuffer(void) : m_symbol(""), + m_period(WRONG_VALUE), + m_size(DEFAULT_BUFFER_SIZE) + { + ArraySetAsSeries(m_data,true); + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CDoubleBuffer::~CDoubleBuffer(void) + { + } +//+------------------------------------------------------------------+ +//| Access to data in a specified position | +//+------------------------------------------------------------------+ +double CDoubleBuffer::At(const int index) const + { +//--- check + if(index>=m_data_total) + return(EMPTY_VALUE); +//--- + double d=CArrayDouble::At(index); +//--- + return(d); + } +//+------------------------------------------------------------------+ +//| Set symbol and period | +//+------------------------------------------------------------------+ +void CDoubleBuffer::SetSymbolPeriod(const string symbol,const ENUM_TIMEFRAMES period) + { + m_symbol=(symbol==NULL) ? ChartSymbol() : symbol; + m_period=(period==0) ? ChartPeriod() : period; + } +//+------------------------------------------------------------------+ diff --git a/Indicators/TimeSeries.mqh b/Indicators/TimeSeries.mqh new file mode 100644 index 0000000..b388fc4 --- /dev/null +++ b/Indicators/TimeSeries.mqh @@ -0,0 +1,1551 @@ +//+------------------------------------------------------------------+ +//| TimeSeries.mqh | +//| Copyright 2000-2024, MetaQuotes Ltd. | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#include "Series.mqh" +#include +#include +//+------------------------------------------------------------------+ +//| Class CPriceSeries. | +//| Purpose: Base class of price series. | +//| Derives from class CSeries. | +//+------------------------------------------------------------------+ +class CPriceSeries : public CSeries + { +public: + CPriceSeries(void); + ~CPriceSeries(void); + //--- method of creation + virtual bool BufferResize(const int size); + //--- methods for searching extremum + virtual int MinIndex(const int start,const int count) const; + virtual double MinValue(const int start,const int count,int &index) const; + virtual int MaxIndex(const int start,const int count) const; + virtual double MaxValue(const int start,const int count,int &index) const; + //--- methods of access to data + double GetData(const int index) const; + //--- method of refreshing of the data + virtual void Refresh(const int flags=OBJ_ALL_PERIODS); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CPriceSeries::CPriceSeries(void) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CPriceSeries::~CPriceSeries(void) + { + } +//+------------------------------------------------------------------+ +//| Set size of buffer | +//+------------------------------------------------------------------+ +bool CPriceSeries::BufferResize(const int size) + { + if(size>m_buffer_size && !CSeries::BufferResize(size)) + return(false); +//-- history is avalible + CDoubleBuffer *buff=At(0); +//--- check pointer + if(buff==NULL) + return(false); +//-- + buff.Size(size); +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Find minimum of specified buffer | +//+------------------------------------------------------------------+ +int CPriceSeries::MinIndex(const int start,const int count) const + { + CDoubleBuffer *buff=At(0); +//--- check + if(buff==NULL) + return(-1); +//--- + return(buff.Minimum(start,count)); + } +//+------------------------------------------------------------------+ +//| Find minimum of specified buffer | +//+------------------------------------------------------------------+ +double CPriceSeries::MinValue(const int start,const int count,int &index) const + { + int idx=MinIndex(start,count); + double res=EMPTY_VALUE; +//--- check + if(idx!=-1) + { + CDoubleBuffer *buff=At(0); + res=buff.At(idx); + index=idx; + } +//--- + return(res); + } +//+------------------------------------------------------------------+ +//| Find maximum of specified buffer | +//+------------------------------------------------------------------+ +int CPriceSeries::MaxIndex(const int start,const int count) const + { + CDoubleBuffer *buff=At(0); +//--- check + if(buff==NULL) + return(-1); +//--- + return(buff.Maximum(start,count)); + } +//+------------------------------------------------------------------+ +//| Find maximum of specified buffer | +//+------------------------------------------------------------------+ +double CPriceSeries::MaxValue(const int start,const int count,int &index) const + { + int idx=MaxIndex(start,count); + double res=EMPTY_VALUE; +//--- check + if(idx!=-1) + { + CDoubleBuffer *buff=At(0); + res=buff.At(idx); + index=idx; + } +//--- + return(res); + } +//+------------------------------------------------------------------+ +//| Method to access data | +//+------------------------------------------------------------------+ +double CPriceSeries::GetData(const int index) const + { + CDoubleBuffer *buff=At(0); +//--- check + if(buff==NULL) + { + Print(__FUNCTION__,": invalid buffer"); + return(EMPTY_VALUE); + } +//--- + return(buff.At(index)); + } +//+------------------------------------------------------------------+ +//| Refreshing of the data | +//+------------------------------------------------------------------+ +void CPriceSeries::Refresh(const int flags) + { + CDoubleBuffer *buff=At(0); +//--- check + if(buff==NULL) + return; +//--- refresh of buffers + if(!(flags&m_timeframe_flags)) + { + if(m_refresh_current) + buff.RefreshCurrent(); + } + else + buff.Refresh(); + } +//+------------------------------------------------------------------+ +//| Class COpenBuffer. | +//| Purpose: Class of buffer of open price series. | +//| Derives from class CDoubleBuffer. | +//+------------------------------------------------------------------+ +class COpenBuffer : public CDoubleBuffer + { +public: + COpenBuffer(void); + ~COpenBuffer(void); + //--- method of refreshing of the data buffer + virtual bool Refresh(void); + virtual bool RefreshCurrent(void); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +COpenBuffer::COpenBuffer(void) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +COpenBuffer::~COpenBuffer(void) + { + } +//+------------------------------------------------------------------+ +//| Refreshing of the data buffer | +//+------------------------------------------------------------------+ +bool COpenBuffer::Refresh(void) + { + m_data_total=CopyOpen(m_symbol,m_period,0,m_size,m_data); +//--- + return(m_data_total>0); + } +//+------------------------------------------------------------------+ +//| Refreshing of the data buffer | +//+------------------------------------------------------------------+ +bool COpenBuffer::RefreshCurrent(void) + { + double array[1]; +//--- + if(CopyOpen(m_symbol,m_period,0,1,array)==1 && m_data_total>0) + { + m_data[0]=array[0]; + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Class CiOpen. | +//| Purpose: Class of open series. | +//| Derives from class CPriceSeries. | +//+------------------------------------------------------------------+ +class CiOpen : public CPriceSeries + { +public: + CiOpen(void); + ~CiOpen(void); + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period); + //--- methods of access to data + double GetData(const int index) const { return(CPriceSeries::GetData(index)); } + int GetData(const int start_pos,const int count,double &buffer[]) const; + int GetData(const datetime start_time,const int count,double &buffer[]) const; + int GetData(const datetime start_time,const datetime stop_time,double &buffer[]) const; + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiOpen::CiOpen(void) + { + m_name="Open"; + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiOpen::~CiOpen(void) + { + } +//+------------------------------------------------------------------+ +//| Creation of open series | +//+------------------------------------------------------------------+ +bool CiOpen::Create(const string symbol,const ENUM_TIMEFRAMES period) + { + CDoubleBuffer *buff; +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + if((buff=new COpenBuffer)==NULL) + return(false); +//--- add + if(!Add(buff)) + { + delete buff; + return(false); + } +//--- tune + buff.SetSymbolPeriod(m_symbol,m_period); +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| API access method "Copying the open buffer by specifying | +//| start position and number of elements" | +//+------------------------------------------------------------------+ +int CiOpen::GetData(const int start_pos,const int count,double &buffer[]) const + { + return(CopyOpen(m_symbol,m_period,start_pos,count,buffer)); + } +//+------------------------------------------------------------------+ +//| API access method "Copying the open buffer by specifying | +//| start time and number of elements" | +//+------------------------------------------------------------------+ +int CiOpen::GetData(const datetime start_time,const int count,double &buffer[]) const + { + return(CopyOpen(m_symbol,m_period,start_time,count,buffer)); + } +//+------------------------------------------------------------------+ +//| API access method "Copying the open buffer by specifying | +//| start and end time" | +//+------------------------------------------------------------------+ +int CiOpen::GetData(const datetime start_time,const datetime stop_time,double &buffer[]) const + { + return(CopyOpen(m_symbol,m_period,start_time,stop_time,buffer)); + } +//+------------------------------------------------------------------+ +//| Class CHighBuffer. | +//| Purpose: Class of buffer of high price series. | +//| Derives from class CDoubleBuffer. | +//+------------------------------------------------------------------+ +class CHighBuffer : public CDoubleBuffer + { +public: + CHighBuffer(void); + ~CHighBuffer(void); + //--- method of refreshing of the data buffer + virtual bool Refresh(void); + virtual bool RefreshCurrent(void); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CHighBuffer::CHighBuffer(void) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CHighBuffer::~CHighBuffer(void) + { + } +//+------------------------------------------------------------------+ +//| Refreshing of data buffer | +//+------------------------------------------------------------------+ +bool CHighBuffer::Refresh(void) + { + m_data_total=CopyHigh(m_symbol,m_period,0,m_size,m_data); +//--- + return(m_data_total>0); + } +//+------------------------------------------------------------------+ +//| Refreshing of data buffer | +//+------------------------------------------------------------------+ +bool CHighBuffer::RefreshCurrent(void) + { + double array[1]; +//--- + if(CopyHigh(m_symbol,m_period,0,1,array)>0 && m_data_total>0) + { + m_data[0]=array[0]; + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Class CiHigh. | +//| Purpose: Class of high series. | +//| Derives from class CPriceSeries. | +//+------------------------------------------------------------------+ +class CiHigh : public CPriceSeries + { +public: + CiHigh(void); + ~CiHigh(void); + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period); + //--- methods of access to data + double GetData(const int index) const { return(CPriceSeries::GetData(index)); } + int GetData(const int start_pos,const int count,double &buffer[]) const; + int GetData(const datetime start_time,const int count,double &buffer[]) const; + int GetData(const datetime start_time,const datetime stop_time,double &buffer[]) const; + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiHigh::CiHigh(void) + { + m_name="High"; + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiHigh::~CiHigh(void) + { + } +//+------------------------------------------------------------------+ +//| Creation of high series | +//+------------------------------------------------------------------+ +bool CiHigh::Create(const string symbol,const ENUM_TIMEFRAMES period) + { + CDoubleBuffer *buff; +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + if((buff=new CHighBuffer)==NULL) + return(false); +//--- add + if(!Add(buff)) + { + delete buff; + return(false); + } +//--- tune + buff.SetSymbolPeriod(m_symbol,m_period); +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| API access method "Copying the high buffer by specifying | +//| start position and number of elements" | +//+------------------------------------------------------------------+ +int CiHigh::GetData(const int start_pos,const int count,double &buffer[]) const + { + return(CopyHigh(m_symbol,m_period,start_pos,count,buffer)); + } +//+------------------------------------------------------------------+ +//| API access method "Copying the high buffer for the initial | +//| time and the number of elements" | +//+------------------------------------------------------------------+ +int CiHigh::GetData(const datetime start_time,const int count,double &buffer[]) const + { + return(CopyHigh(m_symbol,m_period,start_time,count,buffer)); + } +//+------------------------------------------------------------------+ +//| API access method "Copying the high buffer by specifying | +//| start and end time" | +//+------------------------------------------------------------------+ +int CiHigh::GetData(const datetime start_time,const datetime stop_time,double &buffer[]) const + { + return(CopyHigh(m_symbol,m_period,start_time,stop_time,buffer)); + } +//+------------------------------------------------------------------+ +//| Class CLowBuffer. | +//| Purpose: Class of buffer of low price series. | +//| Derives from class CPriceBuffer. | +//+------------------------------------------------------------------+ +class CLowBuffer : public CDoubleBuffer + { +public: + CLowBuffer(void); + ~CLowBuffer(void); + //--- method of refreshing of the data buffer + virtual bool Refresh(void); + virtual bool RefreshCurrent(void); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CLowBuffer::CLowBuffer(void) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CLowBuffer::~CLowBuffer(void) + { + } +//+------------------------------------------------------------------+ +//| Refreshing of data buffer | +//+------------------------------------------------------------------+ +bool CLowBuffer::Refresh(void) + { + m_data_total=CopyLow(m_symbol,m_period,0,m_size,m_data); +//--- + return(m_data_total>0); + } +//+------------------------------------------------------------------+ +//| Refreshing of data buffer | +//+------------------------------------------------------------------+ +bool CLowBuffer::RefreshCurrent(void) + { + double array[1]; +//--- + if(CopyLow(m_symbol,m_period,0,1,array)>0 && m_data_total>0) + { + m_data[0]=array[0]; + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Class CiLow. | +//| Purpose: Class of low series. | +//| Derives from class CPriceSeries. | +//+------------------------------------------------------------------+ +class CiLow : public CPriceSeries + { +public: + CiLow(void); + ~CiLow(void); + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period); + //--- methods of access to data + double GetData(const int index) const { return(CPriceSeries::GetData(index)); } + int GetData(const int start_pos,const int count,double &buffer[]) const; + int GetData(const datetime start_time,const int count,double &buffer[]) const; + int GetData(const datetime start_time,const datetime stop_time,double &buffer[]) const; + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiLow::CiLow(void) + { + m_name="Low"; + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiLow::~CiLow(void) + { + } +//+------------------------------------------------------------------+ +//| Creation of low series | +//+------------------------------------------------------------------+ +bool CiLow::Create(const string symbol,const ENUM_TIMEFRAMES period) + { + CDoubleBuffer *buff; +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + if((buff=new CLowBuffer)==NULL) + return(false); +//--- add + if(!Add(buff)) + { + delete buff; + return(false); + } +//--- tune + buff.SetSymbolPeriod(m_symbol,m_period); +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| API access method "Copying the low buffer by specifying | +//| start position and number of elements" | +//+------------------------------------------------------------------+ +int CiLow::GetData(const int start_pos,const int count,double &buffer[]) const + { + return(CopyLow(m_symbol,m_period,start_pos,count,buffer)); + } +//+------------------------------------------------------------------+ +//| API access method "Copying the low buffer for the initial | +//| time and the number of elements" | +//+------------------------------------------------------------------+ +int CiLow::GetData(const datetime start_time,const int count,double &buffer[]) const + { + return(CopyLow(m_symbol,m_period,start_time,count,buffer)); + } +//+------------------------------------------------------------------+ +//| API access method "Copying the low buffer for the initial | +//| and final time" | +//+------------------------------------------------------------------+ +int CiLow::GetData(const datetime start_time,const datetime stop_time,double &buffer[]) const + { + return(CopyLow(m_symbol,m_period,start_time,stop_time,buffer)); + } +//+------------------------------------------------------------------+ +//| Class CCloseBuffer. | +//| Purpose: Class of buffer of low price series. | +//| Derives from class CPriceBuffer. | +//+------------------------------------------------------------------+ +class CCloseBuffer : public CDoubleBuffer + { +public: + CCloseBuffer(void); + ~CCloseBuffer(void); + //--- method of refreshing of data buffer + virtual bool Refresh(void); + virtual bool RefreshCurrent(void); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CCloseBuffer::CCloseBuffer(void) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CCloseBuffer::~CCloseBuffer(void) + { + } +//+------------------------------------------------------------------+ +//| Refreshing of data buffer | +//+------------------------------------------------------------------+ +bool CCloseBuffer::Refresh(void) + { + m_data_total=CopyClose(m_symbol,m_period,0,m_size,m_data); +//--- + return(m_data_total>0); + } +//+------------------------------------------------------------------+ +//| Refreshing of the data buffer | +//+------------------------------------------------------------------+ +bool CCloseBuffer::RefreshCurrent(void) + { + double array[1]; +//--- + if(CopyClose(m_symbol,m_period,0,1,array)>0 && m_data_total>0) + { + m_data[0]=array[0]; + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Class CiClose. | +//| Purpose: Class of close series. | +//| Derives from class CPriceSeries. | +//+------------------------------------------------------------------+ +class CiClose : public CPriceSeries + { +public: + CiClose(void); + ~CiClose(void); + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period); + //--- methods of access to data + double GetData(const int index) const { return(CPriceSeries::GetData(index)); } + int GetData(const int start_pos,const int count,double &buffer[]) const; + int GetData(const datetime start_time,const int count,double &buffer[]) const; + int GetData(const datetime start_time,const datetime stop_time,double &buffer[]) const; + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiClose::CiClose(void) + { + m_name="Close"; + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiClose::~CiClose(void) + { + } +//+------------------------------------------------------------------+ +//| Creation of the close series | +//+------------------------------------------------------------------+ +bool CiClose::Create(const string symbol,const ENUM_TIMEFRAMES period) + { + CDoubleBuffer *buff; +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + if((buff=new CCloseBuffer)==NULL) + return(false); +//--- add + if(!Add(buff)) + { + delete buff; + return(false); + } +//--- tune + buff.SetSymbolPeriod(m_symbol,m_period); +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| API access method "Copying the close buffer by specifying | +//| start position and number of elements" | +//+------------------------------------------------------------------+ +int CiClose::GetData(const int start_pos,const int count,double &buffer[]) const + { + return(CopyClose(m_symbol,m_period,start_pos,count,buffer)); + } +//+------------------------------------------------------------------+ +//| API access method "Copying the close buffer by specifying | +//| start time and number of elements" | +//+------------------------------------------------------------------+ +int CiClose::GetData(const datetime start_time,const int count,double &buffer[]) const + { + return(CopyClose(m_symbol,m_period,start_time,count,buffer)); + } +//+------------------------------------------------------------------+ +//| API access method "Copying the close buffer by specifying | +//| start and end time" | +//+------------------------------------------------------------------+ +int CiClose::GetData(const datetime start_time,const datetime stop_time,double &buffer[]) const + { + return(CopyClose(m_symbol,m_period,start_time,stop_time,buffer)); + } +//+------------------------------------------------------------------+ +//| Class CSpreadBuffer. | +//| Purpose: Class of buffer of spread series. | +//| Derives from class CArrayInt. | +//+------------------------------------------------------------------+ +class CSpreadBuffer : public CArrayInt + { +protected: + string m_symbol; // symbol + ENUM_TIMEFRAMES m_period; // period + int m_freshed_data; // number of refreshed data + int m_size; // size of used history + +public: + CSpreadBuffer(void); + ~CSpreadBuffer(void); + //--- methods of access to protected data + void Size(const int size) { m_size=size; } + //--- methods of access to data + int At(const int index) const; + //--- method of refreshing of the data buffer + virtual bool Refresh(void); + virtual bool RefreshCurrent(void); + //--- methods of tuning + void SetSymbolPeriod(const string symbol,const ENUM_TIMEFRAMES period); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CSpreadBuffer::CSpreadBuffer(void) : m_symbol(""), + m_period(WRONG_VALUE), + m_freshed_data(0), + m_size(DEFAULT_BUFFER_SIZE) + { + ArraySetAsSeries(m_data,true); + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CSpreadBuffer::~CSpreadBuffer(void) + { + } +//+------------------------------------------------------------------+ +//| Access to data on the position | +//+------------------------------------------------------------------+ +int CSpreadBuffer::At(const int index) const + { +//--- check + if(index>=m_data_total) + return(0); +//--- + return(CArrayInt::At(index)); + } +//+------------------------------------------------------------------+ +//| Refreshing of data buffer | +//+------------------------------------------------------------------+ +bool CSpreadBuffer::Refresh(void) + { + m_freshed_data=CopySpread(m_symbol,m_period,0,m_size,m_data); +//--- + if(m_freshed_data>0) + { + m_data_total=ArraySize(m_data); + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Refreshing of the data buffer | +//+------------------------------------------------------------------+ +bool CSpreadBuffer::RefreshCurrent(void) + { + int array[1]; +//--- + if(CopySpread(m_symbol,m_period,0,1,array)==1 && m_data_total>0) + { + m_data[0]=array[0]; + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Set symbol and period | +//+------------------------------------------------------------------+ +void CSpreadBuffer::SetSymbolPeriod(const string symbol,const ENUM_TIMEFRAMES period) + { + m_symbol=(symbol==NULL) ? ChartSymbol() : symbol; + m_period=(period==0) ? ChartPeriod() : period; + } +//+------------------------------------------------------------------+ +//| Class CiSpread. | +//| Purpose: Class of spread series. | +//| Derives from class CSeries. | +//+------------------------------------------------------------------+ +class CiSpread : public CSeries + { +public: + CiSpread(void); + ~CiSpread(void); + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period); + virtual bool BufferResize(const int size); + //--- methods of access to data + int GetData(const int index) const; + int GetData(const int start_pos,const int count,int &buffer[]) const; + int GetData(const datetime start_time,const int count,int &buffer[]) const; + int GetData(const datetime start_time,const datetime stop_time,int &buffer[]) const; + //--- method of refreshing of the data + virtual void Refresh(const int flags=OBJ_ALL_PERIODS); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiSpread::CiSpread(void) + { + m_name="Spread"; + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiSpread::~CiSpread(void) + { + } +//+------------------------------------------------------------------+ +//| Creating of the spread series | +//+------------------------------------------------------------------+ +bool CiSpread::Create(const string symbol,const ENUM_TIMEFRAMES period) + { + CSpreadBuffer *buff; +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + if((buff=new CSpreadBuffer)==NULL) + return(false); +//--- add + if(!Add(buff)) + { + delete buff; + return(false); + } +//--- tune + buff.SetSymbolPeriod(m_symbol,m_period); +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Method to access data | +//+------------------------------------------------------------------+ +int CiSpread::GetData(const int index) const + { + CSpreadBuffer *buff=At(0); +//--- check + if(buff==NULL) + { + Print(__FUNCTION__,": invalid buffer"); + return(0); + } +//--- + return(buff.At(index)); + } +//+------------------------------------------------------------------+ +//| API access method "Copying the spread buffer by specifying | +//| start position and number of elements" | +//+------------------------------------------------------------------+ +int CiSpread::GetData(const int start_pos,const int count,int &buffer[]) const + { + return(CopySpread(m_symbol,m_period,start_pos,count,buffer)); + } +//+------------------------------------------------------------------+ +//| API access method "Copying the spread buffer by specifying | +//| start time and number of elements" | +//+------------------------------------------------------------------+ +int CiSpread::GetData(const datetime start_time,const int count,int &buffer[]) const + { + return(CopySpread(m_symbol,m_period,start_time,count,buffer)); + } +//+------------------------------------------------------------------+ +//| API access method "Copying the spread buffer by specifying | +//| start and end time" | +//+------------------------------------------------------------------+ +int CiSpread::GetData(const datetime start_time,const datetime stop_time,int &buffer[]) const + { + return(CopySpread(m_symbol,m_period,start_time,stop_time,buffer)); + } +//+------------------------------------------------------------------+ +//| Set size buffer | +//+------------------------------------------------------------------+ +bool CiSpread::BufferResize(const int size) + { + if(size>m_buffer_size && !CSeries::BufferResize(size)) + return(false); +//-- history is avalible + CSpreadBuffer *buff=At(0); +//--- check pointer + if(buff==NULL) + return(false); +//--- + buff.Size(size); +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Refreshing of data | +//+------------------------------------------------------------------+ +void CiSpread::Refresh(const int flags) + { + CSpreadBuffer *buff=At(0); +//--- check + if(buff==NULL) + return; +//--- refresh buffer + if(!(flags&m_timeframe_flags)) + { + if(m_refresh_current) + buff.RefreshCurrent(); + } + else + buff.Refresh(); + } +//+------------------------------------------------------------------+ +//| Class CTimeBuffer. | +//| Purpose: Class of buffer of time series. | +//| Derives from class CArrayLong. | +//+------------------------------------------------------------------+ +class CTimeBuffer : public CArrayLong + { +protected: + string m_symbol; // symbol + ENUM_TIMEFRAMES m_period; // period + int m_freshed_data; // number of refreshed data + int m_size; // size of used history + +public: + CTimeBuffer(void); + ~CTimeBuffer(void); + //--- methods of access to protected data + void Size(const int size) { m_size=size; } + //--- methods of access to data + long At(const int index) const; + //--- method of refreshing of the data buffer + virtual bool Refresh(void); + virtual bool RefreshCurrent(void); + //--- methods of tuning + void SetSymbolPeriod(const string symbol,const ENUM_TIMEFRAMES period); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CTimeBuffer::CTimeBuffer(void) : m_symbol(""), + m_period(WRONG_VALUE), + m_freshed_data(0), + m_size(DEFAULT_BUFFER_SIZE) + { + ArraySetAsSeries(m_data,true); + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CTimeBuffer::~CTimeBuffer(void) + { + } +//+------------------------------------------------------------------+ +//| Access to data in a position | +//+------------------------------------------------------------------+ +long CTimeBuffer::At(const int index) const + { +//--- check + if(index>=m_data_total) + return(0); +//--- + return((datetime)CArrayLong::At(index)); + } +//+------------------------------------------------------------------+ +//| Refreshing of data buffer | +//+------------------------------------------------------------------+ +bool CTimeBuffer::Refresh(void) + { + m_freshed_data=CopyTime(m_symbol,m_period,0,m_size,m_data); +//--- + if(m_freshed_data>0) + { + m_data_total=ArraySize(m_data); + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Refreshing of data buffer | +//+------------------------------------------------------------------+ +bool CTimeBuffer::RefreshCurrent(void) + { + long array[1]; +//--- + if(CopyTime(m_symbol,m_period,0,1,array)==1 && m_data_total>0) + { + m_data[0]=array[0]; + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Set symbol and period | +//+------------------------------------------------------------------+ +void CTimeBuffer::SetSymbolPeriod(const string symbol,const ENUM_TIMEFRAMES period) + { + m_symbol=(symbol==NULL) ? ChartSymbol() : symbol; + m_period=(period==0) ? ChartPeriod() : period; + } +//+------------------------------------------------------------------+ +//| Class CiTime. | +//| Purpose: Class of time series. | +//| Derives from class CSeries. | +//+------------------------------------------------------------------+ +class CiTime : public CSeries + { +public: + CiTime(void); + ~CiTime(void); + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period); + virtual bool BufferResize(const int size); + //--- methods of access to data + datetime GetData(const int index) const; + int GetData(const int start_pos,const int count,datetime &buffer[]) const; + int GetData(const datetime start_time,const int count,datetime &buffer[]) const; + int GetData(const datetime start_time,const datetime stop_time,datetime &buffer[]) const; + //--- method of refreshing of the data + virtual void Refresh(const int flags=OBJ_ALL_PERIODS); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiTime::CiTime(void) + { + m_name="Time"; + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiTime::~CiTime(void) + { + } +//+------------------------------------------------------------------+ +//| Creating of the time series | +//+------------------------------------------------------------------+ +bool CiTime::Create(const string symbol,const ENUM_TIMEFRAMES period) + { + CTimeBuffer *buff; +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + if((buff=new CTimeBuffer)==NULL) + return(false); +//--- add + if(!Add(buff)) + { + delete buff; + return(false); + } +//--- tune + buff.SetSymbolPeriod(m_symbol,m_period); +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Method to access data | +//+------------------------------------------------------------------+ +datetime CiTime::GetData(const int index) const + { + CTimeBuffer *buff=At(0); +//--- check + if(buff==NULL) + { + Print(__FUNCTION__,": invalid buffer"); + return(0); + } +//--- + return((datetime)buff.At(index)); + } +//+------------------------------------------------------------------+ +//| API access method "Copying the time buffer by specifying | +//| start position and number of elements" | +//+------------------------------------------------------------------+ +int CiTime::GetData(const int start_pos,const int count,datetime &buffer[]) const + { + return(CopyTime(m_symbol,m_period,start_pos,count,buffer)); + } +//+------------------------------------------------------------------+ +//| API access method "Copying the time buffer by specifying | +//| start time and number of elements" | +//+------------------------------------------------------------------+ +int CiTime::GetData(const datetime start_time,const int count,datetime &buffer[]) const + { + return(CopyTime(m_symbol,m_period,start_time,count,buffer)); + } +//+------------------------------------------------------------------+ +//| API access method "Copying the time buffer by specifying | +//| start and end time" | +//+------------------------------------------------------------------+ +int CiTime::GetData(const datetime start_time,const datetime stop_time,datetime &buffer[]) const + { + return(CopyTime(m_symbol,m_period,start_time,stop_time,buffer)); + } +//+------------------------------------------------------------------+ +//| Set size buffer | +//+------------------------------------------------------------------+ +bool CiTime::BufferResize(const int size) + { + if(size>m_buffer_size && !CSeries::BufferResize(size)) + return(false); +//-- history is avalible + CTimeBuffer *buff=At(0); +//--- check pointer + if(buff==NULL) + return(false); +//--- + buff.Size(size); +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Refreshing of data | +//+------------------------------------------------------------------+ +void CiTime::Refresh(const int flags) + { + CTimeBuffer *buff=At(0); +//--- check + if(buff==NULL) + return; +//--- refresh buffers + if(!(flags&m_timeframe_flags)) + { + if(m_refresh_current) + buff.RefreshCurrent(); + } + else + buff.Refresh(); + } +//+------------------------------------------------------------------+ +//| Class CTickVolumeBuffer. | +//| Purpose: Class of buffer of tick volume series. | +//| Derives from class CArrayLong. | +//+------------------------------------------------------------------+ +class CTickVolumeBuffer : public CArrayLong + { +protected: + string m_symbol; // symbol + ENUM_TIMEFRAMES m_period; // period + int m_freshed_data; // number of refreshed data + int m_size; // size of used history + +public: + CTickVolumeBuffer(void); + ~CTickVolumeBuffer(void); + //--- methods of access to protected data + void Size(const int size) { m_size=size; } + //--- methods of access to data + long At(const int index) const; + //--- method of refreshing of the data buffer + virtual bool Refresh(void); + virtual bool RefreshCurrent(void); + //--- methods of tuning + void SetSymbolPeriod(const string symbol,const ENUM_TIMEFRAMES period); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CTickVolumeBuffer::CTickVolumeBuffer(void) : m_symbol(""), + m_period(WRONG_VALUE), + m_freshed_data(0), + m_size(DEFAULT_BUFFER_SIZE) + { + ArraySetAsSeries(m_data,true); + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CTickVolumeBuffer::~CTickVolumeBuffer(void) + { + } +//+------------------------------------------------------------------+ +//| Access to data in a position | +//+------------------------------------------------------------------+ +long CTickVolumeBuffer::At(const int index) const + { +//--- check + if(index>=m_data_total) + return(0); +//--- + return((datetime)CArrayLong::At(index)); + } +//+------------------------------------------------------------------+ +//| Refreshing of data buffer | +//+------------------------------------------------------------------+ +bool CTickVolumeBuffer::Refresh(void) + { + m_freshed_data=CopyTickVolume(m_symbol,m_period,0,m_size,m_data); +//--- + if(m_freshed_data>0) + { + m_data_total=ArraySize(m_data); + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Refreshing of data buffer | +//+------------------------------------------------------------------+ +bool CTickVolumeBuffer::RefreshCurrent(void) + { + long array[1]; +//--- + if(CopyTickVolume(m_symbol,m_period,0,1,array)==1 && m_data_total>0) + { + m_data[0]=array[0]; + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Set symbol and period | +//+------------------------------------------------------------------+ +void CTickVolumeBuffer::SetSymbolPeriod(const string symbol,const ENUM_TIMEFRAMES period) + { + m_symbol=(symbol==NULL) ? ChartSymbol() : symbol; + m_period=(period==0) ? ChartPeriod() : period; + } +//+------------------------------------------------------------------+ +//| Class CiTickVolume. | +//| Purpose: Class of tick volume series. | +//| Derives from class CSeries. | +//+------------------------------------------------------------------+ +class CiTickVolume : public CSeries + { +public: + CiTickVolume(void); + ~CiTickVolume(void); + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period); + virtual bool BufferResize(const int size); + //--- methods of access to data + long GetData(const int index) const; + int GetData(const int start_pos,const int count,long &buffer[]) const; + int GetData(const datetime start_time,const int count,long &buffer[]) const; + int GetData(const datetime start_time,const datetime stop_time,long &buffer[]) const; + //--- method of refreshing of the data + virtual void Refresh(const int flags=OBJ_ALL_PERIODS); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiTickVolume::CiTickVolume(void) + { + m_name="Volume"; + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiTickVolume::~CiTickVolume(void) + { + } +//+------------------------------------------------------------------+ +//| Creation of the tick volume series | +//+------------------------------------------------------------------+ +bool CiTickVolume::Create(const string symbol,const ENUM_TIMEFRAMES period) + { + CTickVolumeBuffer *buff; +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + if((buff=new CTickVolumeBuffer)==NULL) + return(false); +//--- add + if(!Add(buff)) + { + delete buff; + return(false); + } +//--- tune + buff.SetSymbolPeriod(m_symbol,m_period); +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Method to access data | +//+------------------------------------------------------------------+ +long CiTickVolume::GetData(const int index) const + { + CTickVolumeBuffer *buff=At(0); +//--- check + if(buff==NULL) + { + Print(__FUNCTION__,": invalid buffer"); + return(0); + } +//--- + return(buff.At(index)); + } +//+------------------------------------------------------------------+ +//| API access method "Copying the tick volume buffer by specifying | +//| start position and number of elements" | +//+------------------------------------------------------------------+ +int CiTickVolume::GetData(const int start_pos,const int count,long &buffer[]) const + { + return(CopyTickVolume(m_symbol,m_period,start_pos,count,buffer)); + } +//+------------------------------------------------------------------+ +//| API access method "Copying the tick volume buffer by specifying | +//| start time and number of elements" | +//+------------------------------------------------------------------+ +int CiTickVolume::GetData(const datetime start_time,const int count,long &buffer[]) const + { + return(CopyTickVolume(m_symbol,m_period,start_time,count,buffer)); + } +//+------------------------------------------------------------------+ +//| API access method "Copying the tick volume buffer by specifying | +//| start and end time" | +//+------------------------------------------------------------------+ +int CiTickVolume::GetData(const datetime start_time,const datetime stop_time,long &buffer[]) const + { + return(CopyTickVolume(m_symbol,m_period,start_time,stop_time,buffer)); + } +//+------------------------------------------------------------------+ +//| Set size buffer | +//+------------------------------------------------------------------+ +bool CiTickVolume::BufferResize(const int size) + { + if(size>m_buffer_size && !CSeries::BufferResize(size)) + return(false); +//-- history is avalible + CTickVolumeBuffer *buff=At(0); +//--- check pointer + if(buff==NULL) + return(false); +//-- + buff.Size(size); +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Refreshing of data | +//+------------------------------------------------------------------+ +void CiTickVolume::Refresh(const int flags) + { + CTickVolumeBuffer *buff=At(0); +//--- check + if(buff==NULL) + return; +//--- refresh buffers + if(!(flags&m_timeframe_flags)) + { + if(m_refresh_current) + buff.RefreshCurrent(); + } + else + buff.Refresh(); + } +//+------------------------------------------------------------------+ +//| Class CRealVolumeBuffer. | +//| Purpose: Class of buffer of real volume series. | +//| Derives from class CArrayLong. | +//+------------------------------------------------------------------+ +class CRealVolumeBuffer : public CArrayLong + { +protected: + string m_symbol; // symbol + ENUM_TIMEFRAMES m_period; // period + int m_freshed_data; // number of refreshed data + int m_size; // size of used history + +public: + CRealVolumeBuffer(void); + ~CRealVolumeBuffer(void); + //--- methods of access to protected data + void Size(const int size) { m_size=size; } + //--- methods of access to data + long At(const int index) const; + //--- method of refreshing of the data buffer + virtual bool Refresh(void); + virtual bool RefreshCurrent(void); + //--- methods of tuning + void SetSymbolPeriod(const string symbol,const ENUM_TIMEFRAMES period); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CRealVolumeBuffer::CRealVolumeBuffer(void) : m_symbol(""), + m_period(WRONG_VALUE), + m_freshed_data(0), + m_size(DEFAULT_BUFFER_SIZE) + { + ArraySetAsSeries(m_data,true); + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CRealVolumeBuffer::~CRealVolumeBuffer(void) + { + } +//+------------------------------------------------------------------+ +//| Access to data in a position | +//+------------------------------------------------------------------+ +long CRealVolumeBuffer::At(const int index) const + { +//--- check + if(index>=m_data_total) + return(0); +//--- + return((datetime)CArrayLong::At(index)); + } +//+------------------------------------------------------------------+ +//| Refreshing of data buffer | +//+------------------------------------------------------------------+ +bool CRealVolumeBuffer::Refresh(void) + { + m_freshed_data=CopyRealVolume(m_symbol,m_period,0,m_size,m_data); +//--- + if(m_freshed_data>0) + { + m_data_total=ArraySize(m_data); + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Refreshing of data buffer | +//+------------------------------------------------------------------+ +bool CRealVolumeBuffer::RefreshCurrent(void) + { + long array[1]; +//--- + if(CopyRealVolume(m_symbol,m_period,0,1,array)==1 && m_data_total>0) + { + m_data[0]=array[0]; + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Set symbol and period | +//+------------------------------------------------------------------+ +void CRealVolumeBuffer::SetSymbolPeriod(const string symbol,const ENUM_TIMEFRAMES period) + { + m_symbol=(symbol==NULL) ? ChartSymbol() : symbol; + m_period=(period==0) ? ChartPeriod() : period; + } +//+------------------------------------------------------------------+ +//| Class CiRealVolume. | +//| Purpose: Class of real volume series. | +//| Derives from class CSeries. | +//+------------------------------------------------------------------+ +class CiRealVolume : public CSeries + { +public: + CiRealVolume(void); + ~CiRealVolume(void); + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period); + virtual bool BufferResize(const int size); + //--- methods of access to data + long GetData(const int index) const; + int GetData(const int start_pos,const int count,long &buffer[]) const; + int GetData(const datetime start_time,const int count,long &buffer[]) const; + int GetData(const datetime start_time,const datetime stop_time,long &buffer[]) const; + //--- method of refreshing of the data + virtual void Refresh(const int flags=OBJ_ALL_PERIODS); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiRealVolume::CiRealVolume(void) + { + m_name="RealVolume"; + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiRealVolume::~CiRealVolume(void) + { + } +//+------------------------------------------------------------------+ +//| Creation of the real volume series | +//+------------------------------------------------------------------+ +bool CiRealVolume::Create(const string symbol,const ENUM_TIMEFRAMES period) + { + CRealVolumeBuffer *buff; +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + if((buff=new CRealVolumeBuffer)==NULL) + return(false); +//--- add + if(!Add(buff)) + { + delete buff; + return(false); + } +//--- tune + buff.SetSymbolPeriod(m_symbol,m_period); +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Method to access data | +//+------------------------------------------------------------------+ +long CiRealVolume::GetData(const int index) const + { + CRealVolumeBuffer *buff=At(0); +//--- check + if(buff==NULL) + { + Print(__FUNCTION__,": invalid buffer"); + return(0); + } +//--- + return(buff.At(index)); + } +//+------------------------------------------------------------------+ +//| API access method "Copying the real volume buffer by specifying | +//| start position and number of elements" | +//+------------------------------------------------------------------+ +int CiRealVolume::GetData(const int start_pos,const int count,long &buffer[]) const + { + return(CopyRealVolume(m_symbol,m_period,start_pos,count,buffer)); + } +//+------------------------------------------------------------------+ +//| API access method "Copying the real volume buffer by specifying | +//| start time and number of elements" | +//+------------------------------------------------------------------+ +int CiRealVolume::GetData(const datetime start_time,const int count,long &buffer[]) const + { + return(CopyRealVolume(m_symbol,m_period,start_time,count,buffer)); + } +//+------------------------------------------------------------------+ +//| API access method "Copying the real volume buffer by specifying | +//| start and end time" | +//+------------------------------------------------------------------+ +int CiRealVolume::GetData(const datetime start_time,const datetime stop_time,long &buffer[]) const + { + return(CopyRealVolume(m_symbol,m_period,start_time,stop_time,buffer)); + } +//+------------------------------------------------------------------+ +//| Set size buffer | +//+------------------------------------------------------------------+ +bool CiRealVolume::BufferResize(const int size) + { + if(size>m_buffer_size && !CSeries::BufferResize(size)) + return(false); +//-- history is avalible + CRealVolumeBuffer *buff=At(0); +//--- check pointer + if(buff==NULL) + return(false); +//-- + buff.Size(size); +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Refreshing of data | +//+------------------------------------------------------------------+ +void CiRealVolume::Refresh(const int flags) + { + CRealVolumeBuffer *buff=At(0); +//--- check + if(buff==NULL) + return; +//--- refresh buffers + if(!(flags&m_timeframe_flags)) + { + if(m_refresh_current) + buff.RefreshCurrent(); + } + else + buff.Refresh(); + } +//+------------------------------------------------------------------+ diff --git a/Indicators/Trend.mqh b/Indicators/Trend.mqh new file mode 100644 index 0000000..5fa3199 --- /dev/null +++ b/Indicators/Trend.mqh @@ -0,0 +1,1717 @@ +//+------------------------------------------------------------------+ +//| Trend.mqh | +//| Copyright 2000-2024, MetaQuotes Ltd. | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#include "Indicator.mqh" +//+------------------------------------------------------------------+ +//| Class CiADX. | +//| Purpose: Class of the "Average Directional Index" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiADX : public CIndicator + { +protected: + int m_ma_period; + +public: + CiADX(void); + ~CiADX(void); + //--- methods of access to protected data + int MaPeriod(void) const { return(m_ma_period); } + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period); + //--- methods of access to indicator data + double Main(const int index) const; + double Plus(const int index) const; + double Minus(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_ADX); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiADX::CiADX(void) : m_ma_period(-1) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiADX::~CiADX(void) + { + } +//+------------------------------------------------------------------+ +//| Create the "Average Directional Index" indicator | +//+------------------------------------------------------------------+ +bool CiADX::Create(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iADX(symbol,period,ma_period); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,ma_period)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiADX::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize indicator with the special parameters | +//+------------------------------------------------------------------+ +bool CiADX::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period) + { + if(CreateBuffers(symbol,period,3)) + { + //--- string of status of drawing + m_name ="ADX"; + m_status="("+symbol+","+PeriodDescription()+","+IntegerToString(ma_period)+") H="+IntegerToString(m_handle); + //--- save settings + m_ma_period=ma_period; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + ((CIndicatorBuffer*)At(1)).Name("PLUS_LINE"); + ((CIndicatorBuffer*)At(2)).Name("MINUS_LINE"); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to Main buffer of "Average Directional Index" | +//+------------------------------------------------------------------+ +double CiADX::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Access to Plus buffer of "Average Directional Index" | +//+------------------------------------------------------------------+ +double CiADX::Plus(const int index) const + { + CIndicatorBuffer *buffer=At(1); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Access to Minus buffer of "Average Directional Index" | +//+------------------------------------------------------------------+ +double CiADX::Minus(const int index) const + { + CIndicatorBuffer *buffer=At(2); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiADXWilder. | +//| Purpose: Class of the "Average Directional Index | +//| by Welles Wilder" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiADXWilder : public CIndicator + { +protected: + int m_ma_period; + +public: + CiADXWilder(void); + ~CiADXWilder(void); + //--- methods of access to protected data + int MaPeriod(void) const { return(m_ma_period); } + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period); + //--- methods of access to indicator data + double Main(const int index) const; + double Plus(const int index) const; + double Minus(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_ADXW); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiADXWilder::CiADXWilder(void) : m_ma_period(-1) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiADXWilder::~CiADXWilder(void) + { + } +//+------------------------------------------------------------------+ +//| Create indicator "Average Directional Index by Welles Wilder" | +//+------------------------------------------------------------------+ +bool CiADXWilder::Create(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iADXWilder(symbol,period,ma_period); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,ma_period)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiADXWilder::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize indicator with the special parameters | +//+------------------------------------------------------------------+ +bool CiADXWilder::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period) + { + if(CreateBuffers(symbol,period,3)) + { + //--- string of status of drawing + m_name ="ADXWilder"; + m_status="("+symbol+","+PeriodDescription()+","+IntegerToString(ma_period)+") H="+IntegerToString(m_handle); + //--- save settings + m_ma_period=ma_period; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + ((CIndicatorBuffer*)At(1)).Name("PLUS_LINE"); + ((CIndicatorBuffer*)At(2)).Name("MINUS_LINE"); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to Main buffer of "Average Directional Index | +//| by Welles Wilder" | +//+------------------------------------------------------------------+ +double CiADXWilder::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Access to Plus buffer of "Average Directional Index | +//| by Welles Wilder" | +//+------------------------------------------------------------------+ +double CiADXWilder::Plus(const int index) const + { + CIndicatorBuffer *buffer=At(1); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Access to Minus buffer of "Average Directional Index | +//| by Welles Wilder" | +//+------------------------------------------------------------------+ +double CiADXWilder::Minus(const int index) const + { + CIndicatorBuffer *buffer=At(2); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiBands. | +//| Purpose: Class of the "Bollinger Bands" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiBands : public CIndicator + { +protected: + int m_ma_period; + int m_ma_shift; + double m_deviation; + int m_applied; + +public: + CiBands(void); + ~CiBands(void); + //--- methods of access to protected data + int MaPeriod(void) const { return(m_ma_period); } + int MaShift(void) const { return(m_ma_shift); } + double Deviation(void) const { return(m_deviation); } + int Applied(void) const { return(m_applied); } + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ma_shift, + const double deviation,const int applied); + //--- methods of access to indicator data + double Base(const int index) const; + double Upper(const int index) const; + double Lower(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_BANDS); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ma_shift, + const double deviation,const int applied); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiBands::CiBands(void) : m_ma_period(-1), + m_ma_shift(-1), + m_deviation(EMPTY_VALUE), + m_applied(-1) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiBands::~CiBands(void) + { + } +//+------------------------------------------------------------------+ +//| Create indicator "Bollinger Bands" | +//+------------------------------------------------------------------+ +bool CiBands::Create(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ma_shift, + const double deviation,const int applied) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iBands(symbol,period,ma_period,ma_shift,deviation,applied); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,ma_period,ma_shift,deviation,applied)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiBands::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value, + params[2].double_value,(int)params[3].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize indicator with the special parameters | +//+------------------------------------------------------------------+ +bool CiBands::Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ma_shift, + const double deviation,const int applied) + { + if(CreateBuffers(symbol,period,3)) + { + //--- string of status of drawing + m_name ="Bands"; + m_status="("+symbol+","+PeriodDescription()+","+ + IntegerToString(ma_period)+","+IntegerToString(ma_shift)+","+ + DoubleToString(deviation)+","+PriceDescription(applied)+") H="+IntegerToString(m_handle); + //--- save settings + m_ma_period=ma_period; + m_ma_shift =ma_shift; + m_deviation=deviation; + m_applied =applied; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("BASE_LINE"); + ((CIndicatorBuffer*)At(0)).Offset(ma_shift); + ((CIndicatorBuffer*)At(1)).Name("UPPER_BAND"); + ((CIndicatorBuffer*)At(1)).Offset(ma_shift); + ((CIndicatorBuffer*)At(2)).Name("LOWER_BAND"); + ((CIndicatorBuffer*)At(2)).Offset(ma_shift); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to Base buffer of "Bollinger Bands" | +//+------------------------------------------------------------------+ +double CiBands::Base(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Access to Upper buffer of "Bollinger Bands" | +//+------------------------------------------------------------------+ +double CiBands::Upper(const int index) const + { + CIndicatorBuffer *buffer=At(1); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Access to Lower buffer of "Bollinger Bands" | +//+------------------------------------------------------------------+ +double CiBands::Lower(const int index) const + { + CIndicatorBuffer *buffer=At(2); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiEnvelopes. | +//| Purpose: Class of the "Envelopes" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiEnvelopes : public CIndicator + { +protected: + int m_ma_period; + int m_ma_shift; + ENUM_MA_METHOD m_ma_method; + int m_applied; + double m_deviation; + +public: + CiEnvelopes(void); + ~CiEnvelopes(void); + //--- methods of access to protected data + int MaPeriod(void) const { return(m_ma_period); } + int MaShift(void) const { return(m_ma_shift); } + ENUM_MA_METHOD MaMethod(void) const { return(m_ma_method); } + int Applied(void) const { return(m_applied); } + double Deviation(void) const { return(m_deviation); } + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ma_shift,const ENUM_MA_METHOD ma_method, + const int applied,const double deviation); + //--- methods of access to indicator data + double Upper(const int index) const; + double Lower(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_ENVELOPES); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ma_shift,const ENUM_MA_METHOD ma_method, + const int applied,const double deviation); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiEnvelopes::CiEnvelopes(void) : m_ma_period(-1), + m_ma_shift(-1), + m_ma_method(WRONG_VALUE), + m_applied(-1), + m_deviation(EMPTY_VALUE) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiEnvelopes::~CiEnvelopes(void) + { + } +//+------------------------------------------------------------------+ +//| Create indicator "Envelopes" | +//+------------------------------------------------------------------+ +bool CiEnvelopes::Create(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ma_shift,const ENUM_MA_METHOD ma_method, + const int applied,const double deviation) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iEnvelopes(symbol,period,ma_period,ma_shift,ma_method,applied,deviation); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,ma_period,ma_shift,ma_method,applied,deviation)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiEnvelopes::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value, + (ENUM_MA_METHOD)params[2].integer_value,(int)params[3].integer_value, + (int)params[4].double_value)); + } +//+------------------------------------------------------------------+ +//| Initialize indicator with the special parameters | +//+------------------------------------------------------------------+ +bool CiEnvelopes::Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ma_shift,const ENUM_MA_METHOD ma_method, + const int applied,const double deviation) + { + if(CreateBuffers(symbol,period,2)) + { + //--- string of status of drawing + m_name="Envelopes"; + m_status="("+symbol+","+PeriodDescription()+","+ + IntegerToString(ma_period)+","+IntegerToString(ma_shift)+","+ + MethodDescription(ma_method)+","+PriceDescription(applied)+","+ + DoubleToString(deviation)+") H="+IntegerToString(m_handle); + //--- save settings + m_ma_period=ma_period; + m_ma_shift =ma_shift; + m_ma_method=ma_method; + m_applied =applied; + m_deviation=deviation; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("UPPER_LINE"); + ((CIndicatorBuffer*)At(0)).Offset(ma_shift); + ((CIndicatorBuffer*)At(1)).Name("LOWER_LINE"); + ((CIndicatorBuffer*)At(1)).Offset(ma_shift); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to Upper buffer of "Envelopes" | +//+------------------------------------------------------------------+ +double CiEnvelopes::Upper(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Access to Lower buffer of "Envelopes" | +//+------------------------------------------------------------------+ +double CiEnvelopes::Lower(const int index) const + { + CIndicatorBuffer *buffer=At(1); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiIchimoku. | +//| Purpose: Class of the "Ichimoku Kinko Hyo" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiIchimoku : public CIndicator + { +protected: + int m_tenkan_sen; + int m_kijun_sen; + int m_senkou_span_b; + +public: + CiIchimoku(void); + ~CiIchimoku(void); + //--- methods of access to protected data + int TenkanSenPeriod(void) const { return(m_tenkan_sen); } + int KijunSenPeriod(void) const { return(m_kijun_sen); } + int SenkouSpanBPeriod(void) const { return(m_senkou_span_b); } + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period, + const int tenkan_sen,const int kijun_sen,const int senkou_span_b); + //--- methods of access to indicator data + double TenkanSen(const int index) const; + double KijunSen(const int index) const; + double SenkouSpanA(const int index) const; + double SenkouSpanB(const int index) const; + double ChinkouSpan(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_ICHIMOKU); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int tenkan_sen,const int kijun_sen,const int senkou_span_b); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiIchimoku::CiIchimoku(void) : m_tenkan_sen(-1), + m_kijun_sen(-1), + m_senkou_span_b(-1) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiIchimoku::~CiIchimoku(void) + { + } +//+------------------------------------------------------------------+ +//| Create indicator "Ichimoku Kinko Hyo" | +//+------------------------------------------------------------------+ +bool CiIchimoku::Create(const string symbol,const ENUM_TIMEFRAMES period, + const int tenkan_sen,const int kijun_sen,const int senkou_span_b) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iIchimoku(symbol,period,tenkan_sen,kijun_sen,senkou_span_b); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,tenkan_sen,kijun_sen,senkou_span_b)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiIchimoku::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value,(int)params[2].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize indicator with the special parameters | +//+------------------------------------------------------------------+ +bool CiIchimoku::Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int tenkan_sen,const int kijun_sen,const int senkou_span_b) + { + if(CreateBuffers(symbol,period,5)) + { + //--- string of status of drawing + m_name ="Ichimoku"; + m_status="("+symbol+","+PeriodDescription()+","+ + IntegerToString(tenkan_sen)+","+IntegerToString(kijun_sen)+","+ + IntegerToString(senkou_span_b)+") H="+IntegerToString(m_handle); + //--- save settings + m_tenkan_sen =tenkan_sen; + m_kijun_sen =kijun_sen; + m_senkou_span_b=senkou_span_b; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("TENKANSEN_LINE"); + ((CIndicatorBuffer*)At(1)).Name("KIJUNSEN_LINE"); + ((CIndicatorBuffer*)At(2)).Name("SENKOUSPANA_LINE"); + ((CIndicatorBuffer*)At(2)).Offset(kijun_sen); + ((CIndicatorBuffer*)At(3)).Name("SENKOUSPANB_LINE"); + ((CIndicatorBuffer*)At(3)).Offset(kijun_sen); + ((CIndicatorBuffer*)At(4)).Name("CHIKOUSPAN_LINE"); + ((CIndicatorBuffer*)At(4)).Offset(-kijun_sen); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to TenkanSen buffer of "Ichimoku Kinko Hyo" | +//+------------------------------------------------------------------+ +double CiIchimoku::TenkanSen(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Access to KijunSen buffer of "Ichimoku Kinko Hyo" | +//+------------------------------------------------------------------+ +double CiIchimoku::KijunSen(const int index) const + { + CIndicatorBuffer *buffer=At(1); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Access to SenkouSpanA buffer of "Ichimoku Kinko Hyo" | +//+------------------------------------------------------------------+ +double CiIchimoku::SenkouSpanA(const int index) const + { + CIndicatorBuffer *buffer=At(2); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Access to SenkouSpanB buffer of "Ichimoku Kinko Hyo" | +//+------------------------------------------------------------------+ +double CiIchimoku::SenkouSpanB(const int index) const + { + CIndicatorBuffer *buffer=At(3); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Access to ChikouSpan buffer of "Ichimoku Kinko Hyo" | +//+------------------------------------------------------------------+ +double CiIchimoku::ChinkouSpan(const int index) const + { + CIndicatorBuffer *buffer=At(4); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiMA. | +//| Purpose: Class of the "Moving Average" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiMA : public CIndicator + { +protected: + int m_ma_period; + int m_ma_shift; + ENUM_MA_METHOD m_ma_method; + int m_applied; + +public: + CiMA(void); + ~CiMA(void); + //--- methods of access to protected data + int MaPeriod(void) const { return(m_ma_period); } + int MaShift(void) const { return(m_ma_shift); } + ENUM_MA_METHOD MaMethod(void) const { return(m_ma_method); } + int Applied(void) const { return(m_applied); } + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ma_shift, + const ENUM_MA_METHOD ma_method,const int applied); + //--- methods of access to indicator data + double Main(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_MA); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ma_shift, + const ENUM_MA_METHOD ma_method,const int applied); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiMA::CiMA(void) : m_ma_period(-1), + m_ma_shift(-1), + m_ma_method(WRONG_VALUE), + m_applied(-1) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiMA::~CiMA(void) + { + } +//+------------------------------------------------------------------+ +//| Create indicator "Moving Average" | +//+------------------------------------------------------------------+ +bool CiMA::Create(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ma_shift, + const ENUM_MA_METHOD ma_method,const int applied) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iMA(symbol,period,ma_period,ma_shift,ma_method,applied); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,ma_period,ma_shift,ma_method,applied)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiMA::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value, + (ENUM_MA_METHOD)params[2].integer_value,(int)params[3].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize indicator with the special parameters | +//+------------------------------------------------------------------+ +bool CiMA::Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ma_shift, + const ENUM_MA_METHOD ma_method,const int applied) + { + if(CreateBuffers(symbol,period,1)) + { + //--- string of status of drawing + m_name ="MA"; + m_status="("+symbol+","+PeriodDescription()+","+ + IntegerToString(ma_period)+","+IntegerToString(ma_shift)+","+ + MethodDescription(ma_method)+","+PriceDescription(applied)+") H="+IntegerToString(m_handle); + //--- save settings + m_ma_period=ma_period; + m_ma_shift =ma_shift; + m_ma_method=ma_method; + m_applied =applied; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + ((CIndicatorBuffer*)At(0)).Offset(ma_shift); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to buffer of "Moving Average" | +//+------------------------------------------------------------------+ +double CiMA::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiSAR. | +//| Purpose: Class of the "Parabolic Stop And Reverse System" | +//| indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiSAR : public CIndicator + { +protected: + double m_step; + double m_maximum; + +public: + CiSAR(void); + ~CiSAR(void); + //--- methods of access to protected data + double SarStep(void) const { return(m_step); } + double Maximum(void) const { return(m_maximum); } + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period,const double step,const double maximum); + //--- methods of access to indicator data + double Main(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_SAR); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const double step,const double maximum); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiSAR::CiSAR(void) : m_step(EMPTY_VALUE), + m_maximum(EMPTY_VALUE) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiSAR::~CiSAR(void) + { + } +//+------------------------------------------------------------------+ +//| Create indicator "Parabolic Stop And Reverse System" | +//+------------------------------------------------------------------+ +bool CiSAR::Create(const string symbol,const ENUM_TIMEFRAMES period,const double step,const double maximum) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iSAR(symbol,period,step,maximum); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,step,maximum)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiSAR::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,params[0].double_value,params[1].double_value)); + } +//+------------------------------------------------------------------+ +//| Initialize indicator with the special parameters | +//+------------------------------------------------------------------+ +bool CiSAR::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const double step,const double maximum) + { + if(CreateBuffers(symbol,period,1)) + { + //--- string of status of drawing + m_name ="SAR"; + m_status="("+symbol+","+PeriodDescription()+","+ + DoubleToString(step,4)+","+DoubleToString(maximum,4)+","+") H="+IntegerToString(m_handle); + //--- save settings + m_step =step; + m_maximum=maximum; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to buffer of "Parabolic Stop And Reverse System" | +//+------------------------------------------------------------------+ +double CiSAR::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiStdDev. | +//| Purpose: Class indicator "Standard Deviation". | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiStdDev : public CIndicator + { +protected: + int m_ma_period; + int m_ma_shift; + ENUM_MA_METHOD m_ma_method; + int m_applied; + +public: + CiStdDev(void); + ~CiStdDev(void); + //--- methods of access to protected data + int MaPeriod(void) const { return(m_ma_period); } + int MaShift(void) const { return(m_ma_shift); } + ENUM_MA_METHOD MaMethod(void) const { return(m_ma_method); } + int Applied(void) const { return(m_applied); } + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ma_shift, + const ENUM_MA_METHOD ma_method,const int applied); + //--- methods of access to indicator data + double Main(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_STDDEV); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ma_shift, + const ENUM_MA_METHOD ma_method,const int applied); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiStdDev::CiStdDev(void) : m_ma_period(-1), + m_ma_shift(-1), + m_ma_method(WRONG_VALUE), + m_applied(-1) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiStdDev::~CiStdDev(void) + { + } +//+------------------------------------------------------------------+ +//| Create indicator "Standard Deviation" | +//+------------------------------------------------------------------+ +bool CiStdDev::Create(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ma_shift, + const ENUM_MA_METHOD ma_method,const int applied) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iStdDev(symbol,period,ma_period,ma_shift,ma_method,applied); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,ma_period,ma_shift,ma_method,applied)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiStdDev::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value, + (ENUM_MA_METHOD)params[2].integer_value,(int)params[3].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize indicator with the special parameters | +//+------------------------------------------------------------------+ +bool CiStdDev::Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ma_shift, + const ENUM_MA_METHOD ma_method,const int applied) + { + if(CreateBuffers(symbol,period,1)) + { + //--- string of status of drawing + m_name ="StdDev"; + m_status="("+symbol+","+PeriodDescription()+","+ + IntegerToString(ma_period)+","+IntegerToString(ma_shift)+","+ + MethodDescription(ma_method)+") H="+IntegerToString(m_handle); + //--- save settings + m_ma_period=ma_period; + m_ma_shift =ma_shift; + m_ma_method=ma_method; + m_applied =applied; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + ((CIndicatorBuffer*)At(0)).Offset(ma_shift); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to buffer of "Standard Deviation" | +//+------------------------------------------------------------------+ +double CiStdDev::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiDEMA. | +//| Purpose: Class indicator "Double Exponential Moving Average". | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiDEMA : public CIndicator + { +protected: + int m_ma_period; + int m_ind_shift; + int m_applied; + +public: + CiDEMA(void); + ~CiDEMA(void); + //--- methods of access to protected data + int MaPeriod(void) const { return(m_ma_period); } + int IndShift(void) const { return(m_ind_shift); } + int Applied(void) const { return(m_applied); } + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ind_shift,const int applied); + //--- methods of access to indicator data + double Main(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_DEMA); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ind_shift,const int applied); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiDEMA::CiDEMA(void) : m_ma_period(-1), + m_ind_shift(-1), + m_applied(-1) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiDEMA::~CiDEMA(void) + { + } +//+------------------------------------------------------------------+ +//| Create indicator "Double Exponential Moving Average" | +//+------------------------------------------------------------------+ +bool CiDEMA::Create(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ind_shift,const int applied) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iDEMA(symbol,period,ma_period,ind_shift,applied); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,ma_period,ind_shift,applied)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiDEMA::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value,(int)params[2].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize indicator with the special parameters | +//+------------------------------------------------------------------+ +bool CiDEMA::Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ind_shift,const int applied) + { + if(CreateBuffers(symbol,period,1)) + { + //--- string of status of drawing + m_name ="DEMA"; + m_status="("+symbol+","+PeriodDescription()+","+ + IntegerToString(ma_period)+","+IntegerToString(ind_shift)+","+ + PriceDescription(applied)+") H="+IntegerToString(m_handle); + //--- save settings + m_ma_period=ma_period; + m_ind_shift=ind_shift; + m_applied =applied; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + ((CIndicatorBuffer*)At(0)).Offset(ind_shift); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to buffer of "Double Exponential Moving Average" | +//+------------------------------------------------------------------+ +double CiDEMA::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiTEMA. | +//| Purpose: Class indicator "Triple Exponential Moving Average". | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiTEMA : public CIndicator + { +protected: + int m_ma_period; + int m_ind_shift; + int m_applied; + +public: + CiTEMA(void); + ~CiTEMA(void); + //--- methods of access to protected data + int MaPeriod(void) const { return(m_ma_period); } + int IndShift(void) const { return(m_ind_shift); } + int Applied(void) const { return(m_applied); } + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ma_shift,const int applied); + //--- methods of access to indicator data + double Main(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_TEMA); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ma_shift,const int applied); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiTEMA::CiTEMA(void) : m_ma_period(-1), + m_ind_shift(-1), + m_applied(-1) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiTEMA::~CiTEMA(void) + { + } +//+------------------------------------------------------------------+ +//| Create indicator "Triple Exponential Moving Average" | +//+------------------------------------------------------------------+ +bool CiTEMA::Create(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ind_shift,const int applied) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iTEMA(symbol,period,ma_period,ind_shift,applied); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,ma_period,ind_shift,applied)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiTEMA::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value,(int)params[2].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize indicator with the special parameters | +//+------------------------------------------------------------------+ +bool CiTEMA::Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ind_shift,const int applied) + { + if(CreateBuffers(symbol,period,1)) + { + //--- string of status of drawing + m_name ="TEMA"; + m_status="("+symbol+","+PeriodDescription()+","+ + IntegerToString(ma_period)+","+IntegerToString(ind_shift)+","+ + PriceDescription(applied)+") H="+IntegerToString(m_handle); + //--- save settings + m_ma_period=ma_period; + m_ind_shift=ind_shift; + m_applied =applied; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + ((CIndicatorBuffer*)At(0)).Offset(ind_shift); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to buffer of "Triple Exponential Moving Average" | +//+------------------------------------------------------------------+ +double CiTEMA::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiFrAMA. | +//| Purpose: Class indicator "Fractal Adaptive Moving Average". | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiFrAMA : public CIndicator + { +protected: + int m_ma_period; + int m_ind_shift; + int m_applied; + +public: + CiFrAMA(void); + ~CiFrAMA(void); + //--- methods of access to protected data + int MaPeriod(void) const { return(m_ma_period); } + int IndShift(void) const { return(m_ind_shift); } + int Applied(void) const { return(m_applied); } + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ind_shift,const int applied); + //--- methods of access to indicator data + double Main(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_FRAMA); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ind_shift,const int applied); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiFrAMA::CiFrAMA(void) : m_ma_period(-1), + m_ind_shift(-1), + m_applied(-1) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiFrAMA::~CiFrAMA(void) + { + } +//+------------------------------------------------------------------+ +//| Create indicator "Fractal Adaptive Moving Average" | +//+------------------------------------------------------------------+ +bool CiFrAMA::Create(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ind_shift,const int applied) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iFrAMA(symbol,period,ma_period,ind_shift,applied); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,ma_period,ind_shift,applied)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiFrAMA::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value,(int)params[2].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize indicator with the special parameters | +//+------------------------------------------------------------------+ +bool CiFrAMA::Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int ind_shift,const int applied) + { + if(CreateBuffers(symbol,period,1)) + { + //--- string of status of drawing + m_name ="FrAMA"; + m_status="("+symbol+","+PeriodDescription()+","+ + IntegerToString(ma_period)+","+IntegerToString(ind_shift)+","+ + PriceDescription(applied)+") H="+IntegerToString(m_handle); + //--- save settings + m_ma_period=ma_period; + m_applied =applied; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + ((CIndicatorBuffer*)At(0)).Offset(ind_shift); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to buffer of "Fractal Adaptive Moving Average" | +//+------------------------------------------------------------------+ +double CiFrAMA::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiAMA. | +//| Purpose: Class indicator "Adaptive Moving Average". | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiAMA : public CIndicator + { +protected: + int m_ma_period; + int m_fast_ema_period; + int m_slow_ema_period; + int m_ind_shift; + int m_applied; + +public: + CiAMA(void); + ~CiAMA(void); + //--- methods of access to protected data + int MaPeriod(void) const { return(m_ma_period); } + int FastEmaPeriod(void) const { return(m_fast_ema_period); } + int SlowEmaPeriod(void) const { return(m_slow_ema_period); } + int IndShift(void) const { return(m_ind_shift); } + int Applied(void) const { return(m_applied); } + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int fast_ema_period,const int slow_ema_period, + const int ind_shift,const int applied); + //--- methods of access to indicator data + double Main(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_AMA); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int fast_ema_period,const int slow_ema_period, + const int ind_shift,const int applied); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiAMA::CiAMA(void) : m_ma_period(-1), + m_fast_ema_period(-1), + m_slow_ema_period(-1), + m_ind_shift(-1), + m_applied(-1) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiAMA::~CiAMA(void) + { + } +//+------------------------------------------------------------------+ +//| Create indicator "Adaptive Moving Average" | +//+------------------------------------------------------------------+ +bool CiAMA::Create(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int fast_ema_period,const int slow_ema_period, + const int ind_shift,const int applied) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iAMA(symbol,period,ma_period,fast_ema_period,slow_ema_period,ind_shift,applied); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,ma_period,fast_ema_period,slow_ema_period,ind_shift,applied)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiAMA::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value, + (int)params[2].integer_value,(int)params[3].integer_value, + (int)params[4].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize indicator with the special parameters | +//+------------------------------------------------------------------+ +bool CiAMA::Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const int fast_ema_period,const int slow_ema_period, + const int ind_shift,const int applied) + { + if(CreateBuffers(symbol,period,1)) + { + //--- string of status of drawing + m_name ="AMA"; + m_status="("+symbol+","+PeriodDescription()+","+ + IntegerToString(ma_period)+","+IntegerToString(fast_ema_period)+","+IntegerToString(slow_ema_period)+","+ + IntegerToString(ind_shift)+","+PriceDescription(applied)+") H="+IntegerToString(m_handle); + //--- save settings + m_ma_period =ma_period; + m_fast_ema_period=fast_ema_period; + m_slow_ema_period=slow_ema_period; + m_ind_shift =ind_shift; + m_applied =applied; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + ((CIndicatorBuffer*)At(0)).Offset(ind_shift); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to buffer of "Adaptive Moving Average" | +//+------------------------------------------------------------------+ +double CiAMA::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiVIDyA. | +//| Purpose: Class indicator "Variable Index DYnamic Average". | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiVIDyA : public CIndicator + { +protected: + int m_cmo_period; + int m_ema_period; + int m_ind_shift; + int m_applied; + +public: + CiVIDyA(void); + ~CiVIDyA(void); + //--- methods of access to protected data + int CmoPeriod(void) const { return(m_cmo_period); } + int EmaPeriod(void) const { return(m_ema_period); } + int IndShift(void) const { return(m_ind_shift); } + int Applied(void) const { return(m_applied); } + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period, + const int cmo_period,const int ema_period, + const int ind_shift,const int applied); + //--- methods of access to indicator data + double Main(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_VIDYA); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int cmo_period,const int ema_period, + const int ind_shift,const int applied); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiVIDyA::CiVIDyA(void) : m_cmo_period(-1), + m_ema_period(-1), + m_ind_shift(-1), + m_applied(-1) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiVIDyA::~CiVIDyA(void) + { + } +//+------------------------------------------------------------------+ +//| Create indicator "Variable Index DYnamic Average" | +//+------------------------------------------------------------------+ +bool CiVIDyA::Create(const string symbol,const ENUM_TIMEFRAMES period, + const int cmo_period,const int ema_period, + const int ind_shift,const int applied) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iVIDyA(symbol,period,cmo_period,ema_period,ind_shift,applied); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,cmo_period,ema_period,ind_shift,applied)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiVIDyA::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { +//--- + return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value, + (int)params[2].integer_value,(int)params[3].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize indicator with the special parameters | +//+------------------------------------------------------------------+ +bool CiVIDyA::Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int cmo_period,const int ema_period, + const int ind_shift,const int applied) + { + if(CreateBuffers(symbol,period,1)) + { + //--- string of status of drawing + m_name ="VIDyA"; + m_status="("+symbol+","+PeriodDescription()+","+ + IntegerToString(cmo_period)+","+IntegerToString(ema_period)+","+IntegerToString(ind_shift)+","+ + PriceDescription(applied)+") H="+IntegerToString(m_handle); + //--- save settings + m_cmo_period=cmo_period; + m_ema_period=ema_period; + m_ind_shift =ind_shift; + m_applied =applied; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + ((CIndicatorBuffer*)At(0)).Offset(ind_shift); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to buffer of "Variable Index DYnamic Average" | +//+------------------------------------------------------------------+ +double CiVIDyA::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ diff --git a/Indicators/Volumes.mqh b/Indicators/Volumes.mqh new file mode 100644 index 0000000..435d8cb --- /dev/null +++ b/Indicators/Volumes.mqh @@ -0,0 +1,424 @@ +//+------------------------------------------------------------------+ +//| Volumes.mqh | +//| Copyright 2000-2024, MetaQuotes Ltd. | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#include "Indicator.mqh" +//+------------------------------------------------------------------+ +//| Class CiAD. | +//| Purpose: Class of the "Accumulation/Distribution" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiAD : public CIndicator + { +protected: + ENUM_APPLIED_VOLUME m_applied; // applied volume + +public: + CiAD(void); + ~CiAD(void); + //--- methods of access to protected data + ENUM_APPLIED_VOLUME Applied(void) const { return(m_applied); } + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period,const ENUM_APPLIED_VOLUME applied); + //--- methods of access to indicator data + double Main(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_AD); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const ENUM_APPLIED_VOLUME applied); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiAD::CiAD(void) : m_applied(WRONG_VALUE) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiAD::~CiAD(void) + { + } +//+------------------------------------------------------------------+ +//| Create the "Accumulation/Distribution" indicator | +//+------------------------------------------------------------------+ +bool CiAD::Create(const string symbol,const ENUM_TIMEFRAMES period,const ENUM_APPLIED_VOLUME applied) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iAD(symbol,period,applied); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,applied)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiAD::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(ENUM_APPLIED_VOLUME)params[0].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with special parameters | +//+------------------------------------------------------------------+ +bool CiAD::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const ENUM_APPLIED_VOLUME applied) + { + if(CreateBuffers(symbol,period,1)) + { + //--- string of status of drawing + m_name ="AD"; + m_status="("+symbol+","+PeriodDescription()+","+VolumeDescription(applied)+") H="+IntegerToString(m_handle); + //--- save settings + m_applied=applied; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to buffer of "Accumulation/Distribution" | +//+------------------------------------------------------------------+ +double CiAD::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiMFI. | +//| Purpose: Class of the "Money Flow Index" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiMFI : public CIndicator + { +protected: + int m_ma_period; + ENUM_APPLIED_VOLUME m_applied; + +public: + CiMFI(void); + ~CiMFI(void); + //--- methods of access to protected data + int MaPeriod(void) const { return(m_ma_period); } + ENUM_APPLIED_VOLUME Applied(void) const { return(m_applied); } + //--- method of creation + bool Create(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const ENUM_APPLIED_VOLUME applied); + //--- methods of access to indicator data + double Main(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_MFI); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const ENUM_APPLIED_VOLUME applied); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiMFI::CiMFI(void) : m_ma_period(-1), + m_applied(WRONG_VALUE) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiMFI::~CiMFI(void) + { + } +//+------------------------------------------------------------------+ +//| Create the "Money Flow Index" indicator | +//+------------------------------------------------------------------+ +bool CiMFI::Create(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const ENUM_APPLIED_VOLUME applied) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iMFI(symbol,period,ma_period,applied); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,ma_period,applied)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiMFI::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(int)params[0].integer_value,(ENUM_APPLIED_VOLUME)params[1].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with special parameters | +//+------------------------------------------------------------------+ +bool CiMFI::Initialize(const string symbol,const ENUM_TIMEFRAMES period, + const int ma_period,const ENUM_APPLIED_VOLUME applied) + { + if(CreateBuffers(symbol,period,1)) + { + //--- string of status of drawing + m_name ="MFI"; + m_status="("+symbol+","+PeriodDescription()+","+ + IntegerToString(ma_period)+","+VolumeDescription(applied)+","+") H="+IntegerToString(m_handle); + //--- save settings + m_ma_period=ma_period; + m_applied =applied; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to buffer of "Money Flow Index" | +//+------------------------------------------------------------------+ +double CiMFI::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiOBV. | +//| Purpose: Class of the "On Balance Volume" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiOBV : public CIndicator + { +protected: + ENUM_APPLIED_VOLUME m_applied; + +public: + CiOBV(void); + ~CiOBV(void); + //--- methods of access to protected data + ENUM_APPLIED_VOLUME Applied(void) const { return(m_applied); } + //--- method create + bool Create(const string symbol,const ENUM_TIMEFRAMES period,const ENUM_APPLIED_VOLUME applied); + //--- methods of access to indicator data + double Main(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_OBV); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const ENUM_APPLIED_VOLUME applied); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiOBV::CiOBV(void) : m_applied(WRONG_VALUE) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiOBV::~CiOBV(void) + { + } +//+------------------------------------------------------------------+ +//| Create the "On Balance Volume" indicator | +//+------------------------------------------------------------------+ +bool CiOBV::Create(const string symbol,const ENUM_TIMEFRAMES period,const ENUM_APPLIED_VOLUME applied) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iOBV(symbol,period,applied); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,applied)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiOBV::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(ENUM_APPLIED_VOLUME)params[0].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with special parameters | +//+------------------------------------------------------------------+ +bool CiOBV::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const ENUM_APPLIED_VOLUME applied) + { + if(CreateBuffers(symbol,period,1)) + { + //--- string of status of drawing + m_name ="OBV"; + m_status="("+symbol+","+PeriodDescription()+","+VolumeDescription(applied)+","+") H="+IntegerToString(m_handle); + //--- save settings + m_applied=applied; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to buffer of "On Balance Volume" | +//+------------------------------------------------------------------+ +double CiOBV::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ +//| Class CiVolumes. | +//| Purpose: Class of the "Volumes" indicator. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiVolumes : public CIndicator + { +protected: + ENUM_APPLIED_VOLUME m_applied; + +public: + CiVolumes(void); + ~CiVolumes(void); + //--- methods of access to protected data + ENUM_APPLIED_VOLUME Applied(void) const { return(m_applied); } + //--- method create + bool Create(const string symbol,const ENUM_TIMEFRAMES period,const ENUM_APPLIED_VOLUME applied); + //--- methods of access to indicator data + double Main(const int index) const; + //--- method of identifying + virtual int Type(void) const { return(IND_VOLUMES); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const ENUM_APPLIED_VOLUME applied); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiVolumes::CiVolumes(void) : m_applied(WRONG_VALUE) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiVolumes::~CiVolumes(void) + { + } +//+------------------------------------------------------------------+ +//| Create the "Volumes" indicator | +//+------------------------------------------------------------------+ +bool CiVolumes::Create(const string symbol,const ENUM_TIMEFRAMES period,const ENUM_APPLIED_VOLUME applied) + { +//--- check history + if(!SetSymbolPeriod(symbol,period)) + return(false); +//--- create + m_handle=iVolumes(symbol,period,applied); +//--- check result + if(m_handle==INVALID_HANDLE) + return(false); +//--- indicator successfully created + if(!Initialize(symbol,period,applied)) + { + //--- initialization failed + IndicatorRelease(m_handle); + m_handle=INVALID_HANDLE; + return(false); + } +//--- ok + return(true); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiVolumes::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + return(Initialize(symbol,period,(ENUM_APPLIED_VOLUME)params[0].integer_value)); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with special parameters | +//+------------------------------------------------------------------+ +bool CiVolumes::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const ENUM_APPLIED_VOLUME applied) + { + if(CreateBuffers(symbol,period,1)) + { + //--- string of status of drawing + m_name ="Volumes"; + m_status="("+symbol+","+PeriodDescription()+","+VolumeDescription(applied)+","+") H="+IntegerToString(m_handle); + //--- save settings + m_applied=applied; + //--- create buffers + ((CIndicatorBuffer*)At(0)).Name("MAIN_LINE"); + //--- ok + return(true); + } +//--- error + return(false); + } +//+------------------------------------------------------------------+ +//| Access to buffer of "Volumes" | +//+------------------------------------------------------------------+ +double CiVolumes::Main(const int index) const + { + CIndicatorBuffer *buffer=At(0); +//--- check + if(buffer==NULL) + return(EMPTY_VALUE); +//--- + return(buffer.At(index)); + } +//+------------------------------------------------------------------+ diff --git a/Layouts/Box.mqh b/Layouts/Box.mqh new file mode 100644 index 0000000..6a05d66 --- /dev/null +++ b/Layouts/Box.mqh @@ -0,0 +1,385 @@ +//+------------------------------------------------------------------+ +//| Box.mqh | +//| Enrico Lambino | +//| www.mql5.com/en/users/iceron| +//+------------------------------------------------------------------+ +#property copyright "Enrico Lambino" +#property link "www.mql5.com/en/users/iceron" +#include +#define CLASS_LAYOUT 999 + +#ifdef LAYOUT_BOX_DEBUG +#define COLOR_BOX_BORDER clrRed +#else +#define COLOR_BOX_BORDER clrNONE +#endif +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +enum LAYOUT_STYLE +{ + LAYOUT_STYLE_VERTICAL, + LAYOUT_STYLE_HORIZONTAL +}; +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +enum VERTICAL_ALIGN +{ + VERTICAL_ALIGN_CENTER, + VERTICAL_ALIGN_CENTER_NOSIDES, + VERTICAL_ALIGN_TOP, + VERTICAL_ALIGN_BOTTOM +}; +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +enum HORIZONTAL_ALIGN +{ + HORIZONTAL_ALIGN_CENTER, + HORIZONTAL_ALIGN_CENTER_NOSIDES, + HORIZONTAL_ALIGN_LEFT, + HORIZONTAL_ALIGN_RIGHT +}; +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +class CBox: public CWndClient +{ + protected: + LAYOUT_STYLE m_layout_style; + VERTICAL_ALIGN m_vertical_align; + HORIZONTAL_ALIGN m_horizontal_align; + CSize m_min_size; + int m_controls_total; + int m_padding_top; + int m_padding_bottom; + int m_padding_left; + int m_padding_right; + int m_total_x; + int m_total_y; + + public: + CBox(); + ~CBox(); + virtual int Type() const + { + return CLASS_LAYOUT; + } + virtual bool Create(const long chart, const string name, const int subwin, + const int x1, const int y1, const int x2, const int y2); + virtual bool Pack(); + void LayoutStyle(LAYOUT_STYLE style) + { + m_layout_style = style; + } + LAYOUT_STYLE LayoutStyle() const + { + return (m_layout_style); + } + void HorizontalAlign(const HORIZONTAL_ALIGN align) + { + m_horizontal_align = align; + } + HORIZONTAL_ALIGN HorizontalAlign() const + { + return (m_horizontal_align); + } + void VerticalAlign(const VERTICAL_ALIGN align) + { + m_vertical_align = align; + } + VERTICAL_ALIGN VerticalAlign() const + { + return (m_vertical_align); + } + void Padding(const int top, const int bottom, const int left, const int right,const int padding); + //void Padding(const int padding); + void PaddingTop(const int padding) + { + m_padding_top = padding; + } + int PaddingTop() const + { + return (m_padding_top); + } + void PaddingRight(const int padding) + { + m_padding_right = padding; + } + int PaddingRight() const + { + return (m_padding_right); + } + void PaddingBottom(const int padding) + { + m_padding_bottom = padding; + } + int PaddingBottom() const + { + return (m_padding_bottom); + } + void PaddingLeft(const int padding) + { + m_padding_left = padding; + } + int PaddingLeft() const + { + return (m_padding_left); + } + CSize GetMinSize() const + { + CSize sz; + sz.cx = m_min_size.cx + m_padding_left + m_padding_right; + sz.cy = m_min_size.cy + m_padding_top + m_padding_bottom; + return sz; + } + + protected: + virtual void CheckControlSize(CWnd *control); + virtual void GetTotalControlsSize(void); + virtual bool GetSpace(int &x_space, int &y_space); + virtual bool Render(void); + virtual void Shift(CWnd *control, int &x, int &y, const int x_space, const int y_space); +}; +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +CBox::CBox(): + m_layout_style(LAYOUT_STYLE_HORIZONTAL), + m_vertical_align(VERTICAL_ALIGN_CENTER), + m_horizontal_align(HORIZONTAL_ALIGN_CENTER), + m_controls_total(0), + m_padding_top(2), + m_padding_bottom(2), + m_padding_left(2), + m_padding_right(2), + m_total_x(0), + m_total_y(0) + +{ + m_min_size.cx = 0; + m_min_size.cy = 0; +} +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +CBox::~CBox() +{ +} +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +bool CBox::Create(const long chart, const string name, const int subwin, + const int x1, const int y1, const int x2, const int y2) +{ + if(!CWndContainer::Create(chart, name, subwin, x1, y1, x2, y2)) + return (false); + if(!CreateBack()) + return (false); + if(!ColorBackground(CONTROLS_DIALOG_COLOR_CLIENT_BG)) + return (false); + if(!ColorBorder(COLOR_BOX_BORDER)) + return (false); + return (true); +} +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +bool CBox::Pack(void) +{ + GetTotalControlsSize(); + return (Render()); +} +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void CBox::CheckControlSize(CWnd *control) +{ + bool adjust = false; + CSize size = Size(); + CSize control_size = control.Size(); + if(control_size.cx > size.cx - (m_padding_left + m_padding_right)) + { + control_size.cx = size.cx - (m_padding_left + m_padding_right); + adjust = true; + } + if(control_size.cy > size.cy - (m_padding_top + m_padding_bottom)) + { + control_size.cy = size.cy - (m_padding_top + m_padding_bottom); + adjust = true; + } + if(adjust) + control.Size(control_size.cx, control_size.cy); +} +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void CBox::GetTotalControlsSize(void) +{ + m_total_x = 0; + m_total_y = 0; + m_controls_total = 0; + m_min_size.cx = 0; + m_min_size.cy = 0; + int total = ControlsTotal(); + + + for(int i = 0; i < total; i++) + { + CWnd *control = Control(i); + if(control == NULL) continue; + if(control == &m_background) continue; + CheckControlSize(control); + if(control.Type() == CLASS_LAYOUT) + { + ((CBox *)control).GetTotalControlsSize(); + } + + CSize control_size = control.Size(); + if(m_min_size.cx < control_size.cx) + m_min_size.cx = control_size.cx; + if(m_min_size.cy < control_size.cy) + m_min_size.cy = control_size.cy; + if(m_layout_style == LAYOUT_STYLE_HORIZONTAL) m_total_x += control_size.cx; + else m_total_x = MathMax(m_min_size.cx, m_total_x); + if(m_layout_style == LAYOUT_STYLE_VERTICAL) m_total_y += control_size.cy; + else m_total_y = MathMax(m_min_size.cy, m_total_y); + m_controls_total++; + } + + CSize size = Size(); + + if(m_total_x > size.cx && m_layout_style == LAYOUT_STYLE_HORIZONTAL) + { + size.cx = m_total_x; + } + if(m_total_y > size.cy && m_layout_style == LAYOUT_STYLE_VERTICAL) // shrink + { + size.cy = m_total_y; + } + + Size(size); +} + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +bool CBox::GetSpace(int &x_space, int &y_space) +{ + if(m_controls_total == 0) + return (true); + if(m_controls_total == 1) + { + if(m_horizontal_align == HORIZONTAL_ALIGN_CENTER_NOSIDES) + m_horizontal_align = HORIZONTAL_ALIGN_CENTER; + if(m_vertical_align == VERTICAL_ALIGN_CENTER_NOSIDES) + m_vertical_align = VERTICAL_ALIGN_CENTER; + } + CSize size = Size(); + + int x_space_total = 0; + int y_space_total = 0; + if(m_layout_style == LAYOUT_STYLE_HORIZONTAL) + { + x_space_total = size.cx - (m_total_x + m_padding_left + m_padding_right); + y_space_total = size.cy - (m_min_size.cy + m_padding_top + m_padding_bottom); + + if(m_horizontal_align == HORIZONTAL_ALIGN_CENTER_NOSIDES) + x_space = x_space_total / (m_controls_total - 1); + else if(m_horizontal_align == HORIZONTAL_ALIGN_CENTER) + x_space = x_space_total / (m_controls_total + 1); + else + x_space = x_space_total / m_controls_total; + + if(m_vertical_align == VERTICAL_ALIGN_CENTER || m_vertical_align == VERTICAL_ALIGN_CENTER_NOSIDES) + y_space = y_space_total / 2; + else + y_space = y_space_total; + } + else if(m_layout_style == LAYOUT_STYLE_VERTICAL) + { + x_space_total = size.cx - (m_min_size.cx + m_padding_left + m_padding_right); + y_space_total = size.cy - (m_total_y + m_padding_top + m_padding_bottom); + + if(m_horizontal_align == HORIZONTAL_ALIGN_CENTER || m_horizontal_align == HORIZONTAL_ALIGN_CENTER_NOSIDES) + x_space = x_space_total / 2; + else + x_space = x_space_total; + + if(m_vertical_align == VERTICAL_ALIGN_CENTER_NOSIDES) + y_space = y_space_total / (m_controls_total - 1); + else if(m_vertical_align == VERTICAL_ALIGN_CENTER) + y_space = y_space_total / (m_controls_total + 1); + else + y_space = y_space_total / m_controls_total; + } + else + return (false); + + if(x_space < 0) x_space = 0; + if(y_space < 0) y_space = 0; + + return (true); +} +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void CBox::Shift(CWnd *control, int &x, int &y, const int x_space, const int y_space) +{ + if(m_layout_style == LAYOUT_STYLE_HORIZONTAL) + x += x_space + control.Width(); + else if(m_layout_style == LAYOUT_STYLE_VERTICAL) + y += y_space + control.Height(); +} +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +bool CBox::Render(void) +{ + int x_space = 0, y_space = 0; + if(!GetSpace(x_space, y_space)) + return (false); + int x = Left() + m_padding_left + + ((m_horizontal_align == HORIZONTAL_ALIGN_LEFT || m_horizontal_align == HORIZONTAL_ALIGN_CENTER_NOSIDES) ? 0 : x_space); + int y = Top() + m_padding_top + + ((m_vertical_align == VERTICAL_ALIGN_TOP || m_vertical_align == VERTICAL_ALIGN_CENTER_NOSIDES) ? 0 : y_space); + for(int j = 0; j < ControlsTotal(); j++) + { + CWnd *control = Control(j); + if(control == NULL) + continue; + if(control == GetPointer(m_background)) + continue; + control.Move(x, y); + if(control.Type() == CLASS_LAYOUT) + { + CBox *container = control; + container.Pack(); + } + if(j < ControlsTotal() - 1) + Shift(GetPointer(control), x, y, x_space, y_space); + } + return (true); +} +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +CBox::Padding(const int top, const int right, const int bottom, const int left,const int padding) +{ + m_padding_top = top; + m_padding_right = right; + m_padding_bottom = bottom; + m_padding_left = left; +} +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +// CBox::Padding(const int padding) +// { +// m_padding_top = padding; +// m_padding_right = padding; +// m_padding_bottom = padding; +// m_padding_left = padding; +// } +//+------------------------------------------------------------------+ diff --git a/Layouts/ComboBoxResizable.mqh b/Layouts/ComboBoxResizable.mqh new file mode 100644 index 0000000..500647c --- /dev/null +++ b/Layouts/ComboBoxResizable.mqh @@ -0,0 +1,66 @@ +//+------------------------------------------------------------------+ +//| ComboBoxResizable.mqh | +//| Copyright (c) 2019, Marketeer | +//| https://www.mql5.com/en/users/marketeer | +//+------------------------------------------------------------------+ + +#include + +class ComboBoxResizable: public CComboBox +{ + public: + virtual bool OnEvent(const int id, const long &lparam, const double &dparam, const string &sparam) override; + + virtual bool OnResize(void) override + { + m_edit.Width(Width()); + + int x1 = Width() - (CONTROLS_BUTTON_SIZE + CONTROLS_COMBO_BUTTON_X_OFF); + int y1 = (Height() - CONTROLS_BUTTON_SIZE) / 2; + m_drop.Move(Left() + x1, Top() + y1); + + m_list.Width(Width()); + + return CWndContainer::OnResize(); + } + + virtual bool OnClickButton(void) override + { + // this is a hack to trigger resizing of elements in the list + // we need it because standard ListView is incorrectly coded in such a way + // that elements are resized only if vscroll is present + bool vs = m_list.VScrolled(); + if(m_drop.Pressed()) + { + m_list.VScrolled(true); + } + bool b = CComboBox::OnClickButton(); + m_list.VScrolled(vs); + return b; + } + + virtual bool Enable(void) override + { + m_edit.Show(); + m_drop.Show(); + return CComboBox::Enable(); + } + + virtual bool Disable(void) override + { + m_edit.Hide(); + m_drop.Hide(); + return CComboBox::Disable(); + } +}; + +#define EXIT_ON_DISABLED \ + if(!IsEnabled()) \ + { \ + return false; \ + } + +EVENT_MAP_BEGIN(ComboBoxResizable) + EXIT_ON_DISABLED + ON_EVENT(ON_CLICK, m_drop, OnClickButton) +EVENT_MAP_END(CComboBox) diff --git a/Layouts/Grid.mqh b/Layouts/Grid.mqh new file mode 100644 index 0000000..5a209e8 --- /dev/null +++ b/Layouts/Grid.mqh @@ -0,0 +1,153 @@ +//+------------------------------------------------------------------+ +//| Grid.mqh | +//| Enrico Lambino | +//| www.mql5.com/en/users/iceron| +//+------------------------------------------------------------------+ +#property copyright "Enrico Lambino" +#property link "http://www.mql5.com" +#property strict +#include "Box.mqh" +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +class CGrid: public CBox +{ + protected: + int m_cols; + int m_rows; + int m_hgap; + int m_vgap; + CSize m_cell_size; + + public: + CGrid(); + CGrid(int rows, int cols, int hgap = 0, int vgap = 0); + ~CGrid(); + virtual int Type() const + { + return CLASS_LAYOUT; + } + virtual bool Init(int rows, int cols, int hgap = 0, int vgap = 0); + virtual bool Create(const long chart, const string name, const int subwin, + const int x1, const int y1, const int x2, const int y2); + virtual int Columns() + { + return (m_cols); + } + virtual void Columns(int cols) + { + m_cols = cols; + } + virtual int Rows() + { + return (m_rows); + } + virtual void Rows(int rows) + { + m_rows = rows; + } + virtual int HGap() + { + return (m_hgap); + } + virtual void HGap(int gap) + { + m_hgap = gap; + } + virtual int VGap() + { + return (m_vgap); + } + virtual void VGap(int gap) + { + m_vgap = gap; + } + virtual bool Pack(); + + protected: + virtual void CheckControlSize(CWnd *control); +}; +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +CGrid::CGrid() +{ +} +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +CGrid::CGrid(int rows, int cols, int hgap = 0, int vgap = 0) +{ + Init(rows, cols, hgap, vgap); +} +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +CGrid::~CGrid() +{ +} +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +bool CGrid::Init(int rows, int cols, int hgap = 0, int vgap = 0) +{ + Columns(cols); + Rows(rows); + HGap(hgap); + VGap(vgap); + return (true); +} +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +bool CGrid::Create(const long chart, const string name, const int subwin, + const int x1, const int y1, const int x2, const int y2) +{ + return (CBox::Create(chart, name, subwin, x1, y1, x2, y2)); +} +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +bool CGrid::Pack() +{ + CSize size = Size(); + m_cell_size.cx = (size.cx - ((m_cols + 1) * m_hgap)) / m_cols; + m_cell_size.cy = (size.cy - ((m_rows + 1) * m_vgap)) / m_rows; + int x = Left(), y = Top(); + int cnt = 0; + for(int i = 0; i < ControlsTotal(); i++) + { + CWnd *control = Control(i); + if(control == NULL) + continue; + if(control == GetPointer(m_background)) + continue; + if(cnt == 0 || Right() - (x + m_cell_size.cx) < m_cell_size.cx + m_hgap) + { + if(cnt == 0) + y += m_vgap; + else + y += m_vgap + m_cell_size.cy; + x = Left() + m_hgap; + } + else + x += m_cell_size.cx + m_hgap; + CheckControlSize(control); + control.Move(x, y); + if(control.Type() == CLASS_LAYOUT) + { + CBox *container = control; + container.Pack(); + } + cnt++; + } + return (true); +} +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +CGrid::CheckControlSize(CWnd *control) +{ + control.Size(m_cell_size.cx, m_cell_size.cy); +} +//+------------------------------------------------------------------+ diff --git a/Layouts/GridTk.mqh b/Layouts/GridTk.mqh new file mode 100644 index 0000000..a9348f7 --- /dev/null +++ b/Layouts/GridTk.mqh @@ -0,0 +1,154 @@ +//+------------------------------------------------------------------+ +//| GridTk.mqh | +//| Enrico Lambino | +//| www.mql5.com/en/users/iceron| +//+------------------------------------------------------------------+ +#property copyright "Enrico Lambino" +#property link "http://www.mql5.com" +#property strict +#include "Grid.mqh" +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +class CGridConstraints: public CObject +{ + protected: + CWnd *m_control; + int m_row; + int m_col; + int m_rowspan; + int m_colspan; + + public: + CGridConstraints(CWnd *control, int row, int column, int rowspan = 1, int colspan = 1); + ~CGridConstraints(); + CWnd *Control() + { + return (m_control); + } + int Row() + { + return (m_row); + } + int Column() + { + return (m_col); + } + int RowSpan() + { + return (m_rowspan); + } + int ColSpan() + { + return (m_colspan); + } +}; +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +CGridConstraints::CGridConstraints(CWnd *control, int row, int column, int rowspan = 1, int colspan = 1) +{ + m_control = control; + m_row = MathMax(0, row); + m_col = MathMax(0, column); + m_rowspan = MathMax(1, rowspan); + m_colspan = MathMax(1, colspan); +} +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +CGridConstraints::~CGridConstraints() +{ +} +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +class CGridTk: public CGrid +{ + protected: + CArrayObj m_constraints; + + public: + CGridTk(); + ~CGridTk(); + bool Grid(CWnd *control, int row, int column, int rowspan, int colspan); + bool Pack(); + CGridConstraints *GetGridConstraints(CWnd *control); +}; +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +CGridTk::CGridTk(void) +{ +} +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +CGridTk::~CGridTk(void) +{ +} +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +bool CGridTk::Grid(CWnd *control, int row, int column, int rowspan = 1, int colspan = 1) +{ + CGridConstraints *constraints = new CGridConstraints(control, row, column, rowspan, colspan); + if(!CheckPointer(constraints)) + return (false); + if(!m_constraints.Add(constraints)) + return (false); + return (Add(control)); +} +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +bool CGridTk::Pack() +{ + CGrid::Pack(); + CSize size = Size(); + m_cell_size.cx = (size.cx - (m_cols + 1) * m_hgap) / m_cols; + m_cell_size.cy = (size.cy - (m_rows + 1) * m_vgap) / m_rows; + for(int i = 0; i < ControlsTotal(); i++) + { + int x = Left(), y = Top(); + CWnd *control = Control(i); + if(control == NULL) + continue; + if(control == GetPointer(m_background)) + continue; + CGridConstraints *constraints = GetGridConstraints(control); + if(constraints == NULL) + continue; + int column = constraints.Column(); + int row = constraints.Row(); + x += (column * m_cell_size.cx) + ((column + 1) * m_hgap); + y += (row * m_cell_size.cy) + ((row + 1) * m_vgap); + int colspan = constraints.ColSpan(); + int rowspan = constraints.RowSpan(); + control.Size(colspan * m_cell_size.cx + ((colspan - 1) * m_hgap), rowspan * m_cell_size.cy + ((rowspan - 1) * m_vgap)); + control.Move(x, y); + if(control.Type() == CLASS_LAYOUT) + { + CBox *container = control; + container.Pack(); + } + } + return (true); +} +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +CGridConstraints *CGridTk::GetGridConstraints(CWnd *control) +{ + for(int i = 0; i < m_constraints.Total(); i++) + { + CGridConstraints *constraints = m_constraints.At(i); + CWnd *ctrl = constraints.Control(); + if(ctrl == NULL) + continue; + if(ctrl == control) + return (constraints); + } + return (NULL); +} +//+------------------------------------------------------------------+ diff --git a/Layouts/MaximizableAppDialog.mqh b/Layouts/MaximizableAppDialog.mqh new file mode 100644 index 0000000..d41c47b --- /dev/null +++ b/Layouts/MaximizableAppDialog.mqh @@ -0,0 +1,337 @@ +//+------------------------------------------------------------------+ +//| MaximizableAppDialog.mqh | +//| Copyright (c) 2019, Marketeer | +//| https://www.mql5.com/en/users/marketeer | +//+------------------------------------------------------------------+ + +#include +#include + +#resource "res\\Expand2.bmp" +#resource "res\\size6.bmp" +#resource "res\\size10.bmp" + +class MaximizableAppDialog: public CAppDialog +{ + protected: + CBmpButton m_button_truemax; + CBmpButton m_button_size; + bool m_maximized; + CRect m_max_rect; + CSize m_size_limit; + bool m_sizing; + + // window maximization + virtual bool CreateButtonMinMax(void) override; + virtual void OnClickButtonMinMax(void) override; + virtual void OnClickButtonTrueMax(void); + virtual void OnClickButtonSizeFixMe(void); + virtual void Expand(void); + virtual void Restore(void); + + virtual void Minimize(void) override; + + // window resizing + bool CreateButtonSize(void); + bool OnDialogSizeStart(void); + virtual bool OnDialogDragStart(void) override; + virtual bool OnDialogDragProcess(void) override; + virtual bool OnDialogDragEnd(void) override; + + virtual void SelfAdjustment(const bool minimized = false) = 0; + + public: + MaximizableAppDialog(): m_maximized(false), m_sizing(false) {} + virtual bool Create(const long chart, const string name, const int subwin, const int x1, const int y1, const int x2, const int y2) override; + virtual bool OnEvent(const int id, const long &lparam, const double &dparam, const string &sparam) override; + + virtual bool OnChartChange(const long &lparam, const double &dparam, const string &sparam); + + void ChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam); + + void SetSizeLimit(const CSize &limit) { m_size_limit = limit; } + CSize GetSizeLimit() { return m_size_limit; } +}; + +void MaximizableAppDialog::ChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) +{ + if(id == CHARTEVENT_CHART_CHANGE) + { + if(OnChartChange(lparam, dparam, sparam)) return; + } + CAppDialog::ChartEvent(id, lparam, dparam, sparam); +} + +EVENT_MAP_BEGIN(MaximizableAppDialog) + ON_EVENT(ON_CLICK, m_button_truemax, OnClickButtonTrueMax) + ON_EVENT(ON_CLICK, m_button_size, OnClickButtonSizeFixMe) + ON_EVENT(ON_DRAG_START, m_button_size, OnDialogSizeStart) + ON_EVENT_PTR(ON_DRAG_PROCESS, m_drag_object, OnDialogDragProcess) + ON_EVENT_PTR(ON_DRAG_END, m_drag_object, OnDialogDragEnd) +EVENT_MAP_END(CAppDialog) + +bool MaximizableAppDialog::Create(const long chart, const string name, const int subwin, const int x1, const int y1, const int x2, const int y2) +{ + // 1 * CONTROLS_BORDER_WIDTH - stays here, because the standard control library minimizes window + // when it's height is 1 pixel smaller than the entire chart height + m_max_rect.SetBound(0, + 0, + (int)ChartGetInteger(ChartID(), CHART_WIDTH_IN_PIXELS) - 0 * CONTROLS_BORDER_WIDTH, + (int)ChartGetInteger(ChartID(), CHART_HEIGHT_IN_PIXELS) - 1 * CONTROLS_BORDER_WIDTH); + if(!CAppDialog::Create(chart, name, subwin, x1, y1, x2, y2)) return false; + if(!CreateButtonSize()) return false; + m_size_limit.cx = x2 - x1; + m_size_limit.cy = y2 - y1; + if(m_size_limit.cx >= m_max_rect.Width() || m_size_limit.cy >= m_max_rect.Height()) + { + m_size_limit.cx = m_min_rect.Width() * 3; + m_size_limit.cy = m_min_rect.Height() * 7; + } + + return true; +} + +bool MaximizableAppDialog::CreateButtonMinMax(void) override +{ + if(!CAppDialog::CreateButtonMinMax()) return false; + + // add maximization button + int off = (m_panel_flag) ? 0 : 2 * CONTROLS_BORDER_WIDTH; + + int x1 = Width() - off - 3 * (CONTROLS_BUTTON_SIZE + CONTROLS_DIALOG_BUTTON_OFF); + int y1 = off + CONTROLS_DIALOG_BUTTON_OFF; + int x2 = x1 + CONTROLS_BUTTON_SIZE; + int y2 = y1 + CONTROLS_BUTTON_SIZE; + + if(!m_button_truemax.Create(m_chart_id, m_name + "TrueMax", m_subwin, x1, y1, x2, y2)) return false; + if(!m_button_truemax.BmpNames("::res\\Expand2.bmp", "::res\\Restore.bmp")) return false; + if(!CWndContainer::Add(m_button_truemax)) return false; + + m_button_truemax.Locking(true); + m_button_truemax.Alignment(WND_ALIGN_RIGHT, 0, 0, off + 2 * CONTROLS_BUTTON_SIZE + 2 * CONTROLS_DIALOG_BUTTON_OFF, 0); + + CaptionAlignment(WND_ALIGN_WIDTH, off, 0, off + 3 * (CONTROLS_BUTTON_SIZE + CONTROLS_DIALOG_BUTTON_OFF), 0); + + return true; +} + +bool MaximizableAppDialog::CreateButtonSize(void) +{ + int off = (m_panel_flag) ? 0 : 2 * CONTROLS_BORDER_WIDTH; + + int x1 = Width() - CONTROLS_BUTTON_SIZE + 1; + int y1 = Height() - CONTROLS_BUTTON_SIZE + 1; + int x2 = x1 + CONTROLS_BUTTON_SIZE - 1; + int y2 = y1 + CONTROLS_BUTTON_SIZE - 1; + + if(!m_button_size.Create(m_chart_id, m_name + "Size", m_subwin, x1, y1, x2, y2)) return false; + if(!m_button_size.BmpNames("::res\\size6.bmp", "::res\\size10.bmp")) return false; + if(!CWndContainer::Add(m_button_size)) return false; + m_button_size.Alignment(WND_ALIGN_RIGHT|WND_ALIGN_BOTTOM, 0, 0, 0, 0); + m_button_size.PropFlagsSet(WND_PROP_FLAG_CAN_DRAG); + + return true; +} + +void MaximizableAppDialog::OnClickButtonTrueMax(void) +{ + if(m_button_truemax.Pressed()) + Expand(); + else + Restore(); + + SubwinOff(); +} + +// This is a hack. It's required because in minimized state sizing button somehow "overlaps" +// the close button and intercepts clicks on it (which prevents exit from minimized app). +// This happens despite the fact that the sizing button is hidden, disabled and assigned +// with minimal Z-order (checked out, then removed). +// Looks like a bug in the standard control library, specifically: +// In CWnd::OnMouseEvent there must be a line: +// +// if(!IS_ENABLED || !IS_VISIBLE) return false; +// +// but it's not there, so invisible, disabled and even background objects are processed +// in the same manner as all other objects. Specifically in CWndContainer::OnMouseEvent +// there is a reverse loop through all objects (it does _not_ respect Z-order anyhow). + +void MaximizableAppDialog::OnClickButtonSizeFixMe(void) +{ + if(m_minimized) + { + Destroy(); + } +} + +void MaximizableAppDialog::Expand(void) +{ + m_maximized = true; + m_minimized = false; + m_button_minmax.Pressed(false); + Rebound(m_max_rect); + m_button_size.Hide(); + m_button_size.StateFlagsReset(WND_STATE_FLAG_ENABLE); + m_button_size.PropFlagsReset(WND_PROP_FLAG_CAN_DRAG); + if(!m_panel_flag) + { + m_caption.PropFlagsReset(WND_PROP_FLAG_CAN_DRAG); + } + + ClientAreaVisible(true); + SelfAdjustment(); +} + +//+------------------------------------------------------------------+ +//| Restore dialog window | +//+------------------------------------------------------------------+ +void MaximizableAppDialog::Restore(void) +{ + m_maximized = false; + m_minimized = false; + m_button_minmax.Pressed(false); + m_button_size.Show(); + m_button_size.StateFlagsSet(WND_STATE_FLAG_ENABLE); + m_button_size.PropFlagsSet(WND_PROP_FLAG_CAN_DRAG); + CAppDialog::Maximize(); + if(!m_panel_flag) + { + m_caption.PropFlagsSet(WND_PROP_FLAG_CAN_DRAG); + } + SelfAdjustment(); +} + +void MaximizableAppDialog::Minimize() +{ + CAppDialog::Minimize(); + m_button_size.Hide(); + m_button_size.StateFlagsReset(WND_STATE_FLAG_ENABLE); + m_button_size.PropFlagsReset(WND_PROP_FLAG_CAN_DRAG); +} + +bool MaximizableAppDialog::OnChartChange(const long &lparam, const double &dparam, const string &sparam) +{ + m_max_rect.SetBound(0, 0, + (int)ChartGetInteger(ChartID(), CHART_WIDTH_IN_PIXELS) - 0 * CONTROLS_BORDER_WIDTH, + (int)ChartGetInteger(ChartID(), CHART_HEIGHT_IN_PIXELS) - 1 * CONTROLS_BORDER_WIDTH); + if(m_maximized) + { + if(m_rect.Width() != m_max_rect.Width() || m_rect.Height() != m_max_rect.Height()) + { + Rebound(m_max_rect); + SelfAdjustment(); + m_chart.Redraw(); + } + return true; + } + return false; +} + +void MaximizableAppDialog::OnClickButtonMinMax(void) +{ + CAppDialog::OnClickButtonMinMax(); + m_button_truemax.Pressed(false); + m_maximized = false; + if(m_minimized) + { + m_button_size.Hide(); + m_button_size.StateFlagsReset(WND_STATE_FLAG_ENABLE); + m_button_size.PropFlagsReset(WND_PROP_FLAG_CAN_DRAG); + } + else + { + m_button_size.Show(); + m_button_size.StateFlagsSet(WND_STATE_FLAG_ENABLE); + m_button_size.PropFlagsSet(WND_PROP_FLAG_CAN_DRAG); + } + if(!m_panel_flag) + { + m_caption.PropFlagsSet(WND_PROP_FLAG_CAN_DRAG); + } + SelfAdjustment(m_minimized); +} + +bool MaximizableAppDialog::OnDialogSizeStart(void) +{ + if(m_drag_object == NULL) + { + m_drag_object = new CDragWnd; + if(m_drag_object == NULL) return false; + } + int x1 = m_button_size.Left() - CONTROLS_DRAG_SPACING; + int y1 = m_button_size.Top() - CONTROLS_DRAG_SPACING; + int x2 = m_button_size.Right() + CONTROLS_DRAG_SPACING; + int y2 = m_button_size.Bottom() + CONTROLS_DRAG_SPACING; + + m_drag_object.Create(m_chart_id, "", m_subwin, x1, y1, x2, y2); + m_drag_object.PropFlagsSet(WND_PROP_FLAG_CAN_DRAG); + + CChart chart; + chart.Attach(m_chart_id); + m_drag_object.Limits(-CONTROLS_DRAG_SPACING, -CONTROLS_DRAG_SPACING, + chart.WidthInPixels() + CONTROLS_DRAG_SPACING, + chart.HeightInPixels(m_subwin) + CONTROLS_DRAG_SPACING); + chart.Detach(); + + m_drag_object.MouseX(m_button_size.MouseX()); + m_drag_object.MouseY(m_button_size.MouseY()); + m_drag_object.MouseFlags(m_button_size.MouseFlags()); + + m_sizing = true; + + return true; +} + +bool MaximizableAppDialog::OnDialogDragStart(void) +{ + if(m_maximized) return false; + + return CAppDialog::OnDialogDragStart(); +} +//+------------------------------------------------------------------+ +//| Continue dragging the dialog box | +//+------------------------------------------------------------------+ +bool MaximizableAppDialog::OnDialogDragProcess(void) +{ + if(!m_sizing) return CDialog::OnDialogDragProcess(); + + if(m_drag_object == NULL) return false; + + int x = m_drag_object.Right() - Right() - CONTROLS_DRAG_SPACING; + int y = m_drag_object.Bottom() - Bottom() - CONTROLS_DRAG_SPACING; + + // resize dialog + CRect r = Rect(); + r.right += x; + r.bottom += y; + + if(r.Width() < m_size_limit.cx) r.right = r.left + m_size_limit.cx; + if(r.Height() < m_size_limit.cy) r.bottom = r.top + m_size_limit.cy; + + Rebound(r); + + SelfAdjustment(); + + return true; +} +//+------------------------------------------------------------------+ +//| End dragging the dialog box | +//+------------------------------------------------------------------+ +bool MaximizableAppDialog::OnDialogDragEnd(void) +{ + if(!m_sizing) return CDialog::OnDialogDragEnd(); + + if(m_drag_object != NULL) + { + m_button_size.MouseFlags(m_drag_object.MouseFlags()); + delete m_drag_object; + m_drag_object = NULL; + } + + m_norm_rect.SetBound(m_rect); + m_sizing = false; + + SelfAdjustment(); + + return true; +} diff --git a/Layouts/SpinEditResizable.mqh b/Layouts/SpinEditResizable.mqh new file mode 100644 index 0000000..e8a1f63 --- /dev/null +++ b/Layouts/SpinEditResizable.mqh @@ -0,0 +1,27 @@ +//+------------------------------------------------------------------+ +//| SpinEditResizable.mqh | +//| Copyright (c) 2019, Marketeer | +//| https://www.mql5.com/en/users/marketeer | +//+------------------------------------------------------------------+ + +#include + +class SpinEditResizable: public CSpinEdit +{ + public: + virtual bool OnResize(void) override + { + m_edit.Width(Width()); + m_edit.Height(Height()); + + int x1 = Width() - (CONTROLS_BUTTON_SIZE + CONTROLS_SPIN_BUTTON_X_OFF); + int y1 = (Height() - 2 * CONTROLS_SPIN_BUTTON_SIZE) / 2; + m_inc.Move(Left() + x1, Top() + y1); + + x1 = Width() - (CONTROLS_BUTTON_SIZE + CONTROLS_SPIN_BUTTON_X_OFF); + y1 = (Height() - 2 * CONTROLS_SPIN_BUTTON_SIZE) / 2 + CONTROLS_SPIN_BUTTON_SIZE; + m_dec.Move(Left() + x1, Top() + y1); + + return CWndContainer::OnResize(); + } +}; \ No newline at end of file diff --git a/Layouts/res/Expand2.bmp b/Layouts/res/Expand2.bmp new file mode 100644 index 0000000000000000000000000000000000000000..40da9f2f3a3fc305b8aa763912f87f56dfb1290f GIT binary patch literal 1078 zcmZ?rHDh4_12Z700mK4O%*dbsWB~zCUWgllAp*mT?C$RVKWWmW{~#KM(fJ^8T)qaW z#U%$5$EP2k96j_C<9>W<7A#mmk^k|TO|1Xdty}jWAI4_~vObVsK>X#)m%}lLkI#=F Wc~BgJXplX~dSPsQ_QU)*lxP4tuasy2 literal 0 HcmV?d00001 diff --git a/Layouts/res/size10.bmp b/Layouts/res/size10.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b54a419fec6f1976d211ba076469d4177d8a3d8d GIT binary patch literal 1078 zcmZ?rHDh4_12Z700mK4O%*dbsWB~zCUWgllAp+DVySuypgD}WsV%X>|AVv?e8g%{C vQEES>`l;!cfi?>O-m7Y- literal 0 HcmV?d00001 diff --git a/Layouts/res/size6.bmp b/Layouts/res/size6.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3c6d8109e339298520fc9d17f2d6588a48e04c15 GIT binary patch literal 1078 zcmZ?rHDh4_12Z700mK4O%*dbsWB~zCUWgllAp*1|ySuypgD}VzTx@(Uz@-OS9G`w_ i$|2i{%qG?jWIf1iV)au~9i{eDs-K#E88wTt5C8xQ%|NFB literal 0 HcmV?d00001 diff --git a/MT4Bridge/MT4Orders.mqh b/MT4Bridge/MT4Orders.mqh new file mode 100644 index 0000000000000000000000000000000000000000..a19ecbf784e0506283c159b225381c0ca1312d96 GIT binary patch literal 182558 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

RWehl`NVprEj*^KnREI4cKf#*PG)Pu*;ZN| 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 literal 0 HcmV?d00001 diff --git a/MT4Bridge/MT4Time.mqh b/MT4Bridge/MT4Time.mqh new file mode 100644 index 0000000000000000000000000000000000000000..73991f022d5a1bb71f74eb460dcd61c5b66ea316 GIT binary patch literal 4222 zcmd6p-EY${6vfXo68}RaB-Ao!VHyt`kK=)th=)}|JXI{qXhoBar3F>n{&nD7JFcCN zIv)$u6s55m`**Id&$aXS&lFP};LQ`b4)7e$7|j%S2p;hYF~bq>B@)D#@b@Pc)W7== z@tooc*Vy8QYTv1{rp^cv#(W;)E#Bc6uh|aqjeUMFo;B~7?T5!BYHO-zI8j;t4Y~Au zS9s4>#OM;fi;?no!=9p?v7LD1c}o5f4@Fop-i%j(k8DW}&HBpwTeY&{v1_#wzw$mO zyZ_}~NFS^!;{)d6g2asX4RaLn`9X~nvSw~@&XG&LD-z4GjJWQ%yU1qD{+UA^(GTK< zs@|B2_k~!?SN+OSQe}NrxB2)s zs@=7^&_m`y^1J9Tmqd+e6T4ogu32hB{=^u>JMGzvd_)_1NGGP`OZB%`NYtn{{4;W8 z$4u$Qtb>B=s?n}O?w#GETE+9q{$ux=7u1dEf0<>>y7AT3OjTBuHYx2A(r?nDN@cIx zr*FO9U)3_kYMDy1lmI105~v*c1EF zPVLA}^f|CKyR;W}F8i6hw&{?*HVz;2g+0*Ku{^xgvw@BEi5DaJdTbZ+VyHV0!oJQRx^8Vrk@Y{^)BZH~4_)RL)$&LfT?wtexJ16dtEcP^Yx?kv zlc#;jll$3g3u$YKo6i!hTUtkz6nc(SAt_%kT<_|9JUQF?KG69{XUEyD+aJmcxQM^# zqZ)P;#f9!&>V$o8?;D*B+tP{cJFZ6HOQ9%Xa!*XT&~>4>hFVkDvZR;wjc%;?3M+)v znR|LyPwz-q8O>k1pV|(n@eK=)qzyaXSL&%}FP)d(SL9x~Siz+4qI;=TJl&k$=UG+T zp8SO2tPZ`W)DrFx3t2mxNN+{*NLAPKn>;^vXdc(B2c5w(U4U4?3RJ6k0o_Y^M`x%? zmHvPWjH^ow)nl%N0XkuNoY$4aU%X1=4!(xCJs*PSKPbvmdEV4n`g!JZ6?{r<<7vwd z#qXcQ*FF1EJut-+%Wont>j)zeJb6DDei&31i#8yii~6}TdnJ^qv7v=5oGQ;vVVPSo zJF^32a3rn{ltU&`ndv20`)&1+C$??->X|#r*>}1=(AB>B&AUeucziDY(2=Rcca0%L zun4E-q5NlsUAINGD;#f&Wy$82aJW)t!6HPn7}jqll@vHIy9?20=#5PHBAJJUI&|0@ z`F=aE!pNeZYoQ(wCjB7BEoGsfX6KH_BiFBP+)iYu&R%F|T1<8v^u7zR^ir05uj@O6 zm{VO{ahDxTb=`(m$Lj(rA?tyCv6Sy|9cd2pk*Hv2(|zY7rK>gMLq3*<+vh!$3|@V! z)9<7yoUK`*}5xS{+Ld zJ&zq$Iw3s+n?f&0t<2n^Jymvo&BPTd5ybzCw|lC8`uQ`}{I2@@j^2REdynlG&FShL zCO}7Ps`ol>GO#|crTYA5*=bAXu0t-3KiBI#KbI8Eny^l%-l7cMb~6S(!qApu*|L5W z%0<|zhMr4q3%w)XHoLIs?fDnFQt1UXNZj=)8S|=Mq2(^&d=eQu`hCY#_UUM)?~L^{ z)`b6U*YV0XBx?0UXfZYX+Md>3XC#^5slIq$TlHvYPqPdjJ5R|BU1=!R|tT%E0pvL}v$UooByF(&p6EIHDZhpzrddXkTyRrSb%rr2tz z_0X$2F0W~ndCzh-0tb8Q=>DGo-n_uRs=K4k%zFj3RKsb!wmNGtD3)gdKT?#*oC5f#hy95&Zvju~&Z2xfpxV7g$0a<@+mAF+Sdte9gCA z--^32|2@%vsmjHBaV`sI(lk&WLe+OCS~tWes*!)uuu<~a-(M9IZ<{CY^_t7aNN<+p z285bAz_+X)?0UYhO>3l@W%_1UlOydb{{Ac$$EfG<2y<>t-ks=3eIvhqB4ORfG|L_+ cmGb!tt$Pvs2s7#uaUBMaW9_jPH1K}-FP0A%1^@s6 literal 0 HcmV?d00001 diff --git a/Marketeer/CSVcolumns.mqh b/Marketeer/CSVcolumns.mqh new file mode 100644 index 0000000000000000000000000000000000000000..368a19fc758da46c8ded48b9c457cb0e85e00ab1 GIT binary patch literal 764 zcmb7?%?^Sv5QOJ!;yaM|00{m7MEwym^q!OOsULKvzXaiAFTZ{Me)k6E-{#W`4dZVPYd<-yMXLso`uxJ#f+Ik z&bW^^^4TW;$V1XBW~CFd)_%Zw!T+jj%#)C6j;M9-)3}GB?fi_{k@bhcHO|=|-^QQq zEQjh2!;_On#AC!SBdc=#Jx+nGDPvCzK6+O;HM_*RY+h>6f9ELXRXu}JhY_nA+FDd) zU5{>5enL0g5Idqr+BfM-V_hw;Nbf1vOI%rB>vd&})mn90JZiSpi!XF`sH(v!e@%6( zoRl5R$tdOR$`EI##ao#xi&RyhNYO97z^}L#UHmRrpLdIEQ@PDt*Q+YHR(^Q{?8&5m literal 0 HcmV?d00001 diff --git a/Marketeer/GroupSettings.mqh b/Marketeer/GroupSettings.mqh new file mode 100644 index 0000000000000000000000000000000000000000..8668560a16a91f7839aa01af0606b2b857bfca2a GIT binary patch literal 50 zcmezWFO?yWp_Cz)L4m=Yp@<9k5X)Kc9~S%p>)T@=3I*$yZmW3eMFlVZ|4Gfvs>d>v(p{QNCX;!;Cb;5; zJ05uQ>yX3afDRRo2ntIBP;sg>?{?U(Y*KaH14txNE7iDDt literal 0 HcmV?d00001 diff --git a/Marketeer/IndexMap.mqh b/Marketeer/IndexMap.mqh new file mode 100644 index 0000000000000000000000000000000000000000..4e467695d54d406bfb43242fa6e9772b8c3b0c54 GIT binary patch literal 17274 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 literal 0 HcmV?d00001 diff --git a/Marketeer/RubbArray.mqh b/Marketeer/RubbArray.mqh new file mode 100644 index 0000000000000000000000000000000000000000..ba260355e04b7cf7a71ba1676302de510d96dbab GIT binary patch literal 7580 zcmd5>Yfl?T6uqA-^*?N>8ky1*(>7I`08&a*DN@=-KtEKdLVyji0Grr`nC9`*+nzJy z%gmjb^{Wt}mA&honfo~RIpcr-S(Q~;k%#x-T9HrX6G*cv@1*)j*S1{BA+D#=$8{jr z^0l1HYk39!@9sdJE$PVxxb&qXC*U#!pN1UCGVb3eSHqZqN=FCb~pNqpqK zTktQ=&={t4EzlU^vnPLzWztcddEp}Q%-PnizrwpdR$pTM8EAbdNJO2L5-A64l#llq zMpeK^$KIQ@F`bn66*TQY8;^Gz5_x*@nw)pYF59rr02Kaqc2ZOr@y#2nO_z#@GLO(l zh-(jbBHI9E`c8#AGYaFm3w}eRUoKxCl!$L1vn%8!{vs{)BP&s?DJC9C7mLi(fjXgH-o|c%*k2Cx{QfmRL z5v0^NDPoG8Mff-QLtfx|V(h}X))V>0u2hfNgDz<#`L(Ha=p7f%=V$i^ZOH5M% zTxQ`Bdcj~n>cX)VT(ib{+OGr|L!YAdy+$5o55%r+A0PG|L)f66#wP4DLd9baOp(^O z^f@f%_L=i)&AquM^_hz!YTH1O{c_xM)k$KbR^@ABE&J;@ighfHO&w7wrfHw^%->kw zog78VKbE!}P3+?ah{wB+pwNq@5xfEJlVhfm2gr=p2XfRkBX(S0pn0*CMMsPZk(wDXVOsc#kf3rCtt+kd@>IWA$on<_dW1#r&-_#Uu`$g?g_MbpK?TcqcC{Vaf zq*VL3o-W!KPDadnY`yJbYq8S$ebEVgj(z7&^k%*umbADVWgX|PDyHo78c&gi7}=BW zkc;+k;-wksEn;U0kbMid&@YIMKKzdn zL_eV?#??c+VP84u+a=%3k+c<{fk;WSpIt+o`O#?M^L*!i$DbDG5!m20Wp;HR}?X%ZQ`CXo)AKaB^u+F~xEPvwHQ~Y!C z96Lv5IbuQ!_!D>Svg$fbYZ0Oraz%YtHSeh{qs{*hz;k`OOR*MWmvfb5;(Dvj*4tVi zq>dha_M5Cpv-h<3#cI^STGnUbt3oBoEo^gNy2j2=bKd99zmA=+^52^mcw)7v3b}%7 R)A`Kp{C9`_K%QN=;y?7jqj>-T literal 0 HcmV?d00001 diff --git a/Marketeer/WebDataExtractor.mqh b/Marketeer/WebDataExtractor.mqh new file mode 100644 index 0000000000000000000000000000000000000000..19a1c6ecf1e5157bdc78831ad3d3d94723e3c2fa GIT binary patch literal 84488 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 B)WrY* literal 0 HcmV?d00001 diff --git a/Marketeer/empty_strings.h b/Marketeer/empty_strings.h new file mode 100644 index 0000000..9f6fcf9 --- /dev/null +++ b/Marketeer/empty_strings.h @@ -0,0 +1,20 @@ +// header +"isindex", +"base", +"meta", +"link", +"nextid", +"range", +// elsewhere +"img", +"br", +"hr", +"frame", +"wbr", +"basefont", +"spacer", +"area", +"param", +"keygen", +"col", +"limittext" \ No newline at end of file diff --git a/Math/Alglib/alglib.mqh b/Math/Alglib/alglib.mqh new file mode 100644 index 0000000..78a53de --- /dev/null +++ b/Math/Alglib/alglib.mqh @@ -0,0 +1,38345 @@ +//+------------------------------------------------------------------+ +//| alglib.mqh | +//| Copyright 2003-2022 Sergey Bochkanov (ALGLIB project) | +//| Copyright 2012-2023, MetaQuotes Ltd. | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +//| Implementation of ALGLIB library in MetaQuotes Language 5 | +//| | +//| The features of the library include: | +//| - Linear algebra (direct algorithms, EVD, SVD) | +//| - Solving systems of linear and non-linear equations | +//| - Interpolation | +//| - Optimization | +//| - FFT (Fast Fourier Transform) | +//| - Numerical integration | +//| - Linear and nonlinear least-squares fitting | +//| - Ordinary differential equations | +//| - Computation of special functions | +//| - Descriptive statistics and hypothesis testing | +//| - Data analysis - classification, regression | +//| - Implementing linear algebra algorithms, interpolation, etc. | +//| in high-precision arithmetic (using MPFR) | +//| | +//| This file is free software; you can redistribute it and/or | +//| modify it under the terms of the GNU General Public License as | +//| published by the Free Software Foundation (www.fsf.org); either | +//| version 2 of the License, or (at your option) any later version. | +//| | +//| This program is distributed in the hope that it will be useful, | +//| but WITHOUT ANY WARRANTY; without even the implied warranty of | +//| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | +//| GNU General Public License for more details. | +//+------------------------------------------------------------------+ + +#include +#include "alglibmisc.mqh" +#include "dataanalysis.mqh" +#include "diffequations.mqh" +#include "delegatefunctions.mqh" +#include "fasttransforms.mqh" +#include "integration.mqh" +#include "interpolation.mqh" + +//+------------------------------------------------------------------+ +//| The main class, which includes functions for users | +//+------------------------------------------------------------------+ +class CAlglib + { +public: + //--- function of package alglibmisc + //--- high quality random number generator + static void HQRndRandomize(CHighQualityRandStateShell &state); + static void HQRndSeed(const int s1,const int s2,CHighQualityRandStateShell &state); + static double HQRndUniformR(CHighQualityRandStateShell &state); + static int HQRndUniformI(CHighQualityRandStateShell &state,const int n); + static double HQRndNormal(CHighQualityRandStateShell &state); + static void HQRndNormalV(CHighQualityRandStateShell &state,int n,CRowDouble &x); + static void HQRndNormalV(CHighQualityRandStateShell &state,int n,vector &x); + static void HQRndNormalM(CHighQualityRandStateShell &state,int m,int n,CMatrixDouble &x); + static void HQRndNormalM(CHighQualityRandStateShell &state,int m,int n,matrix &x); + static void HQRndUnit2(CHighQualityRandStateShell &state,double &x,double &y); + static void HQRndNormal2(CHighQualityRandStateShell &state,double &x1,double &x2); + static double HQRndExponential(CHighQualityRandStateShell &state,const double lambdav); + static double HQRndDiscrete(CHighQualityRandStateShell &state,int n,CRowDouble &x); + static double HQRndDiscrete(CHighQualityRandStateShell &state,int n,vector &x); + static double HQRndContinuous(CHighQualityRandStateShell &state,int n,CRowDouble &x); + static double HQRndContinuous(CHighQualityRandStateShell &state,int n,vector &x); + //--- build KD-trees + static void KDTreeSerialize(CKDTreeShell &obj,string &s_out); + static void KDTreeUnserialize(string s_in,CKDTreeShell &obj); + static void KDTreeBuild(CMatrixDouble &xy,const int n,const int nx,const int ny,const int normtype,CKDTreeShell &kdt); + static void KDTreeBuild(CMatrixDouble &xy,const int nx,const int ny,const int normtype,CKDTreeShell &kdt); + static void KDTreeBuildTagged(CMatrixDouble &xy,int &tags[],const int n,const int nx,const int ny,const int normtype,CKDTreeShell &kdt); + static void KDTreeBuildTagged(CMatrixDouble &xy,CRowInt &tags,const int n,const int nx,const int ny,const int normtype,CKDTreeShell &kdt); + static void KDTreeBuildTagged(CMatrixDouble &xy,int &tags[],const int nx,const int ny,const int normtype,CKDTreeShell &kdt); + static void KDTreeBuildTagged(CMatrixDouble &xy,CRowInt &tags,const int nx,const int ny,const int normtype,CKDTreeShell &kdt); + static void KDTreeCreateRequestBuffer(CKDTreeShell &kdt,CKDTreeRequestBufferShell &buf); + static int KDTreeQueryKNN(CKDTreeShell &kdt,double &x[],const int k,const bool selfmatch=true); + static int KDTreeQueryKNN(CKDTreeShell &kdt,CRowDouble &x,const int k,const bool selfmatch=true); + static int KDTreeQueryKNN(CKDTreeShell &kdt,vector &x,const int k,const bool selfmatch=true); + static int KDTreeTsQueryKNN(CKDTreeShell &kdt,CKDTreeRequestBufferShell &buf,double &x[],const int k,const bool selfmatch=true); + static int KDTreeTsQueryKNN(CKDTreeShell &kdt,CKDTreeRequestBufferShell &buf,CRowDouble &x,const int k,const bool selfmatch=true); + static int KDTreeTsQueryKNN(CKDTreeShell &kdt,CKDTreeRequestBufferShell &buf,vector &x,const int k,const bool selfmatch=true); + static int KDTreeQueryRNN(CKDTreeShell &kdt,double &x[],const double r,const bool selfmatch=true); + static int KDTreeQueryRNN(CKDTreeShell &kdt,CRowDouble &x,const double r,const bool selfmatch=true); + static int KDTreeQueryRNN(CKDTreeShell &kdt,vector &x,const double r,const bool selfmatch=true); + static int KDTreeQueryRNNU(CKDTreeShell &kdt,double &x[],const double r,const bool selfmatch=true); + static int KDTreeQueryRNNU(CKDTreeShell &kdt,CRowDouble &x,const double r,const bool selfmatch=true); + static int KDTreeQueryRNNU(CKDTreeShell &kdt,vector &x,const double r,const bool selfmatch=true); + static int KDTreeTsQueryRNN(CKDTreeShell &kdt,CKDTreeRequestBufferShell &buf,double &x[],const double r,const bool selfmatch=true); + static int KDTreeTsQueryRNN(CKDTreeShell &kdt,CKDTreeRequestBufferShell &buf,CRowDouble &x,const double r,const bool selfmatch=true); + static int KDTreeTsQueryRNN(CKDTreeShell &kdt,CKDTreeRequestBufferShell &buf,vector &x,const double r,const bool selfmatch=true); + static int KDTreeTsQueryRNNU(CKDTreeShell &kdt,CKDTreeRequestBufferShell &buf,double &x[],const double r,const bool selfmatch=true); + static int KDTreeTsQueryRNNU(CKDTreeShell &kdt,CKDTreeRequestBufferShell &buf,CRowDouble &x,const double r,const bool selfmatch=true); + static int KDTreeTsQueryRNNU(CKDTreeShell &kdt,CKDTreeRequestBufferShell &buf,vector &x,const double r,const bool selfmatch=true); + static int KDTreeQueryAKNN(CKDTreeShell &kdt,double &x[],const int k,const bool selfmatch=true,const double eps=0); + static int KDTreeQueryAKNN(CKDTreeShell &kdt,vector &x,const int k,const bool selfmatch=true,const double eps=0); + static int KDTreeQueryAKNN(CKDTreeShell &kdt,CRowDouble &x,const int k,const bool selfmatch=true,const double eps=0); + static int KDTreeQueryBox(CKDTreeShell &kdt,double &boxmin[],double &boxmax[]); + static int KDTreeQueryBox(CKDTreeShell &kdt,vector &boxmin,vector &boxmax); + static int KDTreeQueryBox(CKDTreeShell &kdt,CRowDouble &boxmin,CRowDouble &boxmax); + static int KDTreeTsQueryBox(CKDTreeShell &kdt,CKDTreeRequestBufferShell &buf,double &boxmin[],double &boxmax[]); + static int KDTreeTsQueryBox(CKDTreeShell &kdt,CKDTreeRequestBufferShell &buf,vector &boxmin,vector &boxmax); + static int KDTreeTsQueryBox(CKDTreeShell &kdt,CKDTreeRequestBufferShell &buf,CRowDouble &boxmin,CRowDouble &boxmax); + static void KDTreeQueryResultsX(CKDTreeShell &kdt,CMatrixDouble &x); + static void KDTreeQueryResultsXY(CKDTreeShell &kdt,CMatrixDouble &xy); + static void KDTreeQueryResultsTags(CKDTreeShell &kdt,int &tags[]); + static void KDTreeQueryResultsTags(CKDTreeShell &kdt,CRowInt &tags); + static void KDTreeQueryResultsDistances(CKDTreeShell &kdt,double &r[]); + static void KDTreeQueryResultsDistances(CKDTreeShell &kdt,vector &r); + static void KDTreeQueryResultsDistances(CKDTreeShell &kdt,CRowDouble &r); + static void KDTreeQueryResultsXI(CKDTreeShell &kdt,CMatrixDouble &x); + static void KDTreeQueryResultsXYI(CKDTreeShell &kdt,CMatrixDouble &xy); + static void KDTreeQueryResultsTagsI(CKDTreeShell &kdt,int &tags[]); + static void KDTreeQueryResultsTagsI(CKDTreeShell &kdt,CRowInt &tags); + static void KDTreeQueryResultsDistancesI(CKDTreeShell &kdt,double &r[]); + static void KDTreeQueryResultsDistancesI(CKDTreeShell &kdt,vector &r); + static void KDTreeQueryResultsDistancesI(CKDTreeShell &kdt,CRowDouble &r); + //--- functions of package dataanalysis + //--- data analysis + static void DSOptimalSplit2(double &a[],int &c[],const int n,int &info,double &threshold,double &pal,double &pbl,double &par,double &pbr,double &cve); + static void DSOptimalSplit2(CRowDouble &a,CRowInt &c,const int n,int &info,double &threshold,double &pal,double &pbl,double &par,double &pbr,double &cve); + static void DSOptimalSplit2Fast(double &a[],int &c[],int &tiesbuf[],int &cntbuf[],double &bufr[],int &bufi[],const int n,const int nc,const double alpha,int &info,double &threshold,double &rms,double &cvrms); + static void DSOptimalSplit2Fast(CRowDouble &a,CRowInt &c,CRowInt &tiesbuf,CRowInt &cntbuf,CRowDouble &bufr,CRowInt &bufi,const int n,const int nc,const double alpha,int &info,double &threshold,double &rms,double &cvrms); + //--- decision forest + static void DFSerialize(CDecisionForestShell &obj,string &s_out); + static void DFUnserialize(const string s_in,CDecisionForestShell &obj); + static void DFCreateBuffer(CDecisionForestShell &model,CDecisionForestBuffer &buf); + static void DFBuilderCreate(CDecisionForestBuilder &s); + static void DFBuilderSetDataset(CDecisionForestBuilder &s,CMatrixDouble &xy,int npoints,int nvars,int nclasses); + static void DFBuilderSetRndVars(CDecisionForestBuilder &s,int rndvars); + static void DFBuilderSetRndVarsRatio(CDecisionForestBuilder &s,double f); + static void DFBuilderSetRndVarsAuto(CDecisionForestBuilder &s); + static void DFBuilderSetSubsampleRatio(CDecisionForestBuilder &s,double f); + static void DFBuilderSetSeed(CDecisionForestBuilder &s,int seedval); + static void DFBuilderSetRDFAlgo(CDecisionForestBuilder &s,int algotype); + static void DFBuilderSetRDFSplitStrength(CDecisionForestBuilder &s,int splitstrength); + static void DFBuilderSetImportanceTrnGini(CDecisionForestBuilder &s); + static void DFBuilderSetImportanceOOBGini(CDecisionForestBuilder &s); + static void DFBuilderSetImportancePermutation(CDecisionForestBuilder &s); + static void DFBuilderSetImportanceNone(CDecisionForestBuilder &s); + static double DFBuilderGetProgress(CDecisionForestBuilder &s); + static double DFBuilderPeekProgress(CDecisionForestBuilder &s); + static void DFBuilderBuildRandomForest(CDecisionForestBuilder &s,int ntrees,CDecisionForestShell &df,CDFReportShell &rep); + static double DFBinaryCompression(CDecisionForestShell &df); + static void DFProcess(CDecisionForestShell &df,double &x[],double &y[]); + static void DFProcessI(CDecisionForestShell &df,double &x[],double &y[]); + static double DFProcess0(CDecisionForestShell &model,double &x[]); + static double DFProcess0(CDecisionForestShell &model,CRowDouble &x); + static int DFClassify(CDecisionForestShell &model,double &x[]); + static int DFClassify(CDecisionForestShell &model,CRowDouble &x); + static double DFRelClsError(CDecisionForestShell &df,CMatrixDouble &xy,const int npoints); + static double DFAvgCE(CDecisionForestShell &df,CMatrixDouble &xy,const int npoints); + static double DFRMSError(CDecisionForestShell &df,CMatrixDouble &xy,const int npoints); + static double DFAvgError(CDecisionForestShell &df,CMatrixDouble &xy,const int npoints); + static double DFAvgRelError(CDecisionForestShell &df,CMatrixDouble &xy,const int npoints); + static void DFBuildRandomDecisionForest(CMatrixDouble &xy,const int npoints,const int nvars,const int nclasses,const int ntrees,const double r,int &info,CDecisionForestShell &df,CDFReportShell &rep); + static void DFBuildRandomDecisionForestX1(CMatrixDouble &xy,const int npoints,const int nvars,const int nclasses,const int ntrees,int nrndvars,const double r,int &info,CDecisionForestShell &df,CDFReportShell &rep); + //--- middle and clusterization + static void ClusterizerCreate(CClusterizerState &s); + static void ClusterizerSetPoints(CClusterizerState &s,CMatrixDouble &xy,int npoints,int nfeatures,int disttype); + static void ClusterizerSetPoints(CClusterizerState &s,CMatrixDouble &xy,int disttype); + static void ClusterizerSetDistances(CClusterizerState &s,CMatrixDouble &d,int npoints,bool IsUpper); + static void ClusterizerSetDistances(CClusterizerState &s,CMatrixDouble &d,bool IsUpper); + static void ClusterizerSetAHCAlgo(CClusterizerState &s,int algo); + static void ClusterizerSetKMeansLimits(CClusterizerState &s,int restarts,int maxits); + static void ClusterizerSetKMeansInit(CClusterizerState &s,int initalgo); + static void ClusterizerSetSeed(CClusterizerState &s,int seed); + static void ClusterizerRunAHC(CClusterizerState &s,CAHCReport &rep); + static void ClusterizerRunKMeans(CClusterizerState &s,int k,CKmeansReport &rep); + static void ClusterizerGetDistances(CMatrixDouble &xy,int npoints,int nfeatures,int disttype,CMatrixDouble &d); + static void ClusterizerGetKClusters(CAHCReport &rep,int k,CRowInt &cidx,CRowInt &cz); + static void ClusterizerSeparatedByDist(CAHCReport &rep,double r,int &k,CRowInt &cidx,CRowInt &cz); + static void ClusterizerSeparatedByCorr(CAHCReport &rep,double r,int &k,CRowInt &cidx,CRowInt &cz); + static void KMeansGenerate(CMatrixDouble &xy,const int npoints,const int nvars,const int k,const int restarts,int &info,CMatrixDouble &c,int &xyc[]); + //--- Fisher LDA functions + static void FisherLDA(CMatrixDouble &xy,const int npoints,const int nvars,const int nclasses,int &info,double &w[]); + static void FisherLDA(CMatrixDouble &xy,const int npoints,const int nvars,const int nclasses,int &info,CRowDouble &w); + static void FisherLDAN(CMatrixDouble &xy,const int npoints,const int nvars,const int nclasses,int &info,CMatrixDouble &w); + //--- linear regression + static void LRBuild(CMatrixDouble &xy,const int npoints,const int nvars,int &info,CLinearModelShell &lm,CLRReportShell &ar); + static void LRBuildS(CMatrixDouble &xy,double &s[],const int npoints,const int nvars,int &info,CLinearModelShell &lm,CLRReportShell &ar); + static void LRBuildS(CMatrixDouble &xy,CRowDouble &s,const int npoints,const int nvars,int &info,CLinearModelShell &lm,CLRReportShell &ar); + static void LRBuildZS(CMatrixDouble &xy,double &s[],const int npoints,const int nvars,int &info,CLinearModelShell &lm,CLRReportShell &ar); + static void LRBuildZS(CMatrixDouble &xy,CRowDouble &s,const int npoints,const int nvars,int &info,CLinearModelShell &lm,CLRReportShell &ar); + static void LRBuildZ(CMatrixDouble &xy,const int npoints,const int nvars,int &info,CLinearModelShell &lm,CLRReportShell &ar); + static void LRUnpack(CLinearModelShell &lm,double &v[],int &nvars); + static void LRUnpack(CLinearModelShell &lm,CRowDouble &v,int &nvars); + static void LRPack(double &v[],const int nvars,CLinearModelShell &lm); + static void LRPack(CRowDouble &v,const int nvars,CLinearModelShell &lm); + static double LRProcess(CLinearModelShell &lm,double &x[]); + static double LRProcess(CLinearModelShell &lm,CRowDouble &x); + static double LRRMSError(CLinearModelShell &lm,CMatrixDouble &xy,const int npoints); + static double LRAvgError(CLinearModelShell &lm,CMatrixDouble &xy,const int npoints); + static double LRAvgRelError(CLinearModelShell &lm,CMatrixDouble &xy,const int npoints); + //--- multilayer perceptron + static void MLPSerialize(CMultilayerPerceptronShell &obj,string &s_out); + static void MLPUnserialize(const string s_in,CMultilayerPerceptronShell &obj); + static void MLPCreate0(const int nin,const int nout,CMultilayerPerceptronShell &network); + static void MLPCreate1(const int nin,int nhid,const int nout,CMultilayerPerceptronShell &network); + static void MLPCreate2(const int nin,const int nhid1,const int nhid2,const int nout,CMultilayerPerceptronShell &network); + static void MLPCreateB0(const int nin,const int nout,const double b,const double d,CMultilayerPerceptronShell &network); + static void MLPCreateB1(const int nin,int nhid,const int nout,const double b,const double d,CMultilayerPerceptronShell &network); + static void MLPCreateB2(const int nin,const int nhid1,const int nhid2,const int nout,const double b,const double d,CMultilayerPerceptronShell &network); + static void MLPCreateR0(const int nin,const int nout,double a,const double b,CMultilayerPerceptronShell &network); + static void MLPCreateR1(const int nin,int nhid,const int nout,const double a,const double b,CMultilayerPerceptronShell &network); + static void MLPCreateR2(const int nin,const int nhid1,const int nhid2,const int nout,const double a,const double b,CMultilayerPerceptronShell &network); + static void MLPCreateC0(const int nin,const int nout,CMultilayerPerceptronShell &network); + static void MLPCreateC1(const int nin,int nhid,const int nout,CMultilayerPerceptronShell &network); + static void MLPCreateC2(const int nin,const int nhid1,const int nhid2,const int nout,CMultilayerPerceptronShell &network); + static void MLPRandomize(CMultilayerPerceptronShell &network); + static void MLPRandomizeFull(CMultilayerPerceptronShell &network); + static void MLPInitPreprocessor(CMultilayerPerceptronShell &network,CMatrixDouble &xy,int ssize); + static void MLPProperties(CMultilayerPerceptronShell &network,int &nin,int &nout,int &wcount); + static int MLPGetInputsCount(CMultilayerPerceptronShell &network); + static int MLPGetOutputsCount(CMultilayerPerceptronShell &network); + static int MLPGetWeightsCount(CMultilayerPerceptronShell &network); + static bool MLPIsSoftMax(CMultilayerPerceptronShell &network); + static int MLPGetLayersCount(CMultilayerPerceptronShell &network); + static int MLPGetLayerSize(CMultilayerPerceptronShell &network,const int k); + static void MLPGetInputScaling(CMultilayerPerceptronShell &network,const int i,double &mean,double &sigma); + static void MLPGetOutputScaling(CMultilayerPerceptronShell &network,const int i,double &mean,double &sigma); + static void MLPGetNeuronInfo(CMultilayerPerceptronShell &network,const int k,const int i,int &fkind,double &threshold); + static double MLPGetWeight(CMultilayerPerceptronShell &network,const int k0,const int i0,const int k1,const int i1); + static void MLPSetInputScaling(CMultilayerPerceptronShell &network,const int i,const double mean,const double sigma); + static void MLPSetOutputScaling(CMultilayerPerceptronShell &network,const int i,const double mean,const double sigma); + static void MLPSetNeuronInfo(CMultilayerPerceptronShell &network,const int k,const int i,int fkind,double threshold); + static void MLPSetWeight(CMultilayerPerceptronShell &network,const int k0,const int i0,const int k1,const int i1,const double w); + static void MLPActivationFunction(const double net,const int k,double &f,double &df,double &d2f); + static void MLPProcess(CMultilayerPerceptronShell &network,double &x[],double &y[]); + static void MLPProcessI(CMultilayerPerceptronShell &network,double &x[],double &y[]); + static double MLPError(CMultilayerPerceptronShell &network,CMatrixDouble &xy,const int ssize); + static double MLPErrorSparse(CMultilayerPerceptronShell &network,CSparseMatrix &xy,int npoints); + static double MLPErrorN(CMultilayerPerceptronShell &network,CMatrixDouble &xy,const int ssize); + static int MLPClsError(CMultilayerPerceptronShell &network,CMatrixDouble &xy,const int ssize); + static double MLPRelClsError(CMultilayerPerceptronShell &network,CMatrixDouble &xy,const int npoints); + static double MLPRelClsErrorSparse(CMultilayerPerceptronShell &network,CSparseMatrix &xy,int npoints); + static double MLPAvgCE(CMultilayerPerceptronShell &network,CMatrixDouble &xy,const int npoints); + static double MLPAvgCESparse(CMultilayerPerceptronShell &network,CSparseMatrix &xy,int npoints); + static double MLPRMSError(CMultilayerPerceptronShell &network,CMatrixDouble &xy,const int npoints); + static double MLPRMSErrorSparse(CMultilayerPerceptronShell &network,CSparseMatrix &xy,int npoints); + static double MLPAvgError(CMultilayerPerceptronShell &network,CMatrixDouble &xy,const int npoints); + static double MLPAvgErrorSparse(CMultilayerPerceptronShell &network,CSparseMatrix &xy,int npoints); + static double MLPAvgRelError(CMultilayerPerceptronShell &network,CMatrixDouble &xy,const int npoints); + static double MLPAvgRelErrorSparse(CMultilayerPerceptronShell &network,CSparseMatrix &xy,int npoints); + static void MLPGrad(CMultilayerPerceptronShell &network,double &x[],double &desiredy[],double &e,double &grad[]); + static void MLPGradN(CMultilayerPerceptronShell &network,double &x[],double &desiredy[],double &e,double &grad[]); + static void MLPGradBatch(CMultilayerPerceptronShell &network,CMatrixDouble &xy,const int ssize,double &e,double &grad[]); + static void MLPGradBatch(CMultilayerPerceptronShell &network,CMatrixDouble &xy,const int ssize,double &e,CRowDouble &grad); + static void MLPGradBatchSparse(CMultilayerPerceptronShell &network,CSparseMatrix &xy,int ssize,double &e,CRowDouble &grad); + static void MLPGradBatchSubset(CMultilayerPerceptronShell &network,CMatrixDouble &xy,int setsize,CRowInt &idx,int subsetsize,double &e,CRowDouble &grad); + static void MLPGradBatchSparseSubset(CMultilayerPerceptronShell &network,CSparseMatrix &xy,int setsize,CRowInt &idx,int subsetsize,double &e,CRowDouble &grad); + static void MLPGradNBatch(CMultilayerPerceptronShell &network,CMatrixDouble &xy,const int ssize,double &e,double &grad[]); + static void MLPGradNBatch(CMultilayerPerceptronShell &network,CMatrixDouble &xy,const int ssize,double &e,CRowDouble &grad); + static void MLPHessianNBatch(CMultilayerPerceptronShell &network,CMatrixDouble &xy,const int ssize,double &e,double &grad[],CMatrixDouble &h); + static void MLPHessianNBatch(CMultilayerPerceptronShell &network,CMatrixDouble &xy,const int ssize,double &e,CRowDouble &grad,CMatrixDouble &h); + static void MLPHessianBatch(CMultilayerPerceptronShell &network,CMatrixDouble &xy,const int ssize,double &e,double &grad[],CMatrixDouble &h); + static void MLPHessianBatch(CMultilayerPerceptronShell &network,CMatrixDouble &xy,const int ssize,double &e,CRowDouble &grad,CMatrixDouble &h); + static void MLPAllErrorsSubset(CMultilayerPerceptronShell &network,CMatrixDouble &xy,int setsize,CRowInt &subset,int subsetsize,CModelErrors &rep); + static void MLPAllErrorsSparseSubset(CMultilayerPerceptronShell &network,CSparseMatrix &xy,int setsize,CRowInt &subset,int subsetsize,CModelErrors &rep); + static double MLPErrorSubset(CMultilayerPerceptronShell &network,CMatrixDouble &xy,int setsize,CRowInt &subset,int subsetsize); + static double MLPErrorSparseSubset(CMultilayerPerceptronShell &network,CSparseMatrix &xy,int setsize,CRowInt &subset,int subsetsize); + //--- logit model functions + static void MNLTrainH(CMatrixDouble &xy,const int npoints,const int nvars,const int nclasses,int &info,CLogitModelShell &lm,CMNLReportShell &rep); + static void MNLProcess(CLogitModelShell &lm,double &x[],double &y[]); + static void MNLProcess(CLogitModelShell &lm,CRowDouble &x,CRowDouble &y); + static void MNLProcessI(CLogitModelShell &lm,double &x[],double &y[]); + static void MNLProcessI(CLogitModelShell &lm,CRowDouble &x,CRowDouble &y); + static void MNLUnpack(CLogitModelShell &lm,CMatrixDouble &a,int &nvars,int &nclasses); + static void MNLPack(CMatrixDouble &a,const int nvars,const int nclasses,CLogitModelShell &lm); + static double MNLAvgCE(CLogitModelShell &lm,CMatrixDouble &xy,const int npoints); + static double MNLRelClsError(CLogitModelShell &lm,CMatrixDouble &xy,const int npoints); + static double MNLRMSError(CLogitModelShell &lm,CMatrixDouble &xy,const int npoints); + static double MNLAvgError(CLogitModelShell &lm,CMatrixDouble &xy,const int npoints); + static double MNLAvgRelError(CLogitModelShell &lm,CMatrixDouble &xy,const int ssize); + static int MNLClsError(CLogitModelShell &lm,CMatrixDouble &xy,const int npoints); + //--- Markov chains + static void MCPDCreate(const int n,CMCPDStateShell &s); + static void MCPDCreateEntry(const int n,const int entrystate,CMCPDStateShell &s); + static void MCPDCreateExit(const int n,const int exitstate,CMCPDStateShell &s); + static void MCPDCreateEntryExit(const int n,const int entrystate,const int exitstate,CMCPDStateShell &s); + static void MCPDAddTrack(CMCPDStateShell &s,CMatrixDouble &xy,const int k); + static void MCPDAddTrack(CMCPDStateShell &s,CMatrixDouble &xy); + static void MCPDSetEC(CMCPDStateShell &s,CMatrixDouble &ec); + static void MCPDAddEC(CMCPDStateShell &s,const int i,const int j,const double c); + static void MCPDSetBC(CMCPDStateShell &s,CMatrixDouble &bndl,CMatrixDouble &bndu); + static void MCPDAddBC(CMCPDStateShell &s,const int i,const int j,const double bndl,const double bndu); + static void MCPDSetLC(CMCPDStateShell &s,CMatrixDouble &c,int &ct[],const int k); + static void MCPDSetLC(CMCPDStateShell &s,CMatrixDouble &c,CRowInt &ct,const int k); + static void MCPDSetLC(CMCPDStateShell &s,CMatrixDouble &c,int &ct[]); + static void MCPDSetLC(CMCPDStateShell &s,CMatrixDouble &c,CRowInt &ct); + static void MCPDSetTikhonovRegularizer(CMCPDStateShell &s,const double v); + static void MCPDSetPrior(CMCPDStateShell &s,CMatrixDouble &pp); + static void MCPDSetPredictionWeights(CMCPDStateShell &s,double &pw[]); + static void MCPDSetPredictionWeights(CMCPDStateShell &s,CRowDouble &pw); + static void MCPDSolve(CMCPDStateShell &s); + static void MCPDResults(CMCPDStateShell &s,CMatrixDouble &p,CMCPDReportShell &rep); + //--- training neural networks + static void MLPTrainLM(CMultilayerPerceptronShell &network,CMatrixDouble &xy,const int npoints,const double decay,const int restarts,int &info,CMLPReportShell &rep); + static void MLPTrainLBFGS(CMultilayerPerceptronShell &network,CMatrixDouble &xy,const int npoints,const double decay,const int restarts,const double wstep,int maxits,int &info,CMLPReportShell &rep); + static void MLPTrainES(CMultilayerPerceptronShell &network,CMatrixDouble &trnxy,const int trnsize,CMatrixDouble &valxy,const int valsize,const double decay,const int restarts,int &info,CMLPReportShell &rep); + static void MLPKFoldCVLBFGS(CMultilayerPerceptronShell &network,CMatrixDouble &xy,const int npoints,const double decay,const int restarts,const double wstep,const int maxits,const int foldscount,int &info,CMLPReportShell &rep,CMLPCVReportShell &cvrep); + static void MLPKFoldCVLM(CMultilayerPerceptronShell &network,CMatrixDouble &xy,const int npoints,const double decay,const int restarts,const int foldscount,int &info,CMLPReportShell &rep,CMLPCVReportShell &cvrep); + static void MLPCreateTrainer(int nin,int nout,CMLPTrainer &s); + static void MLPCreateTrainerCls(int nin,int nclasses,CMLPTrainer &s); + static void MLPSetDataset(CMLPTrainer &s,CMatrixDouble &xy,int npoints); + static void MLPSetSparseDataset(CMLPTrainer &s,CSparseMatrix &xy,int npoints); + static void MLPSetDecay(CMLPTrainer &s,double decay); + static void MLPSetCond(CMLPTrainer &s,double wstep,int maxits); + static void MLPSetAlgoBatch(CMLPTrainer &s); + static void MLPTrainNetwork(CMLPTrainer &s,CMultilayerPerceptronShell &network,int nrestarts,CMLPReportShell &rep); + static void MLPStartTraining(CMLPTrainer &s,CMultilayerPerceptronShell &network,bool randomstart); + static bool MLPContinueTraining(CMLPTrainer &s,CMultilayerPerceptronShell &network); + //--- neural networks ensemble functions + static void MLPECreate0(const int nin,const int nout,const int ensemblesize,CMLPEnsembleShell &ensemble); + static void MLPECreate1(const int nin,int nhid,const int nout,const int ensemblesize,CMLPEnsembleShell &ensemble); + static void MLPECreate2(const int nin,const int nhid1,const int nhid2,const int nout,const int ensemblesize,CMLPEnsembleShell &ensemble); + static void MLPECreateB0(const int nin,const int nout,const double b,const double d,const int ensemblesize,CMLPEnsembleShell &ensemble); + static void MLPECreateB1(const int nin,int nhid,const int nout,const double b,const double d,const int ensemblesize,CMLPEnsembleShell &ensemble); + static void MLPECreateB2(const int nin,const int nhid1,const int nhid2,const int nout,const double b,const double d,const int ensemblesize,CMLPEnsembleShell &ensemble); + static void MLPECreateR0(const int nin,const int nout,const double a,const double b,const int ensemblesize,CMLPEnsembleShell &ensemble); + static void MLPECreateR1(const int nin,int nhid,const int nout,const double a,const double b,const int ensemblesize,CMLPEnsembleShell &ensemble); + static void MLPECreateR2(const int nin,const int nhid1,const int nhid2,const int nout,const double a,const double b,const int ensemblesize,CMLPEnsembleShell &ensemble); + static void MLPECreateC0(const int nin,const int nout,const int ensemblesize,CMLPEnsembleShell &ensemble); + static void MLPECreateC1(const int nin,int nhid,const int nout,const int ensemblesize,CMLPEnsembleShell &ensemble); + static void MLPECreateC2(const int nin,const int nhid1,const int nhid2,const int nout,const int ensemblesize,CMLPEnsembleShell &ensemble); + static void MLPECreateFromNetwork(CMultilayerPerceptronShell &network,const int ensemblesize,CMLPEnsembleShell &ensemble); + static void MLPERandomize(CMLPEnsembleShell &ensemble); + static void MLPEProperties(CMLPEnsembleShell &ensemble,int &nin,int &nout); + static bool MLPEIsSoftMax(CMLPEnsembleShell &ensemble); + static void MLPEProcess(CMLPEnsembleShell &ensemble,double &x[],double &y[]); + static void MLPEProcessI(CMLPEnsembleShell &ensemble,double &x[],double &y[]); + static double MLPERelClsError(CMLPEnsembleShell &ensemble,CMatrixDouble &xy,const int npoints); + static double MLPEAvgCE(CMLPEnsembleShell &ensemble,CMatrixDouble &xy,const int npoints); + static double MLPERMSError(CMLPEnsembleShell &ensemble,CMatrixDouble &xy,const int npoints); + static double MLPEAvgError(CMLPEnsembleShell &ensemble,CMatrixDouble &xy,const int npoints); + static double MLPEAvgRelError(CMLPEnsembleShell &ensemble,CMatrixDouble &xy,const int npoints); + static void MLPEBaggingLM(CMLPEnsembleShell &ensemble,CMatrixDouble &xy,const int npoints,const double decay,const int restarts,int &info,CMLPReportShell &rep,CMLPCVReportShell &ooberrors); + static void MLPEBaggingLBFGS(CMLPEnsembleShell &ensemble,CMatrixDouble &xy,const int npoints,const double decay,const int restarts,const double wstep,const int maxits,int &info,CMLPReportShell &rep,CMLPCVReportShell &ooberrors); + static void MLPETrainES(CMLPEnsembleShell &ensemble,CMatrixDouble &xy,const int npoints,const double decay,const int restarts,int &info,CMLPReportShell &rep); + static void MLPTrainEnsembleES(CMLPTrainer &s,CMLPEnsembleShell &ensemble,int nrestarts,CMLPReportShell &rep); + //--- principal components analysis + static void PCABuildBasis(CMatrixDouble &x,const int npoints,const int nvars,int &info,double &s2[],CMatrixDouble &v); + static void PCABuildBasis(CMatrixDouble &x,const int npoints,const int nvars,int &info,CRowDouble &s2,CMatrixDouble &v); + static void PCATruncatedSubspace(CMatrixDouble &x,int npoints,int nvars,int nneeded,double eps,int maxits,CRowDouble &s2,CMatrixDouble &v); + static void PCATruncatedSubspaceSparse(CSparseMatrix &x,int npoints,int nvars,int nneeded,double eps,int maxits,CRowDouble &s2,CMatrixDouble &v); + //--- functions of package diffequations + static void ODESolverRKCK(double &y[],const int n,double &x[],const int m,const double eps,const double h,CODESolverStateShell &state); + static void ODESolverRKCK(double &y[],double &x[],const double eps,const double h,CODESolverStateShell &state); + static bool ODESolverIteration(CODESolverStateShell &state); + static void ODESolverSolve(CODESolverStateShell &state,CNDimensional_ODE_RP &diff,CObject &obj); + static void ODESolverResults(CODESolverStateShell &state,int &m,double &xtbl[],CMatrixDouble &ytbl,CODESolverReportShell &rep); + //--- filters + static void FilterSMA(CRowDouble &x,int n,int k); + static void FilterSMA(CRowDouble &x,int k); + static void FilterEMA(CRowDouble &x,int n,double alpha); + static void FilterEMA(CRowDouble &x,double alpha); + static void FilterLRMA(CRowDouble &x,int n,int k); + static void FilterLRMA(CRowDouble &x,int k); + //--- SSA models + static void SSACreate(CSSAModel &s); + static void SSASetWindow(CSSAModel &s,int windowwidth); + static void SSASetSeed(CSSAModel &s,int seed); + static void SSASetPowerUpLength(CSSAModel &s,int pwlen); + static void SSASetMemoryLimit(CSSAModel &s,int memlimit); + static void SSAAddSequence(CSSAModel &s,CRowDouble &x,int n); + static void SSAAddSequence(CSSAModel &s,CRowDouble &x); + static void SSAAppendPointAndUpdate(CSSAModel &s,double x,double updateits); + static void SSAAppendSequenceAndUpdate(CSSAModel &s,CRowDouble &x,int nticks,double updateits); + static void SSAAppendSequenceAndUpdate(CSSAModel &s,CRowDouble &x,double updateits); + static void SSASetAlgoPrecomputed(CSSAModel &s,CMatrixDouble &a,int windowwidth,int nbasis); + static void SSASetAlgoPrecomputed(CSSAModel &s,CMatrixDouble &a); + static void SSASetAlgoTopKDirect(CSSAModel &s,int topk); + static void SSASetAlgoTopKRealtime(CSSAModel &s,int topk); + static void SSAClearData(CSSAModel &s); + static void SSAGetBasis(CSSAModel &s,CMatrixDouble &a,CRowDouble &sv,int &windowwidth,int &nbasis); + static void SSAGetLRR(CSSAModel &s,CRowDouble &a,int &windowwidth); + static void SSAAnalyzeLastWindow(CSSAModel &s,CRowDouble &trend,CRowDouble &noise,int &nticks); + static void SSAAnalyzeLast(CSSAModel &s,int nticks,CRowDouble &trend,CRowDouble &noise); + static void SSAAnalyzeSequence(CSSAModel &s,CRowDouble &data,int nticks,CRowDouble &trend,CRowDouble &noise); + static void SSAAnalyzeSequence(CSSAModel &s,CRowDouble &data,CRowDouble &trend,CRowDouble &noise); + static void SSAForecastLast(CSSAModel &s,int nticks,CRowDouble &trend); + static void SSAForecastSequence(CSSAModel &s,CRowDouble &data,int datalen,int forecastlen,bool applysmoothing,CRowDouble &trend); + static void SSAForecastSequence(CSSAModel &s,CRowDouble &data,int forecastlen,CRowDouble &trend); + static void SSAForecastAvgLast(CSSAModel &s,int m,int nticks,CRowDouble &trend); + static void SSAForecastAvgSequence(CSSAModel &s,CRowDouble &data,int datalen,int m,int forecastlen,bool applysmoothing,CRowDouble &trend); + static void SSAForecastAvgSequence(CSSAModel &s,CRowDouble &data,int m,int forecastlen,CRowDouble &trend); + //--- KNN models + static void KNNSerialize(CKNNModel &obj,string &s_out); + static void KNNUnserialize(const string s_in,CKNNModel &obj); + static void KNNCreateBuffer(CKNNModel &model,CKNNBuffer &buf); + static void KNNBuilderCreate(CKNNBuilder &s); + static void KNNBuilderSetDatasetReg(CKNNBuilder &s,CMatrixDouble &xy,int npoints,int nvars,int nout); + static void KNNBuilderSetDatasetCLS(CKNNBuilder &s,CMatrixDouble &xy,int npoints,int nvars,int nclasses); + static void KNNBuilderSetNorm(CKNNBuilder &s,int nrmtype); + static void KNNBuilderBuildKNNModel(CKNNBuilder &s,int k,double eps,CKNNModel &model,CKNNReport &rep); + static void KNNRewriteKEps(CKNNModel &model,int k,double eps); + static void KNNProcess(CKNNModel &model,CRowDouble &x,CRowDouble &y); + static double KNNProcess0(CKNNModel &model,CRowDouble &x); + static int KNNClassify(CKNNModel &model,CRowDouble &x); + static void KNNProcessI(CKNNModel &model,CRowDouble &x,CRowDouble &y); + static void KNNTsProcess(CKNNModel &model,CKNNBuffer &buf,CRowDouble &x,CRowDouble &y); + static double KNNRelClsError(CKNNModel &model,CMatrixDouble &xy,int npoints); + static double KNNAvgCE(CKNNModel &model,CMatrixDouble &xy,int npoints); + static double KNNRMSError(CKNNModel &model,CMatrixDouble &xy,int npoints); + static double KNNAvgError(CKNNModel &model,CMatrixDouble &xy,int npoints); + static double KNNAvgRelError(CKNNModel &model,CMatrixDouble &xy,int npoints); + static void KNNAllErrors(CKNNModel &model,CMatrixDouble &xy,int npoints,CKNNReport &rep); + //--- functions of package fasttransforms + //--- fast Fourier transform + static void FFTC1D(complex &a[],const int n); + static void FFTC1D(complex &a[]); + static void FFTC1DInv(complex &a[],const int n); + static void FFTC1DInv(complex &a[]); + static void FFTR1D(double &a[],const int n,complex &f[]); + static void FFTR1D(double &a[],complex &f[]); + static void FFTR1DInv(complex &f[],const int n,double &a[]); + static void FFTR1DInv(complex &f[],double &a[]); + static void FFTC1D(CRowComplex &a,const int n); + static void FFTC1D(CRowComplex &a); + static void FFTC1DInv(CRowComplex &a,const int n); + static void FFTC1DInv(CRowComplex &a); + static void FFTR1D(CRowDouble &a,const int n,CRowComplex &f); + static void FFTR1D(CRowDouble &a,CRowComplex &f); + static void FFTR1DInv(CRowComplex &f,const int n,CRowDouble &a); + static void FFTR1DInv(CRowComplex &f,CRowDouble &a); + //--- convolution + static void ConvC1D(complex &a[],const int m,complex &b[],const int n,complex &r[]); + static void ConvC1DInv(complex &a[],const int m,complex &b[],const int n,complex &r[]); + static void ConvC1DCircular(complex &s[],const int m,complex &r[],const int n,complex &c[]); + static void ConvC1DCircularInv(complex &a[],const int m,complex &b[],const int n,complex &r[]); + static void ConvR1D(double &a[],const int m,double &b[],const int n,double &r[]); + static void ConvR1DInv(double &a[],const int m,double &b[],const int n,double &r[]); + static void ConvR1DCircular(double &s[],const int m,double &r[],const int n,double &c[]); + static void ConvR1DCircularInv(double &a[],const int m,double &b[],const int n,double &r[]); + static void CorrC1D(complex &signal[],const int n,complex &pattern[],const int m,complex &r[]); + static void CorrC1DCircular(complex &signal[],const int m,complex &pattern[],const int n,complex &c[]); + static void CorrR1D(double &signal[],const int n,double &pattern[],const int m,double &r[]); + static void CorrR1DCircular(double &signal[],const int m,double &pattern[],const int n,double &c[]); + //--- fast Hartley transform + static void FHTR1D(double &a[],const int n); + static void FHTR1DInv(double &a[],const int n); + //--- functions of package integration + //--- Gauss quadrature formula + static void GQGenerateRec(double &alpha[],double &beta[],const double mu0,const int n,int &info,double &x[],double &w[]); + static void GQGenerateGaussLobattoRec(double &alpha[],double &beta[],const double mu0,const double a,const double b,const int n,int &info,double &x[],double &w[]); + static void GQGenerateGaussRadauRec(double &alpha[],double &beta[],const double mu0,const double a,const int n,int &info,double &x[],double &w[]); + static void GQGenerateGaussLegendre(const int n,int &info,double &x[],double &w[]); + static void GQGenerateGaussJacobi(const int n,const double alpha,const double beta,int &info,double &x[],double &w[]); + static void GQGenerateGaussLaguerre(const int n,const double alpha,int &info,double &x[],double &w[]); + static void GQGenerateGaussHermite(const int n,int &info,double &x[],double &w[]); + //--- Gauss-Kronrod quadrature formula + static void GKQGenerateRec(double &alpha[],double &beta[],const double mu0,const int n,int &info,double &x[],double &wkronrod[],double &wgauss[]); + static void GKQGenerateGaussLegendre(const int n,int &info,double &x[],double &wkronrod[],double &wgauss[]); + static void GKQGenerateGaussJacobi(const int n,const double alpha,const double beta,int &info,double &x[],double &wkronrod[],double &wgauss[]); + static void GKQLegendreCalc(const int n,int &info,double &x[],double &wkronrod[],double &wgauss[]); + static void GKQLegendreTbl(const int n,double &x[],double &wkronrod[],double &wgauss[],double &eps); + //--- auto Gauss-Kronrod + static void AutoGKSmooth(const double a,const double b,CAutoGKStateShell &state); + static void AutoGKSmoothW(const double a,const double b,double xwidth,CAutoGKStateShell &state); + static void AutoGKSingular(const double a,const double b,const double alpha,const double beta,CAutoGKStateShell &state); + static bool AutoGKIteration(CAutoGKStateShell &state); + static void AutoGKIntegrate(CAutoGKStateShell &state,CIntegrator1_Func &func,CObject &obj); + static void AutoGKResults(CAutoGKStateShell &state,double &v,CAutoGKReportShell &rep); + //--- functions of package interpolation + //--- inverse distance weighting interpolation + static void IDWSerialize(CIDWModelShell &obj,string &s_out); + static void IDWUnserialize(string s_in,CIDWModelShell &obj); + static void IDWCreateCalcBuffer(CIDWModelShell &s,CIDWCalcBuffer &buf); + static void IDWBuilderCreate(int nx,int ny,CIDWBuilder &state); + static void IDWBuilderSetNLayers(CIDWBuilder &state,int nlayers); + static void IDWBuilderSetPoints(CIDWBuilder &state,CMatrixDouble &xy,int n); + static void IDWBuilderSetPoints(CIDWBuilder &state,CMatrixDouble &xy); + static void IDWBuilderSetAlgoMSTAB(CIDWBuilder &state,double srad); + static void IDWBuilderSetAlgoTextBookShepard(CIDWBuilder &state,double p); + static void IDWBuilderSetAlgoTextBookModShepard(CIDWBuilder &state,double r); + static void IDWBuilderSetUserTerm(CIDWBuilder &state,double v); + static void IDWBuilderSetConstTerm(CIDWBuilder &state); + static void IDWBuilderSetZeroTerm(CIDWBuilder &state); + static double IDWCalc1(CIDWModelShell &s,double x0); + static double IDWCalc2(CIDWModelShell &s,double x0,double x1); + static double IDWCalc3(CIDWModelShell &s,double x0,double x1,double x2); + static void IDWCalc(CIDWModelShell &s,CRowDouble &x,CRowDouble &y); + static void IDWCalcBuf(CIDWModelShell &s,CRowDouble &x,CRowDouble &y); + static void IDWTsCalcBuf(CIDWModelShell &s,CIDWCalcBuffer &buf,CRowDouble &x,CRowDouble &y); + static void IDWFit(CIDWBuilder &state,CIDWModelShell &model,CIDWReport &rep); + //--- rational interpolation + static double BarycentricCalc(CBarycentricInterpolantShell &b,const double t); + static void BarycentricDiff1(CBarycentricInterpolantShell &b,const double t,double &f,double &df); + static void BarycentricDiff2(CBarycentricInterpolantShell &b,const double t,double &f,double &df,double &d2f); + static void BarycentricLinTransX(CBarycentricInterpolantShell &b,const double ca,const double cb); + static void BarycentricLinTransY(CBarycentricInterpolantShell &b,const double ca,const double cb); + static void BarycentricUnpack(CBarycentricInterpolantShell &b,int &n,double &x[],double &y[],double &w[]); + static void BarycentricBuildXYW(double &x[],double &y[],double &w[],const int n,CBarycentricInterpolantShell &b); + static void BarycentricBuildFloaterHormann(double &x[],double &y[],const int n,const int d,CBarycentricInterpolantShell &b); + //--- polynomial interpolant + static void PolynomialBar2Cheb(CBarycentricInterpolantShell &p,const double a,const double b,double &t[]); + static void PolynomialCheb2Bar(double &t[],const int n,const double a,const double b,CBarycentricInterpolantShell &p); + static void PolynomialCheb2Bar(double &t[],const double a,const double b,CBarycentricInterpolantShell &p); + static void PolynomialBar2Pow(CBarycentricInterpolantShell &p,const double c,const double s,double &a[]); + static void PolynomialBar2Pow(CBarycentricInterpolantShell &p,double &a[]); + static void PolynomialPow2Bar(double &a[],const int n,const double c,const double s,CBarycentricInterpolantShell &p); + static void PolynomialPow2Bar(double &a[],CBarycentricInterpolantShell &p); + static void PolynomialBuild(double &x[],double &y[],const int n,CBarycentricInterpolantShell &p); + static void PolynomialBuild(double &x[],double &y[],CBarycentricInterpolantShell &p); + static void PolynomialBuildEqDist(const double a,const double b,double &y[],const int n,CBarycentricInterpolantShell &p); + static void PolynomialBuildEqDist(const double a,const double b,double &y[],CBarycentricInterpolantShell &p); + static void PolynomialBuildCheb1(const double a,const double b,double &y[],const int n,CBarycentricInterpolantShell &p); + static void PolynomialBuildCheb1(const double a,const double b,double &y[],CBarycentricInterpolantShell &p); + static void PolynomialBuildCheb2(const double a,const double b,double &y[],const int n,CBarycentricInterpolantShell &p); + static void PolynomialBuildCheb2(const double a,const double b,double &y[],CBarycentricInterpolantShell &p); + static double PolynomialCalcEqDist(const double a,const double b,double &f[],const int n,const double t); + static double PolynomialCalcEqDist(const double a,const double b,double &f[],const double t); + static double PolynomialCalcCheb1(const double a,const double b,double &f[],const int n,const double t); + static double PolynomialCalcCheb1(const double a,const double b,double &f[],const double t); + static double PolynomialCalcCheb2(const double a,const double b,double &f[],const int n,const double t); + static double PolynomialCalcCheb2(const double a,const double b,double &f[],const double t); + //--- 1-dimensional spline interpolation + static void Spline1DBuildLinear(double &x[],double &y[],const int n,CSpline1DInterpolantShell &c); + static void Spline1DBuildLinear(double &x[],double &y[],CSpline1DInterpolantShell &c); + static void Spline1DBuildCubic(double &x[],double &y[],const int n,const int boundltype,const double boundl,const int boundrtype,const double boundr,CSpline1DInterpolantShell &c); + static void Spline1DBuildCubic(double &x[],double &y[],CSpline1DInterpolantShell &c); + static void Spline1DGridDiffCubic(double &x[],double &y[],const int n,const int boundltype,const double boundl,const int boundrtype,const double boundr,double &d[]); + static void Spline1DGridDiffCubic(double &x[],double &y[],double &d[]); + static void Spline1DGridDiff2Cubic(double &x[],double &y[],const int n,const int boundltype,const double boundl,const int boundrtype,const double boundr,double &d1[],double &d2[]); + static void Spline1DGridDiff2Cubic(double &x[],double &y[],double &d1[],double &d2[]); + static void Spline1DConvCubic(double &x[],double &y[],const int n,const int boundltype,const double boundl,const int boundrtype,const double boundr,double &x2[],int n2,double &y2[]); + static void Spline1DConvCubic(double &x[],double &y[],double &x2[],double &y2[]); + static void Spline1DConvDiffCubic(double &x[],double &y[],const int n,const int boundltype,const double boundl,const int boundrtype,const double boundr,double &x2[],int n2,double &y2[],double &d2[]); + static void Spline1DConvDiffCubic(double &x[],double &y[],double &x2[],double &y2[],double &d2[]); + static void Spline1DConvDiff2Cubic(double &x[],double &y[],const int n,const int boundltype,const double boundl,const int boundrtype,const double boundr,double &x2[],const int n2,double &y2[],double &d2[],double &dd2[]); + static void Spline1DConvDiff2Cubic(double &x[],double &y[],double &x2[],double &y2[],double &d2[],double &dd2[]); + static void Spline1DBuildCatmullRom(double &x[],double &y[],const int n,const int boundtype,const double tension,CSpline1DInterpolantShell &c); + static void Spline1DBuildCatmullRom(double &x[],double &y[],CSpline1DInterpolantShell &c); + static void Spline1DBuildHermite(double &x[],double &y[],double &d[],const int n,CSpline1DInterpolantShell &c); + static void Spline1DBuildHermite(double &x[],double &y[],double &d[],CSpline1DInterpolantShell &c); + static void Spline1DBuildAkima(double &x[],double &y[],const int n,CSpline1DInterpolantShell &c); + static void Spline1DBuildAkima(double &x[],double &y[],CSpline1DInterpolantShell &c); + static double Spline1DCalc(CSpline1DInterpolantShell &c,const double x); + static void Spline1DDiff(CSpline1DInterpolantShell &c,const double x,double &s,double &ds,double &d2s); + static void Spline1DUnpack(CSpline1DInterpolantShell &c,int &n,CMatrixDouble &tbl); + static void Spline1DLinTransX(CSpline1DInterpolantShell &c,const double a,const double b); + static void Spline1DLinTransY(CSpline1DInterpolantShell &c,const double a,const double b); + static double Spline1DIntegrate(CSpline1DInterpolantShell &c,const double x); + static void Spline1DFit(double &x[],double &y[],int n,int m,double lambdans,CSpline1DInterpolantShell &s,CSpline1DFitReportShell &rep); + static void Spline1DFit(double &x[],double &y[],int m,double lambdans,CSpline1DInterpolantShell &s,CSpline1DFitReportShell &rep); + static void Spline1DBuildMonotone(double &x[],double &y[],int n,CSpline1DInterpolantShell &c); + static void Spline1DBuildMonotone(double &x[],double &y[],CSpline1DInterpolantShell &c); + static void Spline1DBuildMonotone(CRowDouble &x,CRowDouble &y,CSpline1DInterpolantShell &c); + //--- least squares fitting + static void PolynomialFit(double &x[],double &y[],const int n,const int m,int &info,CBarycentricInterpolantShell &p,CPolynomialFitReportShell &rep); + static void PolynomialFit(double &x[],double &y[],const int m,int &info,CBarycentricInterpolantShell &p,CPolynomialFitReportShell &rep); + static void PolynomialFitWC(double &x[],double &y[],double &w[],const int n,double &xc[],double &yc[],int &dc[],const int k,const int m,int &info,CBarycentricInterpolantShell &p,CPolynomialFitReportShell &rep); + static void PolynomialFitWC(double &x[],double &y[],double &w[],double &xc[],double &yc[],int &dc[],const int m,int &info,CBarycentricInterpolantShell &p,CPolynomialFitReportShell &rep); + static void BarycentricFitFloaterHormannWC(double &x[],double &y[],double &w[],const int n,double &xc[],double &yc[],int &dc[],const int k,const int m,int &info,CBarycentricInterpolantShell &b,CBarycentricFitReportShell &rep); + static void BarycentricFitFloaterHormann(double &x[],double &y[],const int n,const int m,int &info,CBarycentricInterpolantShell &b,CBarycentricFitReportShell &rep); + static void Spline1DFitPenalized(double &x[],double &y[],const int n,const int m,const double rho,int &info,CSpline1DInterpolantShell &s,CSpline1DFitReportShell &rep); + static void Spline1DFitPenalized(double &x[],double &y[],const int m,const double rho,int &info,CSpline1DInterpolantShell &s,CSpline1DFitReportShell &rep); + static void Spline1DFitPenalizedW(double &x[],double &y[],double &w[],const int n,const int m,const double rho,int &info,CSpline1DInterpolantShell &s,CSpline1DFitReportShell &rep); + static void Spline1DFitPenalizedW(double &x[],double &y[],double &w[],const int m,const double rho,int &info,CSpline1DInterpolantShell &s,CSpline1DFitReportShell &rep); + static void Spline1DFitCubicWC(double &x[],double &y[],double &w[],const int n,double &xc[],double &yc[],int &dc[],const int k,const int m,int &info,CSpline1DInterpolantShell &s,CSpline1DFitReportShell &rep); + static void Spline1DFitCubicWC(double &x[],double &y[],double &w[],double &xc[],double &yc[],int &dc[],const int m,int &info,CSpline1DInterpolantShell &s,CSpline1DFitReportShell &rep); + static void Spline1DFitHermiteWC(double &x[],double &y[],double &w[],const int n,double &xc[],double &yc[],int &dc[],const int k,const int m,int &info,CSpline1DInterpolantShell &s,CSpline1DFitReportShell &rep); + static void Spline1DFitHermiteWC(double &x[],double &y[],double &w[],double &xc[],double &yc[],int &dc[],const int m,int &info,CSpline1DInterpolantShell &s,CSpline1DFitReportShell &rep); + static void Spline1DFitCubic(double &x[],double &y[],const int n,const int m,int &info,CSpline1DInterpolantShell &s,CSpline1DFitReportShell &rep); + static void Spline1DFitCubic(double &x[],double &y[],const int m,int &info,CSpline1DInterpolantShell &s,CSpline1DFitReportShell &rep); + static void Spline1DFitHermite(double &x[],double &y[],const int n,const int m,int &info,CSpline1DInterpolantShell &s,CSpline1DFitReportShell &rep); + static void Spline1DFitHermite(double &x[],double &y[],const int m,int &info,CSpline1DInterpolantShell &s,CSpline1DFitReportShell &rep); + static void LSFitLinearW(double &y[],double &w[],CMatrixDouble &fmatrix,const int n,const int m,int &info,double &c[],CLSFitReportShell &rep); + static void LSFitLinearW(double &y[],double &w[],CMatrixDouble &fmatrix,int &info,double &c[],CLSFitReportShell &rep); + static void LSFitLinearWC(double &y[],double &w[],CMatrixDouble &fmatrix,CMatrixDouble &cmatrix,const int n,const int m,const int k,int &info,double &c[],CLSFitReportShell &rep); + static void LSFitLinearWC(double &y[],double &w[],CMatrixDouble &fmatrix,CMatrixDouble &cmatrix,int &info,double &c[],CLSFitReportShell &rep); + static void LSFitLinear(double &y[],CMatrixDouble &fmatrix,const int n,const int m,int &info,double &c[],CLSFitReportShell &rep); + static void LSFitLinear(double &y[],CMatrixDouble &fmatrix,int &info,double &c[],CLSFitReportShell &rep); + static void LSFitLinearC(double &y[],CMatrixDouble &fmatrix,CMatrixDouble &cmatrix,const int n,const int m,const int k,int &info,double &c[],CLSFitReportShell &rep); + static void LSFitLinearC(double &y[],CMatrixDouble &fmatrix,CMatrixDouble &cmatrix,int &info,double &c[],CLSFitReportShell &rep); + static void LSFitCreateWF(CMatrixDouble &x,double &y[],double &w[],double &c[],const int n,const int m,const int k,const double diffstep,CLSFitStateShell &state); + static void LSFitCreateWF(CMatrixDouble &x,double &y[],double &w[],double &c[],const double diffstep,CLSFitStateShell &state); + static void LSFitCreateF(CMatrixDouble &x,double &y[],double &c[],const int n,const int m,const int k,const double diffstep,CLSFitStateShell &state); + static void LSFitCreateF(CMatrixDouble &x,double &y[],double &c[],const double diffstep,CLSFitStateShell &state); + static void LSFitCreateWFG(CMatrixDouble &x,double &y[],double &w[],double &c[],const int n,const int m,const int k,const bool cheapfg,CLSFitStateShell &state); + static void LSFitCreateWFG(CMatrixDouble &x,double &y[],double &w[],double &c[],const bool cheapfg,CLSFitStateShell &state); + static void LSFitCreateFG(CMatrixDouble &x,double &y[],double &c[],const int n,const int m,const int k,const bool cheapfg,CLSFitStateShell &state); + static void LSFitCreateFG(CMatrixDouble &x,double &y[],double &c[],const bool cheapfg,CLSFitStateShell &state); + static void LSFitCreateWFGH(CMatrixDouble &x,double &y[],double &w[],double &c[],const int n,const int m,const int k,CLSFitStateShell &state); + static void LSFitCreateWFGH(CMatrixDouble &x,double &y[],double &w[],double &c[],CLSFitStateShell &state); + static void LSFitCreateFGH(CMatrixDouble &x,double &y[],double &c[],const int n,const int m,const int k,CLSFitStateShell &state); + static void LSFitCreateFGH(CMatrixDouble &x,double &y[],double &c[],CLSFitStateShell &state); + static void LSFitSetCond(CLSFitStateShell &state,const double epsx,const int maxits); + static void LSFitSetStpMax(CLSFitStateShell &state,const double stpmax); + static void LSFitSetXRep(CLSFitStateShell &state,const bool needxrep); + static void LSFitSetScale(CLSFitStateShell &state,double &s[]); + static void LSFitSetBC(CLSFitStateShell &state,double &bndl[],double &bndu[]); + static bool LSFitIteration(CLSFitStateShell &state); + static void LSFitFit(CLSFitStateShell &state,CNDimensional_PFunc &func,CNDimensional_Rep &rep,bool rep_status,CObject &obj); + static void LSFitFit(CLSFitStateShell &state,CNDimensional_PFunc &func,CNDimensional_PGrad &grad,CNDimensional_Rep &rep,bool rep_status,CObject &obj); + static void LSFitFit(CLSFitStateShell &state,CNDimensional_PFunc &func,CNDimensional_PGrad &grad,CNDimensional_PHess &hess,CNDimensional_Rep &rep,bool rep_status,CObject &obj); + static void LSFitResults(CLSFitStateShell &state,int &info,double &c[],CLSFitReportShell &rep); + static double LogisticCalc4(double x,double a,double b,double c,double d); + static double LogisticCalc5(double x,double a,double b,double c,double d,double g); + static void LogisticFit4(CRowDouble &x,CRowDouble &y,int n,double &a,double &b,double &c,double &d,CLSFitReportShell &rep); + static void LogisticFit4ec(CRowDouble &x,CRowDouble &y,int n,double cnstrleft,double cnstrright,double &a,double &b,double &c,double &d,CLSFitReportShell &rep); + static void LogisticFit5(CRowDouble &x,CRowDouble &y,int n,double &a,double &b,double &c,double &d,double &g,CLSFitReportShell &rep); + static void LogisticFit5ec(CRowDouble &x,CRowDouble &y,int n,double cnstrleft,double cnstrright,double &a,double &b,double &c,double &d,double &g,CLSFitReportShell &rep); + static void LogisticFit45x(CRowDouble &x,CRowDouble &y,int n,double cnstrleft,double cnstrright,bool is4pl,double lambdav,double epsx,int rscnt,double &a,double &b,double &c,double &d,double &g,CLSFitReportShell &rep); + //--- least squares (LS) circle + static void FitSphereLS(CMatrixDouble &xy,int npoints,int nx,CRowDouble &cx,double &r); + static void FitSphereMC(CMatrixDouble &xy,int npoints,int nx,CRowDouble &cx,double &rhi); + static void FitSphereMI(CMatrixDouble &xy,int npoints,int nx,CRowDouble &cx,double &rlo); + static void FitSphereMZ(CMatrixDouble &xy,int npoints,int nx,CRowDouble &cx,double &rlo,double &rhi); + static void FitSphereX(CMatrixDouble &xy,int npoints,int nx,int problemtype,double epsx,int aulits,double penalty,CRowDouble &cx,double &rlo,double &rhi); + //--- parametric spline + static void PSpline2Build(CMatrixDouble &xy,const int n,const int st,const int pt,CPSpline2InterpolantShell &p); + static void PSpline3Build(CMatrixDouble &xy,const int n,const int st,const int pt,CPSpline3InterpolantShell &p); + static void PSpline2BuildPeriodic(CMatrixDouble &xy,const int n,const int st,const int pt,CPSpline2InterpolantShell &p); + static void PSpline3BuildPeriodic(CMatrixDouble &xy,const int n,const int st,const int pt,CPSpline3InterpolantShell &p); + static void PSpline2ParameterValues(CPSpline2InterpolantShell &p,int &n,double &t[]); + static void PSpline3ParameterValues(CPSpline3InterpolantShell &p,int &n,double &t[]); + static void PSpline2Calc(CPSpline2InterpolantShell &p,const double t,double &x,double &y); + static void PSpline3Calc(CPSpline3InterpolantShell &p,const double t,double &x,double &y,double &z); + static void PSpline2Tangent(CPSpline2InterpolantShell &p,const double t,double &x,double &y); + static void PSpline3Tangent(CPSpline3InterpolantShell &p,const double t,double &x,double &y,double &z); + static void PSpline2Diff(CPSpline2InterpolantShell &p,const double t,double &x,double &dx,double &y,double &dy); + static void PSpline3Diff(CPSpline3InterpolantShell &p,const double t,double &x,double &dx,double &y,double &dy,double &z,double &dz); + static void PSpline2Diff2(CPSpline2InterpolantShell &p,const double t,double &x,double &dx,double &d2x,double &y,double &dy,double &d2y); + static void PSpline3Diff2(CPSpline3InterpolantShell &p,const double t,double &x,double &dx,double &d2x,double &y,double &dy,double &d2y,double &z,double &dz,double &d2z); + static double PSpline2ArcLength(CPSpline2InterpolantShell &p,const double a,const double b); + static double PSpline3ArcLength(CPSpline3InterpolantShell &p,const double a,const double b); + static void ParametricRDPFixed(CMatrixDouble &x,int n,int d,int stopm,double stopeps,CMatrixDouble &x2,int &idx2[],int &nsections); + //--- 2-dimensional spline interpolation + static void Spline2DSerialize(CSpline2DInterpolantShell &obj,string &s_out); + static void Spline2DUnserialize(string s_in,CSpline2DInterpolantShell &obj); + static double Spline2DCalc(CSpline2DInterpolantShell &c,const double x,const double y); + static void Spline2DDiff(CSpline2DInterpolantShell &c,const double x,const double y,double &f,double &fx,double &fy,double &fxy); + static void Spline2DCalcVBuf(CSpline2DInterpolantShell &c,double x,double y,CRowDouble &f); + static double Spline2DCalcVi(CSpline2DInterpolantShell &c,double x,double y,int i); + static void Spline2DCalcV(CSpline2DInterpolantShell &c,double x,double y,CRowDouble &f); + static void Spline2DDiffVi(CSpline2DInterpolantShell &c,double x,double y,int i,double &f,double &fx,double &fy,double &fxy); + static void Spline2DLinTransXY(CSpline2DInterpolantShell &c,const double ax,const double bx,const double ay,const double by); + static void Spline2DLinTransF(CSpline2DInterpolantShell &c,const double a,const double b); + static void Spline2DCopy(CSpline2DInterpolantShell &c,CSpline2DInterpolantShell &cc); + static void Spline2DResampleBicubic(CMatrixDouble &a,const int oldheight,const int oldwidth,CMatrixDouble &b,const int newheight,const int newwidth); + static void Spline2DResampleBilinear(CMatrixDouble &a,const int oldheight,const int oldwidth,CMatrixDouble &b,const int newheight,const int newwidth); + static void Spline2DBuildBilinearV(CRowDouble &x,int n,CRowDouble &y,int m,CRowDouble &f,int d,CSpline2DInterpolantShell &c); + static void Spline2DBuildBicubicV(CRowDouble &x,int n,CRowDouble &y,int m,CRowDouble &f,int d,CSpline2DInterpolantShell &c); + static void Spline2DUnpackV(CSpline2DInterpolantShell &c,int &m,int &n,int &d,CMatrixDouble &tbl); + static void Spline2DBuildBilinear(double &x[],double &y[],CMatrixDouble &f,const int m,const int n,CSpline2DInterpolantShell &c); + static void Spline2DBuildBicubic(double &x[],double &y[],CMatrixDouble &f,const int m,const int n,CSpline2DInterpolantShell &c); + static void Spline2DUnpack(CSpline2DInterpolantShell &c,int &m,int &n,CMatrixDouble &tbl); + static void Spline2DBuilderCreate(int d,CSpline2DBuilder &state); + static void Spline2DBuilderSetUserTerm(CSpline2DBuilder &state,double v); + static void Spline2DBuilderSetLinTerm(CSpline2DBuilder &state); + static void Spline2DBuilderSetConstTerm(CSpline2DBuilder &state); + static void Spline2DBuilderSetZeroTerm(CSpline2DBuilder &state); + static void Spline2DBuilderSetPoints(CSpline2DBuilder &state,CMatrixDouble &xy,int n); + static void Spline2DBuilderSetAreaAuto(CSpline2DBuilder &state); + static void Spline2DBuilderSetArea(CSpline2DBuilder &state,double xa,double xb,double ya,double yb); + static void Spline2DBuilderSetGrid(CSpline2DBuilder &state,int kx,int ky); + static void Spline2DBuilderSetAlgoFastDDM(CSpline2DBuilder &state,int nlayers,double lambdav); + static void Spline2DBuilderSetAlgoBlockLLS(CSpline2DBuilder &state,double lambdans); + static void Spline2DBuilderSetAlgoNaiveLLS(CSpline2DBuilder &state,double lambdans); + static void Spline2DFit(CSpline2DBuilder &state,CSpline2DInterpolantShell &s,CSpline2DFitReport &rep); + //--- 3-dimensional spline interpolation + static double Spline3DCalc(CSpline3DInterpolant &c,double x,double y,double z); + static void Spline3DLinTransXYZ(CSpline3DInterpolant &c,double ax,double bx,double ay,double by,double az,double bz); + static void Spline3DLinTransF(CSpline3DInterpolant &c,double a,double b); + static void Spline3DResampleTrilinear(CRowDouble &a,int oldzcount,int oldycount,int oldxcount,int newzcount,int newycount,int newxcount,CRowDouble &b); + static void Spline3DBuildTrilinearV(CRowDouble &x,int n,CRowDouble &y,int m,CRowDouble &z,int l,CRowDouble &f,int d,CSpline3DInterpolant &c); + static void Spline3DCalcVBuf(CSpline3DInterpolant &c,double x,double y,double z,CRowDouble &f); + static void Spline3DCalcV(CSpline3DInterpolant &c,double x,double y,double z,CRowDouble &f); + static void Spline3DUnpackV(CSpline3DInterpolant &c,int &n,int &m,int &l,int &d,int &stype,CMatrixDouble &tbl); + //--- RBF model + static void RBFSerialize(CRBFModel &obj,string &s_out); + static void RBFUnserialize(string s_in,CRBFModel &obj); + static void RBFCreate(int nx,int ny,CRBFModel &s); + static void RBFCreateCalcBuffer(CRBFModel &s,CRBFCalcBuffer &buf); + static void RBFSetPoints(CRBFModel &s,CMatrixDouble &xy,int n); + static void RBFSetPoints(CRBFModel &s,CMatrixDouble &xy); + static void RBFSetPointsAndScales(CRBFModel &r,CMatrixDouble &xy,int n,CRowDouble &s); + static void RBFSetPointsAndScales(CRBFModel &r,CMatrixDouble &xy,CRowDouble &s); + static void RBFSetAlgoQNN(CRBFModel &s,double q=1.0,double z=5.0); + static void RBFSetAlgoMultilayer(CRBFModel &s,double rbase,int nlayers,double lambdav=0.01); + static void RBFSetAlgoHierarchical(CRBFModel &s,double rbase,int nlayers,double lambdans); + static void RBFSetAlgoThinPlateSpline(CRBFModel &s,double lambdav=0.0); + static void RBFSetAlgoMultiQuadricManual(CRBFModel &s,double alpha,double lambdav=0.0); + static void RBFSetAlgoMultiQuadricAuto(CRBFModel &s,double lambdav=0.0); + static void RBFSetAlgoBiharmonic(CRBFModel &s,double lambdav=0.0); + static void RBFSetLinTerm(CRBFModel &s); + static void RBFSetConstTerm(CRBFModel &s); + static void RBFSetZeroTerm(CRBFModel &s); + static void RBFSetV2BF(CRBFModel &s,int bf); + static void RBFSetV2Its(CRBFModel &s,int maxits); + static void RBFSetV2SupportR(CRBFModel &s,double r); + static void RBFBuildModel(CRBFModel &s,CRBFReport &rep); + static double RBFCalc1(CRBFModel &s,double x0); + static double RBFCalc2(CRBFModel &s,double x0,double x1); + static double RBFCalc3(CRBFModel &s,double x0,double x1,double x2); + static void RBFDiff1(CRBFModel &s,double x0,double &y,double &dy0); + static void RBFDiff2(CRBFModel &s,double x0,double x1,double &y,double &dy0,double &dy1); + static void RBFDiff3(CRBFModel &s,double x0,double x1,double x2,double &y,double &dy0,double &dy1,double &dy2); + static void RBFCalc(CRBFModel &s,CRowDouble &x,CRowDouble &y); + static void RBFDiff(CRBFModel &s,CRowDouble &x,CRowDouble &y,CRowDouble &dy); + static void RBFHess(CRBFModel &s,CRowDouble &x,CRowDouble &y,CRowDouble &dy,CRowDouble &d2y); + static void RBFCalcBuf(CRBFModel &s,CRowDouble &x,CRowDouble &y); + static void RBFDiffBuf(CRBFModel &s,CRowDouble &x,CRowDouble &y,CRowDouble &dy); + static void RBFHessBuf(CRBFModel &s,CRowDouble &x,CRowDouble &y,CRowDouble &dy,CRowDouble &d2y); + static void RBFTSCalcBuf(CRBFModel &s,CRBFCalcBuffer &buf,CRowDouble &x,CRowDouble &y); + static void RBFTSDiffBuf(CRBFModel &s,CRBFCalcBuffer &buf,CRowDouble &x,CRowDouble &y,CRowDouble &dy); + static void RBFTSHessBuf(CRBFModel &s,CRBFCalcBuffer &buf,CRowDouble &x,CRowDouble &y,CRowDouble &dy,CRowDouble &d2y); + static void RBFGridCalc2(CRBFModel &s,CRowDouble &x0,int n0,CRowDouble &x1,int n1,CMatrixDouble &y); + static void RBFGridCalc2V(CRBFModel &s,CRowDouble &x0,int n0,CRowDouble &x1,int n1,CRowDouble &y); + static void RBFGridCalc2VSubset(CRBFModel &s,CRowDouble &x0,int n0,CRowDouble &x1,int n1,bool &flagy[],CRowDouble &y); + static void RBFGridCalc3V(CRBFModel &s,CRowDouble &x0,int n0,CRowDouble &x1,int n1,CRowDouble &x2,int n2,CRowDouble &y); + static void RBFGridCalc3VSubset(CRBFModel &s,CRowDouble &x0,int n0,CRowDouble &x1,int n1,CRowDouble &x2,int n2,bool &flagy[],CRowDouble &y); + static void RBFUnpack(CRBFModel &s,int &nx,int &ny,CMatrixDouble &xwr,int &nc,CMatrixDouble &v,int &modelversion); + static int RBFGetModelVersion(CRBFModel &s); + static double RBFPeekProgress(CRBFModel &s); + static void RBFRequestTermination(CRBFModel &s); + //--- functions of package linalg + //--- working with matrix forms + static void CMatrixTranspose(const int m,const int n,CMatrixComplex &a,const int ia,const int ja,CMatrixComplex &b,const int ib,const int jb); + static void RMatrixTranspose(const int m,const int n,CMatrixDouble &a,const int ia,const int ja,CMatrixDouble &b,const int ib,const int jb); + static void RMatrixEnforceSymmetricity(CMatrixDouble &a,int n,bool IsUpper); + static void CMatrixCopy(const int m,const int n,CMatrixComplex &a,const int ia,const int ja,CMatrixComplex &b,const int ib,const int jb); + static void RVectorCopy(int n,CRowDouble &a,int ia,CRowDouble &b,int ib); + static void RMatrixCopy(const int m,const int n,CMatrixDouble &a,const int ia,const int ja,CMatrixDouble &b,const int ib,const int jb); + static void RMatrixGenCopy(int m,int n,double alpha,CMatrixDouble &a,int ia,int ja,double beta,CMatrixDouble &b,int ib,int jb); + static void RMatrixGer(int m,int n,CMatrixDouble &a,int ia,int ja,double alpha,CRowDouble &u,int iu,CRowDouble &v,int iv); + static void CMatrixRank1(const int m,const int n,CMatrixComplex &a,const int ia,const int ja,complex &u[],const int iu,complex &v[],const int iv); + static void RMatrixRank1(const int m,const int n,CMatrixDouble &a,const int ia,const int ja,double &u[],const int iu,double &v[],const int iv); + static void RMatrixGemVect(int m,int n,double alpha,CMatrixDouble &a,int ia,int ja,int opa,CRowDouble &x,int ix,double beta,CRowDouble &y,int iy); + static void CMatrixMVect(const int m,const int n,CMatrixComplex &a,const int ia,const int ja,const int opa,complex &x[],const int ix,complex &y[],const int iy); + static void RMatrixMVect(const int m,const int n,CMatrixDouble &a,const int ia,const int ja,const int opa,double &x[],const int ix,double &y[],const int iy); + static void RMatrixSymVect(int n,double alpha,CMatrixDouble &a,int ia,int ja,bool IsUpper,CRowDouble &x,int ix,double beta,CRowDouble &y,int iy); + static double RMatrixSyvMVect(int n,CMatrixDouble &a,int ia,int ja,bool IsUpper,CRowDouble &x,int ix,CRowDouble &tmp); + static void RMatrixTrsVect(int n,CMatrixDouble &a,int ia,int ja,bool IsUpper,bool IsUnit,int OpType,CRowDouble &x,int ix); + static void CMatrixRightTrsM(const int m,const int n,CMatrixComplex &a,const int i1,const int j1,const bool IsUpper,const bool IsUnit,const int OpType,CMatrixComplex &x,const int i2,const int j2); + static void CMatrixLeftTrsM(const int m,const int n,CMatrixComplex &a,const int i1,const int j1,const bool IsUpper,const bool IsUnit,const int OpType,CMatrixComplex &x,const int i2,const int j2); + static void RMatrixRightTrsM(const int m,const int n,CMatrixDouble &a,const int i1,const int j1,const bool IsUpper,const bool IsUnit,const int OpType,CMatrixDouble &x,const int i2,const int j2); + static void RMatrixLeftTrsM(const int m,const int n,CMatrixDouble &a,const int i1,const int j1,const bool IsUpper,const bool IsUnit,const int OpType,CMatrixDouble &x,const int i2,const int j2); + static void CMatrixSyrk(const int n,const int k,const double alpha,CMatrixComplex &a,const int ia,const int ja,const int optypea,const double beta,CMatrixComplex &c,const int ic,const int jc,const bool IsUpper); + static void RMatrixSyrk(const int n,const int k,const double alpha,CMatrixDouble &a,const int ia,const int ja,const int optypea,const double beta,CMatrixDouble &c,const int ic,const int jc,const bool IsUpper); + static void CMatrixGemm(const int m,const int n,const int k,complex alpha,CMatrixComplex &a,const int ia,const int ja,const int optypea,CMatrixComplex &b,const int ib,const int jb,const int optypeb,complex beta,CMatrixComplex &c,const int ic,const int jc); + static void RMatrixGemm(const int m,const int n,const int k,const double alpha,CMatrixDouble &a,const int ia,const int ja,const int optypea,CMatrixDouble &b,const int ib,const int jb,const int optypeb,const double beta,CMatrixDouble &c,const int ic,const int jc); + //--- orthogonal factorizations + static void RMatrixQR(CMatrixDouble &a,const int m,const int n,double &tau[]); + static void RMatrixLQ(CMatrixDouble &a,const int m,const int n,double &tau[]); + static void CMatrixQR(CMatrixComplex &a,const int m,const int n,complex &tau[]); + static void CMatrixLQ(CMatrixComplex &a,const int m,const int n,complex &tau[]); + static void RMatrixQRUnpackQ(CMatrixDouble &a,const int m,const int n,double &tau[],const int qcolumns,CMatrixDouble &q); + static void RMatrixQRUnpackR(CMatrixDouble &a,const int m,const int n,CMatrixDouble &r); + static void RMatrixLQUnpackQ(CMatrixDouble &a,const int m,const int n,double &tau[],const int qrows,CMatrixDouble &q); + static void RMatrixLQUnpackL(CMatrixDouble &a,const int m,const int n,CMatrixDouble &l); + static void CMatrixQRUnpackQ(CMatrixComplex &a,const int m,const int n,complex &tau[],const int qcolumns,CMatrixComplex &q); + static void CMatrixQRUnpackR(CMatrixComplex &a,const int m,const int n,CMatrixComplex &r); + static void CMatrixLQUnpackQ(CMatrixComplex &a,const int m,const int n,complex &tau[],const int qrows,CMatrixComplex &q); + static void CMatrixLQUnpackL(CMatrixComplex &a,const int m,const int n,CMatrixComplex &l); + static void RMatrixBD(CMatrixDouble &a,const int m,const int n,double &tauq[],double &taup[]); + static void RMatrixBDUnpackQ(CMatrixDouble &qp,const int m,const int n,double &tauq[],const int qcolumns,CMatrixDouble &q); + static void RMatrixBDMultiplyByQ(CMatrixDouble &qp,const int m,const int n,double &tauq[],CMatrixDouble &z,const int zrows,const int zcolumns,const bool fromtheright,const bool dotranspose); + static void RMatrixBDUnpackPT(CMatrixDouble &qp,const int m,const int n,double &taup[],const int ptrows,CMatrixDouble &pt); + static void RMatrixBDMultiplyByP(CMatrixDouble &qp,const int m,const int n,double &taup[],CMatrixDouble &z,const int zrows,const int zcolumns,const bool fromtheright,const bool dotranspose); + static void RMatrixBDUnpackDiagonals(CMatrixDouble &b,const int m,const int n,bool &IsUpper,double &d[],double &e[]); + static void RMatrixHessenberg(CMatrixDouble &a,const int n,double &tau[]); + static void RMatrixHessenbergUnpackQ(CMatrixDouble &a,const int n,double &tau[],CMatrixDouble &q); + static void RMatrixHessenbergUnpackH(CMatrixDouble &a,const int n,CMatrixDouble &h); + static void SMatrixTD(CMatrixDouble &a,const int n,const bool IsUpper,double &tau[],double &d[],double &e[]); + static void SMatrixTDUnpackQ(CMatrixDouble &a,const int n,const bool IsUpper,double &tau[],CMatrixDouble &q); + static void HMatrixTD(CMatrixComplex &a,const int n,const bool IsUpper,complex &tau[],double &d[],double &e[]); + static void HMatrixTDUnpackQ(CMatrixComplex &a,const int n,const bool IsUpper,complex &tau[],CMatrixComplex &q); + //--- eigenvalues and eigenvectors + static void EigSubSpaceCreate(int n,int k,CEigSubSpaceState &state); + static void EigSubSpaceCreateBuf(int n,int k,CEigSubSpaceState &state); + static void EigSubSpaceSetCond(CEigSubSpaceState &state,double eps,int maxits); + static void EigSubSpaceSetWarmStart(CEigSubSpaceState &state,bool usewarmstart); + static void EigSubSpaceOOCStart(CEigSubSpaceState &state,int mtype); + static bool EigSubSpaceOOCContinue(CEigSubSpaceState &state); + static void EigSubSpaceOOCGetRequestInfo(CEigSubSpaceState &state,int &requesttype,int &requestsize); + static void EigSubSpaceOOCGetRequestData(CEigSubSpaceState &state,CMatrixDouble &x); + static void EigSubSpaceOOCSendResult(CEigSubSpaceState &state,CMatrixDouble &ax); + static void EigSubSpaceOOCStop(CEigSubSpaceState &state,CRowDouble &w,CMatrixDouble &z,CEigSubSpaceReport &rep); + static void EigSubSpaceSolveDenses(CEigSubSpaceState &state,CMatrixDouble &a,bool IsUpper,CRowDouble &w,CMatrixDouble &z,CEigSubSpaceReport &rep); + static void EigSubSpaceSolveSparses(CEigSubSpaceState &state,CSparseMatrix &a,bool IsUpper,CRowDouble &w,CMatrixDouble &z,CEigSubSpaceReport &rep); + static bool SMatrixEVD(CMatrixDouble &a,const int n,int zneeded,const bool IsUpper,double &d[],CMatrixDouble &z); + static bool SMatrixEVDR(CMatrixDouble &a,const int n,int zneeded,const bool IsUpper,double b1,double b2,int &m,double &w[],CMatrixDouble &z); + static bool SMatrixEVDI(CMatrixDouble &a,const int n,int zneeded,const bool IsUpper,const int i1,const int i2,double &w[],CMatrixDouble &z); + static bool HMatrixEVD(CMatrixComplex &a,const int n,const int zneeded,const bool IsUpper,double &d[],CMatrixComplex &z); + static bool HMatrixEVDR(CMatrixComplex &a,const int n,const int zneeded,const bool IsUpper,double b1,double b2,int &m,double &w[],CMatrixComplex &z); + static bool HMatrixEVDI(CMatrixComplex &a,const int n,const int zneeded,const bool IsUpper,const int i1,const int i2,double &w[],CMatrixComplex &z); + static bool SMatrixTdEVD(double &d[],double &e[],const int n,const int zneeded,CMatrixDouble &z); + static bool SMatrixTdEVDR(double &d[],double &e[],const int n,const int zneeded,const double a,const double b,int &m,CMatrixDouble &z); + static bool SMatrixTdEVDI(double &d[],double &e[],const int n,const int zneeded,const int i1,const int i2,CMatrixDouble &z); + static bool RMatrixEVD(CMatrixDouble &a,const int n,const int vneeded,double &wr[],double &wi[],CMatrixDouble &vl,CMatrixDouble &vr); + //--- random matrix generation + static void RMatrixRndOrthogonal(const int n,CMatrixDouble &a); + static void RMatrixRndCond(const int n,const double c,CMatrixDouble &a); + static void CMatrixRndOrthogonal(const int n,CMatrixComplex &a); + static void CMatrixRndCond(const int n,const double c,CMatrixComplex &a); + static void SMatrixRndCond(const int n,const double c,CMatrixDouble &a); + static void SPDMatrixRndCond(const int n,const double c,CMatrixDouble &a); + static void HMatrixRndCond(const int n,const double c,CMatrixComplex &a); + static void HPDMatrixRndCond(const int n,const double c,CMatrixComplex &a); + static void RMatrixRndOrthogonalFromTheRight(CMatrixDouble &a,const int m,const int n); + static void RMatrixRndOrthogonalFromTheLeft(CMatrixDouble &a,const int m,const int n); + static void CMatrixRndOrthogonalFromTheRight(CMatrixComplex &a,const int m,const int n); + static void CMatrixRndOrthogonalFromTheLeft(CMatrixComplex &a,const int m,const int n); + static void SMatrixRndMultiply(CMatrixDouble &a,const int n); + static void HMatrixRndMultiply(CMatrixComplex &a,const int n); + //--- sparse matrix + static void SparseSerialize(CSparseMatrix &obj,string &s_out); + static void SparseUunserialize(string s_in,CSparseMatrix &obj); + static void SparseCreate(int m,int n,int k,CSparseMatrix &s); + static void SparseCreate(int m,int n,CSparseMatrix &s); + static void SparseCreateBuf(int m,int n,int k,CSparseMatrix &s); + static void SparseCreateBuf(int m,int n,CSparseMatrix &s); + static void SparseCreateCRS(int m,int n,CRowInt &ner,CSparseMatrix &s); + static void SparseCreateCRS(int m,int n,int &ner[],CSparseMatrix &s); + static void SparseCreateCRSBuf(int m,int n,CRowInt &ner,CSparseMatrix &s); + static void SparseCreateCRSBuf(int m,int n,int &ner[],CSparseMatrix &s); + static void SparseCreateSKS(int m,int n,CRowInt &d,CRowInt &u,CSparseMatrix &s); + static void SparseCreateSKS(int m,int n,int &d[],int &u[],CSparseMatrix &s); + static void SparseCreateSKSBuf(int m,int n,CRowInt &d,CRowInt &u,CSparseMatrix &s); + static void SparseCreateSKSBuf(int m,int n,int &d[],int &u[],CSparseMatrix &s); + static void SparseCreateSKSBand(int m,int n,int bw,CSparseMatrix &s); + static void SparseCreateSKSBandBuf(int m,int n,int bw,CSparseMatrix &s); + static void SparseCopy(CSparseMatrix &s0,CSparseMatrix &s1); + static void SparseCopyBuf(CSparseMatrix &s0,CSparseMatrix &s1); + static void SparseSwap(CSparseMatrix &s0,CSparseMatrix &s1); + static void SparseAdd(CSparseMatrix &s,int i,int j,double v); + static void SparseSet(CSparseMatrix &s,int i,int j,double v); + static double SparseGet(CSparseMatrix &s,int i,int j); + static bool SparseExists(CSparseMatrix &s,int i,int j); + static double SparseGetDiagonal(CSparseMatrix &s,int i); + static void SparseMV(CSparseMatrix &s,CRowDouble &x,CRowDouble &y); + static void SparseMTV(CSparseMatrix &s,CRowDouble &x,CRowDouble &y); + static void SparseGemV(CSparseMatrix &s,double alpha,int ops,CRowDouble &x,int ix,double beta,CRowDouble &y,int iy); + static void SparseMV2(CSparseMatrix &s,CRowDouble &x,CRowDouble &y0,CRowDouble &y1); + static void SparseSMV(CSparseMatrix &s,bool IsUpper,CRowDouble &x,CRowDouble &y); + static double SparseVSMV(CSparseMatrix &s,bool IsUpper,CRowDouble &x); + static void SparseMM(CSparseMatrix &s,CMatrixDouble &a,int k,CMatrixDouble &b); + static void SparseMTM(CSparseMatrix &s,CMatrixDouble &a,int k,CMatrixDouble &b); + static void SparseMM2(CSparseMatrix &s,CMatrixDouble &a,int k,CMatrixDouble &b0,CMatrixDouble &b1); + static void SparseSMM(CSparseMatrix &s,bool IsUpper,CMatrixDouble &a,int k,CMatrixDouble &b); + static void SparseTRMV(CSparseMatrix &s,bool IsUpper,bool IsUnit,int OpType,CRowDouble &x,CRowDouble &y); + static void SparseTRSV(CSparseMatrix &s,bool IsUpper,bool IsUnit,int OpType,CRowDouble &x); + static void SparseSymmPermTbl(CSparseMatrix &a,bool IsUpper,CRowInt &p,CSparseMatrix &b); + static void SparseSymmPermTblBuf(CSparseMatrix &a,bool IsUpper,CRowInt &p,CSparseMatrix &b); + static void SparseResizeMatrix(CSparseMatrix &s); + static bool SparseEnumerate(CSparseMatrix &s,int &t0,int &t1,int &i,int &j,double &v); + static bool SparseRewriteExisting(CSparseMatrix &s,int i,int j,double v); + static void SparseGetRow(CSparseMatrix &s,int i,CRowDouble &irow); + static void SparseGetCompressedRow(CSparseMatrix &s,int i,CRowInt &colidx,CRowDouble &vals,int &nzcnt); + static void SparseTransposeSKS(CSparseMatrix &s); + static void SparseTransposeCRS(CSparseMatrix &s); + static void SparseCopyTransposeCRS(CSparseMatrix &s0,CSparseMatrix &s1); + static void SparseCopyTransposeCRSBuf(CSparseMatrix &s0,CSparseMatrix &s1); + static void SparseConvertTo(CSparseMatrix &s0,int fmt); + static void SparseCopyToBuf(CSparseMatrix &s0,int fmt,CSparseMatrix &s1); + static void SparseConvertToHash(CSparseMatrix &s); + static void SparseCopyToHash(CSparseMatrix &s0,CSparseMatrix &s1); + static void SparseCopyToHashBuf(CSparseMatrix &s0,CSparseMatrix &s1); + static void SparseConvertToCRS(CSparseMatrix &s); + static void SparseCopyToCRS(CSparseMatrix &s0,CSparseMatrix &s1); + static void SparseCopyToCRSBuf(CSparseMatrix &s0,CSparseMatrix &s1); + static void SparseConvertToSKS(CSparseMatrix &s); + static void SparseCopyToSKS(CSparseMatrix &s0,CSparseMatrix &s1); + static void SparseCopyToSKSBuf(CSparseMatrix &s0,CSparseMatrix &s1); + static int SparseGetMatrixType(CSparseMatrix &s); + static bool SparseIsHash(CSparseMatrix &s); + static bool SparseIsCRS(CSparseMatrix &s); + static bool SparseIsSKS(CSparseMatrix &s); + static void SparseFree(CSparseMatrix &s); + static int SparseGetNRows(CSparseMatrix &s); + static int SparseGetNCols(CSparseMatrix &s); + static int SparseGetUpperCount(CSparseMatrix &s); + static int SparseGetLowerCount(CSparseMatrix &s); + //--- triangular factorizations + static void RMatrixLU(CMatrixDouble &a,const int m,const int n,int &pivots[]); + static void CMatrixLU(CMatrixComplex &a,const int m,const int n,int &pivots[]); + static bool HPDMatrixCholesky(CMatrixComplex &a,const int n,const bool IsUpper); + static bool SPDMatrixCholesky(CMatrixDouble &a,const int n,const bool IsUpper); + static void SPDMatrixCholeskyUpdateAdd1(CMatrixDouble &a,int n,bool IsUpper,CRowDouble &u); + static void SPDMatrixCholeskyUpdateFix(CMatrixDouble &a,int n,bool IsUpper,bool &fix[]); + static void SPDMatrixCholeskyUpdateAdd1Buf(CMatrixDouble &a,int n,bool IsUpper,CRowDouble &u,CRowDouble &bufr); + static void SPDMatrixCholeskyUpdateFixBuf(CMatrixDouble &a,int n,bool IsUpper,bool &fix[],CRowDouble &bufr); + static bool SparseLU(CSparseMatrix &a,int pivottype,CRowInt &p,CRowInt &q); + static bool SparseCholeskySkyLine(CSparseMatrix &a,int n,bool IsUpper); + static bool SparseCholesky(CSparseMatrix &a,bool IsUpper); + static bool SparseCholeskyP(CSparseMatrix &a,bool IsUpper,CRowInt &p); + static bool sparsecholeskyanalyze(CSparseMatrix &a,bool IsUpper,int facttype,int permtype,CSparseDecompositionAnalysis &analysis); + static bool SparseCholeskyFactorize(CSparseDecompositionAnalysis &analysis,bool needupper,CSparseMatrix &a,CRowDouble &d,CRowInt &p); + static void SparseCholeskyReload(CSparseDecompositionAnalysis &analysis,CSparseMatrix &a,bool IsUpper); + //--- estimate of the condition numbers + static double RMatrixRCond1(CMatrixDouble &a,const int n); + static double RMatrixRCondInf(CMatrixDouble &a,const int n); + static double SPDMatrixRCond(CMatrixDouble &a,const int n,const bool IsUpper); + static double RMatrixTrRCond1(CMatrixDouble &a,const int n,const bool IsUpper,const bool IsUnit); + static double RMatrixTrRCondInf(CMatrixDouble &a,const int n,const bool IsUpper,const bool IsUnit); + static double HPDMatrixRCond(CMatrixComplex &a,const int n,const bool IsUpper); + static double CMatrixRCond1(CMatrixComplex &a,const int n); + static double CMatrixRCondInf(CMatrixComplex &a,const int n); + static double RMatrixLURCond1(CMatrixDouble &lua,const int n); + static double RMatrixLURCondInf(CMatrixDouble &lua,const int n); + static double SPDMatrixCholeskyRCond(CMatrixDouble &a,const int n,const bool IsUpper); + static double HPDMatrixCholeskyRCond(CMatrixComplex &a,const int n,const bool IsUpper); + static double CMatrixLURCond1(CMatrixComplex &lua,const int n); + static double CMatrixLURCondInf(CMatrixComplex &lua,const int n); + static double CMatrixTrRCond1(CMatrixComplex &a,const int n,const bool IsUpper,const bool IsUnit); + static double CMatrixTrRCondInf(CMatrixComplex &a,const int n,const bool IsUpper,const bool IsUnit); + //--- norm estimator + static void NormEstimatorCreate(int m,int n,int nstart,int nits,CNormEstimatorState &state); + static void NormEstimatorSetSeed(CNormEstimatorState &state,int seedval); + static void NormEstimatorEstimateSparse(CNormEstimatorState &state,CSparseMatrix &a); + static void NormEstimatorResults(CNormEstimatorState &state,double &nrm); + //--- matrix inversion + static void RMatrixLUInverse(CMatrixDouble &a,int &pivots[],const int n,int &info,CMatInvReportShell &rep); + static void RMatrixLUInverse(CMatrixDouble &a,int &pivots[],int &info,CMatInvReportShell &rep); + static void RMatrixInverse(CMatrixDouble &a,const int n,int &info,CMatInvReportShell &rep); + static void RMatrixInverse(CMatrixDouble &a,int &info,CMatInvReportShell &rep); + static void CMatrixLUInverse(CMatrixComplex &a,int &pivots[],const int n,int &info,CMatInvReportShell &rep); + static void CMatrixLUInverse(CMatrixComplex &a,int &pivots[],int &info,CMatInvReportShell &rep); + static void CMatrixInverse(CMatrixComplex &a,const int n,int &info,CMatInvReportShell &rep); + static void CMatrixInverse(CMatrixComplex &a,int &info,CMatInvReportShell &rep); + static void SPDMatrixCholeskyInverse(CMatrixDouble &a,const int n,const bool IsUpper,int &info,CMatInvReportShell &rep); + static void SPDMatrixCholeskyInverse(CMatrixDouble &a,int &info,CMatInvReportShell &rep); + static void SPDMatrixInverse(CMatrixDouble &a,const int n,const bool IsUpper,int &info,CMatInvReportShell &rep); + static void SPDMatrixInverse(CMatrixDouble &a,int &info,CMatInvReportShell &rep); + static void HPDMatrixCholeskyInverse(CMatrixComplex &a,const int n,const bool IsUpper,int &info,CMatInvReportShell &rep); + static void HPDMatrixCholeskyInverse(CMatrixComplex &a,int &info,CMatInvReportShell &rep); + static void HPDMatrixInverse(CMatrixComplex &a,const int n,const bool IsUpper,int &info,CMatInvReportShell &rep); + static void HPDMatrixInverse(CMatrixComplex &a,int &info,CMatInvReportShell &rep); + static void RMatrixTrInverse(CMatrixDouble &a,const int n,const bool IsUpper,const bool IsUnit,int &info,CMatInvReportShell &rep); + static void RMatrixTrInverse(CMatrixDouble &a,const bool IsUpper,int &info,CMatInvReportShell &rep); + static void CMatrixTrInverse(CMatrixComplex &a,const int n,const bool IsUpper,const bool IsUnit,int &info,CMatInvReportShell &rep); + static void CMatrixTrInverse(CMatrixComplex &a,const bool IsUpper,int &info,CMatInvReportShell &rep); + //--- singular value decomposition of a bidiagonal matrix + static bool RMatrixBdSVD(double &d[],double &e[],const int n,const bool IsUpper,bool isfractionalaccuracyrequired,CMatrixDouble &u,const int nru,CMatrixDouble &c,const int ncc,CMatrixDouble &vt,const int ncvt); + //--- singular value decomposition + static bool RMatrixSVD(CMatrixDouble &a,const int m,const int n,const int uneeded,const int vtneeded,const int additionalmemory,double &w[],CMatrixDouble &u,CMatrixDouble &vt); + //--- calculation determinant of the matrix + static double RMatrixLUDet(CMatrixDouble &a,int &pivots[],const int n); + static double RMatrixLUDet(CMatrixDouble &a,int &pivots[]); + static double RMatrixDet(CMatrixDouble &a,const int n); + static double RMatrixDet(CMatrixDouble &a); + static complex CMatrixLUDet(CMatrixComplex &a,int &pivots[],const int n); + static complex CMatrixLUDet(CMatrixComplex &a,int &pivots[]); + static complex CMatrixDet(CMatrixComplex &a,const int n); + static complex CMatrixDet(CMatrixComplex &a); + static double SPDMatrixCholeskyDet(CMatrixDouble &a,const int n); + static double SPDMatrixCholeskyDet(CMatrixDouble &a); + static double SPDMatrixDet(CMatrixDouble &a,const int n,const bool IsUpper); + static double SPDMatrixDet(CMatrixDouble &a); + //--- generalized symmetric positive definite eigenproblem + static bool SMatrixGEVD(CMatrixDouble &a,const int n,const bool isuppera,CMatrixDouble &b,const bool isupperb,const int zneeded,const int problemtype,double &d[],CMatrixDouble &z); + static bool SMatrixGEVDReduce(CMatrixDouble &a,const int n,const bool isuppera,CMatrixDouble &b,const bool isupperb,const int problemtype,CMatrixDouble &r,bool &isupperr); + //--- update of the inverse matrix by the Sherman-Morrison formula + static void RMatrixInvUpdateSimple(CMatrixDouble &inva,const int n,const int updrow,const int updcolumn,const double updval); + static void RMatrixInvUpdateRow(CMatrixDouble &inva,const int n,const int updrow,double &v[]); + static void RMatrixInvUpdateColumn(CMatrixDouble &inva,const int n,const int updcolumn,double &u[]); + static void RMatrixInvUpdateUV(CMatrixDouble &inva,const int n,double &u[],double &v[]); + //--- Schur decomposition + static bool RMatrixSchur(CMatrixDouble &a,const int n,CMatrixDouble &s); + //--- functions of package optimization + //--- conjugate gradient method + static void MinCGCreate(const int n,double &x[],CMinCGStateShell &state); + static void MinCGCreate(double &x[],CMinCGStateShell &state); + static void MinCGCreateF(const int n,double &x[],double diffstep,CMinCGStateShell &state); + static void MinCGCreateF(double &x[],double diffstep,CMinCGStateShell &state); + static void MinCGSetCond(CMinCGStateShell &state,double epsg,double epsf,double epsx,int maxits); + static void MinCGSetScale(CMinCGStateShell &state,double &s[]); + static void MinCGSetXRep(CMinCGStateShell &state,bool needxrep); + static void MinCGSetCGType(CMinCGStateShell &state,int cgtype); + static void MinCGSetStpMax(CMinCGStateShell &state,double stpmax); + static void MinCGSuggestStep(CMinCGStateShell &state,double stp); + static void MinCGSetPrecDefault(CMinCGStateShell &state); + static void MinCGSetPrecDiag(CMinCGStateShell &state,double &d[]); + static void MinCGSetPrecScale(CMinCGStateShell &state); + static bool MinCGIteration(CMinCGStateShell &state); + static void MinCGOptimize(CMinCGStateShell &state,CNDimensional_Func &func,CNDimensional_Rep &rep,bool rep_status,CObject &obj); + static void MinCGOptimize(CMinCGStateShell &state,CNDimensional_Grad &grad,CNDimensional_Rep &rep,bool rep_status,CObject &obj); + static void MinCGResults(CMinCGStateShell &state,double &x[],CMinCGReportShell &rep); + static void MinCGResultsBuf(CMinCGStateShell &state,double &x[],CMinCGReportShell &rep); + static void MinCGRestartFrom(CMinCGStateShell &state,double &x[]); + static void MinLBFGSRequestTermination(CMinLBFGSStateShell &state); + //--- bound constrained optimization with additional linear equality and inequality constraints + static void MinBLEICCreate(const int n,double &x[],CMinBLEICStateShell &state); + static void MinBLEICCreate(double &x[],CMinBLEICStateShell &state); + static void MinBLEICCreateF(const int n,double &x[],double diffstep,CMinBLEICStateShell &state); + static void MinBLEICCreateF(double &x[],double diffstep,CMinBLEICStateShell &state); + static void MinBLEICSetBC(CMinBLEICStateShell &state,double &bndl[],double &bndu[]); + static void MinBLEICSetLC(CMinBLEICStateShell &state,CMatrixDouble &c,int &ct[],const int k); + static void MinBLEICSetLC(CMinBLEICStateShell &state,CMatrixDouble &c,int &ct[]); + static void MinBLEICSetInnerCond(CMinBLEICStateShell &state,const double epsg,const double epsf,const double epsx); + static void MinBLEICSetOuterCond(CMinBLEICStateShell &state,const double epsx,const double epsi); + static void MinBLEICSetScale(CMinBLEICStateShell &state,double &s[]); + static void MinBLEICSetPrecDefault(CMinBLEICStateShell &state); + static void MinBLEICSetPrecDiag(CMinBLEICStateShell &state,double &d[]); + static void MinBLEICSetPrecScale(CMinBLEICStateShell &state); + static void MinBLEICSetMaxIts(CMinBLEICStateShell &state,const int maxits); + static void MinBLEICSetXRep(CMinBLEICStateShell &state,bool needxrep); + static void MinBLEICSetStpMax(CMinBLEICStateShell &state,double stpmax); + static bool MinBLEICIteration(CMinBLEICStateShell &state); + static void MinBLEICOptimize(CMinBLEICStateShell &state,CNDimensional_Func &func,CNDimensional_Rep &rep,bool rep_status,CObject &obj); + static void MinBLEICOptimize(CMinBLEICStateShell &state,CNDimensional_Grad &grad,CNDimensional_Rep &rep,bool rep_status,CObject &obj); + static void MinBLEICOptGuardGradient(CMinBLEICStateShell &state,double teststep); + static void MinBLEICOptGuardSmoothness(CMinBLEICStateShell &state,int level=1); + static void MinBLEICOptGuardResults(CMinBLEICStateShell &state,COptGuardReport &rep); + static void MinBLEICOptGuardNonC1Test0Results(CMinBLEICStateShell &state,COptGuardNonC1Test0Report &strrep,COptGuardNonC1Test0Report &lngrep); + static void MinBLEICOptGuardNonC1Test1Results(CMinBLEICStateShell &state,COptGuardNonC1Test1Report &strrep,COptGuardNonC1Test1Report &lngrep); + static void MinBLEICResults(CMinBLEICStateShell &state,double &x[],CMinBLEICReportShell &rep); + static void MinBLEICResultsBuf(CMinBLEICStateShell &state,double &x[],CMinBLEICReportShell &rep); + static void MinBLEICRestartFrom(CMinBLEICStateShell &state,double &x[]); + static void MinBLEICRequestTermination(CMinBLEICStateShell &state); + //--- limited memory BFGS method for large scale optimization + static void MinLBFGSCreate(const int n,const int m,double &x[],CMinLBFGSStateShell &state); + static void MinLBFGSCreate(const int m,double &x[],CMinLBFGSStateShell &state); + static void MinLBFGSCreateF(const int n,const int m,double &x[],const double diffstep,CMinLBFGSStateShell &state); + static void MinLBFGSCreateF(const int m,double &x[],const double diffstep,CMinLBFGSStateShell &state); + static void MinLBFGSSetCond(CMinLBFGSStateShell &state,const double epsg,const double epsf,const double epsx,const int maxits); + static void MinLBFGSSetXRep(CMinLBFGSStateShell &state,const bool needxrep); + static void MinLBFGSSetStpMax(CMinLBFGSStateShell &state,const double stpmax); + static void MinLBFGSSetScale(CMinLBFGSStateShell &state,double &s[]); + static void MinLBFGSSetPrecDefault(CMinLBFGSStateShell &state); + static void MinLBFGSSetPrecCholesky(CMinLBFGSStateShell &state,CMatrixDouble &p,const bool IsUpper); + static void MinLBFGSSetPrecDiag(CMinLBFGSStateShell &state,double &d[]); + static void MinLBFGSSetPrecScale(CMinLBFGSStateShell &state); + static bool MinLBFGSIteration(CMinLBFGSStateShell &state); + static void MinLBFGSOptimize(CMinLBFGSStateShell &state,CNDimensional_Func &func,CNDimensional_Rep &rep,bool rep_status,CObject &obj); + static void MinLBFGSOptimize(CMinLBFGSStateShell &state,CNDimensional_Grad &grad,CNDimensional_Rep &rep,bool rep_status,CObject &obj); + static void MinLBFGSResults(CMinLBFGSStateShell &state,double &x[],CMinLBFGSReportShell &rep); + static void MinLBFGSresultsbuf(CMinLBFGSStateShell &state,double &x[],CMinLBFGSReportShell &rep); + static void MinLBFGSRestartFrom(CMinLBFGSStateShell &state,double &x[]); + //--- constrained quadratic programming + static void MinQPCreate(const int n,CMinQPStateShell &state); + static void MinQPSetLinearTerm(CMinQPStateShell &state,double &b[]); + static void MinQPSetQuadraticTerm(CMinQPStateShell &state,CMatrixDouble &a,const bool IsUpper); + static void MinQPSetQuadraticTerm(CMinQPStateShell &state,CMatrixDouble &a); + static void MinQPSetQuadraticTermSparse(CMinQPStateShell &state,CSparseMatrix &a,bool IsUpper); + static void MinQPSetStartingPoint(CMinQPStateShell &state,double &x[]); + static void MinQPSetOrigin(CMinQPStateShell &state,double &xorigin[]); + static void MinQPSetScale(CMinQPStateShell &state,CRowDouble &s); + static void MinQPSetScaleAutoDiag(CMinQPStateShell &state); + static void MinQPSetAlgoBLEIC(CMinQPStateShell &state,double epsg,double epsf,double epsx,int maxits); + static void MinQPSetAlgoDenseAUL(CMinQPStateShell &state,double epsx,double rho,int itscnt); + static void MinQPSetAlgoDenseIPM(CMinQPStateShell &state,double eps); + static void MinQPSetAlgoSparseIPM(CMinQPStateShell &state,double eps); + static void MinQPSetAlgoQuickQP(CMinQPStateShell &state,double epsg,double epsf,double epsx,int maxouterits,bool usenewton); + static void MinQPSetBCAll(CMinQPStateShell &state,double bndl,double bndu); + static void MinQPSetAlgoCholesky(CMinQPStateShell &state); + static void MinQPSetBC(CMinQPStateShell &state,double &bndl[],double &bndu[]); + static void MinQPSetBCI(CMinQPStateShell &state,int i,double bndl,double bndu); + static void MinQPSetLC(CMinQPStateShell &state,CMatrixDouble &c,CRowInt &ct,int k); + static void MinQPSetLC(CMinQPStateShell &state,CMatrixDouble &c,CRowInt &ct); + static void MinQPSetLCSparse(CMinQPStateShell &state,CSparseMatrix &c,CRowInt &ct,int k); + static void MinQPSetLCMixed(CMinQPStateShell &state,CSparseMatrix &sparsec,CRowInt &sparsect,int sparsek,CMatrixDouble &densec,CRowInt &densect,int densek); + static void MinQPSetLCMixedLegacy(CMinQPStateShell &state,CMatrixDouble &densec,CRowInt &densect,int densek,CSparseMatrix &sparsec,CRowInt &sparsect,int sparsek); + static void MinQPSetLC2Dense(CMinQPStateShell &state,CMatrixDouble &a,CRowDouble &al,CRowDouble &au,int k); + static void MinQPSetLC2Dense(CMinQPStateShell &state,CMatrixDouble &a,CRowDouble &al,CRowDouble &au); + static void MinQPSetLC2(CMinQPStateShell &state,CSparseMatrix &a,CRowDouble &al,CRowDouble &au,int k); + static void MinQPSetLC2Mixed(CMinQPStateShell &state,CSparseMatrix &sparsea,int ksparse,CMatrixDouble &densea,int kdense,CRowDouble &al,CRowDouble &au); + static void MinQPAddLC2Dense(CMinQPStateShell &state,CRowDouble &a,double al,double au); + static void MinQPAddLC2(CMinQPStateShell &state,CRowInt &idxa,CRowDouble &vala,int nnz,double al,double au); + static void MinQPAddLC2SparseFromDense(CMinQPStateShell &state,CRowDouble &da,double al,double au); + static void MinQPOptimize(CMinQPStateShell &state); + static void MinQPResults(CMinQPStateShell &state,double &x[],CMinQPReportShell &rep); + static void MinQPResultsBuf(CMinQPStateShell &state,double &x[],CMinQPReportShell &rep); + //--- Levenberg-Marquardt method + static void MinLMCreateVJ(const int n,const int m,double &x[],CMinLMStateShell &state); + static void MinLMCreateVJ(const int m,double &x[],CMinLMStateShell &state); + static void MinLMCreateV(const int n,const int m,double &x[],double diffstep,CMinLMStateShell &state); + static void MinLMCreateV(const int m,double &x[],const double diffstep,CMinLMStateShell &state); + static void MinLMCreateFGH(const int n,double &x[],CMinLMStateShell &state); + static void MinLMCreateFGH(double &x[],CMinLMStateShell &state); + static void MinLMSetCond(CMinLMStateShell &state,const double epsx,const int maxits); + static void MinLMSetXRep(CMinLMStateShell &state,const bool needxrep); + static void MinLMSetStpMax(CMinLMStateShell &state,const double stpmax); + static void MinLMSetScale(CMinLMStateShell &state,double &s[]); + static void MinLMSetBC(CMinLMStateShell &state,double &bndl[],double &bndu[]); + static void MinLMSetAccType(CMinLMStateShell &state,const int acctype); + static bool MinLMIteration(CMinLMStateShell &state); + static void MinLMOptimize(CMinLMStateShell &state,CNDimensional_FVec &fvec,CNDimensional_Rep &rep,bool rep_status,CObject &obj); + static void MinLMOptimize(CMinLMStateShell &state,CNDimensional_FVec &fvec,CNDimensional_Jac &jac,CNDimensional_Rep &rep,bool rep_status,CObject &obj); + static void MinLMOptimize(CMinLMStateShell &state,CNDimensional_Func &func,CNDimensional_Grad &grad,CNDimensional_Hess &hess,CNDimensional_Rep &rep,bool rep_status,CObject &obj); + static void MinLMOptimize(CMinLMStateShell &state,CNDimensional_Func &func,CNDimensional_Jac &jac,CNDimensional_Rep &rep,bool rep_status,CObject &obj); + static void MinLMOptimize(CMinLMStateShell &state,CNDimensional_Func &func,CNDimensional_Grad &grad,CNDimensional_Jac &jac,CNDimensional_Rep &rep,bool rep_status,CObject &obj); + static void MinLMResults(CMinLMStateShell &state,double &x[],CMinLMReportShell &rep); + static void MinLMResultsBuf(CMinLMStateShell &state,double &x[],CMinLMReportShell &rep); + static void MinLMRestartFrom(CMinLMStateShell &state,double &x[]); + static void MinLMCreateVGJ(const int n,const int m,double &x[],CMinLMStateShell &state); + static void MinLMCreateVGJ(const int m,double &x[],CMinLMStateShell &state); + static void MinLMCreateFGJ(const int n,const int m,double &x[],CMinLMStateShell &state); + static void MinLMCreateFGJ(const int m,double &x[],CMinLMStateShell &state); + static void MinLMCreateFJ(const int n,const int m,double &x[],CMinLMStateShell &state); + static void MinLMCreateFJ(const int m,double &x[],CMinLMStateShell &state); + //--- linear programming + static void MinLPCreate(int n,CMinLPState &state); + static void MinLPSetAlgoDSS(CMinLPState &state,double eps); + static void MinLPSetAlgoIPM(CMinLPState &state,double eps=0); + static void MinLPSetCost(CMinLPState &state,CRowDouble &c); + static void MinLPSetScale(CMinLPState &state,CRowDouble &s); + static void MinLPSetBC(CMinLPState &state,CRowDouble &bndl,CRowDouble &bndu); + static void MinLPSetBCAll(CMinLPState &state,double bndl,double bndu); + static void MinLPSetBCi(CMinLPState &state,int i,double bndl,double bndu); + static void MinLPSetLC(CMinLPState &state,CMatrixDouble &a,CRowInt &ct,int k); + static void MinLPSetLC(CMinLPState &state,CMatrixDouble &a,CRowInt &ct); + static void MinLPSetLC2Dense(CMinLPState &state,CMatrixDouble &a,CRowDouble &al,CRowDouble &au,int k); + static void MinLPSetLC2Dense(CMinLPState &state,CMatrixDouble &a,CRowDouble &al,CRowDouble &au); + static void MinLPSetLC2(CMinLPState &state,CSparseMatrix &a,CRowDouble &al,CRowDouble &au,int k); + static void MinLPAddLC2Dense(CMinLPState &state,CRowDouble &a,double al,double au); + static void MinLPAddLC2(CMinLPState &state,CRowInt &idxa,CRowDouble &vala,int nnz,double al,double au); + static void MinLPOptimize(CMinLPState &state); + static void MinLPResults(CMinLPState &state,CRowDouble &x,CMinLPReport &rep); + static void MinLPResultsBuf(CMinLPState &state,CRowDouble &x,CMinLPReport &rep); + //--- non-linear constrained optimization + static void MinNLCCreate(int n,CRowDouble &x,CMinNLCState &state); + static void MinNLCCreate(CRowDouble &x,CMinNLCState &state); + static void MinNLCCreateF(int n,CRowDouble &x,double diffstep,CMinNLCState &state); + static void MinNLCCreateF(CRowDouble &x,double diffstep,CMinNLCState &state); + static void MinNLCSetBC(CMinNLCState &state,CRowDouble &bndl,CRowDouble &bndu); + static void MinNLCSetLC(CMinNLCState &state,CMatrixDouble &c,CRowInt &ct,int k); + static void MinNLCSetLC(CMinNLCState &state,CMatrixDouble &c,CRowInt &ct); + static void MinNLCSetNLC(CMinNLCState &state,int nlec,int nlic); + static void MinNLCSetCond(CMinNLCState &state,double epsx,int maxits); + static void MinNLCSetScale(CMinNLCState &state,CRowDouble &s); + static void MinNLCSetPrecInexact(CMinNLCState &state); + static void MinNLCSetPrecExactLowRank(CMinNLCState &state,int updatefreq); + static void MinNLCSetPrecExactRobust(CMinNLCState &state,int updatefreq); + static void MinNLCSetPrecNone(CMinNLCState &state); + static void MinNLCSetSTPMax(CMinNLCState &state,double stpmax); + static void MinNLCSetAlgoAUL(CMinNLCState &state,double rho,int itscnt); + static void MinNLCSetAlgoSLP(CMinNLCState &state); + static void MinNLCSetAlgoSQP(CMinNLCState &state); + static void MinNLCSetXRep(CMinNLCState &state,bool needxrep); + static bool MinNLCIteration(CMinNLCState &state); + static void MinNLCOptimize(CMinNLCState &state,CNDimensional_FVec &fvec,CNDimensional_Rep &rep,CObject &obj); + static void MinNLCOptimize(CMinNLCState &state,CNDimensional_Jac &jac,CNDimensional_Rep &rep,CObject &obj); + static void MinNLCOptGuardGradient(CMinNLCState &state,double teststep); + static void MinNLCOptGuardSmoothness(CMinNLCState &state,int level=1); + static void MinNLCOptGuardResults(CMinNLCState &state,COptGuardReport &rep); + static void MinNLCOptGuardNonC1Test0Results(CMinNLCState &state,COptGuardNonC1Test0Report &strrep,COptGuardNonC1Test0Report &lngrep); + static void MinNLCOptGuardNonC1Test1Results(CMinNLCState &state,COptGuardNonC1Test1Report &strrep,COptGuardNonC1Test1Report &lngrep); + static void MinNLCResults(CMinNLCState &state,CRowDouble &x,CMinNLCReport &rep); + static void MinNLCResultsBuf(CMinNLCState &state,CRowDouble &x,CMinNLCReport &rep); + static void MinNLCRequestTermination(CMinNLCState &state); + static void MinNLCRestartFrom(CMinNLCState &state,CRowDouble &x); + //--- non-smooth non-convex optimization + static void MinNSCreate(int n,CRowDouble &x,CMinNSState &state); + static void MinNSCreate(CRowDouble &x,CMinNSState &state); + static void MinNSCreateF(int n,CRowDouble &x,double diffstep,CMinNSState &state); + static void MinNSCreateF(CRowDouble &x,double diffstep,CMinNSState &state); + static void MinNSSetBC(CMinNSState &state,CRowDouble &bndl,CRowDouble &bndu); + static void MinNSSetLC(CMinNSState &state,CMatrixDouble &c,CRowInt &ct,int k); + static void MinNSSetLC(CMinNSState &state,CMatrixDouble &c,CRowInt &ct); + static void MinNSSetNLC(CMinNSState &state,int nlec,int nlic); + static void MinNSSetCond(CMinNSState &state,double epsx,int maxits); + static void MinNSSetScale(CMinNSState &state,CRowDouble &s); + static void MinNSSetAlgoAGS(CMinNSState &state,double radius,double penalty); + static void MinNSSetXRep(CMinNSState &state,bool needxrep); + static void MinNSRequestTermination(CMinNSState &state); + static bool MinNSIteration(CMinNSState &state); + static void MinNSOptimize(CMinNSState &state,CNDimensional_FVec &fvec,CNDimensional_Rep &rep,CObject &obj); + static void MinNSOptimize(CMinNSState &state,CNDimensional_Jac &jac,CNDimensional_Rep &rep,CObject &obj); + static void MinNSResults(CMinNSState &state,CRowDouble &x,CMinNSReport &rep); + static void MinNSResultsBuf(CMinNSState &state,CRowDouble &x,CMinNSReport &rep); + static void MinNSRestartFrom(CMinNSState &state,CRowDouble &x); + //---box constrained optimization + static void MinBCCreate(int n,CRowDouble &x,CMinBCState &state); + static void MinBCCreate(CRowDouble &x,CMinBCState &state); + static void MinBCCreateF(int n,CRowDouble &x,double diffstep,CMinBCState &state); + static void MinBCCreateF(CRowDouble &x,double diffstep,CMinBCState &state); + static void MinBCSetBC(CMinBCState &state,CRowDouble &bndl,CRowDouble &bndu); + static void MinBCSetCond(CMinBCState &state,double epsg,double epsf,double epsx,int maxits); + static void MinBCSetScale(CMinBCState &state,CRowDouble &s); + static void MinBCSetPrecDefault(CMinBCState &state); + static void MinBCSetPrecDiag(CMinBCState &state,CRowDouble &d); + static void MinBCSetPrecScale(CMinBCState &state); + static void MinBCSetXRep(CMinBCState &state,bool needxrep); + static void MinBCSetStpMax(CMinBCState &state,double stpmax); + static bool MinBCIteration(CMinBCState &state); + static void MinBCOptimize(CMinBCState &state,CNDimensional_Func &func,CNDimensional_Rep &rep,CObject &obj); + static void MinBCOptimize(CMinBCState &state,CNDimensional_Grad &grad,CNDimensional_Rep &rep,CObject &obj); + static void MinBCOptGuardGradient(CMinBCState &state,double teststep); + static void MinBCOptGuardSmoothness(CMinBCState &state,int level=1); + static void MinBCOptGuardResults(CMinBCState &state,COptGuardReport &rep); + static void MinBCOptGuardNonC1Test0Results(CMinBCState &state,COptGuardNonC1Test0Report &strrep,COptGuardNonC1Test0Report &lngrep); + static void MinBCOptGuardNonC1Test1Results(CMinBCState &state,COptGuardNonC1Test1Report &strrep,COptGuardNonC1Test1Report &lngrep); + static void MinBCResults(CMinBCState &state,CRowDouble &x,CMinBCReport &rep); + static void MinBCResultsBuf(CMinBCState &state,CRowDouble &x,CMinBCReport &rep); + static void MinBCRestartFrom(CMinBCState &state,CRowDouble &x); + static void MinBCRequestTermination(CMinBCState &state); + //--- optimization + static void MinLBFGSSetDefaultPreconditioner(CMinLBFGSStateShell &state); + static void MinLBFGSSetCholeskyPreconditioner(CMinLBFGSStateShell &state,CMatrixDouble &p,bool IsUpper); + static void MinBLEICSetBarrierWidth(CMinBLEICStateShell &state,const double mu); + static void MinBLEICSetBarrierDecay(CMinBLEICStateShell &state,const double mudecay); + static void MinASACreate(const int n,double &x[],double &bndl[],double &bndu[],CMinASAStateShell &state); + static void MinASACreate(double &x[],double &bndl[],double &bndu[],CMinASAStateShell &state); + static void MinASASetCond(CMinASAStateShell &state,const double epsg,const double epsf,const double epsx,const int maxits); + static void MinASASetXRep(CMinASAStateShell &state,const bool needxrep); + static void MinASASetAlgorithm(CMinASAStateShell &state,const int algotype); + static void MinASASetStpMax(CMinASAStateShell &state,const double stpmax); + static bool MinASAIteration(CMinASAStateShell &state); + static void MinASAOptimize(CMinASAStateShell &state,CNDimensional_Grad &grad,CNDimensional_Rep &rep,bool rep_status,CObject &obj); + static void MinASAResults(CMinASAStateShell &state,double &x[],CMinASAReportShell &rep); + static void MinASAResultsBuf(CMinASAStateShell &state,double &x[],CMinASAReportShell &rep); + static void MinASARestartFrom(CMinASAStateShell &state,double &x[],double &bndl[],double &bndu[]); + //--- functions of package solvers + //--- polynomial root finding + static void PolynomialSolve(CRowDouble &a,int n,CRowComplex &x,CPolynomialSolverReport &rep); + //--- dense solver + static void RMatrixSolve(CMatrixDouble &a,const int n,double &b[],int &info,CDenseSolverReportShell &rep,double &x[]); + static void RMatrixSolveM(CMatrixDouble &a,const int n,CMatrixDouble &b,const int m,const bool rfs,int &info,CDenseSolverReportShell &rep,CMatrixDouble &x); + static void RMatrixLUSolve(CMatrixDouble &lua,int &p[],const int n,double &b[],int &info,CDenseSolverReportShell &rep,double &x[]); + static void RMatrixLUSolveM(CMatrixDouble &lua,int &p[],const int n,CMatrixDouble &b,const int m,int &info,CDenseSolverReportShell &rep,CMatrixDouble &x); + static void RMatrixMixedSolve(CMatrixDouble &a,CMatrixDouble &lua,int &p[],const int n,double &b[],int &info,CDenseSolverReportShell &rep,double &x[]); + static void RMatrixMixedSolveM(CMatrixDouble &a,CMatrixDouble &lua,int &p[],const int n,CMatrixDouble &b,const int m,int &info,CDenseSolverReportShell &rep,CMatrixDouble &x); + static void CMatrixSolveM(CMatrixComplex &a,const int n,CMatrixComplex &b,const int m,const bool rfs,int &info,CDenseSolverReportShell &rep,CMatrixComplex &x); + static void CMatrixSolve(CMatrixComplex &a,const int n,complex &b[],int &info,CDenseSolverReportShell &rep,complex &x[]); + static void CMatrixLUSolveM(CMatrixComplex &lua,int &p[],const int n,CMatrixComplex &b,const int m,int &info,CDenseSolverReportShell &rep,CMatrixComplex &x); + static void CMatrixLUSolve(CMatrixComplex &lua,int &p[],const int n,complex &b[],int &info,CDenseSolverReportShell &rep,complex &x[]); + static void CMatrixMixedSolveM(CMatrixComplex &a,CMatrixComplex &lua,int &p[],const int n,CMatrixComplex &b,const int m,int &info,CDenseSolverReportShell &rep,CMatrixComplex &x); + static void CMatrixMixedSolve(CMatrixComplex &a,CMatrixComplex &lua,int &p[],const int n,complex &b[],int &info,CDenseSolverReportShell &rep,complex &x[]); + static void SPDMatrixSolveM(CMatrixDouble &a,const int n,const bool IsUpper,CMatrixDouble &b,const int m,int &info,CDenseSolverReportShell &rep,CMatrixDouble &x); + static void SPDMatrixSolve(CMatrixDouble &a,const int n,const bool IsUpper,double &b[],int &info,CDenseSolverReportShell &rep,double &x[]); + static void SPDMatrixCholeskySolveM(CMatrixDouble &cha,const int n,const bool IsUpper,CMatrixDouble &b,const int m,int &info,CDenseSolverReportShell &rep,CMatrixDouble &x); + static void SPDMatrixCholeskySolve(CMatrixDouble &cha,const int n,const bool IsUpper,double &b[],int &info,CDenseSolverReportShell &rep,double &x[]); + static void HPDMatrixSolveM(CMatrixComplex &a,const int n,const bool IsUpper,CMatrixComplex &b,const int m,int &info,CDenseSolverReportShell &rep,CMatrixComplex &x); + static void HPDMatrixSolve(CMatrixComplex &a,const int n,const bool IsUpper,complex &b[],int &info,CDenseSolverReportShell &rep,complex &x[]); + static void HPDMatrixCholeskySolveM(CMatrixComplex &cha,const int n,const bool IsUpper,CMatrixComplex &b,const int m,int &info,CDenseSolverReportShell &rep,CMatrixComplex &x); + static void HPDMatrixCholeskySolve(CMatrixComplex &cha,const int n,const bool IsUpper,complex &b[],int &info,CDenseSolverReportShell &rep,complex &x[]); + static void RMatrixSolveLS(CMatrixDouble &a,const int nrows,const int ncols,double &b[],const double threshold,int &info,CDenseSolverLSReportShell &rep,double &x[]); + //--- sparse linear solver + static void SparseSPDSolveSKS(CSparseMatrix &a,bool IsUpper,CRowDouble &b,CRowDouble &x,CSparseSolverReport &rep); + static void SparseSPDSolve(CSparseMatrix &a,bool IsUpper,CRowDouble &b,CRowDouble &x,CSparseSolverReport &rep); + static void SparseSPDCholeskySolve(CSparseMatrix &a,bool IsUpper,CRowDouble &b,CRowDouble &x,CSparseSolverReport &rep); + static void SparseSolve(CSparseMatrix &a,CRowDouble &b,CRowDouble &x,CSparseSolverReport &rep); + static void SparseLUSolve(CSparseMatrix &a,CRowInt &p,CRowInt &q,CRowDouble &b,CRowDouble &x,CSparseSolverReport &rep); + //--- sparse symmetric linear solver + static void SparseSolveSymmetricGMRES(CSparseMatrix &a,bool IsUpper,CRowDouble &b,int k,double epsf,int maxits,CRowDouble &x,CSparseSolverReport &rep); + static void SparseSolveGMRES(CSparseMatrix &a,CRowDouble &b,int k,double epsf,int maxits,CRowDouble &x,CSparseSolverReport &rep); + static void SparseSolverCreate(int n,CSparseSolverState &state); + static void SparseSolverSetAlgoGMRES(CSparseSolverState &state,int k); + static void SparseSolverSetStartingPoint(CSparseSolverState &state,CRowDouble &x); + static void SparseSolverSetCond(CSparseSolverState &state,double epsf,int maxits); + static void SparseSolverSolveSymmetric(CSparseSolverState &state,CSparseMatrix &a,bool IsUpper,CRowDouble &b); + static void SparseSolverSolve(CSparseSolverState &state,CSparseMatrix &a,CRowDouble &b); + static void SparseSolverResults(CSparseSolverState &state,CRowDouble &x,CSparseSolverReport &rep); + static void SparseSolverSetXRep(CSparseSolverState &state,bool needxrep); + static void SparseSolverOOCStart(CSparseSolverState &state,CRowDouble &b); + static bool SparseSolverOOCContinue(CSparseSolverState &state); + static void SparseSolverOOCGetRequestInfo(CSparseSolverState &state,int &requesttype); + static void SparseSolverOOCGetRequestData(CSparseSolverState &state,CRowDouble &x); + static void SparseSolverOOCGetRequestData1(CSparseSolverState &state,double &v); + static void SparseSolverOOCSendResult(CSparseSolverState &state,CRowDouble &ax); + static void SparseSolverOOCStop(CSparseSolverState &state,CRowDouble &x,CSparseSolverReport &rep); + static void SparseSolverRequestTermination(CSparseSolverState &state); + //--- linear CG Solver + static void LinCGCreate(int n,CLinCGState &state); + static void LinCGSetStartingPoint(CLinCGState &state,CRowDouble &x); + static void LinCGSetPrecUnit(CLinCGState &state); + static void LinCGSetPrecDiag(CLinCGState &state); + static void LinCGSetCond(CLinCGState &state,double epsf,int maxits); + static void LinCGSolveSparse(CLinCGState &state,CSparseMatrix &a,bool IsUpper,CRowDouble &b); + static void LinCGResult(CLinCGState &state,CRowDouble &x,CLinCGReport &rep); + static void LinCGSetRestartFreq(CLinCGState &state,int srf); + static void LinCGSetRUpdateFreq(CLinCGState &state,int freq); + static void LinCGSetXRep(CLinCGState &state,bool needxrep); + //--- linear LSQR Solver + static void LinLSQRCreate(int m,int n,CLinLSQRState &state); + static void LinLSQRCreateBuf(int m,int n,CLinLSQRState &state); + static void LinLSQRSetPrecUnit(CLinLSQRState &state); + static void LinLSQRSetPrecDiag(CLinLSQRState &state); + static void LinLSQRSetLambdaI(CLinLSQRState &state,double lambdai); + static void LinLSQRSolveSparse(CLinLSQRState &state,CSparseMatrix &a,CRowDouble &b); + static void LinLSQRSetCond(CLinLSQRState &state,double epsa,double epsb,int maxits); + static void LinLSQRResults(CLinLSQRState &state,CRowDouble &x,CLinLSQRReport &rep); + static void LinLSQRSetXRep(CLinLSQRState &state,bool needxrep); + static int LinLSQRPeekIterationsCount(CLinLSQRState &s); + static void LinLSQRRequestTermination(CLinLSQRState &state); + //--- solving systems of nonlinear equations + static void NlEqCreateLM(const int n,const int m,double &x[],CNlEqStateShell &state); + static void NlEqCreateLM(const int m,double &x[],CNlEqStateShell &state); + static void NlEqSetCond(CNlEqStateShell &state,const double epsf,const int maxits); + static void NlEqSetXRep(CNlEqStateShell &state,const bool needxrep); + static void NlEqSetStpMax(CNlEqStateShell &state,const double stpmax); + static bool NlEqIteration(CNlEqStateShell &state); + static void NlEqSolve(CNlEqStateShell &state,CNDimensional_Func &func,CNDimensional_Jac &jac,CNDimensional_Rep &rep,bool rep_status,CObject &obj); + static void NlEqResults(CNlEqStateShell &state,double &x[],CNlEqReportShell &rep); + static void NlEqResultsBuf(CNlEqStateShell &state,double &x[],CNlEqReportShell &rep); + static void NlEqRestartFrom(CNlEqStateShell &state,double &x[]); + //--- functions of package specialfunctions + //--- gamma function + static double GammaFunction(const double x); + static double LnGamma(const double x,double &sgngam); + //--- normal distribution + static double ErrorFunction(const double x); + static double ErrorFunctionC(const double x); + static double NormalDistribution(const double x); + static double NormalPDF(const double x); + static double NormalCDF(const double x); + static double InvErF(const double e); + static double InvNormalDistribution(double y0); + static double InvNormalCDF(const double y0); + static double BivariateNormalPDF(const double x,const double y,const double rho); + static double BivariateNormalCDF(double x,double y,const double rho); + + //--- incomplete gamma function + static double IncompleteGamma(const double a,const double x); + static double IncompleteGammaC(const double a,const double x); + static double InvIncompleteGammaC(const double a,const double y0); + //--- airy function + static void Airy(const double x,double &ai,double &aip,double &bi,double &bip); + //--- Bessel function + static double BesselJ0(const double x); + static double BesselJ1(const double x); + static double BesselJN(const int n,const double x); + static double BesselY0(const double x); + static double BesselY1(const double x); + static double BesselYN(const int n,const double x); + static double BesselI0(const double x); + static double BesselI1(const double x); + static double BesselK0(const double x); + static double BesselK1(const double x); + static double BesselKN(const int nn,const double x); + //--- beta function + static double Beta(const double a,const double b); + static double IncompleteBeta(const double a,const double b,const double x); + static double InvIncompleteBeta(const double a,const double b,double y); + //--- binomial distribution + static double BinomialDistribution(const int k,const int n,const double p); + static double BinomialComplDistribution(const int k,const int n,const double p); + static double InvBinomialDistribution(const int k,const int n,const double y); + //--- Chebyshev polynom + static double ChebyshevCalculate(int r,const int n,const double x); + static double ChebyshevSum(double &c[],const int r,const int n,const double x); + static void ChebyshevCoefficients(const int n,double &c[]); + static void FromChebyshev(double &a[],const int n,double &b[]); + //--- chi-square distribution + static double ChiSquareDistribution(const double v,const double x); + static double ChiSquareComplDistribution(const double v,const double x); + static double InvChiSquareDistribution(const double v,const double y); + //--- Dawson's Integral + static double DawsonIntegral(const double x); + //--- elliptic integral + static double EllipticIntegralK(const double m); + static double EllipticIntegralKhighPrecision(const double m1); + static double IncompleteEllipticIntegralK(const double phi,const double m); + static double EllipticIntegralE(const double m); + static double IncompleteEllipticIntegralE(const double phi,const double m); + //--- exponential integral + static double ExponentialIntegralEi(const double x); + static double ExponentialIntegralEn(const double x,const int n); + //--- F distribution functions + static double FDistribution(const int a,const int b,const double x); + static double FComplDistribution(const int a,const int b,const double x); + static double InvFDistribution(const int a,const int b,const double y); + //--- Fresnel integral + static void FresnelIntegral(const double x,double &c,double &s); + //--- Hermite polynomial + static double HermiteCalculate(const int n,const double x); + static double HermiteSum(double &c[],const int n,const double x); + static void HermiteCoefficients(const int n,double &c[]); + //--- Jacobian elliptic functions + static void JacobianEllipticFunctions(const double u,const double m,double &sn,double &cn,double &dn,double &ph); + //--- Laguerre polynomial + static double LaguerreCalculate(const int n,const double x); + static double LaguerreSum(double &c[],const int n,const double x); + static void LaguerreCoefficients(const int n,double &c[]); + //--- Legendre polynomial + static double LegendreCalculate(const int n,const double x); + static double LegendreSum(double &c[],const int n,const double x); + static void LegendreCoefficients(const int n,double &c[]); + //--- Poisson distribution + static double PoissonDistribution(const int k,const double m); + static double PoissonComplDistribution(const int k,const double m); + static double InvPoissonDistribution(const int k,const double y); + //--- psi function + static double Psi(const double x); + //--- Student's t distribution + static double StudenttDistribution(const int k,const double t); + static double InvStudenttDistribution(const int k,const double p); + //--- trigonometric integrals + static void SineCosineIntegrals(const double x,double &si,double &ci); + static void HyperbolicSineCosineIntegrals(const double x,double &shi,double &chi); + //--- functions of package statistics + //--- basic statistics methods + static void SampleMoments(const double &x[],const int n,double &mean,double &variance,double &skewness,double &kurtosis); + static void SampleMoments(const double &x[],double &mean,double &variance,double &skewness,double &kurtosis); + static double SampleMean(CRowDouble &x,int n); + static double SampleMean(CRowDouble &x); + static double SampleVariance(CRowDouble &x,int n); + static double SampleVariance(CRowDouble &x); + static double SampleSkewness(CRowDouble &x,int n); + static double SampleSkewness(CRowDouble &x); + static double SampleKurtosis(CRowDouble &x,int n); + static double SampleKurtosis(CRowDouble &x); + static void SampleAdev(const double &x[],const int n,double &adev); + static void SampleAdev(const double &x[],double &adev); + static void SampleMedian(const double &x[],const int n,double &median); + static void SampleMedian(const double &x[],double &median); + static void SamplePercentile(const double &x[],const int n,const double p,double &v); + static void SamplePercentile(const double &x[],const double p,double &v); + static double Cov2(const double &x[],const double &y[],const int n); + static double Cov2(const double &x[],const double &y[]); + static double PearsonCorr2(const double &x[],const double &y[],const int n); + static double PearsonCorr2(const double &x[],const double &y[]); + static double SpearmanCorr2(const double &x[],const double &y[],const int n); + static double SpearmanCorr2(const double &x[],const double &y[]); + static void CovM(const CMatrixDouble &x,const int n,const int m,CMatrixDouble &c); + static void CovM(const CMatrixDouble &x,CMatrixDouble &c); + static void PearsonCorrM(const CMatrixDouble &x,const int n,const int m,CMatrixDouble &c); + static void PearsonCorrM(CMatrixDouble &x,CMatrixDouble &c); + static void SpearmanCorrM(const CMatrixDouble &x,const int n,const int m,CMatrixDouble &c); + static void SpearmanCorrM(const CMatrixDouble &x,CMatrixDouble &c); + static void CovM2(const CMatrixDouble &x,const CMatrixDouble &y,const int n,const int m1,const int m2,CMatrixDouble &c); + static void CovM2(const CMatrixDouble &x,const CMatrixDouble &y,CMatrixDouble &c); + static void PearsonCorrM2(const CMatrixDouble &x,const CMatrixDouble &y,const int n,const int m1,const int m2,CMatrixDouble &c); + static void PearsonCorrM2(const CMatrixDouble &x,const CMatrixDouble &y,CMatrixDouble &c); + static void SpearmanCorrM2(const CMatrixDouble &x,const CMatrixDouble &y,const int n,const int m1,const int m2,CMatrixDouble &c); + static void SpearmanCorrM2(const CMatrixDouble &x,const CMatrixDouble &y,CMatrixDouble &c); + static void RankData(CMatrixDouble &xy,int npoints,int nfeatures); + static void RankData(CMatrixDouble &xy); + static void RankDataCentered(CMatrixDouble &xy,int npoints,int nfeatures); + static void RankDataCentered(CMatrixDouble &xy); + //--- correlation tests + static void PearsonCorrelationSignificance(const double r,const int n,double &bothTails,double &leftTail,double &rightTail); + static void SpearmanRankCorrelationSignificance(const double r,const int n,double &bothTails,double &leftTail,double &rightTail); + //--- Jarque-Bera test + static void JarqueBeraTest(const double &x[],const int n,double &p); + //--- Mann-Whitney U-test + static void MannWhitneyUTest(const double &x[],const int n,const double &y[],const int m,double &bothTails,double &leftTail,double &rightTail); + //--- sign test + static void OneSampleSignTest(const double &x[],const int n,const double median,double &bothTails,double &leftTail,double &rightTail); + //--- Student Tests + static void StudentTest1(const double &x[],const int n,const double mean,double &bothTails,double &leftTail,double &rightTail); + static void StudentTest2(const double &x[],const int n,const double &y[],const int m,double &bothTails,double &leftTail,double &rightTail); + static void UnequalVarianceTest(const double &x[],const int n,const double &y[],const int m,double &bothTails,double &leftTail,double &rightTail); + //--- variance tests + static void FTest(const double &x[],const int n,const double &y[],const int m,double &bothTails,double &leftTail,double &rightTail); + static void OneSampleVarianceTest(double &x[],int n,double variance,double &bothTails,double &leftTail,double &rightTail); + //--- Wilcoxon signed-rank test + static void WilcoxonSignedRankTest(const double &x[],const int n,const double e,double &bothTails,double &leftTail,double &rightTail); + }; +//+------------------------------------------------------------------+ +//| HQRNDState initialization with random values which come from | +//| standard RNG. | +//+------------------------------------------------------------------+ +void CAlglib::HQRndRandomize(CHighQualityRandStateShell &state) + { + CHighQualityRand::HQRndRandomize(state.GetInnerObj()); + } +//+------------------------------------------------------------------+ +//| HQRNDState initialization with seed values | +//+------------------------------------------------------------------+ +void CAlglib::HQRndSeed(const int s1,const int s2,CHighQualityRandStateShell &state) + { + CHighQualityRand::HQRndSeed(s1,s2,state.GetInnerObj()); + } +//+------------------------------------------------------------------+ +//| This function generates random real number in (0,1), | +//| not including interval boundaries | +//| State structure must be initialized with HQRNDRandomize() or | +//| HQRNDSeed(). | +//+------------------------------------------------------------------+ +double CAlglib::HQRndUniformR(CHighQualityRandStateShell &state) + { + return(CHighQualityRand::HQRndUniformR(state.GetInnerObj())); + } +//+------------------------------------------------------------------+ +//| This function generates random integer number in [0, N) | +//| 1. N must be less than HQRNDMax-1. | +//| 2. State structure must be initialized with HQRNDRandomize() or | +//| HQRNDSeed() | +//+------------------------------------------------------------------+ +int CAlglib::HQRndUniformI(CHighQualityRandStateShell &state,const int n) + { + return(CHighQualityRand::HQRndUniformI(state.GetInnerObj(),n)); + } +//+------------------------------------------------------------------+ +//| Random number generator: normal numbers | +//| This function generates one random number from normal | +//| distribution. | +//| Its performance is equal to that of HQRNDNormal2() | +//| State structure must be initialized with HQRNDRandomize() or | +//| HQRNDSeed(). | +//+------------------------------------------------------------------+ +double CAlglib::HQRndNormal(CHighQualityRandStateShell &state) + { + return(CHighQualityRand::HQRndNormal(state.GetInnerObj())); + } +//+------------------------------------------------------------------+ +//| Random number generator: vector with random entries (normal | +//| distribution) | +//| This function generates N random numbers from normal | +//| distribution. | +//| State structure must be initialized with HQRNDRandomize() or | +//| HQRNDSeed(). | +//+------------------------------------------------------------------+ +void CAlglib::HQRndNormalV(CHighQualityRandStateShell &state, + int n,CRowDouble &x) + { + CHighQualityRand::HQRndNormalV(state.GetInnerObj(),n,x); + } +//+------------------------------------------------------------------+ +//| Random number generator: vector with random entries (normal | +//| distribution) | +//| This function generates N random numbers from normal | +//| distribution. | +//| State structure must be initialized with HQRNDRandomize() or | +//| HQRNDSeed(). | +//+------------------------------------------------------------------+ +void CAlglib::HQRndNormalV(CHighQualityRandStateShell &state, + int n,vector &x) + { + CRowDouble X=x; + HQRndNormalV(state,n,X); + x=X.ToVector(); + } +//+------------------------------------------------------------------+ +//| Random number generator: matrix with random entries (normal | +//| distribution) | +//| This function generates MxN random matrix. | +//| State structure must be initialized with HQRNDRandomize() or | +//| HQRNDSeed(). | +//+------------------------------------------------------------------+ +void CAlglib::HQRndNormalM(CHighQualityRandStateShell &state, + int m,int n,CMatrixDouble &x) + { + CHighQualityRand::HQRndNormalM(state.GetInnerObj(),m,n,x); + } +//+------------------------------------------------------------------+ +//| Random number generator: matrix with random entries (normal | +//| distribution) | +//| This function generates MxN random matrix. | +//| State structure must be initialized with HQRNDRandomize() or | +//| HQRNDSeed(). | +//+------------------------------------------------------------------+ +void CAlglib::HQRndNormalM(CHighQualityRandStateShell &state, + int m,int n,matrix &x) + { + CMatrixDouble X=x; + HQRndNormalM(state,m,n,X); + x=X.ToMatrix(); + } +//+------------------------------------------------------------------+ +//| Random number generator: random X and Y such that X^2+Y^2=1 | +//| State structure must be initialized with HQRNDRandomize() or | +//| HQRNDSeed(). | +//+------------------------------------------------------------------+ +void CAlglib::HQRndUnit2(CHighQualityRandStateShell &state, + double &x,double &y) + { +//--- initialization + x=0; + y=0; +//--- function call + CHighQualityRand::HQRndUnit2(state.GetInnerObj(),x,y); + } +//+------------------------------------------------------------------+ +//| Random number generator: normal numbers | +//| This function generates two independent random numbers from | +//| normal distribution. Its performance is equal to that of | +//| HQRNDNormal() | +//| State structure must be initialized with HQRNDRandomize() or | +//| HQRNDSeed(). | +//+------------------------------------------------------------------+ +void CAlglib::HQRndNormal2(CHighQualityRandStateShell &state, + double &x1,double &x2) + { +//--- initialization + x1=0; + x2=0; +//--- function call + CHighQualityRand::HQRndNormal2(state.GetInnerObj(),x1,x2); + } +//+------------------------------------------------------------------+ +//| Random number generator: exponential distribution | +//| State structure must be initialized with HQRNDRandomize() or | +//| HQRNDSeed(). | +//+------------------------------------------------------------------+ +double CAlglib::HQRndExponential(CHighQualityRandStateShell &state, + const double lambdav) + { + return(CHighQualityRand::HQRndExponential(state.GetInnerObj(),lambdav)); + } +//+------------------------------------------------------------------+ +//| This function generates random number from discrete distribution| +//| given by finite sample X. | +//| INPUT PARAMETERS | +//| State - high quality random number generator, must be | +//| initialized with HQRNDRandomize() or HQRNDSeed(). | +//| X - finite sample | +//| N - number of elements to use, N>=1 | +//| RESULT | +//| this function returns one of the X[i] for random i=0..N-1 | +//+------------------------------------------------------------------+ +double CAlglib::HQRndDiscrete(CHighQualityRandStateShell &state, + int n,CRowDouble &x) + { + return(CHighQualityRand::HQRndDiscrete(state.GetInnerObj(),n,x)); + } +//+------------------------------------------------------------------+ +//| This function generates random number from discrete distribution| +//| given by finite sample X. | +//| INPUT PARAMETERS | +//| State - high quality random number generator, must be | +//| initialized with HQRNDRandomize() or HQRNDSeed(). | +//| X - finite sample | +//| N - number of elements to use, N>=1 | +//| RESULT | +//| this function returns one of the X[i] for random i=0..N-1 | +//+------------------------------------------------------------------+ +double CAlglib::HQRndDiscrete(CHighQualityRandStateShell &state, + int n,vector &x) + { + return(CHighQualityRand::HQRndDiscrete(state.GetInnerObj(),n,x)); + } +//+------------------------------------------------------------------+ +//| This function generates random number from continuous | +//| distribution given by finite sample X. | +//| INPUT PARAMETERS | +//| State - high quality random number generator, must be | +//| initialized with HQRNDRandomize() or HQRNDSeed(). | +//| X - finite sample, array[N] (can be larger, in this | +//| case only leading N elements are used). THIS ARRAY | +//| MUST BE SORTED BY ASCENDING. | +//| N - number of elements to use, N>=1 | +//| RESULT | +//| this function returns random number from continuous | +//| distribution which tries to approximate X as mush as possible. | +//| min(X)<=Result<=max(X). | +//+------------------------------------------------------------------+ +double CAlglib::HQRndContinuous(CHighQualityRandStateShell &state, + int n,CRowDouble &x) + { + return(CHighQualityRand::HQRndContinuous(state.GetInnerObj(),n,x)); + } +//+------------------------------------------------------------------+ +//| This function generates random number from continuous | +//| distribution given by finite sample X. | +//| INPUT PARAMETERS | +//| State - high quality random number generator, must be | +//| initialized with HQRNDRandomize() or HQRNDSeed(). | +//| X - finite sample, array[N] (can be larger, in this | +//| case only leading N elements are used). THIS ARRAY | +//| MUST BE SORTED BY ASCENDING. | +//| N - number of elements to use, N>=1 | +//| RESULT | +//| this function returns random number from continuous | +//| distribution which tries to approximate X as mush as possible. | +//| min(X)<=Result<=max(X). | +//+------------------------------------------------------------------+ +double CAlglib::HQRndContinuous(CHighQualityRandStateShell &state, + int n,vector &x) + { + return(CHighQualityRand::HQRndContinuous(state.GetInnerObj(),n,x)); + } +//+------------------------------------------------------------------+ +//| This function serializes data structure to string. | +//| Important properties of s_out: | +//| * it contains alphanumeric characters, dots, underscores, minus | +//| signs | +//| * these symbols are grouped into words, which are separated by | +//| spaces and Windows-style (CR+LF) newlines | +//| * although serializer uses spaces and CR+LF as separators, you | +//| can replace any separator character by arbitrary combination | +//| of spaces, tabs, Windows or Unix newlines. It allows flexible | +//| reformatting of the string in case you want to include it into | +//| text or XML file. But you should not insert separators into the| +//| middle of the "words" nor you should change case of letters. | +//| * s_out can be freely moved between 32-bit and 64-bit systems, | +//| little and big endian machines, and so on. You can reference | +//| structure on 32-bit machine and unserialize it on 64-bit one | +//| (or vice versa), or reference it on SPARC and unserialize on | +//| x86. You can also reference it in C# version of ALGLIB and | +//| unserialize in C++ one, and vice versa. | +//+------------------------------------------------------------------+ +void CAlglib::KDTreeSerialize(CKDTreeShell &obj,string &s_out) + { +//--- create a variable + CSerializer s; +//--- serialization start + s.Alloc_Start(); +//--- function call + CNearestNeighbor::KDTreeAlloc(s,obj.GetInnerObj()); + s.SStart_Str(); +//--- function call + CNearestNeighbor::KDTreeSerialize(s,obj.GetInnerObj()); + s.Stop(); +//--- get result + s_out=s.Get_String(); + } +//+------------------------------------------------------------------+ +//| This function unserializes data structure from string. | +//+------------------------------------------------------------------+ +void CAlglib::KDTreeUnserialize(string s_in,CKDTreeShell &obj) + { +//--- object of class + CSerializer s; + s.UStart_Str(s_in); +//--- function call + CNearestNeighbor::KDTreeUnserialize(s,obj.GetInnerObj()); + s.Stop(); + } +//+------------------------------------------------------------------+ +//| KD-tree creation | +//| This subroutine creates KD-tree from set of X-values and optional| +//| Y-values | +//| INPUT PARAMETERS | +//| XY - dataset,array[0..N-1, 0..NX+NY-1]. | +//| one row corresponds to one point. | +//| first NX columns contain X-values, next NY (NY | +//| may be zero) | +//| columns may contain associated Y-values | +//| N - number of points, N>=1 | +//| NX - space dimension, NX>=1. | +//| NY - number of optional Y-values, NY>=0. | +//| NormType- norm type: | +//| * 0 denotes infinity-norm | +//| * 1 denotes 1-norm | +//| * 2 denotes 2-norm (Euclidean norm) | +//| OUTPUT PARAMETERS | +//| KDT - KD-tree | +//| NOTES | +//| 1. KD-tree creation have O(N*logN) complexity and | +//| O(N*(2*NX+NY)) memory requirements. | +//| 2. Although KD-trees may be used with any combination of N and | +//| NX, they are more efficient than brute-force search only when | +//| N >> 4^NX. So they are most useful in low-dimensional tasks | +//| (NX=2, NX=3). NX=1 is another inefficient case, because | +//| simple binary search (without additional structures) is | +//| much more efficient in such tasks than KD-trees. | +//+------------------------------------------------------------------+ +void CAlglib::KDTreeBuild(CMatrixDouble &xy,const int n,const int nx, + const int ny,const int normtype,CKDTreeShell &kdt) + { + CNearestNeighbor::KDTreeBuild(xy,n,nx,ny,normtype,kdt.GetInnerObj()); + } +//+------------------------------------------------------------------+ +//| KD-tree creation | +//| This subroutine creates KD-tree from set of X-values and optional| +//| Y-values | +//| INPUT PARAMETERS | +//| XY - dataset,array[0..N-1, 0..NX+NY-1]. | +//| one row corresponds to one point. | +//| first NX columns contain X-values, next NY (NY | +//| may be zero) | +//| columns may contain associated Y-values | +//| N - number of points, N>=1 | +//| NX - space dimension, NX>=1. | +//| NY - number of optional Y-values, NY>=0. | +//| NormType- norm type: | +//| * 0 denotes infinity-norm | +//| * 1 denotes 1-norm | +//| * 2 denotes 2-norm (Euclidean norm) | +//| OUTPUT PARAMETERS | +//| KDT - KD-tree | +//| NOTES | +//| 1. KD-tree creation have O(N*logN) complexity and | +//| O(N*(2*NX+NY)) memory requirements. | +//| 2. Although KD-trees may be used with any combination of N and | +//| NX, they are more efficient than brute-force search only when | +//| N >> 4^NX. So they are most useful in low-dimensional tasks | +//| (NX=2, NX=3). NX=1 is another inefficient case, because | +//| simple binary search (without additional structures) is | +//| much more efficient in such tasks than KD-trees. | +//+------------------------------------------------------------------+ +void CAlglib::KDTreeBuild(CMatrixDouble &xy,const int nx,const int ny, + const int normtype,CKDTreeShell &kdt) + { +//--- create a variable + int n=(int)CAp::Rows(xy); +//--- function call + CNearestNeighbor::KDTreeBuild(xy,n,nx,ny,normtype,kdt.GetInnerObj()); + } +//+------------------------------------------------------------------+ +//| KD-tree creation | +//| This subroutine creates KD-tree from set of X-values, integer | +//| tags and optional Y-values | +//| INPUT PARAMETERS | +//| XY - dataset,array[0..N-1, 0..NX+NY-1]. | +//| one row corresponds to one point. | +//| first NX columns contain X-values, next NY (NY | +//| may be zero) | +//| columns may contain associated Y-values | +//| Tags - tags, array[0..N-1], contains integer tags | +//| associated with points. | +//| N - number of points, N>=1 | +//| NX - space dimension, NX>=1. | +//| NY - number of optional Y-values, NY>=0. | +//| NormType- norm type: | +//| * 0 denotes infinity-norm | +//| * 1 denotes 1-norm | +//| * 2 denotes 2-norm (Euclidean norm) | +//| OUTPUT PARAMETERS | +//| KDT - KD-tree | +//| NOTES | +//| 1. KD-tree creation have O(N*logN) complexity and | +//| O(N*(2*NX+NY)) memory requirements. | +//| 2. Although KD-trees may be used with any combination of N and | +//| NX, they are more efficient than brute-force search only when | +//| N >> 4^NX. So they are most useful in low-dimensional tasks | +//| (NX=2, NX=3). NX=1 is another inefficient case, because simple| +//| binary search (without additional structures) is much more | +//| efficient in such tasks than KD-trees. | +//+------------------------------------------------------------------+ +void CAlglib::KDTreeBuildTagged(CMatrixDouble &xy,int &tags[], + const int n,const int nx, + const int ny,const int normtype, + CKDTreeShell &kdt) + { + CNearestNeighbor::KDTreeBuildTagged(xy,tags,n,nx,ny,normtype,kdt.GetInnerObj()); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void CAlglib::KDTreeBuildTagged(CMatrixDouble &xy,CRowInt &tags, + const int n,const int nx, + const int ny,const int normtype, + CKDTreeShell &kdt) + { + CNearestNeighbor::KDTreeBuildTagged(xy,tags,n,nx,ny,normtype,kdt.GetInnerObj()); + } +//+------------------------------------------------------------------+ +//| KD-tree creation | +//| This subroutine creates KD-tree from set of X-values, integer | +//| tags and optional Y-values | +//| INPUT PARAMETERS | +//| XY - dataset,array[0..N-1, 0..NX+NY-1]. | +//| one row corresponds to one point. | +//| first NX columns contain X-values, next NY (NY | +//| may be zero) | +//| columns may contain associated Y-values | +//| Tags - tags, array[0..N-1], contains integer tags | +//| associated with points. | +//| N - number of points, N>=1 | +//| NX - space dimension, NX>=1. | +//| NY - number of optional Y-values, NY>=0. | +//| NormType- norm type: | +//| * 0 denotes infinity-norm | +//| * 1 denotes 1-norm | +//| * 2 denotes 2-norm (Euclidean norm) | +//| OUTPUT PARAMETERS | +//| KDT - KD-tree | +//| NOTES | +//| 1. KD-tree creation have O(N*logN) complexity and | +//| O(N*(2*NX+NY)) memory requirements. | +//| 2. Although KD-trees may be used with any combination of N and | +//| NX, they are more efficient than brute-force search only when | +//| N >> 4^NX. So they are most useful in low-dimensional tasks | +//| (NX=2, NX=3). NX=1 is another inefficient case, because simple| +//| binary search (without additional structures) is much more | +//| efficient in such tasks than KD-trees. | +//+------------------------------------------------------------------+ +void CAlglib::KDTreeBuildTagged(CMatrixDouble &xy,int &tags[], + const int nx,const int ny, + const int normtype,CKDTreeShell &kdt) + { +//--- check + if((CAp::Rows(xy)!=CAp::Len(tags))) + { + Print(__FUNCTION__+": looks like one of arguments has wrong size"); + CAp::exception_happened=true; + return; + } +//--- initialization + int n=(int)CAp::Rows(xy); +//--- function call + CNearestNeighbor::KDTreeBuildTagged(xy,tags,n,nx,ny,normtype,kdt.GetInnerObj()); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void CAlglib::KDTreeBuildTagged(CMatrixDouble &xy,CRowInt &tags, + const int nx,const int ny, + const int normtype,CKDTreeShell &kdt) + { +//--- check + if((CAp::Rows(xy)!=CAp::Len(tags))) + { + Print(__FUNCTION__+": looks like one of arguments has wrong size"); + CAp::exception_happened=true; + return; + } +//--- initialization + int n=(int)CAp::Rows(xy); +//--- function call + CNearestNeighbor::KDTreeBuildTagged(xy,tags,n,nx,ny,normtype,kdt.GetInnerObj()); + } +//+------------------------------------------------------------------+ +//| K-NN query: K nearest neighbors | +//| INPUT PARAMETERS | +//| KDT - KD-tree | +//| X - point, array[0..NX-1]. | +//| K - number of neighbors to return, K>=1 | +//| SelfMatch - whether self-matches are allowed: | +//| * if True, nearest neighbor may be the point | +//| itself (if it exists in original dataset) | +//| * if False, then only points with non-zero | +//| distance are returned | +//| * if not given, considered True | +//| RESULT | +//| number of actual neighbors found (either K or N, if K>N). | +//| This subroutine performs query and stores its result in the | +//| internal structures of the KD-tree. You can use following | +//| subroutines to obtain these results: | +//| * KDTreeQueryResultsX() to get X-values | +//| * KDTreeQueryResultsXY() to get X- and Y-values | +//| * KDTreeQueryResultsTags() to get tag values | +//| * KDTreeQueryResultsDistances() to get distances | +//+------------------------------------------------------------------+ +int CAlglib::KDTreeQueryKNN(CKDTreeShell &kdt,double &x[], + const int k,const bool selfmatch=true) + { + return(CNearestNeighbor::KDTreeQueryKNN(kdt.GetInnerObj(),x,k,selfmatch)); + } +//+------------------------------------------------------------------+ +//| K-NN query: K nearest neighbors | +//| INPUT PARAMETERS | +//| KDT - KD-tree | +//| X - point, array[0..NX-1]. | +//| K - number of neighbors to return, K>=1 | +//| SelfMatch - whether self-matches are allowed: | +//| * if True, nearest neighbor may be the point | +//| itself (if it exists in original dataset) | +//| * if False, then only points with non-zero | +//| distance are returned | +//| * if not given, considered True | +//| RESULT | +//| number of actual neighbors found (either K or N, if K>N). | +//| This subroutine performs query and stores its result in the | +//| internal structures of the KD-tree. You can use following | +//| subroutines to obtain these results: | +//| * KDTreeQueryResultsX() to get X-values | +//| * KDTreeQueryResultsXY() to get X- and Y-values | +//| * KDTreeQueryResultsTags() to get tag values | +//| * KDTreeQueryResultsDistances() to get distances | +//+------------------------------------------------------------------+ +int CAlglib::KDTreeQueryKNN(CKDTreeShell &kdt,vector &x, + const int k,const bool selfmatch) + { + CRowDouble X=x; + return(CNearestNeighbor::KDTreeQueryKNN(kdt.GetInnerObj(),X,k,selfmatch)); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +int CAlglib::KDTreeQueryKNN(CKDTreeShell &kdt,CRowDouble &x, + const int k,const bool selfmatch=true) + { + return(CNearestNeighbor::KDTreeQueryKNN(kdt.GetInnerObj(),x,k,selfmatch)); + } +//+------------------------------------------------------------------+ +//| K-NN query: K nearest neighbors, using external thread-local | +//| buffer. | +//| You can call this function from multiple threads for same kd-tree| +//| instance, assuming that different instances of buffer object are | +//| passed to different threads. | +//| INPUT PARAMETERS | +//| KDT - kd-tree | +//| Buf - request buffer object created for this particular | +//| instance of kd-tree structure with | +//| KDTreeCreateRequestBuffer() function. | +//| X - point, array[0..NX-1]. | +//| K - number of neighbors to return, K>=1 | +//| SelfMatch - whether self-matches are allowed: | +//| * if True, nearest neighbor may be the point | +//| itself (if it exists in original dataset) | +//| * if False, then only points with non-zero | +//| distance are returned | +//| * if not given, considered True | +//| RESULT | +//| number of actual neighbors found (either K or N, if K>N). | +//| This subroutine performs query and stores its result in the | +//| internal structures of the buffer object. You can use following | +//| subroutines to obtain these results (pay attention to "buf" in | +//| their names): | +//| * KDTreeTsQueryResultsX() to get X-values | +//| * KDTreeTsQueryResultsXY() to get X- and Y-values | +//| * KDTreeTsQueryResultsTags() to get tag values | +//| * KDTreeTsQueryResultsDistances() to get distances | +//| IMPORTANT: kd-tree buffer should be used only with KD-tree object| +//| which was used to initialize buffer. Any attempt to use biffer | +//| with different object is dangerous - you may get integrity check | +//| failure (exception) because sizes of internal arrays do not fit | +//| to dimensions of KD-tree structure. | +//+------------------------------------------------------------------+ +int CAlglib::KDTreeTsQueryKNN(CKDTreeShell &kdt,CKDTreeRequestBufferShell &buf, + double &x[],const int k,const bool selfmatch) + { + CRowDouble X=x; + return(CNearestNeighbor::KDTreeTsQueryKNN(kdt.GetInnerObj(),buf.GetInnerObj(),X,k,selfmatch)); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +int CAlglib::KDTreeTsQueryKNN(CKDTreeShell &kdt,CKDTreeRequestBufferShell &buf, + vector &x,const int k,const bool selfmatch) + { + CRowDouble X=x; + return(CNearestNeighbor::KDTreeTsQueryKNN(kdt.GetInnerObj(),buf.GetInnerObj(),X,k,selfmatch)); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +int CAlglib::KDTreeTsQueryKNN(CKDTreeShell &kdt,CKDTreeRequestBufferShell &buf, + CRowDouble &x,const int k,const bool selfmatch) + { + return(CNearestNeighbor::KDTreeTsQueryKNN(kdt.GetInnerObj(),buf.GetInnerObj(),x,k,selfmatch)); + } +//+------------------------------------------------------------------+ +//| R-NN query: all points within R-sphere centered at X | +//| INPUT PARAMETERS | +//| KDT - KD-tree | +//| X - point, array[0..NX-1]. | +//| R - radius of sphere (in corresponding norm), R>0| +//| SelfMatch - whether self-matches are allowed: | +//| * if True, nearest neighbor may be the point | +//| itself (if it exists in original dataset) | +//| * if False, then only points with non-zero | +//| distance are returned | +//| * if not given, considered True | +//| RESULT | +//| number of neighbors found, >=0 | +//| This subroutine performs query and stores its result in the | +//| internal structures of the KD-tree. You can use following | +//| subroutines to obtain actual results: | +//| * KDTreeQueryResultsX() to get X-values | +//| * KDTreeQueryResultsXY() to get X- and Y-values | +//| * KDTreeQueryResultsTags() to get tag values | +//| * KDTreeQueryResultsDistances() to get distances | +//+------------------------------------------------------------------+ +int CAlglib::KDTreeQueryRNN(CKDTreeShell &kdt,double &x[], + const double r,const bool selfmatch) + { + return(CNearestNeighbor::KDTreeQueryRNN(kdt.GetInnerObj(),x,r,selfmatch)); + } +//+------------------------------------------------------------------+ +//| R-NN query: all points within R-sphere centered at X | +//| INPUT PARAMETERS | +//| KDT - KD-tree | +//| X - point, array[0..NX-1]. | +//| R - radius of sphere (in corresponding norm), R>0| +//| SelfMatch - whether self-matches are allowed: | +//| * if True, nearest neighbor may be the point | +//| itself (if it exists in original dataset) | +//| * if False, then only points with non-zero | +//| distance are returned | +//| * if not given, considered True | +//| RESULT | +//| number of neighbors found, >=0 | +//| This subroutine performs query and stores its result in the | +//| internal structures of the KD-tree. You can use following | +//| subroutines to obtain actual results: | +//| * KDTreeQueryResultsX() to get X-values | +//| * KDTreeQueryResultsXY() to get X- and Y-values | +//| * KDTreeQueryResultsTags() to get tag values | +//| * KDTreeQueryResultsDistances() to get distances | +//+------------------------------------------------------------------+ +int CAlglib::KDTreeQueryRNN(CKDTreeShell &kdt,vector &x, + const double r,const bool selfmatch) + { + CRowDouble X=x; + return(CNearestNeighbor::KDTreeQueryRNN(kdt.GetInnerObj(),X,r,selfmatch)); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +int CAlglib::KDTreeQueryRNN(CKDTreeShell &kdt,CRowDouble &x, + const double r,const bool selfmatch) + { + return(CNearestNeighbor::KDTreeQueryRNN(kdt.GetInnerObj(),x,r,selfmatch)); + } +//+------------------------------------------------------------------+ +//| R-NN query: all points within R-sphere centered at X, no ordering| +//| by distance as undicated by "U" suffix (faster that ordered | +//| query, for large queries - significantly faster). | +//| IMPORTANT: this function can not be used in multithreaded code | +//| because it uses internal temporary buffer of kd-tree | +//| object, which can not be shared between multiple | +//| threads. If you want to perform parallel requests, use| +//| function which uses external request buffer: | +//| KDTreeTsQueryRNN() ("Ts" stands for "thread-safe"). | +//| INPUT PARAMETERS | +//| KDT - KD-tree | +//| X - point, array[0..NX-1]. | +//| R - radius of sphere (in corresponding norm), R>0 | +//| SelfMatch - whether self-matches are allowed: | +//| * if True, nearest neighbor may be the point | +//| itself (if it exists in original dataset) | +//| * if False, then only points with non-zero | +//| distance are returned | +//| * if not given, considered True | +//| RESULT | +//| number of neighbors found, >=0 | +//| This subroutine performs query and stores its result in the | +//| internal structures of the KD-tree. You can use following | +//| subroutines to obtain actual results: | +//| * KDTreeQueryResultsX() to get X-values | +//| * KDTreeQueryResultsXY() to get X- and Y-values | +//| * KDTreeQueryResultsTags() to get tag values | +//| * KDTreeQueryResultsDistances() to get distances | +//| As indicated by "U" suffix, this function returns unordered | +//| results. | +//+------------------------------------------------------------------+ +int CAlglib::KDTreeQueryRNNU(CKDTreeShell &kdt,double &x[],const double r,bool selfmatch) + { + return(CNearestNeighbor::KDTreeQueryRNNU(kdt.GetInnerObj(),x,r,selfmatch)); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +int CAlglib::KDTreeQueryRNNU(CKDTreeShell &kdt,vector &x,const double r,bool selfmatch) + { + CRowDouble X=x; + return(CNearestNeighbor::KDTreeQueryRNNU(kdt.GetInnerObj(),X,r,selfmatch)); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +int CAlglib::KDTreeQueryRNNU(CKDTreeShell &kdt,CRowDouble &x,const double r,bool selfmatch) + { + return(CNearestNeighbor::KDTreeQueryRNNU(kdt.GetInnerObj(),x,r,selfmatch)); + } +//+------------------------------------------------------------------+ +//| R-NN query: all points within R-sphere centered at X, using | +//| external thread-local buffer, sorted by distance between point | +//| and X (by ascending) | +//| You can call this function from multiple threads for same kd-tree| +//| instance, assuming that different instances of buffer object are | +//| passed to different threads. | +//| NOTE: it is also possible to perform undordered queries performed| +//| by means of KDTreeQueryRNNU() and KDTreeTsQueryRNNU() functions. | +//| Such queries are faster because we do not have to use heap | +//| structure for sorting. | +//| INPUT PARAMETERS | +//| KDT - KD-tree | +//| Buf - request buffer object created for this particular | +//| instance of kd-tree structure with | +//| KDTreeCreateRequestBuffer() function. | +//| X - point, array[0..NX-1]. | +//| R - radius of sphere (in corresponding norm), R>0 | +//| SelfMatch - whether self-matches are allowed: | +//| * if True, nearest neighbor may be the point itself | +//| (if it exists in original dataset) | +//| * if False, then only points with non-zero distance | +//| are returned | +//| * if not given, considered True | +//| RESULT | +//| number of neighbors found, >=0 | +//| This subroutine performs query and stores its result in the | +//| internal structures of the buffer object. You can use following | +//| subroutines to obtain these results (pay attention to "buf" in | +//| their names): | +//| * KDTreeTsQueryResultsX() to get X-values | +//| * KDTreeTsQueryResultsXY() to get X- and Y-values | +//| * KDTreeTsQueryResultsTags() to get tag values | +//| * KDTreeTsQueryResultsDistances() to get distances | +//| IMPORTANT: kd-tree buffer should be used only with KD-tree object| +//| which was used to initialize buffer. Any attempt to | +//| use biffer with different object is dangerous - you | +//| may get integrity check failure (exception) because | +//| sizes of internal arrays do not fit to dimensions of | +//| KD-tree structure. | +//+------------------------------------------------------------------+ +int CAlglib::KDTreeTsQueryRNN(CKDTreeShell &kdt,CKDTreeRequestBufferShell &buf, + double &x[],const double r,bool selfmatch) + { + CRowDouble X=x; + return(CNearestNeighbor::KDTreeTsQueryRNN(kdt.GetInnerObj(),buf.GetInnerObj(),X,r,selfmatch)); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +int CAlglib::KDTreeTsQueryRNN(CKDTreeShell &kdt,CKDTreeRequestBufferShell &buf, + vector &x,const double r,bool selfmatch) + { + CRowDouble X=x; + return(CNearestNeighbor::KDTreeTsQueryRNN(kdt.GetInnerObj(),buf.GetInnerObj(),X,r,selfmatch)); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +int CAlglib::KDTreeTsQueryRNN(CKDTreeShell &kdt,CKDTreeRequestBufferShell &buf, + CRowDouble &x,const double r,bool selfmatch) + { + return(CNearestNeighbor::KDTreeTsQueryRNN(kdt.GetInnerObj(),buf.GetInnerObj(),x,r,selfmatch)); + } +//+------------------------------------------------------------------+ +//| R-NN query: all points within R-sphere centered at X, using | +//| external thread-local buffer, no ordering by distance as | +//| undicated by "U" suffix (faster that ordered query, for large | +//| queries - significantly faster). | +//| You can call this function from multiple threads for same kd-tree| +//| instance, assuming that different instances of buffer object are | +//| passed to different threads. | +//| INPUT PARAMETERS | +//| KDT - KD-tree | +//| Buf - request buffer object created for this particular | +//| instance of kd-tree structure with | +//| KDTreeCreateRequestBuffer() function. | +//| X - point, array[0..NX-1]. | +//| R - radius of sphere (in corresponding norm), R>0 | +//| SelfMatch - whether self-matches are allowed: | +//| * if True, nearest neighbor may be the point itself| +//| (if it exists in original dataset) | +//| * if False, then only points with non-zero distance| +//| are returned | +//| * if not given, considered True | +//| RESULT | +//| number of neighbors found, >=0 | +//| This subroutine performs query and stores its result in the | +//| internal structures of the buffer object. You can use following | +//| subroutines to obtain these results (pay attention to "buf" in | +//| their names): | +//| * KDTreeTsQueryResultsX() to get X-values | +//| * KDTreeTsQueryResultsXY() to get X- and Y-values | +//| * KDTreeTsQueryResultsTags() to get tag values | +//| * KDTreeTsQueryResultsDistances() to get distances | +//| As indicated by "U" suffix, this function returns unordered | +//| results. | +//| IMPORTANT: kd-tree buffer should be used only with KD-tree object| +//| which was used to initialize buffer. Any attempt to | +//| use biffer with different object is dangerous - you | +//| may get integrity check failure (exception) because | +//| sizes of internal arrays do not fit to dimensions of | +//| KD-tree structure. | +//+------------------------------------------------------------------+ +int CAlglib::KDTreeTsQueryRNNU(CKDTreeShell &kdt,CKDTreeRequestBufferShell &buf, + double &x[],const double r,const bool selfmatch) + { + CRowDouble X=x; + return(CNearestNeighbor::KDTreeTsQueryRNNU(kdt.GetInnerObj(),buf.GetInnerObj(),X,r,selfmatch)); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +int CAlglib::KDTreeTsQueryRNNU(CKDTreeShell &kdt,CKDTreeRequestBufferShell &buf, + vector &x,const double r,const bool selfmatch) + { + CRowDouble X=x; + return(CNearestNeighbor::KDTreeTsQueryRNNU(kdt.GetInnerObj(),buf.GetInnerObj(),X,r,selfmatch)); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +int CAlglib::KDTreeTsQueryRNNU(CKDTreeShell &kdt,CKDTreeRequestBufferShell &buf, + CRowDouble &x,const double r,const bool selfmatch) + { + return(CNearestNeighbor::KDTreeTsQueryRNNU(kdt.GetInnerObj(),buf.GetInnerObj(),x,r,selfmatch)); + } +//+------------------------------------------------------------------+ +//| K-NN query: approximate K nearest neighbors | +//| INPUT PARAMETERS | +//| KDT - KD-tree | +//| X - point, array[0..NX-1]. | +//| K - number of neighbors to return, K>=1 | +//| SelfMatch - whether self-matches are allowed: | +//| * if True, nearest neighbor may be the point | +//| itself (if it exists in original dataset) | +//| * if False, then only points with non-zero | +//| distance are returned | +//| * if not given, considered True | +//| Eps - approximation factor, Eps>=0. eps-approximate| +//| nearest neighbor is a neighbor whose distance| +//| from X is at most (1+eps) times distance of | +//| true nearest neighbor. | +//| RESULT | +//| number of actual neighbors found (either K or N, if K>N). | +//| NOTES | +//| significant performance gain may be achieved only when Eps is| +//| on the order of magnitude of 1 or larger. | +//| This subroutine performs query and stores its result in the | +//| internal structures of the KD-tree. You can use following | +//| these subroutines to obtain results: | +//| * KDTreeQueryResultsX() to get X-values | +//| * KDTreeQueryResultsXY() to get X- and Y-values | +//| * KDTreeQueryResultsTags() to get tag values | +//| * KDTreeQueryResultsDistances() to get distances | +//+------------------------------------------------------------------+ +int CAlglib::KDTreeQueryAKNN(CKDTreeShell &kdt,double &x[], + const int k,const bool selfmatch, + const double eps) + { + return(CNearestNeighbor::KDTreeQueryAKNN(kdt.GetInnerObj(),x,k,selfmatch,eps)); + } +//+------------------------------------------------------------------+ +//| K-NN query: approximate K nearest neighbors | +//| INPUT PARAMETERS | +//| KDT - KD-tree | +//| X - point, array[0..NX-1]. | +//| K - number of neighbors to return, K>=1 | +//| SelfMatch - whether self-matches are allowed: | +//| * if True, nearest neighbor may be the point | +//| itself (if it exists in original dataset) | +//| * if False, then only points with non-zero | +//| distance are returned | +//| * if not given, considered True | +//| Eps - approximation factor, Eps>=0. eps-approximate| +//| nearest neighbor is a neighbor whose distance| +//| from X is at most (1+eps) times distance of | +//| true nearest neighbor. | +//| RESULT | +//| number of actual neighbors found (either K or N, if K>N). | +//| NOTES | +//| significant performance gain may be achieved only when Eps is| +//| on the order of magnitude of 1 or larger. | +//| This subroutine performs query and stores its result in the | +//| internal structures of the KD-tree. You can use following | +//| these subroutines to obtain results: | +//| * KDTreeQueryResultsX() to get X-values | +//| * KDTreeQueryResultsXY() to get X- and Y-values | +//| * KDTreeQueryResultsTags() to get tag values | +//| * KDTreeQueryResultsDistances() to get distances | +//+------------------------------------------------------------------+ +int CAlglib::KDTreeQueryAKNN(CKDTreeShell &kdt,vector &x, + const int k,const bool selfmatch, + const double eps=0) + { + CRowDouble X=x; + return(CNearestNeighbor::KDTreeQueryAKNN(kdt.GetInnerObj(),X,k,selfmatch,eps)); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +int CAlglib::KDTreeQueryAKNN(CKDTreeShell &kdt,CRowDouble &x, + const int k,const bool selfmatch, + const double eps) + { + return(CNearestNeighbor::KDTreeQueryAKNN(kdt.GetInnerObj(),x,k,selfmatch,eps)); + } +//+------------------------------------------------------------------+ +//| Box query: all points within user-specified box. | +//| IMPORTANT: this function can not be used in multithreaded code | +//| because it uses internal temporary buffer of kd-tree | +//| object, which can not be shared between multiple | +//| threads. If you want to perform parallel requests, | +//| use function which uses external request buffer: | +//| KDTreeTsQueryBox() ("Ts" stands for "thread-safe"). | +//| INPUT PARAMETERS | +//| KDT - KD-tree | +//| BoxMin - lower bounds, array[0..NX-1]. | +//| BoxMax - upper bounds, array[0..NX-1]. | +//| RESULT | +//| number of actual neighbors found (in [0,N]). | +//| This subroutine performs query and stores its result in the | +//| internal structures of the KD-tree. You can use following | +//| subroutines to obtain these results: | +//| * KDTreeQueryResultsX() to get X-values | +//| * KDTreeQueryResultsXY() to get X- and Y-values | +//| * KDTreeQueryResultsTags() to get tag values | +//| * KDTreeQueryResultsDistances() returns zeros for this request | +//| NOTE: this particular query returns unordered results, because | +//| there is no meaningful way of ordering points. Furthermore,| +//| no 'distance' is associated with points - it is either | +//| INSIDE or OUTSIDE (so request for distances will return | +//| zeros). | +//+------------------------------------------------------------------+ +int CAlglib::KDTreeQueryBox(CKDTreeShell &kdt,double &boxmin[],double &boxmax[]) + { + return(CNearestNeighbor::KDTreeQueryBox(kdt.GetInnerObj(),boxmin,boxmax)); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +int CAlglib::KDTreeQueryBox(CKDTreeShell &kdt,vector &boxmin,vector &boxmax) + { + CRowDouble Min=boxmin; + CRowDouble Max=boxmax; + return(CNearestNeighbor::KDTreeQueryBox(kdt.GetInnerObj(),Min,Max)); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +int CAlglib::KDTreeQueryBox(CKDTreeShell &kdt,CRowDouble &boxmin,CRowDouble &boxmax) + { + return(CNearestNeighbor::KDTreeQueryBox(kdt.GetInnerObj(),boxmin,boxmax)); + } +//+------------------------------------------------------------------+ +//| Box query: all points within user-specified box, using | +//| thread-local buffer. | +//| You can call this function from multiple threads for same kd-tree| +//| instance, assuming that different instances of buffer object are | +//| passed to different threads. | +//| INPUT PARAMETERS | +//| KDT - KD-tree | +//| Buf - request buffer object created for this particular | +//| instance of kd-tree structure with | +//| KDTreeCreateRequestBuffer() function. | +//| BoxMin - lower bounds, array[0..NX-1]. | +//| BoxMax - upper bounds, array[0..NX-1]. | +//| RESULT | +//| number of actual neighbors found (in [0,N]). | +//| This subroutine performs query and stores its result in the | +//| internal structures of the buffer object. You can use following | +//| subroutines to obtain these results (pay attention to "ts" in | +//| their names): | +//| * KDTreeTsQueryResultsX() to get X-values | +//| * KDTreeTsQueryResultsXY() to get X- and Y-values | +//| * KDTreeTsQueryResultsTags() to get tag values | +//| * KDTreeTsQueryResultsDistances() returns zeros for this query | +//| NOTE: this particular query returns unordered results, because | +//| there is no meaningful way of ordering points. Furthermore,| +//| no 'distance' is associated with points - it is either | +//| INSIDE or OUTSIDE (so request for distances will return | +//| zeros). | +//| IMPORTANT: kd-tree buffer should be used only with KD-tree object| +//| which was used to initialize buffer. Any attempt to | +//| use biffer with different object is dangerous - you | +//| may get integrity check failure (exception) because| +//| sizes of internal arrays do not fit to dimensions of | +//| KD-tree structure. | +//+------------------------------------------------------------------+ +int CAlglib::KDTreeTsQueryBox(CKDTreeShell &kdt,CKDTreeRequestBufferShell &buf,double &boxmin[],double &boxmax[]) + { + return(CNearestNeighbor::KDTreeTsQueryBox(kdt.GetInnerObj(),buf.GetInnerObj(),boxmin,boxmax)); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +int CAlglib::KDTreeTsQueryBox(CKDTreeShell &kdt,CKDTreeRequestBufferShell &buf,CRowDouble &boxmin,CRowDouble &boxmax) + { + return(CNearestNeighbor::KDTreeTsQueryBox(kdt.GetInnerObj(),buf.GetInnerObj(),boxmin,boxmax)); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +int CAlglib::KDTreeTsQueryBox(CKDTreeShell &kdt,CKDTreeRequestBufferShell &buf,vector &boxmin,vector &boxmax) + { + CRowDouble Min=boxmin; + CRowDouble Max=boxmax; + return(CNearestNeighbor::KDTreeTsQueryBox(kdt.GetInnerObj(),buf.GetInnerObj(),Min,Max)); + } +//+------------------------------------------------------------------+ +//| X-values from last query | +//| INPUT PARAMETERS | +//| KDT - KD-tree | +//| X - possibly pre-allocated buffer. If X is too small | +//| to store result, it is resized. If size(X) is | +//| enough to store result, it is left unchanged. | +//| OUTPUT PARAMETERS | +//| X - rows are filled with X-values | +//| NOTES | +//| 1. points are ordered by distance from the query point (first = | +//| closest) | +//| 2. if XY is larger than required to store result, only leading | +//| part will be overwritten; trailing part will be left | +//| unchanged. So if on input XY = [[A,B],[C,D]], and result is | +//| [1,2], then on exit we will get XY = [[1,2],[C,D]]. This is | +//| done purposely to increase performance; if you want function | +//| to resize array according to result size, use function with | +//| same name and suffix 'I'. | +//| SEE ALSO | +//| * KDTreeQueryResultsXY() X- and Y-values | +//| * KDTreeQueryResultsTags() tag values | +//| * KDTreeQueryResultsDistances() distances | +//+------------------------------------------------------------------+ +void CAlglib::KDTreeQueryResultsX(CKDTreeShell &kdt,CMatrixDouble &x) + { + CNearestNeighbor::KDTreeQueryResultsX(kdt.GetInnerObj(),x); + } +//+------------------------------------------------------------------+ +//| X- and Y-values from last query | +//| INPUT PARAMETERS | +//| KDT - KD-tree | +//| XY - possibly pre-allocated buffer. If XY is too small| +//| to store result, it is resized. If size(XY) is | +//| enough to store result, it is left unchanged. | +//| OUTPUT PARAMETERS | +//| XY - rows are filled with points: first NX columns | +//| with X-values, next NY columns - with Y-values. | +//| NOTES | +//| 1. points are ordered by distance from the query point (first = | +//| closest) | +//| 2. if XY is larger than required to store result, only leading | +//| part will be overwritten; trailing part will be left | +//| unchanged. So if on input XY = [[A,B],[C,D]], and result is | +//| [1,2], then on exit we will get XY = [[1,2],[C,D]]. This is | +//| done purposely to increase performance; if you want function | +//| to resize array according to result size, use function with | +//| same name and suffix 'I'. | +//| SEE ALSO | +//| * KDTreeQueryResultsX() X-values | +//| * KDTreeQueryResultsTags() tag values | +//| * KDTreeQueryResultsDistances() distances | +//+------------------------------------------------------------------+ +void CAlglib::KDTreeQueryResultsXY(CKDTreeShell &kdt,CMatrixDouble &xy) + { + CNearestNeighbor::KDTreeQueryResultsXY(kdt.GetInnerObj(),xy); + } +//+------------------------------------------------------------------+ +//| Tags from last query | +//| INPUT PARAMETERS | +//| KDT - KD-tree | +//| Tags - possibly pre-allocated buffer. If X is too small | +//| to store result, it is resized. If size(X) is | +//| enough to store result, it is left unchanged. | +//| OUTPUT PARAMETERS | +//| Tags - filled with tags associated with points, | +//| or, when no tags were supplied, with zeros | +//| NOTES | +//| 1. points are ordered by distance from the query point (first | +//| = closest) | +//| 2. if XY is larger than required to store result, only leading | +//| part will be overwritten; trailing part will be left | +//| unchanged. So if on input XY = [[A,B],[C,D]], and result is | +//| [1,2],then on exit we will get XY = [[1,2], [C,D]]. This is | +//| done purposely to increase performance; if you want function | +//| to resize array according to result size, use function with | +//| same name and suffix 'I'. | +//| SEE ALSO | +//| * KDTreeQueryResultsX() X-values | +//| * KDTreeQueryResultsXY() X- and Y-values | +//| * KDTreeQueryResultsDistances() distances | +//+------------------------------------------------------------------+ +void CAlglib::KDTreeQueryResultsTags(CKDTreeShell &kdt,int &tags[]) + { + CNearestNeighbor::KDTreeQueryResultsTags(kdt.GetInnerObj(),tags); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void CAlglib::KDTreeQueryResultsTags(CKDTreeShell &kdt,CRowInt &tags) + { + CNearestNeighbor::KDTreeQueryResultsTags(kdt.GetInnerObj(),tags); + } +//+------------------------------------------------------------------+ +//| Distances from last query | +//| INPUT PARAMETERS | +//| KDT - KD-tree | +//| R - possibly pre-allocated buffer. If X is too small | +//| to store result, it is resized. If size(X) is | +//| enough to store result, it is left unchanged. | +//| OUTPUT PARAMETERS | +//| R - filled with distances (in corresponding norm) | +//| NOTES | +//| 1. points are ordered by distance from the query point (first | +//| = closest) | +//| 2. if XY is larger than required to store result, only leading | +//| part will be overwritten; trailing part will be left | +//| unchanged. So if on input XY = [[A,B], [C,D]],and result is | +//| [1,2], then on exit we will get XY = [[1,2], C,D]]. This is | +//| done purposely to increase performance; if you want function | +//| to resize array according to result size, use function with | +//| same name and suffix 'I'. | +//| SEE ALSO | +//| * KDTreeQueryResultsX() X-values | +//| * KDTreeQueryResultsXY() X- and Y-values | +//| * KDTreeQueryResultsTags() tag values | +//+------------------------------------------------------------------+ +void CAlglib::KDTreeQueryResultsDistances(CKDTreeShell &kdt,double &r[]) + { + CNearestNeighbor::KDTreeQueryResultsDistances(kdt.GetInnerObj(),r); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void CAlglib::KDTreeQueryResultsDistances(CKDTreeShell &kdt,CRowDouble &r) + { + CNearestNeighbor::KDTreeQueryResultsDistances(kdt.GetInnerObj(),r); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void CAlglib::KDTreeQueryResultsDistances(CKDTreeShell &kdt,vector &r) + { +//--- create variables + CRowDouble R; +//--- function call + CNearestNeighbor::KDTreeQueryResultsDistances(kdt.GetInnerObj(),R); +//---copy result + r=R.ToVector(); + } +//+------------------------------------------------------------------+ +//| X-values from last query; 'interactive' variant for languages | +//| like Python which support constructs like "X = | +//| KDTreeQueryResultsXI(KDT)" and interactive mode of interpreter. | +//| This function allocates new array on each call, so it is | +//| significantly slower than its 'non-interactive' counterpart, but | +//| it is more convenient when you call it from command line. | +//+------------------------------------------------------------------+ +void CAlglib::KDTreeQueryResultsXI(CKDTreeShell &kdt,CMatrixDouble &x) + { + CNearestNeighbor::KDTreeQueryResultsXI(kdt.GetInnerObj(),x); + } +//+------------------------------------------------------------------+ +//| XY-values from last query; 'interactive' variant for languages | +//| like Python which support constructs like "XY = | +//| KDTreeQueryResultsXYI(KDT)" and interactive mode of interpreter. | +//| This function allocates new array on each call, so it is | +//| significantly slower than its 'non-interactive' counterpart, but | +//| it is more convenient when you call it from command line. | +//+------------------------------------------------------------------+ +void CAlglib::KDTreeQueryResultsXYI(CKDTreeShell &kdt,CMatrixDouble &xy) + { + CNearestNeighbor::KDTreeQueryResultsXYI(kdt.GetInnerObj(),xy); + } +//+------------------------------------------------------------------+ +//| Tags from last query; 'interactive' variant for languages like | +//| Python which support constructs like "Tags = | +//| KDTreeQueryResultsTagsI(KDT)" and interactive mode of | +//| interpreter. | +//| This function allocates new array on each call, so it is | +//| significantly slower than its 'non-interactive' counterpart, but | +//| it is more convenient when you call it from command line. | +//+------------------------------------------------------------------+ +void CAlglib::KDTreeQueryResultsTagsI(CKDTreeShell &kdt,int &tags[]) + { + CNearestNeighbor::KDTreeQueryResultsTagsI(kdt.GetInnerObj(),tags); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void CAlglib::KDTreeQueryResultsTagsI(CKDTreeShell &kdt,CRowInt &tags) + { + CNearestNeighbor::KDTreeQueryResultsTagsI(kdt.GetInnerObj(),tags); + } +//+------------------------------------------------------------------+ +//| Distances from last query; 'interactive' variant for languages | +//| like Python which support constructs like "R = | +//| KDTreeQueryResultsDistancesI(KDT)" and interactive mode of | +//| interpreter. | +//| This function allocates new array on each call, so it is | +//| significantly slower than its 'non-interactive' counterpart, but | +//| it is more convenient when you call it from command line. | +//+------------------------------------------------------------------+ +void CAlglib::KDTreeQueryResultsDistancesI(CKDTreeShell &kdt,double &r[]) + { + CNearestNeighbor::KDTreeQueryResultsDistancesI(kdt.GetInnerObj(),r); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void CAlglib::KDTreeQueryResultsDistancesI(CKDTreeShell &kdt,vector &r) + { + CRowDouble R; + CNearestNeighbor::KDTreeQueryResultsDistancesI(kdt.GetInnerObj(),R); + r=R.ToVector(); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void CAlglib::KDTreeQueryResultsDistancesI(CKDTreeShell &kdt,CRowDouble &r) + { + CNearestNeighbor::KDTreeQueryResultsDistancesI(kdt.GetInnerObj(),r); + } +//+------------------------------------------------------------------+ +//| Optimal binary classification | +//| Algorithms finds optimal (=with minimal cross-entropy) binary | +//| partition. | +//| Internal subroutine. | +//| INPUT PARAMETERS: | +//| A - array[0..N-1], variable | +//| C - array[0..N-1], class numbers (0 or 1). | +//| N - array size | +//| OUTPUT PARAMETERS: | +//| Info - completetion code: | +//| * -3, all values of A[] are same (partition is | +//| impossible) | +//| * -2, one of C[] is incorrect (<0, >1) | +//| * -1, incorrect pararemets were passed (N<=0). | +//| * 1, OK | +//| Threshold- partiton boundary. Left part contains values | +//| which are strictly less than Threshold. Right | +//| part contains values which are greater than or | +//| equal to Threshold. | +//| PAL, PBL- probabilities P(0|v=Threshold) and | +//| P(1|v>=Threshold) | +//| CVE - cross-validation estimate of cross-entropy | +//+------------------------------------------------------------------+ +void CAlglib::DSOptimalSplit2(double &a[],int &c[],const int n, + int &info,double &threshold, + double &pal,double &pbl,double &par, + double &pbr,double &cve) + { +//--- initialization + info=0; + threshold=0; + pal=0; + pbl=0; + par=0; + pbr=0; + cve=0; +//--- function call + CBdSS::DSOptimalSplit2(a,c,n,info,threshold,pal,pbl,par,pbr,cve); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void CAlglib::DSOptimalSplit2(CRowDouble &a,CRowInt &c,const int n, + int &info,double &threshold, + double &pal,double &pbl,double &par, + double &pbr,double &cve) + { +//--- initialization + info=0; + threshold=0; + pal=0; + pbl=0; + par=0; + pbr=0; + cve=0; +//--- function call + CBdSS::DSOptimalSplit2(a,c,n,info,threshold,pal,pbl,par,pbr,cve); + } +//+------------------------------------------------------------------+ +//| Optimal partition, internal subroutine. Fast version. | +//| Accepts: | +//| A array[0..N-1] array of attributes array[0..N-1]| +//| C array[0..N-1] array of class labels | +//| TiesBuf array[0..N] temporaries (ties) | +//| CntBuf array[0..2*NC-1] temporaries (counts) | +//| Alpha centering factor (0<=alpha<=1, | +//| recommended value - 0.05) | +//| BufR array[0..N-1] temporaries | +//| BufI array[0..N-1] temporaries | +//| Output: | +//| Info error code (">0"=OK, "<0"=bad) | +//| RMS training set RMS error | +//| CVRMS leave-one-out RMS error | +//| Note: | +//| content of all arrays is changed by subroutine; | +//| it doesn't allocate temporaries. | +//+------------------------------------------------------------------+ +void CAlglib::DSOptimalSplit2Fast(double &a[],int &c[],int &tiesbuf[], + int &cntbuf[],double &bufr[], + int &bufi[],const int n, + const int nc,const double alpha, + int &info,double &threshold, + double &rms,double &cvrms) + { +//--- initialization + info=0; + threshold=0; + rms=0; + cvrms=0; +//--- function call + CBdSS::DSOptimalSplit2Fast(a,c,tiesbuf,cntbuf,bufr,bufi,n,nc,alpha,info,threshold,rms,cvrms); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void CAlglib::DSOptimalSplit2Fast(CRowDouble &a,CRowInt &c,CRowInt &tiesbuf, + CRowInt &cntbuf,CRowDouble &bufr, + CRowInt &bufi,const int n, + const int nc,const double alpha, + int &info,double &threshold, + double &rms,double &cvrms) + { +//--- initialization + info=0; + threshold=0; + rms=0; + cvrms=0; +//--- function call + CBdSS::DSOptimalSplit2Fast(a,c,tiesbuf,cntbuf,bufr,bufi,n,nc,alpha,info,threshold,rms,cvrms); + } +//+------------------------------------------------------------------+ +//| This function serializes data structure to string. | +//| Important properties of s_out: | +//| * it contains alphanumeric characters, dots, underscores, minus | +//| signs | +//| * these symbols are grouped into words, which are separated by | +//| spaces and Windows-style (CR+LF) newlines | +//| * although serializer uses spaces and CR+LF as separators, you| +//| can replace any separator character by arbitrary combination of| +//| spaces, tabs, Windows or Unix newlines. It allows flexible | +//| reformatting of the string in case you want to include it into | +//| text or XML file. But you should not insert separators into the| +//| middle of the "words" nor you should change case of letters. | +//| * s_out can be freely moved between 32-bit and 64-bit systems, | +//| little and big endian machines, and so on. You can reference | +//| structure on 32-bit machine and unserialize it on 64-bit one | +//| (or vice versa), or reference it on SPARC and unserialize on | +//| x86. You can also reference it in C# version of ALGLIB and | +//| unserialize in C++ one, and vice versa. | +//+------------------------------------------------------------------+ +void CAlglib::DFSerialize(CDecisionForestShell &obj,string &s_out) + { + CSerializer s; +//--- serialization start + s.Alloc_Start(); +//--- function call + CDForest::DFAlloc(s,obj.GetInnerObj()); +//--- serialization + s.SStart_Str(); +//--- function call + CDForest::DFSerialize(s,obj.GetInnerObj()); +//--- stop + s.Stop(); +//--- change value + s_out=s.Get_String(); + } +//+------------------------------------------------------------------+ +//| This function unserializes data structure from string. | +//+------------------------------------------------------------------+ +void CAlglib::DFUnserialize(const string s_in,CDecisionForestShell &obj) + { + CSerializer s; +//--- unserialization + s.UStart_Str(s_in); +//--- function call + CDForest::DFUnserialize(s,obj.GetInnerObj()); +//--- stop + s.Stop(); + } +//+------------------------------------------------------------------+ +//| This function creates buffer structure which can be used to | +//| perform parallel inference requests. | +//| DF subpackage provides two sets of computing functions - ones | +//| which use internal buffer of DF model (these functions are | +//| single-threaded because they use same buffer, which can not | +//| shared between threads), and ones which use external buffer. | +//| This function is used to initialize external buffer. | +//| INPUT PARAMETERS: | +//| Model - DF model which is associated with newly created | +//| buffer | +//| OUTPUT PARAMETERS: | +//| Buf - external buffer. | +//| IMPORTANT: buffer object should be used only with model which was| +//| used to initialize buffer. Any attempt to use buffer | +//| with different object is dangerous - you may get | +//| integrity check failure (exception) because sizes of | +//| internal arrays do not fit to dimensions of the model | +//| structure. | +//+------------------------------------------------------------------+ +void CAlglib::DFCreateBuffer(CDecisionForestShell &model, + CDecisionForestBuffer &buf) + { + CDForest::DFCreateBuffer(model.GetInnerObj(),buf); + } +//+------------------------------------------------------------------+ +//| This subroutine creates CDecisionForestBuilder object which is | +//| used to train decision forests. | +//| By default, new builder stores empty dataset and some reasonable | +//| default settings. At the very least, you should specify dataset | +//| prior to building decision forest. You can also tweak settings of| +//| the forest construction algorithm (recommended, although default | +//| setting should work well). | +//| Following actions are mandatory: | +//| * calling DFBuilderSetDataset() to specify dataset | +//| * calling DFBuilderBuildRandomForest() to build decision forest| +//| using current dataset and default settings | +//| Additionally, you may call: | +//| * DFBuilderSetRndVars() or DFBuilderSetRndVarsRatio() to | +//| specify number of variables randomly chosen for each split | +//| * DFBuilderSetSubsampleRatio() to specify fraction of the | +//| dataset randomly subsampled to build each tree | +//| * DFBuilderSetSeed() to control random seed chosen for tree | +//| construction | +//| INPUT PARAMETERS: | +//| none | +//| OUTPUT PARAMETERS: | +//| S - decision forest builder | +//+------------------------------------------------------------------+ +void CAlglib::DFBuilderCreate(CDecisionForestBuilder &s) + { + CDForest::DFBuilderCreate(s); + } +//+------------------------------------------------------------------+ +//| This subroutine adds dense dataset to the internal storage of the| +//| builder object. Specifying your dataset in the dense format means| +//| that the dense version of the forest construction algorithm will | +//| be invoked. | +//| INPUT PARAMETERS: | +//| S - decision forest builder object | +//| XY - array[NPoints,NVars+1] (minimum size; actual size | +//| can be larger, only leading part is used anyway), | +//| dataset: | +//| * first NVars elements of each row store values of | +//| the independent variables | +//| * last column store class number(in 0...NClasses-1)| +//| or real value of the dependent variable | +//| NPoints - number of rows in the dataset, NPoints>=1 | +//| NVars - number of independent variables, NVars>=1 | +//| NClasses - indicates type of the problem being solved: | +//| * NClasses>=2 means that classification problem is | +//| solved (last column of the dataset stores class | +//| number) | +//| * NClasses=1 means that regression problem is | +//| solved (last column of the dataset stores | +//| variable value) | +//| OUTPUT PARAMETERS: | +//| S - decision forest builder | +//+------------------------------------------------------------------+ +void CAlglib::DFBuilderSetDataset(CDecisionForestBuilder &s,CMatrixDouble &xy, + int npoints,int nvars,int nclasses) + { + CDForest::DFBuilderSetDataset(s,xy,npoints,nvars,nclasses); + } +//+------------------------------------------------------------------+ +//| This function sets number of variables (in [1,NVars] range) used | +//| by decision forest construction algorithm. | +//| The default option is to use roughly sqrt(NVars) variables. | +//| INPUT PARAMETERS: | +//| S - decision forest builder object | +//| RndVars - number of randomly selected variables; values | +//| outside of [1,NVars] range are silently clipped. | +//| OUTPUT PARAMETERS: | +//| S - decision forest builder | +//+------------------------------------------------------------------+ +void CAlglib::DFBuilderSetRndVars(CDecisionForestBuilder &s,int rndvars) + { + CDForest::DFBuilderSetRndVars(s,rndvars); + } +//+------------------------------------------------------------------+ +//| This function sets number of variables used by decision forest | +//| construction algorithm as a fraction of total variable count | +//| (0,1) range. | +//| The default option is to use roughly sqrt(NVars) variables. | +//| INPUT PARAMETERS: | +//| S - decision forest builder object | +//| F - round(NVars*F) variables are selected | +//| OUTPUT PARAMETERS: | +//| S - decision forest builder | +//+------------------------------------------------------------------+ +void CAlglib::DFBuilderSetRndVarsRatio(CDecisionForestBuilder &s,double f) + { + CDForest::DFBuilderSetRndVarsRatio(s,f); + } +//+------------------------------------------------------------------+ +//| This function tells decision forest builder to automatically | +//| choose number of variables used by decision forest construction | +//| algorithm. Roughly sqrt(NVars) variables will be used. | +//| INPUT PARAMETERS: | +//| S - decision forest builder object | +//| OUTPUT PARAMETERS: | +//| S - decision forest builder | +//+------------------------------------------------------------------+ +void CAlglib::DFBuilderSetRndVarsAuto(CDecisionForestBuilder &s) + { + CDForest::DFBuilderSetRndVarsAuto(s); + } +//+------------------------------------------------------------------+ +//| This function sets size of dataset subsample generated the | +//| decision forest construction algorithm. Size is specified as a | +//| fraction of total dataset size. | +//| The default option is to use 50% of the dataset for training, | +//| 50% for the OOB estimates. You can decrease fraction F down to | +//| 10%, 1% or even below in order to reduce overfitting. | +//| INPUT PARAMETERS: | +//| S - decision forest builder object | +//| F - fraction of the dataset to use, in (0,1] range. | +//| Values outside of this range will be silently | +//| clipped. At least one element is always selected | +//| for the training set. | +//| OUTPUT PARAMETERS: | +//| S - decision forest builder | +//+------------------------------------------------------------------+ +void CAlglib::DFBuilderSetSubsampleRatio(CDecisionForestBuilder &s,double f) + { + CDForest::DFBuilderSetSubsampleRatio(s,f); + } +//+------------------------------------------------------------------+ +//| This function sets seed used by internal RNG for random | +//| subsampling and random selection of variable subsets. | +//| By default random seed is used, i.e. every time you build | +//| decision forest, we seed generator with new value obtained from | +//| system-wide RNG. Thus, decision forest builder returns | +//| non-deterministic results. You can change such behavior by | +//| specyfing fixed positive seed value. | +//| INPUT PARAMETERS: | +//| S - decision forest builder object | +//| SeedVal - seed value: | +//| * positive values are used for seeding RNG with | +//| fixed seed, i.e. subsequent runs on same data | +//| will return same decision forests | +//| * non-positive seed means that random seed is used | +//| for every run of builder, i.e. subsequent runs | +//| on same datasets will return slightly different | +//| decision forests | +//| OUTPUT PARAMETERS: | +//| S - decision forest builder, see | +//+------------------------------------------------------------------+ +void CAlglib::DFBuilderSetSeed(CDecisionForestBuilder &s,int seedval) + { + CDForest::DFBuilderSetSeed(s,seedval); + } +//+------------------------------------------------------------------+ +//| This function sets random decision forest construction algorithm.| +//| As for now, only one decision forest construction algorithm is | +//| supported-a dense "baseline" RDF algorithm. | +//| INPUT PARAMETERS: | +//| S - decision forest builder object | +//| AlgoType - algorithm type: | +//| * 0 = baseline dense RDF | +//| OUTPUT PARAMETERS: | +//| S - decision forest builder, see | +//+------------------------------------------------------------------+ +void CAlglib::DFBuilderSetRDFAlgo(CDecisionForestBuilder &s,int algotype) + { + CDForest::DFBuilderSetRDFAlgo(s,algotype); + } +//+------------------------------------------------------------------+ +//| This function sets split selection algorithm used by decision | +//| forest classifier. You may choose several algorithms, with | +//| different speed and quality of the results. | +//| INPUT PARAMETERS: | +//| S - decision forest builder object | +//| SplitStrength - split type: | +//| * 0 = split at the random position, fastest one | +//| * 1 = split at the middle of the range | +//| * 2 = strong split at the best point of the range | +//| (default) | +//| OUTPUT PARAMETERS: | +//| S - decision forest builder, see | +//+------------------------------------------------------------------+ +void CAlglib::DFBuilderSetRDFSplitStrength(CDecisionForestBuilder &s, + int splitstrength) + { + CDForest::DFBuilderSetRDFSplitStrength(s,splitstrength); + } +//+------------------------------------------------------------------+ +//| This function tells decision forest construction algorithm to use| +//| Gini impurity based variable importance estimation (also known as| +//| MDI). | +//| This version of importance estimation algorithm analyzes mean | +//| decrease in impurity (MDI) on training sample during splits. The | +//| result is divided by impurity at the root node in order to | +//| produce estimate in [0,1] range. | +//| Such estimates are fast to calculate and beautifully normalized | +//| (sum to one) but have following downsides: | +//| * They ALWAYS sum to 1.0, even if output is completely | +//| unpredictable. I.e. MDI allows to order variables by | +//| importance, but does not tell us about "absolute" | +//| importances of variables | +//| * there exist some bias towards continuous and high-cardinality| +//| categorical variables | +//| NOTE: informally speaking, MDA (permutation importance) rating | +//| answers the question "what part of the model | +//| predictive power is ruined by permuting k-th variable?" | +//| while MDI tells us "what part of the model predictive power| +//| was achieved due to usage of k-th variable". | +//| Thus, MDA rates each variable independently at "0 to 1" scale | +//| while MDI (and OOB-MDI too) tends to divide "unit amount of | +//| importance" between several important variables. | +//| If all variables are equally important, they will have same | +//| MDI/OOB-MDI rating, equal (for OOB-MDI: roughly equal) to | +//| 1/NVars. However, roughly same picture will be produced for | +//| the "all variables provide information no one is critical" | +//| situation and for the "all variables are critical, drop any one, | +//| everything is ruined" situation. | +//| Contrary to that, MDA will rate critical variable as ~1.0 | +//| important, and important but non-critical variable will have less| +//| than unit rating. | +//| NOTE: quite an often MDA and MDI return same results. It | +//| generally happens on problems with low test set error | +//| (a few percents at most) and large enough training set | +//| to avoid overfitting. | +//| The difference between MDA, MDI and OOB-MDI becomes important | +//| only on "hard" tasks with high test set error and/or small | +//| training set. | +//| INPUT PARAMETERS: | +//| S - decision forest builder object | +//| OUTPUT PARAMETERS: | +//| S - decision forest builder object. Next call to the | +//| forest construction function will produce: | +//| * importance estimates in rep.varimportances field | +//| * variable ranks in rep.topvars field | +//+------------------------------------------------------------------+ +void CAlglib::DFBuilderSetImportanceTrnGini(CDecisionForestBuilder &s) + { + CDForest::DFBuilderSetImportanceTrnGini(s); + } +//+------------------------------------------------------------------+ +//| This function tells decision forest construction algorithm to use| +//| out-of-bag version of Gini variable importance estimation (also | +//| known as OOB-MDI). | +//| This version of importance estimation algorithm analyzes mean | +//| decrease in impurity (MDI) on out-of-bag sample during splits. | +//| The result is divided by impurity at the root node in order to | +//| produce estimate in [0,1] range. | +//| Such estimates are fast to calculate and resistant to overfitting| +//| issues (thanks to the out-of-bag estimates used). However, OOB | +//| Gini rating has following downsides: | +//| * there exist some bias towards continuous and | +//| high-cardinality categorical variables | +//| * Gini rating allows us to order variables by importance,| +//| but it is hard to define importance of the variable by | +//| itself. | +//| NOTE: informally speaking, MDA (permutation importance) rating | +//| answers the question "what part of the model predictive | +//| power is ruined by permuting k-th variable?" while MDI | +//| tells us "what part of the model predictive power was | +//| achieved due to usage of k-th variable". | +//| Thus, MDA rates each variable independently at "0 to 1" scale | +//| while MDI (and OOB-MDI too) tends to divide "unit amount of | +//| importance" between several important variables. | +//| If all variables are equally important, they will have same | +//| MDI/OOB-MDI rating, equal (for OOB-MDI: roughly equal) to | +//| 1/NVars. However, roughly same picture will be produced for the | +//| "all variables provide information no one is critical" situation | +//| and for the "all variables are critical, drop any one, everything| +//| is ruined" situation. | +//| Contrary to that, MDA will rate critical variable as ~1.0 | +//| important, and important but non-critical variable will have less| +//| than unit rating. | +//| NOTE: quite an often MDA and MDI return same results. It | +//| generally happens on problems with low test set error | +//| (a few percents at most) and large enough training set to | +//| avoid overfitting. | +//| The difference between MDA, MDI and OOB-MDI becomes important | +//| only on "hard" tasks with high test set error and/or small | +//| training set. | +//| INPUT PARAMETERS: | +//| S - decision forest builder object | +//| OUTPUT PARAMETERS: | +//| S - decision forest builder object. Next call to the| +//| forest construction function will produce: | +//| * importance estimates in rep.varimportances field | +//| * variable ranks in rep.topvars field | +//+------------------------------------------------------------------+ +void CAlglib::DFBuilderSetImportanceOOBGini(CDecisionForestBuilder &s) + { + CDForest::DFBuilderSetImportanceOOBGini(s); + } +//+------------------------------------------------------------------+ +//| This function tells decision forest construction algorithm to use| +//| permutation variable importance estimator (also known as MDA). | +//| This version of importance estimation algorithm analyzes mean | +//| increase in out-of-bag sum of squared residuals after random | +//| permutation of J-th variable. The result is divided by error | +//| computed with all variables being perturbed in order to produce | +//| R-squared-like estimate in [0,1] range. | +//| Such estimate is slower to calculate than Gini-based rating | +//| because it needs multiple inference runs for each of variables | +//| being studied. | +//| MDA rating has following benefits over Gini-based ones: | +//| * no bias towards specific variable types | +//| *ability to directly evaluate "absolute" importance of some| +//| variable at "0 to 1" scale (contrary to Gini-based rating,| +//| which returns comparative importances). | +//| NOTE: informally speaking, MDA (permutation importance) rating | +//| answers the question "what part of the model predictive | +//| power is ruined by permuting k-th variable?" while MDI | +//| tells us "what part of the model predictive power was | +//| achieved due to usage of k-th variable". | +//| Thus, MDA rates each variable independently at "0 to 1" scale | +//| while MDI (and OOB-MDI too) tends to divide "unit amount of | +//| importance" between several important variables. | +//| If all variables are equally important, they will have same | +//| MDI/OOB-MDI rating, equal (for OOB-MDI: roughly equal) to | +//| 1/NVars. However, roughly same picture will be produced forthe | +//| "all variables provide information no one is critical" situation | +//| and for the "all variables are critical, drop any one, everything| +//| is ruined" situation. | +//| Contrary to that, MDA will rate critical variable as ~1.0 | +//| important, and important but non-critical variable will have less| +//| than unit rating. | +//| NOTE: quite an often MDA and MDI return same results. It | +//| generally happens on problems with low test set error | +//| (a few percents at most) and large enough training set | +//| to avoid overfitting. | +//| The difference between MDA, MDI and OOB-MDI becomes important | +//| only on "hard" tasks with high test set error and/or small | +//| training set. | +//| INPUT PARAMETERS: | +//| S - decision forest builder object | +//| OUTPUT PARAMETERS: | +//| S - decision forest builder object. Next call to | +//| the forest construction function will produce: | +//| * importance estimates in rep.varimportances field | +//| * variable ranks in rep.topvars field | +//+------------------------------------------------------------------+ +void CAlglib::DFBuilderSetImportancePermutation(CDecisionForestBuilder &s) + { + CDForest::DFBuilderSetImportancePermutation(s); + } +//+------------------------------------------------------------------+ +//| This function tells decision forest construction algorithm to | +//| skip variable importance estimation. | +//| INPUT PARAMETERS: | +//| S - decision forest builder object | +//| OUTPUT PARAMETERS: | +//| S - decision forest builder object. Next call to the | +//| forest construction function will result in forest | +//| being built without variable importance estimation.| +//+------------------------------------------------------------------+ +void CAlglib::DFBuilderSetImportanceNone(CDecisionForestBuilder &s) + { + CDForest::DFBuilderSetImportanceNone(s); + } +//+------------------------------------------------------------------+ +//| This function is an alias for dfbuilderpeekprogress(), left in | +//| ALGLIB for backward compatibility reasons. | +//+------------------------------------------------------------------+ +double CAlglib::DFBuilderGetProgress(CDecisionForestBuilder &s) + { + return(CDForest::DFBuilderGetProgress(s)); + } +//+------------------------------------------------------------------+ +//| This function is used to peek into decision forest construction | +//| process from some other thread and get current progress indicator| +//| It returns value in [0,1]. | +//| INPUT PARAMETERS: | +//| S - decision forest builder object used to build forest| +//| in some other thread | +//| RESULT: | +//| progress value, in [0,1] | +//+------------------------------------------------------------------+ +double CAlglib::DFBuilderPeekProgress(CDecisionForestBuilder &s) + { + return(CDForest::DFBuilderPeekProgress(s)); + } +//+------------------------------------------------------------------+ +//| This subroutine builds decision forest according to current | +//| settings using dataset internally stored in the builder object. | +//| Dense algorithm is used. | +//| NOTE: this function uses dense algorithm for forest construction | +//| independently from the dataset format (dense or sparse). | +//| NOTE: forest built with this function is stored in-memory using | +//| 64-bit data structures for offsets/indexes/split values. It| +//| is possible to convert forest into more memory-efficient | +//| compressed binary representation. Depending on the problem | +//| properties, 3.7x-5.7x compression factors are possible. | +//| The downsides of compression are (a) slight reduction in the | +//| model accuracy and (b) ~1.5x reduction in the inference speed | +//| (due to increased complexity of the storage format). | +//| See comments on DFBinaryCompression() for more info. | +//| Default settings are used by the algorithm; you can tweak them | +//| with the help of the following functions: | +//| * DFBuilderSetRFactor() - to control a fraction of the | +//| dataset used for subsampling | +//| * DFBuilderSetRandomVars() - to control number of variables | +//| randomly chosen for decision rule | +//| creation | +//| INPUT PARAMETERS: | +//| S - decision forest builder object | +//| NTrees - NTrees>=1, number of trees to train | +//| OUTPUT PARAMETERS: | +//| D - decision forest. You can compress this forest to | +//| more compact 16-bit representation with | +//| DFBinaryCompression() | +//| Rep - report, see below for information on its fields. | +//| == report information produced by forest construction function = | +//| Decision forest training report includes following information: | +//| * training set errors | +//| * out-of-bag estimates of errors | +//| * variable importance ratings | +//| Following fields are used to store information: | +//| * training set errors are stored in rep.RelCLSError, rep.AvgCE,| +//| rep.RMSError, rep.AvgError and rep.AvgRelError | +//| * out-of-bag estimates of errors are stored in | +//| rep.oobrelclserror, rep.oobavgce, rep.oobrmserror, | +//| rep.oobavgerror and rep.oobavgrelerror | +//| Variable importance reports, if requested by | +//| DFBuilderSetImportanceGini(), DFBuilderSetImportanceTrnGini() or | +//| DFBuilderSetImportancePermutation() call, are stored in: | +//| * rep.varimportances field stores importance ratings | +//| * rep.topvars stores variable indexes ordered from the most | +//| important to less important ones | +//| You can find more information about report fields in: | +//| * comments on CDFReport structure | +//| * comments on DFBuilderSetImportanceGini function | +//| * comments on DFBuilderSetImportanceTrnGini function | +//| * comments on DFBuilderDetImportancePermutation function | +//+------------------------------------------------------------------+ +void CAlglib::DFBuilderBuildRandomForest(CDecisionForestBuilder &s,int ntrees, + CDecisionForestShell &df, + CDFReportShell &rep) + { + CDForest::DFBuilderBuildRandomForest(s,ntrees,df.GetInnerObj(),rep.GetInnerObj()); + } +//+------------------------------------------------------------------+ +//| This function performs binary compression of the decision forest.| +//| Original decision forest produced by the forest builder is stored| +//| using 64-bit representation for all numbers - offsets, variable | +//| indexes, split points. | +//| It is possible to significantly reduce model size by means of: | +//| * using compressed dynamic encoding for integers (offsets and | +//| variable indexes), which uses just 1 byte to store small ints| +//| (less than 128), just 2 bytes for larger values (less than | +//| 128^2) and so on | +//| * storing floating point numbers using 8-bit exponent and | +//| 16-bit mantissa | +//| As result, model needs significantly less memory (compression | +//| factor depends on variable and class counts). In particular: | +//| * NVars<128 and NClasses<128 result in 4.4x-5.7x model size | +//| reduction | +//| * NVars<16384 and NClasses<128 result in 3.7x-4.5x model size | +//| reduction | +//| Such storage format performs lossless compression of all integers| +//| but compression of floating point values (split values) is lossy,| +//| with roughly 0.01% relative error introduced during rounding. | +//| Thus, we recommend you to re-evaluate model accuracy after | +//| compression. | +//| Another downside of compression is ~1.5x reduction in the | +//| inference speed due to necessity of dynamic decompression of the | +//| compressed model. | +//| INPUT PARAMETERS: | +//| DF - decision forest built by forest builder | +//| OUTPUT PARAMETERS: | +//| DF - replaced by compressed forest | +//| RESULT: | +//| compression factor (in-RAM size of the compressed model vs than | +//| of the uncompressed one), positive number larger than 1.0 | +//+------------------------------------------------------------------+ +double CAlglib::DFBinaryCompression(CDecisionForestShell &df) + { + return(CDForest::DFBinaryCompression(df.GetInnerObj())); + } +//+------------------------------------------------------------------+ +//| Procesing | +//| INPUT PARAMETERS: | +//| DF - decision forest model | +//| X - input vector, array[0..NVars-1]. | +//| OUTPUT PARAMETERS: | +//| Y - result. Regression estimate when solving | +//| regression task, vector of posterior | +//| probabilities for classification task. | +//| See also DFProcessI. | +//+------------------------------------------------------------------+ +void CAlglib::DFProcess(CDecisionForestShell &df,double &x[], + double &y[]) + { + CDForest::DFProcess(df.GetInnerObj(),x,y); + } +//+------------------------------------------------------------------+ +//| 'interactive' variant of DFProcess for languages like Python | +//| which support constructs like "Y = DFProcessI(DF,X)" and | +//| interactive mode of interpreter | +//| This function allocates new array on each call, so it is | +//| significantly slower than its 'non-interactive' counterpart, but | +//| it is more convenient when you call it from command line. | +//+------------------------------------------------------------------+ +void CAlglib::DFProcessI(CDecisionForestShell &df, + double &x[],double &y[]) + { + CDForest::DFProcessI(df.GetInnerObj(),x,y); + } +//+------------------------------------------------------------------+ +//| This function returns first component of the inferred vector | +//| (i.e. one with index #0). | +//| It is a convenience wrapper for dfprocess() intended for either: | +//| * 1-dimensional regression problems | +//| * 2-class classification problems | +//| In the former case this function returns inference result as | +//| scalar, which is definitely more convenient that wrapping it as | +//| vector. In the latter case it returns probability of object | +//| belonging to class #0. | +//| If you call it for anything different from two cases above, it | +//| will work as defined, i.e. return y[0], although it is of less | +//| use in such cases. | +//| INPUT PARAMETERS: | +//| Model - DF model | +//| X - input vector, array[0..NVars-1]. | +//| RESULT: | +//| Y[0] | +//+------------------------------------------------------------------+ +double CAlglib::DFProcess0(CDecisionForestShell &model,double &X[]) + { + CRowDouble x=X; + return(CDForest::DFProcess0(model.GetInnerObj(),x)); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +double CAlglib::DFProcess0(CDecisionForestShell &model,CRowDouble &x) + { + return(CDForest::DFProcess0(model.GetInnerObj(),x)); + } +//+------------------------------------------------------------------+ +//| This function returns most probable class number for an input X. | +//| It is same as calling DFProcess(model,x,y), then determining | +//| i=ArgMax(y[i]) and returning i. | +//| A class number in [0,NOut) range in returned for classification | +//| problems, -1 is returned when this function is called for | +//| regression problems. | +//| INPUT PARAMETERS: | +//| Model - decision forest model | +//| X - input vector, array[0..NVars-1]. | +//| RESULT: | +//| class number, -1 for regression tasks | +//+------------------------------------------------------------------+ +int CAlglib::DFClassify(CDecisionForestShell &model,double &X[]) + { + CRowDouble x=X; + return(CDForest::DFClassify(model.GetInnerObj(),x)); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +int CAlglib::DFClassify(CDecisionForestShell &model,CRowDouble &x) + { + return(CDForest::DFClassify(model.GetInnerObj(),x)); + } +//+------------------------------------------------------------------+ +//| Relative classification error on the test set | +//| INPUT PARAMETERS: | +//| DF - decision forest model | +//| XY - test set | +//| NPoints - test set size | +//| RESULT: | +//| percent of incorrectly classified cases. | +//| Zero if model solves regression task. | +//+------------------------------------------------------------------+ +double CAlglib::DFRelClsError(CDecisionForestShell &df,CMatrixDouble &xy, + const int npoints) + { + return(CDForest::DFRelClsError(df.GetInnerObj(),xy,npoints)); + } +//+------------------------------------------------------------------+ +//| Average cross-entropy (in bits per element) on the test set | +//| INPUT PARAMETERS: | +//| DF - decision forest model | +//| XY - test set | +//| NPoints - test set size | +//| RESULT: | +//| CrossEntropy/(NPoints*LN(2)). | +//| Zero if model solves regression task. | +//+------------------------------------------------------------------+ +double CAlglib::DFAvgCE(CDecisionForestShell &df,CMatrixDouble &xy, + const int npoints) + { + return(CDForest::DFAvgCE(df.GetInnerObj(),xy,npoints)); + } +//+------------------------------------------------------------------+ +//| RMS error on the test set | +//| INPUT PARAMETERS: | +//| DF - decision forest model | +//| XY - test set | +//| NPoints - test set size | +//| RESULT: | +//| root mean square error. | +//| Its meaning for regression task is obvious. As for | +//| classification task,RMS error means error when estimating | +//| posterior probabilities. | +//+------------------------------------------------------------------+ +double CAlglib::DFRMSError(CDecisionForestShell &df,CMatrixDouble &xy, + const int npoints) + { + return(CDForest::DFRMSError(df.GetInnerObj(),xy,npoints)); + } +//+------------------------------------------------------------------+ +//| Average error on the test set | +//| INPUT PARAMETERS: | +//| DF - decision forest model | +//| XY - test set | +//| NPoints - test set size | +//| RESULT: | +//| Its meaning for regression task is obvious. As for | +//| classification task, it means average error when estimating | +//| posterior probabilities. | +//+------------------------------------------------------------------+ +double CAlglib::DFAvgError(CDecisionForestShell &df,CMatrixDouble &xy, + const int npoints) + { + return(CDForest::DFAvgError(df.GetInnerObj(),xy,npoints)); + } +//+------------------------------------------------------------------+ +//| Average relative error on the test set | +//| INPUT PARAMETERS: | +//| DF - decision forest model | +//| XY - test set | +//| NPoints - test set size | +//| RESULT: | +//| Its meaning for regression task is obvious. As for | +//| classification task, it means average relative error when | +//| estimating posterior probability of belonging to the correct | +//| class. | +//+------------------------------------------------------------------+ +double CAlglib::DFAvgRelError(CDecisionForestShell &df,CMatrixDouble &xy, + const int npoints) + { + return(CDForest::DFAvgRelError(df.GetInnerObj(),xy,npoints)); + } +//+------------------------------------------------------------------+ +//| This subroutine builds random decision forest. | +//| ---- DEPRECATED VERSION! USE DECISION FOREST BUILDER OBJECT ---- | +//+------------------------------------------------------------------+ +void CAlglib::DFBuildRandomDecisionForest(CMatrixDouble &xy,const int npoints, + const int nvars,const int nclasses, + const int ntrees,const double r, + int &info,CDecisionForestShell &df, + CDFReportShell &rep) + { +//--- initialization + info=0; +//--- function call + CDForest::DFBuildRandomDecisionForest(xy,npoints,nvars,nclasses,ntrees,r,info,df.GetInnerObj(),rep.GetInnerObj()); + } +//+------------------------------------------------------------------+ +//| This subroutine builds random decision forest. | +//| ---- DEPRECATED VERSION! USE DECISION FOREST BUILDER OBJECT ---- | +//+------------------------------------------------------------------+ +void CAlglib::DFBuildRandomDecisionForestX1(CMatrixDouble &xy, + const int npoints, + const int nvars, + const int nclasses, + const int ntrees, + int nrndvars, + const double r, + int &info, + CDecisionForestShell &df, + CDFReportShell &rep) + { +//--- initialization + info=0; +//--- function call + CDForest::DFBuildRandomDecisionForestX1(xy,npoints,nvars,nclasses,ntrees,nrndvars,r,info,df.GetInnerObj(),rep.GetInnerObj()); + } +//+------------------------------------------------------------------+ +//| This function initializes clusterizer object. Newly initialized | +//| object is empty, i.e. it does not contain dataset. You should | +//| use it as follows: | +//| 1. creation | +//| 2. dataset is added with ClusterizerSetPoints() | +//| 3. additional parameters are set | +//| 3. clusterization is performed with one of the clustering | +//| functions | +//+------------------------------------------------------------------+ +void CAlglib::ClusterizerCreate(CClusterizerState &s) + { + CClustering::ClusterizerCreate(s); + } +//+------------------------------------------------------------------+ +//| This function adds dataset to the clusterizer structure. | +//| This function overrides all previous calls of | +//| ClusterizerSetPoints() or ClusterizerSetDistances(). | +//| INPUT PARAMETERS: | +//| S - clusterizer state, initialized by | +//| ClusterizerCreate() | +//| XY - array[NPoints,NFeatures], dataset | +//| NPoints - number of points, >=0 | +//| NFeatures- number of features, >=1 | +//| DistType - distance function: | +//| * 0 Chebyshev distance (L-inf norm) | +//| * 1 city block distance (L1 norm) | +//| * 2 Euclidean distance (L2 norm), non-squared | +//| * 10 Pearson correlation: | +//| dist(a,b) = 1-corr(a,b) | +//| * 11 Absolute Pearson correlation: | +//| dist(a,b) = 1-|corr(a,b)| | +//| * 12 Uncentered Pearson correlation (cosine of | +//| the angle): dist(a,b) = a'*b/(|a|*|b|) | +//| * 13 Absolute uncentered Pearson correlation | +//| dist(a,b) = |a'*b|/(|a|*|b|) | +//| * 20 Spearman rank correlation: | +//| dist(a,b) = 1-rankcorr(a,b) | +//| * 21 Absolute Spearman rank correlation | +//| dist(a,b) = 1-|rankcorr(a,b)| | +//| NOTE 1: different distance functions have different performance | +//| penalty: | +//| * Euclidean or Pearson correlation distances are | +//| the fastest ones | +//| * Spearman correlation distance function is a bit slower | +//| * city block and Chebyshev distances are order | +//| of magnitude slower | +//| The reason behing difference in performance is that | +//| correlation-based distance functions are computed using | +//| optimized linear algebra kernels, while Chebyshev and | +//| city block distance functions are computed using simple | +//| nested loops with two branches at each iteration. | +//| NOTE 2: different clustering algorithms have different | +//| limitations: | +//| * agglomerative hierarchical clustering algorithms may | +//| be used with any kind of distance metric | +//| * k-means++ clustering algorithm may be used only with | +//| Euclidean distance function | +//| Thus, list of specific clustering algorithms you may use | +//| depends on distance function you specify when you set | +//| your dataset. | +//+------------------------------------------------------------------+ +void CAlglib::ClusterizerSetPoints(CClusterizerState &s,CMatrixDouble &xy, + int npoints,int nfeatures,int disttype) + { + CClustering::ClusterizerSetPoints(s,xy,npoints,nfeatures,disttype); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void CAlglib::ClusterizerSetPoints(CClusterizerState &s,CMatrixDouble &xy,int disttype) + { +//--- create variables + int npoints=CAp::Rows(xy); + int nfeatures=CAp::Cols(xy); +//--- function call + CClustering::ClusterizerSetPoints(s,xy,npoints,nfeatures,disttype); + } +//+------------------------------------------------------------------+ +//| This function adds dataset given by distance matrix to the | +//| clusterizer structure. It is important that dataset is not given | +//| explicitly - only distance matrix is given. | +//| This function overrides all previous calls of | +//| ClusterizerSetPoints() or ClusterizerSetDistances(). | +//| INPUT PARAMETERS: | +//| S - clusterizer state, initialized by | +//| ClusterizerCreate() | +//| D - array[NPoints,NPoints], distance matrix given by | +//| its upper or lower triangle (main diagonal is | +//| ignored because its entries are expected to | +//| be zero). | +//| NPoints - number of points | +//| IsUpper - whether upper or lower triangle of D is given. | +//| NOTE 1: different clustering algorithms have different | +//| limitations: | +//| * agglomerative hierarchical clustering algorithms may | +//| be used with any kind of distance metric, including | +//| one which is given by distance matrix | +//| * k-means++ clustering algorithm may be used only with | +//| Euclidean distance function and explicitly given | +//| points - it can not be used with dataset given by | +//| distance matrix. Thus, if you call this function, you | +//| will be unable to use k-means clustering algorithm | +//| to process your problem. | +//+------------------------------------------------------------------+ +void CAlglib::ClusterizerSetDistances(CClusterizerState &s,CMatrixDouble &d,int npoints,bool IsUpper) + { + CClustering::ClusterizerSetDistances(s,d,npoints,IsUpper); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void CAlglib::ClusterizerSetDistances(CClusterizerState &s,CMatrixDouble &d,bool IsUpper) + { +//--- check + if(!CAp::Assert(CAp::Rows(d)==CAp::Cols(d),"Error while calling 'ClusterizerSetDistances': looks like one of arguments has wrong size")) + return; +//--- initialization + int npoints=CAp::Rows(d); +//--- function call + CClustering::ClusterizerSetDistances(s,d,npoints,IsUpper); + } +//+------------------------------------------------------------------+ +//| This function sets agglomerative hierarchical clustering | +//| algorithm | +//| INPUT PARAMETERS: | +//| S - clusterizer state, initialized by ClusterizerCreate() | +//| Algo - algorithm type: | +//| * 0 complete linkage(default algorithm) | +//| * 1 single linkage | +//| * 2 unweighted average linkage | +//| * 3 weighted average linkage | +//| * 4 Ward's method | +//| NOTE: Ward's method works correctly only with Euclidean distance,| +//| that's why algorithm will return negative termination | +//| code(failure) for any other distance type. | +//| It is possible, however, to use this method with user - supplied | +//| distance matrix. It is your responsibility to pass one which was | +//| calculated with Euclidean distance function. | +//+------------------------------------------------------------------+ +void CAlglib::ClusterizerSetAHCAlgo(CClusterizerState &s,int algo) + { + CClustering::ClusterizerSetAHCAlgo(s,algo); + } +//+------------------------------------------------------------------+ +//| This function sets k-means properties: | +//| number of restarts and maximum | +//| number of iterations per one run. | +//| INPUT PARAMETERS: | +//| S - clusterizer state, initialized by | +//| ClusterizerCreate() | +//| Restarts - restarts count, >= 1. | +//| k-means++ algorithm performs several restarts | +//| and chooses best set of centers(one with minimum | +//| squared distance). | +//| MaxIts - maximum number of k-means iterations performed | +//| during one run. >= 0, zero value means that | +//| algorithm performs unlimited number of iterations. | +//+------------------------------------------------------------------+ +void CAlglib::ClusterizerSetKMeansLimits(CClusterizerState &s,int restarts,int maxits) + { + CClustering::ClusterizerSetKMeansLimits(s,restarts,maxits); + } +//+------------------------------------------------------------------+ +//| This function sets k-means initialization algorithm. Several | +//| different algorithms can be chosen, including k-means++. | +//| INPUT PARAMETERS: | +//| S - clusterizer state, initialized by | +//| ClusterizerCreate() | +//| InitAlgo - initialization algorithm: | +//| * 0 automatic selection(different versions of ALGLIB | +//| may select different algorithms) | +//| * 1 random initialization | +//| * 2 k-means++ initialization(best quality of initial | +//| centers, but long non-parallelizable initialization | +//| phase with bad cache locality) | +//| *3 "fast-greedy" algorithm with efficient, easy to | +//| parallelize initialization. Quality of initial centers | +//| is somewhat worse than that of k-means++. This | +//| algorithm is a default one in the current version of | +//| ALGLIB. | +//| *-1 "debug" algorithm which always selects first K rows | +//| of dataset; this algorithm is used for debug purposes | +//| only. Do not use it in the industrial code! | +//+------------------------------------------------------------------+ +void CAlglib::ClusterizerSetKMeansInit(CClusterizerState &s,int initalgo) + { + CClustering::ClusterizerSetKMeansInit(s,initalgo); + } +//+------------------------------------------------------------------+ +//| This function sets seed which is used to initialize internal RNG.| +//| By default, deterministic seed is used - same for each run of | +//| clusterizer. If you specify non-deterministic seed value, then | +//| some algorithms which depend on random initialization(in current | +//| version : k-means) may return slightly different results after | +//| each run. | +//| INPUT PARAMETERS: | +//| S - clusterizer state, initialized by | +//| ClusterizerCreate() | +//| Seed - seed: | +//| * positive values = use deterministic seed for each| +//| run of algorithms which depend on random | +//| initialization | +//| * zero or negative values = use non-deterministic | +//| seed | +//+------------------------------------------------------------------+ +void CAlglib::ClusterizerSetSeed(CClusterizerState &s,int seed) + { + CClustering::ClusterizerSetSeed(s,seed); + } +//+------------------------------------------------------------------+ +//| This function performs agglomerative hierarchical clustering | +//| NOTE: Agglomerative hierarchical clustering algorithm has two | +//| phases: distance matrix calculation and clustering itself. | +//| INPUT PARAMETERS: | +//| S - clusterizer state, initialized by | +//| ClusterizerCreate() | +//| OUTPUT PARAMETERS: | +//| Rep - clustering results; see description of AHCReport | +//| structure for more information. | +//| NOTE 1: hierarchical clustering algorithms require large amounts | +//| of memory. In particular, this implementation needs | +//| sizeof(double) *NPoints^2 bytes, which are used to store | +//| distance matrix. In case we work with user - supplied | +//| matrix, this amount is multiplied by 2 (we have to store | +//| original matrix and to work with its copy). | +//| For example, problem with 10000 points would require 800M| +//| of RAM, even when working in a 1-dimensional space. | +//+------------------------------------------------------------------+ +void CAlglib::ClusterizerRunAHC(CClusterizerState &s,CAHCReport &rep) + { + CClustering::ClusterizerRunAHC(s,rep); + } +//+------------------------------------------------------------------+ +//| This function performs clustering by k-means++ algorithm. | +//| You may change algorithm properties by calling: | +//| * ClusterizerSetKMeansLimits() to change number of restarts | +//| or iterations | +//| * ClusterizerSetKMeansInit() to change initialization | +//| algorithm | +//| By default, one restart and unlimited number of iterations are | +//| used. Initialization algorithm is chosen automatically. | +//| NOTE: k-means clustering algorithm has two phases: selection of | +//| initial centers and clustering itself. | +//| INPUT PARAMETERS: | +//| S - clusterizer state, initialized by | +//| ClusterizerCreate() | +//| K - number of clusters, K >= 0. | +//| K can be zero only when algorithm is called for | +//| empty dataset, in this case completion code is set | +//| to success(+1). | +//| If K = 0 and dataset size is non-zero, we can not | +//| meaningfully assign points to some center(there are| +//| no centers because K = 0) and return -3 as | +//| completion code (failure). | +//| OUTPUT PARAMETERS: | +//| Rep - clustering results; see description of KMeansReport| +//| structure for more information. | +//| NOTE 1: k-means clustering can be performed only for datasets | +//| with Euclidean distance function. Algorithm will return | +//| negative completion code in Rep.TerminationType in case | +//| dataset was added to clusterizer with DistType other | +//| than Euclidean (or dataset was specified by distance | +//| matrix instead of explicitly given points). | +//| NOTE 2: by default, k-means uses non-deterministic seed to | +//| initialize RNG which is used to select initial centers. | +//| As result, each run of algorithm may return different | +//| values. If you need deterministic behavior, use | +//| ClusterizerSetSeed() function. | +//+------------------------------------------------------------------+ +void CAlglib::ClusterizerRunKMeans(CClusterizerState &s,int k,CKmeansReport &rep) + { + CClustering::ClusterizerRunKMeans(s,k,rep); + } +//+------------------------------------------------------------------+ +//| This function returns distance matrix for dataset | +//| INPUT PARAMETERS: | +//| XY - array[NPoints, NFeatures], dataset | +//| NPoints - number of points, >= 0 | +//| NFeatures- number of features, >= 1 | +//| DistType - distance function: | +//| * 0 Chebyshev distance(L - inf norm) | +//| * 1 city block distance(L1 norm) | +//| * 2 Euclidean distance(L2 norm, non - squared) | +//| * 10 Pearson correlation: | +//| dist(a, b) = 1 - corr(a, b) | +//| * 11 Absolute Pearson correlation: | +//| dist(a, b) = 1 - |corr(a, b)| | +//| * 12 Uncentered Pearson correlation(cosine of | +//| the angle): dist(a, b) = a'*b/(|a|*|b|) | +//| * 13 Absolute uncentered Pearson correlation | +//| dist(a, b) = |a'*b|/(|a|*|b|) | +//| * 20 Spearman rank correlation: | +//| dist(a, b) = 1 - rankcorr(a, b) | +//| * 21 Absolute Spearman rank correlation | +//| dist(a, b) = 1 - |rankcorr(a, b)| | +//| OUTPUT PARAMETERS: | +//| D - array[NPoints, NPoints], distance matrix (full | +//| matrix is returned, with lower and upper triangles)| +//| NOTE: different distance functions have different performance | +//| penalty: | +//| * Euclidean or Pearson correlation distances are the fastest| +//| ones | +//| * Spearman correlation distance function is a bit slower | +//| * city block and Chebyshev distances are order of magnitude | +//| slower | +//| The reason behing difference in performance is that correlation -| +//| based distance functions are computed using optimized linear | +//| algebra kernels, while Chebyshev and city block distance | +//| functions are computed using simple nested loops with two | +//| branches at each iteration. | +//+------------------------------------------------------------------+ +void CAlglib::ClusterizerGetDistances(CMatrixDouble &xy,int npoints, + int nfeatures,int disttype, + CMatrixDouble &d) + { + d.Resize(0,0); + CClustering::ClusterizerGetDistances(xy,npoints,nfeatures,disttype,d); + } +//+------------------------------------------------------------------+ +//| This function takes as input clusterization report Rep, desired | +//| clusters count K, and builds top K clusters from hierarchical | +//| clusterization tree. | +//| It returns assignment of points to clusters(array of cluster | +//| indexes). | +//| INPUT PARAMETERS: | +//| Rep - report from ClusterizerRunAHC() performed on XY | +//| K - desired number of clusters, 1 <= K <= NPoints. | +//| K can be zero only when NPoints = 0. | +//| OUTPUT PARAMETERS: | +//| CIdx - array[NPoints], I-th element contains cluster | +//| index(from 0 to K-1) for I-th point of the dataset.| +//| CZ - array[K]. This array allows to convert cluster | +//| indexes returned by this function to indexes used | +//| by Rep.Z. J-th cluster returned by this function | +//| corresponds to CZ[J]-th cluster stored in | +//| Rep.Z/PZ/PM. It is guaranteed that CZ[I] < CZ[I+1].| +//| NOTE: K clusters built by this subroutine are assumed to have no | +//| hierarchy. Although they were obtained by manipulation with| +//| top K nodes of dendrogram(i.e. hierarchical decomposition | +//| of dataset), this function does not return information | +//| about hierarchy. Each of the clusters stand on its own. | +//| NOTE: Cluster indexes returned by this function does not | +//| correspond to indexes returned in Rep.Z/PZ/PM. Either you | +//| work with hierarchical representation of the dataset | +//| (dendrogram), or you work with "flat" representation | +//| returned by this function. Each of representations has its | +//| own clusters indexing system(former uses [0,2*NPoints-2]), | +//| while latter uses [0..K-1]), although it is possible to | +//| perform conversion from one system to another by means of | +//| CZ array, returned by this function, which allows you to | +//| convert indexes stored in CIdx to the numeration system | +//| used by Rep.Z. | +//| NOTE: this subroutine is optimized for moderate values of K. | +//| Say, for K=5 it will perform many times faster than for | +//| K=100. Its worst - case performance is O(N*K), although in | +//| average case it perform better (up to O(N*log(K))). | +//+------------------------------------------------------------------+ +void CAlglib::ClusterizerGetKClusters(CAHCReport &rep,int k,CRowInt &cidx,CRowInt &cz) + { + cidx.Resize(0); + cz.Resize(0); + CClustering::ClusterizerGetKClusters(rep,k,cidx,cz); + } +//+------------------------------------------------------------------+ +//| This function accepts AHC report Rep, desired minimum | +//| intercluster distance and returns top clusters from hierarchical | +//| clusterization tree which are separated by distance R or HIGHER. | +//| It returns assignment of points to clusters (array of cluster | +//| indexes). | +//| There is one more function with similar name - | +//| ClusterizerSeparatedByCorr, which returns clusters with | +//| intercluster correlation equal to R or LOWER (note: higher for | +//| distance, lower for correlation). | +//| INPUT PARAMETERS: | +//| Rep - report from ClusterizerRunAHC() performed on XY | +//| R - desired minimum intercluster distance, R >= 0 | +//| OUTPUT PARAMETERS: | +//| K - number of clusters, 1 <= K <= NPoints | +//| CIdx - array[NPoints], I-th element contains cluster | +//| index (from 0 to K-1) for I-th point of the dataset| +//| CZ - array[K]. This array allows to convert cluster | +//| indexes returned by this function to indexes used | +//| by Rep.Z. J-th cluster returned by this function | +//| corresponds to CZ[J]-th cluster stored in | +//| Rep.Z/PZ/PM. It is guaranteed that CZ[I] < CZ[I+1].| +//| NOTE: K clusters built by this subroutine are assumed to have no | +//| hierarchy. Although they were obtained by manipulation with| +//| top K nodes of dendrogram (i.e. hierarchical decomposition | +//| of dataset), this function does not return information | +//| about hierarchy. Each of the clusters stand on its own. | +//| NOTE: Cluster indexes returned by this function does not | +//| correspond to indexes returned in Rep.Z/PZ/PM. Either you | +//| work with hierarchical representation of the dataset | +//| (dendrogram), or you work with "flat" representation | +//| returned by this function. Each of representations has its | +//| own clusters indexing system (former uses [0,2*NPoints-2]),| +//| while latter uses [0..K-1]), although it is possible to | +//| perform conversion from one system to another by means of | +//| CZ array, returned by this function, which allows you to | +//| convert indexes stored in CIdx to the numeration system | +//| used by Rep.Z. | +//| NOTE: this subroutine is optimized for moderate values of K. Say,| +//| for K=5 it will perform many times faster than for K=100. | +//| Its worst - case performance is O(N*K), although in average| +//| case it perform better (up to O(N*log(K))). | +//+------------------------------------------------------------------+ +void CAlglib::ClusterizerSeparatedByDist(CAHCReport &rep,double r,int &k, + CRowInt &cidx,CRowInt &cz) + { + k=0; + cidx.Resize(0); + cz.Resize(0); + CClustering::ClusterizerSeparatedByDist(rep,r,k,cidx,cz); + } +//+------------------------------------------------------------------+ +//| This function accepts AHC report Rep, desired maximum | +//| intercluster correlation and returns top clusters from | +//| hierarchical clusterization tree which are separated by | +//| correlation R or LOWER. | +//| It returns assignment of points to clusters(array of cluster | +//| indexes). | +//| There is one more function with similar name - | +//| ClusterizerSeparatedByDist, which returns clusters with | +//| intercluster distance equal to R or HIGHER (note: higher for | +//| distance, lower for correlation). | +//| INPUT PARAMETERS: | +//| Rep - report from ClusterizerRunAHC() performed on XY | +//| R - desired maximum intercluster correlation, -1<=R<=+1| +//| OUTPUT PARAMETERS: | +//| K - number of clusters, 1 <= K <= NPoints | +//| CIdx - array[NPoints], I-th element contains cluster index| +//| (from 0 to K-1) for I-th point of the dataset. | +//| CZ - array[K]. This array allows to convert cluster | +//| indexes returned by this function to indexes used | +//| by Rep.Z. J-th cluster returned by this function | +//| corresponds to CZ[J]-th cluster stored in | +//| Rep.Z/PZ/PM. It is guaranteed that CZ[I] < CZ[I+1].| +//| NOTE: K clusters built by this subroutine are assumed to have no | +//| hierarchy. Although they were obtained by manipulation with| +//| top K nodes of dendrogram (i.e. hierarchical decomposition | +//| of dataset), this function does not return information | +//| about hierarchy. Each of the clusters stand on its own. | +//| NOTE: Cluster indexes returned by this function does not | +//| correspond to indexes returned in Rep.Z/PZ/PM. Either you | +//| work with hierarchical representation of the dataset | +//| (dendrogram), or you work with "flat" representation | +//| returned by this function. Each of representations has its | +//| own clusters indexing system (former uses [0,2*NPoints-2]),| +//| while latter uses [0..K-1]), although it is possible to | +//| perform conversion from one system to another by means of | +//| CZ array, returned by this function, which allows you to | +//| convert indexes stored in CIdx to the numeration system | +//| used by Rep.Z. | +//| NOTE: this subroutine is optimized for moderate values of K. Say,| +//| for K=5 it will perform many times faster than for K=100. | +//| Its worst - case performance is O(N*K), although in average| +//| case it perform better (up to O(N*log(K))). | +//+------------------------------------------------------------------+ +void CAlglib::ClusterizerSeparatedByCorr(CAHCReport &rep,double r, + int &k,CRowInt &cidx,CRowInt &cz) + { + k=0; + cidx.Resize(0); + cz.Resize(0); + CClustering::ClusterizerSeparatedByCorr(rep,r,k,cidx,cz); + } +//+------------------------------------------------------------------+ +//| k-means++ clusterization | +//| Backward compatibility function, we recommend to use CLUSTERING | +//| subpackage as better replacement. | +//| INPUT PARAMETERS: | +//| XY - dataset, array [0..NPoints-1,0..NVars-1]. | +//| NPoints - dataset size, NPoints>=K | +//| NVars - number of variables, NVars>=1 | +//| K - desired number of clusters, K>=1 | +//| Restarts - number of restarts, Restarts>=1 | +//| OUTPUT PARAMETERS: | +//| Info - return code: | +//| * -3, if task is degenerate (number of | +//| distinct points is less than K) | +//| * -1, if incorrect | +//| NPoints/NFeatures/K/Restarts was passed| +//| * 1, if subroutine finished successfully | +//| C - array[0..NVars-1,0..K-1].matrix whose columns| +//| store cluster's centers | +//| XYC - array[NPoints], which contains cluster | +//| indexes | +//+------------------------------------------------------------------+ +void CAlglib::KMeansGenerate(CMatrixDouble &xy,const int npoints, + const int nvars,const int k, + const int restarts,int &info, + CMatrixDouble &c,int &xyc[]) + { +//--- initialization + info=0; +//--- function call + CKMeans::KMeansGenerate(xy,npoints,nvars,k,restarts,info,c,xyc); + } +//+------------------------------------------------------------------+ +//| Multiclass Fisher LDA | +//| Subroutine finds coefficients of linear combination which | +//| optimally separates training set on classes. | +//| INPUT PARAMETERS: | +//| XY - training set, array[0..NPoints-1,0..NVars]. | +//| First NVars columns store values of | +//| independent variables, next column stores | +//| number of class (from 0 to NClasses-1) which | +//| dataset element belongs to. Fractional values| +//| are rounded to nearest integer. | +//| NPoints - training set size, NPoints>=0 | +//| NVars - number of independent variables, NVars>=1 | +//| NClasses - number of classes, NClasses>=2 | +//| OUTPUT PARAMETERS: | +//| Info - return code: | +//| * -4, if internal EVD subroutine hasn't | +//| converged | +//| * -2, if there is a point with class number | +//| outside of [0..NClasses-1]. | +//| * -1, if incorrect parameters was passed | +//| (NPoints<0, NVars<1, NClasses<2) | +//| * 1, if task has been solved | +//| * 2, if there was a multicollinearity in | +//| training set, but task has been solved.| +//| W - linear combination coefficients, | +//| array[0..NVars-1] | +//+------------------------------------------------------------------+ +void CAlglib::FisherLDA(CMatrixDouble &xy,const int npoints, + const int nvars,const int nclasses, + int &info,double &w[]) + { +//--- initialization + info=0; +//--- function call + CLDA::FisherLDA(xy,npoints,nvars,nclasses,info,w); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void CAlglib::FisherLDA(CMatrixDouble &xy,const int npoints, + const int nvars,const int nclasses, + int &info,CRowDouble &w) + { +//--- initialization + info=0; +//--- function call + CLDA::FisherLDA(xy,npoints,nvars,nclasses,info,w); + } +//+------------------------------------------------------------------+ +//| N-dimensional multiclass Fisher LDA | +//| Subroutine finds coefficients of linear combinations which | +//| optimally separates | +//| training set on classes. It returns N-dimensional basis whose | +//| vector are sorted | +//| by quality of training set separation (in descending order). | +//| INPUT PARAMETERS: | +//| XY - training set, array[0..NPoints-1,0..NVars]. | +//| First NVars columns store values of | +//| independent variables, next column stores | +//| number of class (from 0 to NClasses-1) which | +//| dataset element belongs to. Fractional values| +//| are rounded to nearest integer. | +//| NPoints - training set size, NPoints>=0 | +//| NVars - number of independent variables, NVars>=1 | +//| NClasses - number of classes, NClasses>=2 | +//| OUTPUT PARAMETERS: | +//| Info - return code: | +//| * -4, if internal EVD subroutine hasn't | +//| converged | +//| * -2, if there is a point with class number | +//| outside of [0..NClasses-1]. | +//| * -1, if incorrect parameters was passed | +//| (NPoints<0, NVars<1, NClasses<2) | +//| * 1, if task has been solved | +//| * 2, if there was a multicollinearity in | +//| training set, but task has been solved.| +//| W - basis, array[0..NVars-1,0..NVars-1] | +//| columns of matrix stores basis vectors, | +//| sorted by quality of training set separation | +//| (in descending order) | +//+------------------------------------------------------------------+ +void CAlglib::FisherLDAN(CMatrixDouble &xy,const int npoints, + const int nvars,const int nclasses, + int &info,CMatrixDouble &w) + { +//--- initialization + info=0; +//--- function call + CLDA::FisherLDAN(xy,npoints,nvars,nclasses,info,w); + } +//+------------------------------------------------------------------+ +//| Linear regression | +//| Subroutine builds model: | +//| Y = A(0)*X[0] + ... + A(N-1)*X[N-1] + A(N) | +//| and model found in ALGLIB format, covariation matrix, training | +//| set errors (rms, average, average relative) and leave-one-out | +//| cross-validation estimate of the generalization error. CV | +//| estimate calculated using fast algorithm with O(NPoints*NVars) | +//| complexity. | +//| When covariation matrix is calculated standard deviations of| +//| function values are assumed to be equal to RMS error on the | +//| training set. | +//| INPUT PARAMETERS: | +//| XY - training set, array [0..NPoints-1,0..NVars]: | +//| * NVars columns - independent variables | +//| * last column - dependent variable | +//| NPoints - training set size, NPoints>NVars+1 | +//| NVars - number of independent variables | +//| OUTPUT PARAMETERS: | +//| Info - return code: | +//| * -255, in case of unknown internal error | +//| * -4, if internal SVD subroutine haven't | +//| converged | +//| * -1, if incorrect parameters was passed | +//| (NPoints0. | +//| NPoints - training set size, NPoints>NVars+1 | +//| NVars - number of independent variables | +//| OUTPUT PARAMETERS: | +//| Info - return code: | +//| * -255, in case of unknown internal error | +//| * -4, if internal SVD subroutine haven't | +//| converged | +//| * -1, if incorrect parameters was passed | +//| (NPoints

    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.0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } + + error_code=ERR_OK; + if(x<0.0) + return TailLog0(true,log_mode); +//--- calculate gamma factor for the density + double coef=MathRound(MathExp(MathGammaLog(r+x)-MathGammaLog(x+1.0)-MathGammaLog(r))); +//--- return density + return TailLogValue(coef*MathPow(p,r)*MathPow(1.0-p,x),true,log_mode); + } +//+------------------------------------------------------------------+ +//| Negative Binomial probability mass function (PDF) | +//+------------------------------------------------------------------+ +//| The function returns the probability mass function | +//| of the Negative Binomial distribution with parameters r and p. | +//| | +//| Arguments: | +//| x : Random variable | +//| r : Number of successes | +//| p : Probability of success | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The probability mass evaluated at x. | +//+------------------------------------------------------------------+ +double MathProbabilityDensityNegativeBinomial(const double x,const double r,const double p,int &error_code) + { + return MathProbabilityDensityNegativeBinomial(x,r,p,false,error_code); + } +//+------------------------------------------------------------------+ +//| Negative Binomial probability mass function (PDF) | +//+------------------------------------------------------------------+ +//| The function calculates the probability mass function | +//| of the Negative Binomial distribution with parameters r and p | +//| for values from x[] array. | +//| | +//| Arguments: | +//| x : Array with random variables | +//| r : Number of successes | +//| p : Probability of success | +//| log_mode : Logarithm mode flag, if true it returns Log values | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathProbabilityDensityNegativeBinomial(const double &x[],const double r,const double p,const bool log_mode,double &result[]) + { +//--- check NaN + if(!MathIsValidNumber(r) || !MathIsValidNumber(p)) + return false; +//--- check arguments + if(r!=MathRound(r) || r<1.0 || p<0.0 || p>1.0) + return false; + + int data_count=ArraySize(x); + if(data_count==0) + return false; + + double power_p_r=MathPow(p,r); + double log_gamma_r=MathGammaLog(r); + int error_code=0; + ArrayResize(result,data_count); + for(int i=0; i1.0 || x<0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } + + error_code=ERR_OK; + if(x<0.0) + return TailLog0(tail,log_mode); + int err_code=0; +//--- calculate max term of the sum + int max_j=(int)MathFloor(x); + double p1=1.0-p; +//--- initial factors + double factor1=MathFactorial((int)r-1); + double factor2=1.0; + double factor_p=1.0; + double factor_r=1.0/factor1; + double power_p_r=MathPowInt(p,int(r))*factor_r; + double cdf=0.0; + for(int j=0; j<=max_j; j++) + { + if(j>0) + { + factor1*=(j+1); + factor2*=j; + factor_p*=p1; + } + double pdf=power_p_r*factor1*factor_p/factor2; + cdf+=pdf; + } +//--- take into account round-off errors for probability + return TailLogValue(MathMin(cdf,1.0),tail,log_mode); + } +//+------------------------------------------------------------------+ +//| Negative Binomial cumulative distribution function (CDF) | +//+------------------------------------------------------------------+ +//| The function returns the probability that an observation | +//| from the Negative Binomial distribution with parameters r and p | +//| is less than or equal to x. | +//| | +//| Arguments: | +//| x : The desired quantile | +//| r : Number of successes | +//| p : Probability of success | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The value of the Negative Binomial cumulative distribution | +//| function with parameters r and p, evaluated at x. | +//+------------------------------------------------------------------+ +double MathCumulativeDistributionNegativeBinomial(const double x,const double r,double p,int error_code) + { + return MathCumulativeDistributionNegativeBinomial(x,r,p,true,false,error_code); + } +//+------------------------------------------------------------------+ +//| Negative Binomial cumulative distribution function (CDF) | +//+------------------------------------------------------------------+ +//| The function calculates the cumulative distribution function | +//| of the Negative Binomial distribution with parameters r and p | +//| for values from x[] array. | +//| | +//| Arguments: | +//| x : Array with random variables | +//| r : Number of successes | +//| p : Probability of success | +//| tail : Flag to calculate lower tail | +//| log_mode : Logarithm mode, if true it calculates Log values | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathCumulativeDistributionNegativeBinomial(const double &x[],const double r,double p,const bool tail,const bool log_mode,double &result[]) + { +//--- check NaN + if(!MathIsValidNumber(r) || !MathIsValidNumber(p)) + return false; +//--- check arguments + if(r!=MathRound(r) || r<1.0 || p<0.0 || p>1.0) + return false; + + int data_count=ArraySize(x); + if(data_count==0) + return false; +//--- common factors + double fact1=MathFactorial((int)r-1); + double factor_r=1.0/fact1; + double power_p_r=MathPowInt(p,int(r))*factor_r; + double p1=1.0-p; + int error_code=0; + ArrayResize(result,data_count); + for(int i=0; i0) + { + factor1*=(j+1); + factor2*=j; + factor_p*=p1; + } + double pdf=power_p_r*factor1*factor_p/factor2; + cdf+=pdf; + } + //--- take into account round-off errors for probability + result[i]=TailLogValue(MathMin(cdf,1.0),tail,log_mode); + } + } + return true; + } +//+------------------------------------------------------------------+ +//| Negative Binomial cumulative distribution function (CDF) | +//+------------------------------------------------------------------+ +//| The function calculates the cumulative distribution function | +//| of the Negative Binomial distribution with parameters r and p | +//| for values from x[] array. | +//| | +//| Arguments: | +//| x : Array with random variables | +//| r : Number of successes | +//| p : Probability of success | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathCumulativeDistributionNegativeBinomial(const double &x[],const double r,double p,double &result[]) + { + return MathCumulativeDistributionNegativeBinomial(x,r,p,true,false,result); + } +//+------------------------------------------------------------------+ +//| Negative Binomial distribution quantile function (inverse CDF) | +//+------------------------------------------------------------------+ +//| The function returns the inverse cumulative distribution | +//| function of the Negative Binomial distribution with parameters | +//| r and p for the desired probability. | +//| | +//| Arguments: | +//| probability : The desired probability | +//| r : Number of successes | +//| p : Probability of success | +//| tail : Flag to calculate lower tail | +//| log_mode : Logarithm mode, if true it calculates Log values | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The value of the inverse cumulative distribution function | +//| of the Negative Binomial distribution with parameters r and p. | +//+------------------------------------------------------------------+ +double MathQuantileNegativeBinomial(const double probability,const double r,const double p,const bool tail,const bool log_mode,int &error_code) + { +//--- check NaN + if(!MathIsValidNumber(probability) || !MathIsValidNumber(r) || !MathIsValidNumber(p)) + { + error_code=ERR_ARGUMENTS_NAN; + return QNaN; + } +//--- check arguments + if(r!=MathRound(r) || r<1.0 || p<0.0 || p>1.0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } +//--- calculate real probability + double prob=TailLogProbability(probability,tail,log_mode); +//--- check probability range + if(prob<0.0 || prob>1.0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } +//--- check cases p=0 and p=1 + if(prob==1.0) + { + error_code=ERR_RESULT_INFINITE; + return QPOSINF; + } + error_code=ERR_OK; + if(prob==0.0) + return 0.0; + + int max_terms=1000; + int err_code=0; +//--- factors + double fact1=MathFactorial((int)r-1); + double factor_r=1.0/fact1; + double power_p_r=MathPowInt(p,int(r))*factor_r; + double p1=1.0-p; +//--- initial factors + double factor1=fact1; + double factor2=1.0; + double factor_p=1.0; + double cdf=0.0; + int j=0; + while(cdf0) + { + factor1*=(j+1); + factor2*=j; + factor_p*=p1; + } + double pdf=power_p_r*factor1*factor_p/factor2; + cdf+=pdf; + j++; + } +//--- check convergence + if(j1.0) + return false; + + int data_count=ArraySize(probability); + if(data_count==0) + return false; +//--- common factors + double fact1=MathFactorial((int)r-1); + double factor_r=1.0/fact1; + double power_p_r=MathPowInt(p,int(r))*factor_r; + double p1=1.0-p; + int max_terms=500; + ArrayResize(result,data_count); + for(int i=0; i1.0) + return false; + + if(prob==0.0) + result[i]=0.0; + else + if(prob==1.0) + result[i]=QPOSINF; + else + { + double factor1=fact1; + double factor2=1.0; + double factor_p=1.0; + double cdf=0.0; + int j=0; + while(cdf0) + { + factor1*=(j+1); + factor2*=j; + factor_p*=p1; + } + double pdf=power_p_r*factor1*factor_p/factor2; + cdf+=pdf; + j++; + } + if(j=1.0) + { + error_code=ERR_ARGUMENTS_NAN; + return QNaN; + } + double r_gamma=MathRandomGamma(r,(1-p)/p); + return MathRandomPoisson(r_gamma,error_code); + } +//+------------------------------------------------------------------+ +//| Random variate from the Negative Binomial distribution | +//+------------------------------------------------------------------+ +//| Generates random variables from the Negative Binomial | +//| distribution with parameters r and p. | +//| | +//| Arguments: | +//| r : Number of successes | +//| p : Probability of success | +//| data_count : Number of values needed | +//| result : Output array with random values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathRandomNegativeBinomial(const double r,const double p,const int data_count,double &result[]) + { +//--- check NaN + if(!MathIsValidNumber(r) || !MathIsValidNumber(p)) + return false; +//--- check arguments + if(r<=0.0 || p<=0.0 || p>=1.0) + return false; + + double p_coef=(1-p)/p; + int error_code=0; +//--- prepare output array and calculate random values + ArrayResize(result,data_count); + for(int i=0; i=1.0) + { + error_code=ERR_ARGUMENTS_INVALID; + return false; + } + + error_code=ERR_OK; +//--- calculate moments + mean =r*(1.0-p)/p; + variance=mean/p; + skewness=(2.0-p)/MathSqrt((r*(1.0-p))); + kurtosis=(p*p-6*p+6)/(r*(1.0-p)); +//--- successful + return true; + } +//+------------------------------------------------------------------+ diff --git a/Math/Stat/NoncentralBeta.mqh b/Math/Stat/NoncentralBeta.mqh new file mode 100644 index 0000000..aa62679 --- /dev/null +++ b/Math/Stat/NoncentralBeta.mqh @@ -0,0 +1,954 @@ +//+------------------------------------------------------------------+ +//| NoncentralBeta.mqh | +//| Copyright 2000-2024, MetaQuotes Ltd. | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#include "Math.mqh" +#include "Beta.mqh" +#include "NoncentralChiSquare.mqh" + +//+------------------------------------------------------------------+ +//| Noncental Beta density function (PDF) | +//+------------------------------------------------------------------+ +//| The function returns the probability density function | +//| of the Noncental Beta distribution with parameters a,b,lambda | +//| Infinity | +//| f(x,a,b,lambda)=Sum [p(k)*x^(a+k-1)*(1-x)^(b-1)]/Beta(a+k,b) | +//| k=0 | +//| | +//| where p(k)=(1/k!)*exp(-lambda/2)*(lambda/2)^k, | +//| Beta(a,b)=Gamma(a)*Gamma(b)/Gamma(a+b) | +//| | +//| Arguments: | +//| x : Random variable | +//| a : First shape parameter | +//| b : Second shape parameter | +//| lambda : Noncentrality parameter | +//| log_mode : Logarithm mode flag, if true it returns Log values | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The probability density evaluated at x. | +//+------------------------------------------------------------------+ +double MathProbabilityDensityNoncentralBeta(const double x,const double a,const double b,const double lambda,const bool log_mode,int &error_code) + { +//--- if lambda==0, return Beta density + if(lambda==0.0) + return MathProbabilityDensityBeta(x,a,b,error_code); +//--- check parameters + if(!MathIsValidNumber(x) || !MathIsValidNumber(a) || !MathIsValidNumber(b)) + { + error_code=ERR_ARGUMENTS_NAN; + return QNaN; + } +//--- a,b,lambda must be positive + if(a<=0.0 || b<=0.0 || lambda<0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } + + error_code=ERR_OK; + if(x<=0.0 || x>=1.0) + return TailLog0(true,log_mode); +//--- factors + double lambda_half=lambda*0.5; + double fact_mult=1.0; + double pwr_lambda_half=1.0; + double pwr_x=MathExp((a-1.0)*MathLog(x)); + double r_beta=MathBeta(a,b); + double pdf=0; +//--- direct sum calculation + for(int j=0;; j++) + { + if(j>0) + { + pwr_x*=x; + pwr_lambda_half*=lambda_half; + fact_mult/=j; + double jm1=j-1; + r_beta*=((a+jm1)/(a+b+jm1)); + } + double term=pwr_x*fact_mult*pwr_lambda_half/r_beta; + //--- + if(term<10E-18) + break; + pdf+=term; + } +//--- calculate density coef + pdf*=MathExp((b-1.0)*MathLog(1.0-x))*MathExp(-lambda_half); +//--- return density + return TailLogValue(pdf,true,log_mode); + } +//+------------------------------------------------------------------+ +//| Noncental Beta density function (PDF) | +//+------------------------------------------------------------------+ +//| The function returns the probability density function | +//| of the Noncental Beta distribution with parameters a,b,lambda. | +//| | +//| Arguments: | +//| x : Random variable | +//| a : First shape parameter | +//| b : Second shape parameter | +//| lambda : Noncentrality parameter | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The probability density evaluated at x. | +//+------------------------------------------------------------------+ +double MathProbabilityDensityNoncentralBeta(const double x,const double a,const double b,const double lambda,int &error_code) + { + return MathProbabilityDensityNoncentralBeta(x,a,b,lambda,false,error_code); + } +//+------------------------------------------------------------------+ +//| Noncental Beta density function (PDF) | +//+------------------------------------------------------------------+ +//| The function calculates the probability density function of | +//| the Noncentral Beta distribution with parameters a,b,lambda | +//| for values in x. | +//| | +//| Arguments: | +//| x : Array with random variables | +//| a : First shape parameter | +//| b : Second shape parameter | +//| lambda : Noncentrality parameter | +//| tail : Flag to calculate lower tail | +//| log_mode : Logarithm mode flag, if true it returns Log values | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathProbabilityDensityNoncentralBeta(const double &x[],const double a,const double b,const double lambda,const bool log_mode,double &result[]) + { +//--- if lambda==0, return Beta density + if(lambda==0.0) + return MathProbabilityDensityBeta(x,a,b,log_mode,result); +//--- check parameters + if(!MathIsValidNumber(a) || !MathIsValidNumber(b)) + return false; +//--- a,b,lambda must be positive + if(a<=0.0 || b<=0.0 || lambda<0) + return false; + + int data_count=ArraySize(x); + if(data_count==0) + return false; +//--- common factors + double lambda_half=lambda*0.5; + double exp_lambda_half=MathExp(-lambda_half); + double r_beta0=MathBeta(a,b); + ArrayResize(result,data_count); + for(int i=0; i=1.0) + result[i]=TailLog0(true,log_mode); + else + { + double fact_mult=1.0; + double pwr_lambda_half=1.0; + double pwr_x=MathExp((a-1.0)*MathLog(x_arg)); + double r_beta=r_beta0; + double pdf=0; + for(int j=0;; j++) + { + if(j>0) + { + pwr_x*=x_arg; + pwr_lambda_half*=lambda_half; + fact_mult/=j; + double jm1=j-1; + r_beta*=((a+jm1)/(a+b+jm1)); + } + double term=pwr_x*fact_mult*pwr_lambda_half/r_beta; + //--- + if(term<10E-18) + break; + pdf+=term; + } + //--- calculate density coef + pdf*=MathExp((b-1.0)*MathLog(1.0-x_arg))*exp_lambda_half; + result[i]=TailLogValue(pdf,true,log_mode); + } + } + return true; + } +//+------------------------------------------------------------------+ +//| Noncental Beta density function (PDF) | +//+------------------------------------------------------------------+ +//| The function calculates the probability density function of | +//| the Noncentral Beta distribution with parameters a,b,lambda | +//| for values in x. | +//| | +//| Arguments: | +//| x : Array with random variables | +//| a : First shape parameter | +//| b : Second shape parameter | +//| lambda : Noncentrality parameter | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathProbabilityDensityNoncentralBeta(const double &x[],const double a,const double b,const double lambda,double &result[]) + { + return MathProbabilityDensityNoncentralBeta(x,a,b,lambda,false,result); + } +//+------------------------------------------------------------------+ +//| Noncental Beta cumulative distribution function (CDF) | +//+------------------------------------------------------------------+ +//| The function returns the probability that an observation | +//| from the Noncental Beta distribution with parameters a,b,lambda | +//| is less than or equal to x. | +//| | +//| Input parameters: | +//| x : The desired quantile | +//| a : First shape parameter | +//| b : Second shape parameter | +//| lambda : Noncentrality parameter | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The value of the Noncental Beta cumulative distribution function | +//| with parameters a,b,lambda, evaluated at x. | +//| | +//| Infinity | +//| F(x,a,b,lambda)=Sum p(k)*Ix(a+k,b) | +//| k=0 | +//| | +//| where p(k)=(1/k!)*exp(-lambda/2)*(lambda/2)^k, | +//| Ix(a,b) - incomplete Beta function | +//| | +//| Author: John Burkardt | +//| | +//| Reference: | +//| Harry Posten,"An Effective Algorithm for the Noncentral Beta | +//| Distribution Function", The American Statistician, | +//| Volume 47, Number 2, May 1993, pages 129-131. | +//+------------------------------------------------------------------+ +double MathCumulativeDistributionNoncentralBeta(const double x,const double a,const double b,const double lambda,const bool tail,const bool log_mode,int &error_code) + { +//--- if lambda==0, return Beta CDF + if(lambda==0.0) + return MathCumulativeDistributionBeta(x,a,b,error_code); +//--- check parameters + if(!MathIsValidNumber(x) || !MathIsValidNumber(a) || !MathIsValidNumber(b)) + { + error_code=ERR_ARGUMENTS_NAN; + return QNaN; + } +//--- a,b,lambda must be positive + if(a<=0.0 || b<=0.0 || lambda<0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } + + error_code=ERR_OK; + if(x<=0.0) + return TailLog0(tail,log_mode); + if(x>=1.0) + return TailLog1(tail,log_mode); + + const int max_terms=100; + double c=lambda*0.5; + double x0 = int(MathMax(c - 5*MathSqrt(c), 0)); + double a0 = a + x0; + double beta = MathGammaLog(a0) + MathGammaLog(b) - MathGammaLog(a0+b); + double temp = MathBetaIncomplete(x, a0, b); + double gx=MathExp(a0*MathLog(x)+b*MathLog(1-x)-beta-MathLog(a0)); + + double q=0; + if(a0>a) + q=MathExp(-c+x0*MathLog(c)-MathGammaLog(x0+1)); + else + q=MathExp(-c); + + double sumq=1-q; + double betanc=q*temp; + double ab=a+b; + int j=0; + for(;;) + { + j++; + temp-=gx; + gx*=x*(ab+j-1)/(a+j); + q*=c/j; + sumq-=q; + betanc+=temp*q; + double err=(temp-gx)*sumq; + if(j>max_terms || err<1E-18) + break; + } + double cdf=MathMin(betanc,1.0); + return TailLogValue(cdf,tail,log_mode); + } +//+------------------------------------------------------------------+ +//| Noncental Beta cumulative distribution function (CDF) | +//+------------------------------------------------------------------+ +//| The function returns the probability that an observation | +//| from the Noncental Beta distribution with parameters a,b,lambda | +//| is less than or equal to x. | +//| | +//| Input parameters: | +//| x : The desired quantile | +//| a : First shape parameter | +//| b : Second shape parameter | +//| lambda : Noncentrality parameter | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The value of the Noncental Beta cumulative distribution function | +//| with parameters a,b,lambda, evaluated at x. | +//+------------------------------------------------------------------+ +double MathCumulativeDistributionNoncentralBeta(const double x,const double a,const double b,const double lambda,int &error_code) + { + return MathCumulativeDistributionNoncentralBeta(x,a,b,lambda,true,false,error_code); + } +//+------------------------------------------------------------------+ +//| Noncental Beta cumulative distribution function (CDF) | +//+------------------------------------------------------------------+ +//| The function calculates the cumulative distribution function of | +//| the Noncentral Beta distribution with parameters a,b,lambda | +//| for values in x. | +//| | +//| Arguments: | +//| x : Array with random variables | +//| a : First shape parameter | +//| b : Second shape parameter | +//| lambda : Noncentrality parameter | +//| log_mode : Logarithm mode, if true it calculates Log values | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathCumulativeDistributionNoncentralBeta(const double &x[],const double a,const double b,const double lambda,const bool tail,const bool log_mode,double &result[]) + { +//--- if lambda==0, return Beta CDF + if(lambda==0.0) + return MathCumulativeDistributionBeta(x,a,b,tail,log_mode,result); +//--- check parameters + if(!MathIsValidNumber(a) || !MathIsValidNumber(b)) + return false; +//--- a,b,lambda must be positive + if(a<=0.0 || b<=0.0 || lambda<0) + return false; + + int data_count=ArraySize(x); + if(data_count==0) + return false; + + const int max_terms=100; + ArrayResize(result,data_count); + for(int i=0; i=1.0) + result[i]=TailLog1(tail,log_mode); + else + { + double c=lambda*0.5; + double x0 = int(MathMax(c - 5*MathSqrt(c), 0)); + double a0 = a + x0; + double beta = MathGammaLog(a0) + MathGammaLog(b) - MathGammaLog(a0+b); + double temp = MathBetaIncomplete(x_arg, a0, b); + double gx=MathExp(a0*MathLog(x_arg)+b*MathLog(1-x_arg)-beta-MathLog(a0)); + + double q=0; + if(a0>a) + q=MathExp(-c+x0*MathLog(c)-MathGammaLog(x0+1)); + else + q=MathExp(-c); + + double sumq=1-q; + double betanc=q*temp; + int j=0; + double ab=a+b; + for(;;) + { + j++; + temp-=gx; + gx*=x_arg*(ab+j-1)/(a+j); + q*=c/j; + sumq-=q; + betanc+=temp*q; + double err=(temp-gx)*sumq; + if(j>max_terms || err<1E-18) + break; + } + double cdf=MathMin(betanc,1.0); + result[i]=TailLogValue(cdf,tail,log_mode); + } + } + return true; + } +//+------------------------------------------------------------------+ +//| Noncental Beta cumulative distribution function (CDF) | +//+------------------------------------------------------------------+ +//| The function calculates the cumulative distribution function of | +//| the Noncentral Beta distribution with parameters a,b,lambda | +//| for values in x[] array. | +//| | +//| Arguments: | +//| x : Array with random variables | +//| a : First shape parameter | +//| b : Second shape parameter | +//| lambda : Noncentrality parameter | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathCumulativeDistributionNoncentralBeta(const double &x[],const double a,const double b,const double lambda,double &result[]) + { + return MathCumulativeDistributionNoncentralBeta(x,a,b,lambda,true,false,result); + } +//+------------------------------------------------------------------+ +//| Noncental Beta distribution quantile function (inverse CDF) | +//+------------------------------------------------------------------+ +//| The function returns the inverse cumulative distribution | +//| function of the Noncental Beta distribution with parameters a,b | +//| and lambda for the desired probability. | +//| | +//| Arguments: | +//| probability : The desired probability | +//| a : First shape parameter | +//| b : Second shape parameter | +//| lambda : Noncentrality parameter | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The value of the inverse cumulative distribution function of | +//| of Noncental Beta distribution with parameters a,b and lambda. | +//+------------------------------------------------------------------+ +double MathQuantileNoncentralBeta(const double probability,const double a,const double b,const double lambda,const bool tail,const bool log_mode,int &error_code) + { + if(log_mode==true && probability==QNEGINF) + return 0.0; + if(log_mode==false && probability==0) + return 0.0; +//--- if lambda==0, return beta quantile + if(lambda==0.0) + return MathQuantileBeta(probability,a,b,error_code); +//--- check parameters + if(!MathIsValidNumber(probability) || !MathIsValidNumber(a) || !MathIsValidNumber(b) || !MathIsValidNumber(lambda)) + { + error_code=ERR_ARGUMENTS_NAN; + return QNaN; + } +//--- a,b,lambda must be positive + if(a<=0.0 || b<=0.0 || lambda<0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } + +//--- calculate real probability + double prob=TailLogProbability(probability,tail,log_mode); +//--- check probability range + if(prob<0.0 || prob>1.0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } + + error_code=ERR_OK; +//--- check probabilty + if(prob==0.0) + return 0.0; + if(prob==1.0) + return 1.0; + + double lambda_half=lambda*0.5; + double lambda_half_log=MathLog(lambda_half); + double lambda_half_sqrt=MathSqrt(lambda_half); + double lambda_half_exp=MathExp(-lambda_half); + + double x0=int(MathMax(lambda_half-5*lambda_half_sqrt,0)); + double b_gamma_log=MathGammaLog(b); + double eps=10E-18; + double h_min=MathSqrt(eps); + +//double lambda_half=lambda*0.5; + double r_beta0=MathBeta(a,b); + + int err_code=0; + double x=0.5; + double h=1.0; + const int max_terms=100; +//--- Newton iterations + const int max_iterations=50; + int iterations=0; + while(iterationsh_min*MathAbs(x) && MathAbs(h)>h_min)==false) + break; + + //--- calculate PDF + double pdf=0; + if(x<=0.0 || x>=1.0) + pdf=0; + else + { + double fact_mult=1.0; + double pwr_lambda_half=1.0; + double pwr_x=MathExp((a-1.0)*MathLog(x)); + double r_beta=r_beta0; + //--- direct sum calculation + for(int j=0;; j++) + { + if(j>0) + { + pwr_x*=x; + pwr_lambda_half*=lambda_half; + fact_mult/=j; + double jm1=j-1; + r_beta*=((a+jm1)/(a+b+jm1)); + } + double term=pwr_x*fact_mult*pwr_lambda_half/r_beta; + //--- + if(term<10E-18) + break; + pdf+=term; + } + //--- calculate density coef + pdf*=MathExp((b-1.0)*MathLog(1.0-x))*lambda_half_exp; + } + + //--- calculate CDF + double cdf=0; + if(x<=0.0) + cdf=0; + if(x>=1.0) + cdf=1; + else + { + double a0=a+x0; + double beta = MathGammaLog(a0) + b_gamma_log - MathGammaLog(a0+b); + double temp = MathBetaIncomplete(x, a0, b); + double gx=MathExp(a0*MathLog(x)+b*MathLog(1-x)-beta-MathLog(a0)); + + double q=0; + if(a0>a) + q=MathExp(-lambda_half+x0*lambda_half_log-MathGammaLog(x0+1)); + else + q=lambda_half_exp; + + double sumq=1-q; + double betanc=q*temp; + int j=0; + double ab=a+b; + for(;;) + { + j++; + temp-=gx; + gx*=x*(ab+j-1)/(a+j); + q*=lambda_half/j; + sumq-=q; + betanc+=temp*q; + double err=(temp-gx)*sumq; + if(j>max_terms || err<1E-18) + break; + } + cdf=MathMin(betanc,1.0); + } + + //--- calculate ratio + h=(cdf-prob)/pdf; + + double x_new=x-h; + if(x_new<0.0) + x_new=x*0.1; + else + if(x_new>1.0) + x_new=1.0-(1-x)*0.1; + + if(MathAbs(x_new-x)<10E-16) + break; + x=x_new; + + iterations++; + } +//--- check convergence + if(iterationsh_min*MathAbs(x) && MathAbs(h)>h_min)==false) + break; + + //--- calculate PDF + double pdf=0; + if(x<=0.0 || x>=1.0) + pdf=0; + else + { + double fact_mult=1.0; + double pwr_lambda_half=1.0; + double pwr_x=MathExp((a-1.0)*MathLog(x)); + double r_beta=r_beta0; + //--- direct sum calculation + for(int j=0;; j++) + { + if(j>0) + { + pwr_x*=x; + pwr_lambda_half*=lambda_half; + fact_mult/=j; + double jm1=j-1; + r_beta*=((a+jm1)/(a+b+jm1)); + } + double term=pwr_x*fact_mult*pwr_lambda_half/r_beta; + //--- + if(term<10E-18) + break; + pdf+=term; + } + //--- calculate density coef + pdf*=MathExp((b-1.0)*MathLog(1.0-x))*lambda_half_exp; + } + + //--- calculate CDF + double cdf=0; + if(x<=0.0) + cdf=0; + if(x>=1.0) + cdf=1; + else + { + double a0=a+x0; + double beta = MathGammaLog(a0) + b_gamma_log - MathGammaLog(a0+b); + double temp = MathBetaIncomplete(x, a0, b); + double gx=MathExp(a0*MathLog(x)+b*MathLog(1-x)-beta-MathLog(a0)); + + double q=0; + if(a0>a) + q=MathExp(-lambda_half+x0*lambda_half_log-MathGammaLog(x0+1)); + else + q=lambda_half_exp; + + double sumq=1-q; + double betanc=q*temp; + int j=0; + double ab=a+b; + for(;;) + { + j++; + temp-=gx; + gx*=x*(ab+j-1)/(a+j); + q*=lambda_half/j; + sumq-=q; + betanc+=temp*q; + double err=(temp-gx)*sumq; + if(j>max_terms || err<1E-18) + break; + } + cdf=MathMin(betanc,1.0); + } + + //--- calculate ratio + h=(cdf-prob)/pdf; + + double x_new=x-h; + if(x_new<0.0) + x_new=x*0.1; + else + if(x_new>1.0) + x_new=1.0-(1-x)*0.1; + + if(MathAbs(x_new-x)<10E-16) + break; + x=x_new; + + iterations++; + } + //--- check convergence + if(iterations0) + { + pwr_lambda*=lambda; + pwr_x*=x; + pwr_two*=0.5; + fact_mult*=1.0/j; + inv_factor*=1.0/(j+half_nu-1); + } + double dp=coef_gamma*inv_factor*pwr_lambda*pwr_two*pwr_x*fact_mult*coef_lambda_x; + pdf=pdf+dp; + //--- check stop + if(dp/(pdf+10E-10)<10E-16) + break; + j++; + } +//--- check convergence + if(j0) + { + pwr_lambda*=lambda; + pwr_x*=x_arg; + pwr_two*=0.5; + fact_mult*=1.0/j; + inv_factor*=1.0/(j+half_nu-1); + } + double dp=coef_gamma*inv_factor*pwr_lambda*pwr_two*pwr_x*fact_mult*coef_lambda_x; + pdf=pdf+dp; + //--- check stop + if(dp/(pdf+10E-10)<10E-16) + break; + j++; + } + //--- check convergence + if(j0) + { + pwr_lambda*=lambda; + fact_mult/=j; + } + double coef1=coef_lambda*pwr_lambda*fact_mult; + double coef2=MathMin(MathGammaIncomplete(half_x,half_nu+j),1.0); + double dp=coef1*coef2; + cdf=cdf+dp; + if((dp/(cdf+10E-10))<10E-16) + break; + j++; + } +//--- + if(j0) + { + pwr_lambda*=lambda; + fact_mult/=j; + } + double coef1=coef_lambda*pwr_lambda*fact_mult; + double coef2=MathMin(MathGammaIncomplete(half_x,half_nu+j),1.0); + double dp=coef1*coef2; + cdf=cdf+dp; + if((dp/(cdf+10E-10))<10E-16) + break; + j++; + } + //--- + if(j1.0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } + + error_code=ERR_OK; + if(prob==0.0) + return 0.0; + + if(prob==1.0) + return QPOSINF; + + error_code=ERR_OK; +//--- common factors for pdf and cdf calculation + const int max_terms=1000; + double lambda=sigma*0.5; + double half_nu=nu*0.5; + double coef_lambda=MathExp(-lambda); + double half_nu_m1=half_nu-1.0; + double coef_gamma=1.0/MathGamma(half_nu); + double pwr_two2=MathExp(-half_nu*MathLog(2)); + double pwr_half_num1=(half_nu-1.0); +//--- prepare values for initial x estimation + double x=0.5; + double h=1.0; + double h_min=10E-10; +//--- Newton iterations + const int max_iterations=50; + int iterations=0; +// int err_code=0; + while(iterationsh_min && MathAbs(h)>MathAbs(h_min*x))==false) + break; + + //double pdf=MathProbabilityDensityNoncentralChiSquare(x,nu,sigma,false,err_code); + double half_x=x*0.5; + double pwr_lambda=1.0; + double pwr_two=pwr_two2; + double pwr_x=MathPow(x,pwr_half_num1); + double fact_mult=1.0; + double coef_lambda_x=coef_lambda*MathExp(-half_x); + double inv_factor=1.0; + //--- calculate density using direct summation + int j=0; + double pdf=0; + while(j0) + { + pwr_lambda*=lambda; + pwr_x*=x; + pwr_two*=0.5; + fact_mult*=1.0/j; + inv_factor*=1.0/(j+half_nu-1); + } + double dp=coef_gamma*inv_factor*pwr_lambda*pwr_two*pwr_x*fact_mult*coef_lambda_x; + pdf=pdf+dp; + //--- check stop + if(dp/(pdf+10E-10)<10E-16) + break; + j++; + } + //--- check convergence + if(j>max_terms) + { + error_code=ERR_NON_CONVERGENCE; + return QNaN; + } + + //--- calculate cdf + pwr_lambda=1.0; + fact_mult=1.0; + double cdf=0.0; + j=0; + //--- direct summation + while(j0) + { + pwr_lambda*=lambda; + fact_mult/=j; + } + double coef1=coef_lambda*pwr_lambda*fact_mult; + double coef2=MathMin(MathGammaIncomplete(half_x,half_nu+j),1.0); + double dp=coef1*coef2; + cdf=cdf+dp; + if((dp/(cdf+10E-10))<10E-16) + break; + j++; + } + //--- + if(j>max_terms) + { + error_code=ERR_NON_CONVERGENCE; + return QNaN; + } + + //--- calculate ratio + h=(cdf-prob)/pdf; + + double x_new=x-h; + if(x_new<0.0) + x_new=x*0.1; + else + if(x_new>1.0) + x_new=1.0-(1-x)*0.1; + x=x_new; + + iterations++; + } +//--- check convergence + if(iterations1.0) + return false; + + //--- prepare values for initial x estimation + int err_code=0; + double x=0.5; + double h=1.0; + //--- Newton iterations + int iterations=0; + while(iterationsh_min && MathAbs(h)>MathAbs(h_min*x))==false) + break; + + //double pdf=MathProbabilityDensityNoncentralChiSquare(x,nu,sigma,false,err_code); + double half_x=x*0.5; + double pwr_lambda=1.0; + double pwr_two=pwr_two0; + double pwr_x=MathPow(x,half_nu_m1); + double fact_mult=1.0; + double coef_lambda_x=coef_lambda*MathExp(-half_x); + double inv_factor=1.0; + //--- calculate density using direct summation + int j=0; + double pdf=0; + while(j0) + { + pwr_lambda*=lambda; + pwr_x*=x; + pwr_two*=0.5; + fact_mult*=1.0/j; + inv_factor*=1.0/(j+half_nu-1); + } + double dp=pwr_gamma0*inv_factor*pwr_lambda*pwr_two*pwr_x*fact_mult*coef_lambda_x; + pdf=pdf+dp; + //--- check stop + if(dp/(pdf+10E-10)<10E-16) + break; + j++; + } + //--- check convergence + if(j>max_terms) + return false; + + //--- calculate cdf + pwr_lambda=1.0; + fact_mult=1.0; + pwr_lambda=1.0; + fact_mult=1.0; + double cdf=0.0; + j=0; + //--- direct summation + while(j0) + { + pwr_lambda*=lambda; + fact_mult/=j; + } + double coef1=coef_lambda*pwr_lambda*fact_mult; + double coef2=MathMin(MathGammaIncomplete(half_x,half_nu+j),1.0); + double dp=coef1*coef2; + cdf=cdf+dp; + if((dp/(cdf+10E-10))<10E-16) + break; + j++; + } + //--- + if(j>max_terms) + return false; + + //--- calculate ratio + h=(cdf-prob)/pdf; + + double x_new=x-h; + if(x_new<0.0) + x_new=x*0.1; + else + if(x_new>1.0) + x_new=1.0-(1-x)*0.1; + x=x_new; + + iterations++; + } + //--- check convergence + if(iterations1.0) + { + double rnd_chisquare=MathRandomGamma((nu-1)*0.5,2.0,err_code); + double rnd_normal=MathSqrt(sigma)+MathRandomNormal(0,1,err_code); + return rnd_chisquare+rnd_normal*rnd_normal; + } + else + { + int rnd_poisson=(int)MathRandomPoisson(sigma*0.5); + return MathRandomChiSquare(nu+2*rnd_poisson,err_code); + } + } +//+------------------------------------------------------------------+ +//| Random variate from the Noncentral Chi-Square distribution | +//+------------------------------------------------------------------+ +//| Generates random variables from the Noncentral Chi-Square | +//| distribution with parameters nu and sigma. | +//| | +//| Arguments: | +//| nu : Degrees of freedom | +//| sigma : Noncentrality parameter | +//| data_count : Number of values needed | +//| result : Output array with random values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +//| Author: Robert Kern | +//+------------------------------------------------------------------+ +bool MathRandomNoncentralChiSquare(const double nu,const double sigma,const int data_count,double &result[]) + { +//--- return ChiSquare if sigma==0 + if(sigma==0.0) + return MathRandomChiSquare(nu,data_count,result); +//--- check NaN + if(!MathIsValidNumber(nu) || !MathIsValidNumber(sigma)) + return false; +//--- check nu + if(nu!=MathRound(nu) || nu<=0) + return false; +//--- check sigma + if(sigma<0.0) + return false; + + int err_code=0; +//--- prepare output array and calculate random values + ArrayResize(result,data_count); + for(int i=0; i1.0) + { + double rnd_chisquare=MathRandomGamma((nu-1)*0.5,2.0,err_code); + double rnd_normal=MathSqrt(sigma)+MathRandomNormal(0,1,err_code); + result[i]=rnd_chisquare+rnd_normal*rnd_normal; + } + else + { + int rnd_poisson=(int)MathRandomPoisson(sigma*0.5); + result[i]=MathRandomChiSquare(nu+2*rnd_poisson,err_code); + } + } + return true; + } +//+------------------------------------------------------------------+ +//| Noncentral Chi-Square distribution moments | +//+------------------------------------------------------------------+ +//| The function calculates 4 first moments of Noncental Chi-Square | +//| distribution with parameters nu and sigma. | +//| | +//| Arguments: | +//| nu : Degrees of freedom | +//| sigma : Noncentrality parameter | +//| mean : Variable for mean value (1st moment) | +//| variance : Variable for variance value (2nd moment) | +//| skewness : Variable for skewness value (3rd moment) | +//| kurtosis : Variable for kurtosis value (4th moment) | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| true if moments calculated successfully, otherwise false. | +//+------------------------------------------------------------------+ +bool MathMomentsNoncentralChiSquare(const double nu,const double sigma,double &mean,double &variance,double &skewness,double &kurtosis,int &error_code) + { +//--- default values + mean =QNaN; + variance=QNaN; + skewness=QNaN; + kurtosis=QNaN; +//--- check NaN + if(!MathIsValidNumber(nu) || !MathIsValidNumber(sigma)) + { + error_code=ERR_ARGUMENTS_NAN; + return false; + } +//--- check nu + if(nu!=MathRound(nu) || nu<=0.0) + { + error_code=ERR_ARGUMENTS_INVALID; + return false; + } + + error_code=ERR_OK; +//--- calculate moments + mean =nu+sigma; + variance=2*nu+4*sigma; + skewness=2*M_SQRT2*(nu+3*sigma)*MathPow(nu+2*sigma,-1.5); + kurtosis=12*(nu+4*sigma)*MathPow(nu+2*sigma,-2); +//--- successful + return true; + } +//+------------------------------------------------------------------+ diff --git a/Math/Stat/NoncentralF.mqh b/Math/Stat/NoncentralF.mqh new file mode 100644 index 0000000..78c4946 --- /dev/null +++ b/Math/Stat/NoncentralF.mqh @@ -0,0 +1,790 @@ +//+------------------------------------------------------------------+ +//| NoncentralF.mqh | +//| Copyright 2000-2024, MetaQuotes Ltd. | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#include "Math.mqh" +#include "F.mqh" +#include "Gamma.mqh" +#include "NoncentralBeta.mqh" + +//+------------------------------------------------------------------+ +//| Noncentral-F probability density function (PDF) | +//+------------------------------------------------------------------+ +//| The function returns the probability density function | +//| of the Noncentral-F distribution with parameters nu1,nu2,sigma. | +//| | +//| Arguments: | +//| x : Random variable | +//| nu1 : Numerator degrees of freedom | +//| nu2 : Denominator degrees of freedom | +//| sigma : Noncentrality parameter | +//| log_mode : Logarithm mode flag, if true it returns Log values | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The probability density evaluated at x. | +//+------------------------------------------------------------------+ +double MathProbabilityDensityNoncentralF(const double x,const double nu1,const double nu2,const double sigma,const bool log_mode,int &error_code) + { +//--- return F if sigma==0 + if(sigma==0.0) + return MathProbabilityDensityF(x,nu1,nu2,error_code); +//--- check NaN + if(!MathIsValidNumber(x) || !MathIsValidNumber(nu1) || !MathIsValidNumber(nu2) || !MathIsValidNumber(sigma)) + { + error_code=ERR_ARGUMENTS_NAN; + return QNaN; + } +//--- check arguments + if(nu1!=MathRound(nu1) || nu2!=MathRound(nu2) || nu1<=0 || nu2<=0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } + + error_code=ERR_OK; + if(x<=0.0) + return TailLog0(true,log_mode); +//--- factors + double nu1_half=nu1*0.5; + double nu2_half=nu2*0.5; + double nu12_half=nu1_half+nu2_half; + double lambda=sigma*0.5; + double coef_lambda=MathExp(-lambda); + double nu_coef=nu1/nu2; + double g=x*nu_coef; + double pwr_g=MathExp((nu1_half-1)*MathLog(g)); + double g1=g+1.0; + double pwr_g1=MathExp(-nu12_half*MathLog(g1)); + double pwr_lambda=1.0; + double fact_mult=1.0; +//--- initial value for recurrent calculation + double r_beta=MathBeta(nu1_half,nu2_half); +//--- direct calculation of the sum + int max_terms=100; + int j=0; + double pdf=0; + while(j0) + { + pwr_g*=g; + pwr_lambda*=lambda; + fact_mult/=j; + pwr_g1/=g1; + double jm1=j-1; + r_beta*=((nu1_half+jm1)/(nu12_half+jm1)); + } + double dp=pwr_g*pwr_g1*coef_lambda*pwr_lambda*fact_mult/r_beta; + pdf+=dp; + if(dp/(pdf+10E-10)<10E-14) + break; + j++; + } +//--- check convergence + if(j0) + { + pwr_g*=g; + pwr_lambda*=lambda; + fact_mult/=j; + pwr_g1/=g1; + double jm1=j-1; + r_beta*=((nu1_half+jm1)/(nu12_half+jm1)); + } + double dp=pwr_g*pwr_g1*coef_lambda*pwr_lambda*fact_mult/r_beta; + pdf+=dp; + if(dp/(pdf+10E-10)<10E-14) + break; + j++; + } + //--- check convergence + if(j1.0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } + + if(prob==1.0) + { + error_code=ERR_RESULT_INFINITE; + return QPOSINF; + } + error_code=ERR_OK; + if(prob==0.0) + return 0.0; +//--- + int max_iterations=50; + int iterations=0; +//--- initial values + double h=1.0; + double h_min=10E-10; + double x=0.5; + int err_code=0; +//--- Newton iterations + while(iterationsh_min && MathAbs(h)>MathAbs(h_min*x))==false) + break; + //--- calculate pdf and cdf + double pdf=MathProbabilityDensityNoncentralF(x,nu1,nu2,sigma,err_code); + double cdf=MathCumulativeDistributionNoncentralF(x,nu1,nu2,sigma,err_code); + //--- calculate ratio + h=(cdf-prob)/pdf; + //--- + double x_new=x-h; + //--- check x + if(x_new<0.0) + x_new=x*0.1; + else + if(x_new>1.0) + x_new=1.0-(1.0-x)*0.1; + + x=x_new; + + iterations++; + } +//--- check convergence + if(iterations1.0) + return false; + + if(prob==1.0) + result[i]=QPOSINF; + else + if(prob==0.0) + result[i]=0.0; + else + { + int max_iterations=50; + int iterations=0; + //--- initial values + double h=1.0; + double h_min=10E-10; + double x=0.5; + int err_code=0; + //--- Newton iterations + while(iterationsh_min && MathAbs(h)>MathAbs(h_min*x))==false) + break; + //--- calculate pdf and cdf + double pdf=MathProbabilityDensityNoncentralF(x,nu1,nu2,sigma,err_code); + double cdf=MathCumulativeDistributionNoncentralF(x,nu1,nu2,sigma,err_code); + //--- calculate ratio + h=(cdf-prob)/pdf; + //--- + double x_new=x-h; + //--- check x + if(x_new<0.0) + x_new=x*0.1; + else + if(x_new>1.0) + x_new=1.0-(1.0-x)*0.1; + + x=x_new; + + iterations++; + } + //--- check convergence + if(iterations2) + mean=nu2*(nu1+sigma)/(nu1*(nu2-2)); +//--- variance + if(nu2>4) + variance=2*MathPow(nu2/nu1,2)*((nu2-2)*(nu1+2*sigma)+MathPow(nu1+sigma,2))/((nu2-4)*MathPow(nu2-2,2)); +//--- factors + double sigma_sqr=MathPow(sigma,2); + double sigma_cube=sigma_sqr*sigma; + double nu12m2=(nu1+nu2-2); + double nu2p10=(nu2+10); +//--- skewness + if(nu2>6) + { + skewness=2*M_SQRT2*MathSqrt(nu2-4); + skewness*=(nu12m2*(6*sigma_sqr+(2*nu1+nu2-2)*(3*sigma+nu1))+2*sigma_cube); + skewness/=(nu2-6); + skewness/=MathPow(nu12m2*(2*sigma+nu1)+sigma_sqr,1.5); + } +//--- kurtosis + if(nu2>8) + { + double coef=nu2p10*(MathPow(nu1,2)+nu1*(nu2-2))+4*MathPow(nu2-2,2); + kurtosis=1; + kurtosis=3*(nu2-4); + kurtosis*=(nu12m2*(coef*(4*sigma+nu1)+nu2p10*(4*sigma_cube+2*sigma_sqr*(3*nu1+2*nu2-4)))+nu2p10*MathPow(sigma,4)); + kurtosis/=(nu2-8)*(nu2-6); + kurtosis/=MathPow((nu12m2*(2*sigma+nu1)+sigma_sqr),2); + kurtosis-=3; + } +//--- successful + return true; + } +//+------------------------------------------------------------------+ diff --git a/Math/Stat/NoncentralT.mqh b/Math/Stat/NoncentralT.mqh new file mode 100644 index 0000000..fb5ae3c --- /dev/null +++ b/Math/Stat/NoncentralT.mqh @@ -0,0 +1,1192 @@ +//+------------------------------------------------------------------+ +//| NoncentralT.mqh | +//| Copyright 2000-2024, MetaQuotes Ltd. | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#include "Math.mqh" +#include "T.mqh" +#include "Normal.mqh" + +//+------------------------------------------------------------------+ +//| Noncentral T probability density function (PDF) | +//+------------------------------------------------------------------+ +//| The function returns the probability density function | +//| of the Noncentral T distribution with parameters nu and delta. | +//| | +//| Arguments: | +//| x : Random variable | +//| nu : Degrees of freedom | +//| delta : Noncentrality parameter | +//| log_mode : Logarithm mode, if true it calculates Log values | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The probability density evaluated at x. | +//+------------------------------------------------------------------+ +double MathProbabilityDensityNoncentralT(const double x,const double nu,const double delta,const bool log_mode,int &error_code) + { +//--- return T + if(delta==0.0) + return MathProbabilityDensityT(x,nu,error_code); +//--- check NaN + if(!MathIsValidNumber(x) || !MathIsValidNumber(nu) || !MathIsValidNumber(delta)) + { + error_code=ERR_ARGUMENTS_NAN; + return QNaN; + } +//--- check nu + if(nu!=MathRound(nu) || nu<=0.0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } + + error_code=ERR_OK; +//--- + double nu_1=nu+1.0; + double nu_1_half=nu_1*0.5; + double log_nu=MathLog(nu); + double factor1=MathExp(-0.5*(MathLog(M_PI)+log_nu)-(delta*delta)*0.5-MathGammaLog(nu*0.5)+nu_1_half*log_nu); + + double nu_xx=nu+x*x; + double log_nu_xx=MathLog(nu_xx); + double factor2=MathExp(-nu_1_half*log_nu_xx); +//--- + const int max_terms=500; + double pwr=1.0; + double pwr_factor=x*delta*M_SQRT2; + double pwr_nuxx=1.0; + double pwr_nuxx_factor=1.0/MathSqrt(nu_xx); + double pwr_gamma=1.0; + int j=0; + double pdf=0.0; + while(j0) + { + pwr_nuxx*=pwr_nuxx_factor; + pwr_gamma/=j; + pwr*=pwr_factor; + } + double t=pwr*pwr_gamma*pwr_nuxx*MathGamma((nu_1+j)*0.5); + pdf+=t; + //--- check precision + if((t/(pdf+10E-10))<10E-20) + break; + j++; + } +//--- check convergence + if(j0) + { + pwr_nuxx*=pwr_nuxx_factor; + pwr_gamma/=j; + pwr*=pwr_factor; + } + double t=pwr*pwr_gamma*pwr_nuxx*MathGamma((nu_1+j)*0.5); + pdf+=t; + //--- check precision + if((t/(pdf+10E-10))<10E-20) + break; + j++; + } + //--- check convergence + if(j=max_iterations) + break; + } + else + { + if(error<=errtol || j>=max_iterations) + break; + } + } +//--- check convergence + if(j=max_iterations) + break; + } + else + { + if(error<=errtol || j>=max_iterations) + break; + } + } + //--- check convergence + if(j1.0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } + + if(prob==0.0 || prob==1.0) + { + error_code=ERR_RESULT_INFINITE; + if(prob==0.0) + return QNEGINF; + else + return QPOSINF; + } +//--- coefficients for pdf and cdf + double sqr_delta_half=delta*delta*0.5; + double nu_half=nu*0.5; + double log_sqr_delta_half=MathLog(sqr_delta_half); + double exp_sqr_delta_half=MathExp(-sqr_delta_half); + double sqrt_sqr_delta_half=MathSqrt(sqr_delta_half); + double nu_1=nu+1.0; + double nu_1_half=nu_1*0.5; + double log_nu=MathLog(nu); + double factor1=MathExp(-0.5*(MathLog(M_PI)+log_nu)-sqr_delta_half-MathGammaLog(nu*0.5)+nu_1_half*log_nu); + +//--- probability for -delta + int err_code=0; + double p0=MathCumulativeDistributionNormal(-delta,0.0,1.0,err_code); +//--- + error_code=ERR_OK; + double precision=10E-20; + const int max_iterations=150; + int iterations=0; + double x=0.5; + double h=1.0; + double h_min=precision; + const int max_terms=500; +//--- Newton iterations + while(iterationsh_min && MathAbs(h)>MathAbs(h_min*x))==false) + break; + + //--- calculate pdf + double x_arg_sqr=x*x; + double nu_xx=nu+x_arg_sqr; + double log_nu_xx=MathLog(nu_xx); + double factor2=MathExp(-nu_1_half*log_nu_xx); + double pwr=1.0; + double pwr_factor=x*delta*M_SQRT2; + double pwr_nuxx=1.0; + double pwr_nuxx_factor=1.0/MathSqrt(nu_xx); + double pwr_gamma=1.0; + int j=0; + double pdf=0.0; + while(j0) + { + pwr_nuxx*=pwr_nuxx_factor; + pwr_gamma/=j; + pwr*=pwr_factor; + } + double t=pwr*pwr_gamma*pwr_nuxx*MathGamma((nu_1+j)*0.5); + pdf+=t; + //--- check precision + if((t/(pdf+10E-10))<10E-20) + break; + j++; + } + //--- check convergence + if(j>max_terms) + return false; + pdf=factor1*factor2*pdf; + + //--- calculate cdf + double t=(x*x)/(nu+x*x); + double sum1 = 0.0; + double sum2 = 0.0; + //--- + double pwr_coef1=1.0; + double pwr_coef2=1.0; + double fact=1.0; + j=0; + if(x!=0) + { + while(j0) + { + pwr_coef1*=sqrt_sqr_delta_half; + pwr_coef2*=sqr_delta_half; + fact/=j; + } + double coef=1.0/MathGamma(j*0.5+1.0); + //--- term1: t between 0 and x + double t1=pwr_coef1*coef*MathBetaIncomplete(t,(j+1.0)*0.5,nu_half); + sum1+=t1; + //--- term2: t between x and -x + double t2=pwr_coef2*fact*MathBetaIncomplete(t,(j+0.5),nu_half); + sum2+=t2; + //--- check precision + if((MathAbs(t1/(sum1+10E-10))max_terms) + return false; + + //--- compute probability for positive x + double cdf=p0+exp_sqr_delta_half*sum1*0.5; + //--- compute probability for negative x + if(x<0) + cdf=cdf-exp_sqr_delta_half*sum2; + //--- take into account round-off errors for probability + cdf=MathMin(cdf,1.0); + + //--- calculate ratio + h=(cdf-prob)/pdf; + + double x_new=x-h; + if(x_new<0.0) + x_new=x*0.1; + else + if(x_new>1.0) + x_new=1.0-(1.0-x)*0.1; + + if(MathAbs(x_new-x)<10E-15) + break; + + x=x_new; + iterations++; + } +//--- check convergence + if(iterations1.0) + return false; + + if(prob==0.0 || prob==1.0) + { + if(prob==0.0) + result[i]=QNEGINF; + else + result[i]=QPOSINF; + } + else + { + double x=0.5; + double h=1.0; + int iterations=0; + //--- Newton iterations + while(iterationsh_min && MathAbs(h)>MathAbs(h_min*x))==false) + break; + + //--- calculate pdf and cdf + //double cdf=MathCumulativeDistributionNoncentralT(x,nu,delta,err_code); + //double pdf=MathProbabilityDensityNoncentralT(x,nu,delta,err_code); + + //--- calculate pdf + double x_arg_sqr=x*x; + double nu_xx=nu+x_arg_sqr; + double log_nu_xx=MathLog(nu_xx); + double factor2=MathExp(-nu_1_half*log_nu_xx); + double pwr=1.0; + double pwr_factor=x*delta*M_SQRT2; + double pwr_nuxx=1.0; + double pwr_nuxx_factor=1.0/MathSqrt(nu_xx); + double pwr_gamma=1.0; + int j=0; + double pdf=0.0; + while(j0) + { + pwr_nuxx*=pwr_nuxx_factor; + pwr_gamma/=j; + pwr*=pwr_factor; + } + double t=pwr*pwr_gamma*pwr_nuxx*MathGamma((nu_1+j)*0.5); + pdf+=t; + //--- check precision + if((t/(pdf+10E-10))<10E-20) + break; + j++; + } + //--- check convergence + if(j>max_terms) + return false; + + pdf=factor1*factor2*pdf; + + //--- calculate cdf + double t=(x*x)/(nu+x*x); + double sum1 = 0.0; + double sum2 = 0.0; + //--- + double pwr_coef1=1.0; + double pwr_coef2=1.0; + double fact=1.0; + j=0; + if(x!=0) + { + while(j0) + { + pwr_coef1*=sqrt_sqr_delta_half; + pwr_coef2*=sqr_delta_half; + fact/=j; + } + double coef=1.0/MathGamma(j*0.5+1.0); + //--- term1: t between 0 and x + double t1=pwr_coef1*coef*MathBetaIncomplete(t,(j+1.0)*0.5,nu_half); + sum1+=t1; + //--- term2: t between x and -x + double t2=pwr_coef2*fact*MathBetaIncomplete(t,(j+0.5),nu_half); + sum2+=t2; + //--- check precision + if((MathAbs(t1/(sum1+10E-10))max_terms) + return false; + + //--- compute probability for positive x + double cdf=p0+exp_sqr_delta_half*sum1*0.5; + //--- compute probability for negative x + if(x<0) + cdf=cdf-exp_sqr_delta_half*sum2; + //--- take into account round-off errors for probability + cdf=MathMin(cdf,1.0); + + //--- calculate ratio + h=(cdf-prob)/pdf; + + double x_new=x-h; + if(x_new<0.0) + x_new=x*0.1; + else + if(x_new>1.0) + x_new=1.0-(1.0-x)*0.1; + + if(MathAbs(x_new-x)<10E-15) + break; + + x=x_new; + iterations++; + } + //--- check convergence + if(iterations1) + mean=delta*MathSqrt(nu)*MathGamma((nu-1)*0.5)/(MathSqrt(2)*MathGamma(nu*0.5)); +//--- delta^2 + double delta_sqr=delta*delta; +//--- 1/((nu-3)*(nu-2)) + double nu32=1/((nu-3)*(nu-2)); + if(nu>2) + variance=((delta_sqr+1)*nu)/(nu-2)-MathPow(mean,2); +//--- skewness + if(nu>3) + { + skewness=-2*variance; + skewness+= nu*(delta_sqr+2*nu-3)*nu32; + skewness*= mean*MathPow(variance,-1.5); + } +//--- kurtosis + if(nu>4) + { + kurtosis=-3*variance; + kurtosis+= nu*(delta_sqr*(nu+1)+3*(3*nu-5))*nu32; + kurtosis*= -MathPow(mean,2); + kurtosis+= MathPow(nu,2)*(MathPow(delta,4)+6*delta_sqr+3)/((nu-4)*(nu-2)); + kurtosis*= MathPow(variance,-2); + kurtosis-=3; + } +//--- successful + return true; + } +//+------------------------------------------------------------------+ diff --git a/Math/Stat/Normal.mqh b/Math/Stat/Normal.mqh new file mode 100644 index 0000000..e5c1630 --- /dev/null +++ b/Math/Stat/Normal.mqh @@ -0,0 +1,914 @@ +//+------------------------------------------------------------------+ +//| Normal.mqh | +//| Copyright 2000-2024, MetaQuotes Ltd. | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#include "Math.mqh" + +const static double normal_cdf_a[5]= + { + 2.2352520354606839287E00,1.6102823106855587881E02, + 1.0676894854603709582E03,1.8154981253343561249E04, + 6.5682337918207449113E-2 + }; +const static double normal_cdf_b[4]= + { + 4.7202581904688241870E01,9.7609855173777669322E02, + 1.0260932208618978205E04,4.5507789335026729956E04 + }; +//--- coefficients for approximation in second interval +const static double normal_cdf_c[9]= + { + 3.9894151208813466764E-1,8.8831497943883759412E00, + 9.3506656132177855979E01,5.9727027639480026226E02, + 2.4945375852903726711E03,6.8481904505362823326E03, + 1.1602651437647350124E04,9.8427148383839780218E03, + 1.0765576773720192317E-8 + }; +const static double normal_cdf_d[8]= + { + 2.2266688044328115691E01,2.3538790178262499861E02, + 1.5193775994075548050E03,6.4855582982667607550E03, + 1.8615571640885098091E04,3.4900952721145977266E04, + 3.8912003286093271411E04,1.9685429676859990727E04 + }; +//--- coefficients for approximation in third interval +const static double normal_cdf_p[6]= + { + 2.1589853405795699E-1,1.274011611602473639E-1, + 2.2235277870649807E-2,1.421619193227893466E-3, + 2.9112874951168792E-5,2.307344176494017303E-2 + }; +const static double normal_cdf_q[5]= + { + 1.28426009614491121E00,4.68238212480865118E-1, + 6.59881378689285515E-2,3.78239633202758244E-3, + 7.29751555083966205E-5 + }; + +//--- coefficients for p close to 0.5 +const double normal_q_a0 = 3.3871328727963666080; +const double normal_q_a1 = 1.3314166789178437745E+2; +const double normal_q_a2 = 1.9715909503065514427E+3; +const double normal_q_a3 = 1.3731693765509461125E+4; +const double normal_q_a4 = 4.5921953931549871457E+4; +const double normal_q_a5 = 6.7265770927008700853E+4; +const double normal_q_a6 = 3.3430575583588128105E+4; +const double normal_q_a7 = 2.5090809287301226727E+3; +const double normal_q_b1 = 4.2313330701600911252E+1; +const double normal_q_b2 = 6.8718700749205790830E+2; +const double normal_q_b3 = 5.3941960214247511077E+3; +const double normal_q_b4 = 2.1213794301586595867E+4; +const double normal_q_b5 = 3.9307895800092710610E+4; +const double normal_q_b6 = 2.8729085735721942674E+4; +const double normal_q_b7 = 5.2264952788528545610E+3; +//--- coefficients for p not close to 0, 0.5 or 1 +const double normal_q_c0 = 1.42343711074968357734; +const double normal_q_c1 = 4.63033784615654529590; +const double normal_q_c2 = 5.76949722146069140550; +const double normal_q_c3 = 3.64784832476320460504; +const double normal_q_c4 = 1.27045825245236838258; +const double normal_q_c5 = 2.41780725177450611770E-1; +const double normal_q_c6 = 2.27238449892691845833E-2; +const double normal_q_c7 = 7.74545014278341407640E-4; +const double normal_q_d1 = 2.05319162663775882187; +const double normal_q_d2 = 1.67638483018380384940; +const double normal_q_d3 = 6.89767334985100004550E-1; +const double normal_q_d4 = 1.48103976427480074590E-1; +const double normal_q_d5 = 1.51986665636164571966E-2; +const double normal_q_d6 = 5.47593808499534494600E-4; +const double normal_q_d7 = 1.05075007164441684324E-9; +//--- coefficients for p near 0 or 1. +const double normal_q_e0 = 6.65790464350110377720E0; +const double normal_q_e1 = 5.46378491116411436990E0; +const double normal_q_e2 = 1.78482653991729133580E0; +const double normal_q_e3 = 2.96560571828504891230E-1; +const double normal_q_e4 = 2.65321895265761230930E-2; +const double normal_q_e5 = 1.24266094738807843860E-3; +const double normal_q_e6 = 2.71155556874348757815E-5; +const double normal_q_e7 = 2.01033439929228813265E-7; +const double normal_q_f1 = 5.99832206555887937690E-1; +const double normal_q_f2 = 1.36929880922735805310E-1; +const double normal_q_f3 = 1.48753612908506148525E-2; +const double normal_q_f4 = 7.86869131145613259100E-4; +const double normal_q_f5 = 1.84631831751005468180E-5; +const double normal_q_f6 = 1.42151175831644588870E-7; +const double normal_q_f7 = 2.04426310338993978564E-15; +//+------------------------------------------------------------------+ +//| Normal probability density function (PDF) | +//+------------------------------------------------------------------+ +//| The function returns the probability density function | +//| of the Normal distribution with parameters mu and sigma. | +//| | +//| Arguments: | +//| x : Random variable | +//| mu : Mean | +//| sigma : Standard deviation (sigma>0) | +//| log_mode : Logarithm mode flag, if true it returns Log values | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The probability density evaluated at x. | +//+------------------------------------------------------------------+ +double MathProbabilityDensityNormal(const double x,const double mu,const double sigma,const bool log_mode,int &error_code) + { +//--- check NaN + if(!MathIsValidNumber(x) || !MathIsValidNumber(mu) || !MathIsValidNumber(sigma)) + { + error_code=ERR_ARGUMENTS_NAN; + return QNaN; + } +//--- check sigma + if(sigma<=0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } + + error_code=ERR_OK; + +//--- prepare argument + double y=(x-mu)/sigma; +//--- check it + if(!MathIsValidNumber(y)) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } +//--- check overflow + y=MathAbs(y); + if(y>=2*MathSqrt(DBL_MAX)) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } +//--- return density + return TailLogValue(M_1_SQRT_2PI*MathExp(-0.5*y*y)/sigma,true,log_mode); + } +//+------------------------------------------------------------------+ +//| Normal probability density function (PDF) | +//+------------------------------------------------------------------+ +//| The function returns the probability density function | +//| of the Normal distribution with parameters mu and sigma. | +//| | +//| Arguments: | +//| x : Random variable | +//| mu : Mean | +//| sigma : Standard deviation (sigma>0) | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The probability density evaluated at x. | +//+------------------------------------------------------------------+ +double MathProbabilityDensityNormal(const double x,const double mu,const double sigma,int &error_code) + { + return MathProbabilityDensityNormal(x,mu,sigma,false,error_code); + } +//+------------------------------------------------------------------+ +//| Normal probability density function (PDF) | +//+------------------------------------------------------------------+ +//| The function calculates the probability density function of | +//| the Normal distribution with parameters mu and sigma | +//| for values in x. | +//| | +//| Arguments: | +//| x : Array with random variables | +//| mu : Mean | +//| sigma : Standard deviation (sigma>0) | +//| log_mode : Logarithm mode flag, if true it returns Log values | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathProbabilityDensityNormal(const double &x[],const double mu,const double sigma,const bool log_mode,double &result[]) + { +//--- check NaN + if(!MathIsValidNumber(mu) || !MathIsValidNumber(sigma)) + return false; +//--- check sigma + if(sigma<=0) + return false; + + int data_count=ArraySize(x); + if(data_count==0) + return false; + + int error_code=0; + ArrayResize(result,data_count); + + for(int i=0; i=2*MathSqrt(DBL_MAX)) + return false; + + //--- calculate density + result[i]=TailLogValue(M_1_SQRT_2PI*MathExp(-0.5*y*y)/sigma,true,log_mode); + } + return true; + } +//+------------------------------------------------------------------+ +//| Normal probability density function (PDF) | +//+------------------------------------------------------------------+ +//| The function calculates the probability density function of | +//| the Normal distribution with parameters mu and sigma | +//| for values in x[] array. | +//| | +//| Arguments: | +//| x : Array with random variables | +//| mu : Mean | +//| sigma : Standard deviation (sigma>0) | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathProbabilityDensityNormal(const double &x[],const double mu,const double sigma,double &result[]) + { + return MathProbabilityDensityNormal(x,mu,sigma,false,result); + } +//+------------------------------------------------------------------+ +//| Normal cumulative distribution function (CDF) | +//+------------------------------------------------------------------+ +//| The function returns the probability that an observation | +//| from the Normal distribution with parameters mu and sigma | +//| is less than or equal to x. | +//| | +//| Arguments: | +//| x : The desired quantile | +//| mu : Mean | +//| sigma : Standard deviation (must be positive) | +//| tail : Flag to calculate lower tail | +//| log_mode : Logarithm mode, if true it calculates Log values | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The value of the Normal cumulative distribution function with | +//| parameters mu and sigma, evaluated at x. | +//+------------------------------------------------------------------+ +//| Comment from original FORTRAN code | +//| https://www.netlib.org/toms-2014-06-10/639 | +//| https://www.netlib.org/toms-2014-06-10/715 | +//| | +//| This function evaluates the normal distribution function: | +//| | +//| / x | +//| 1 | -t*t/2 | +//| P(x) = ----------- | e dt | +//| sqrt(2 pi) | | +//| /-oo | +//| | +//| The main computation evaluates near-minimax approximations | +//| derived from those in "Rational Chebyshev approximations for | +//| the error function" by W. J. Cody, Math. Comp., 1969, 631-637. | +//| This transportable program uses rational functions that | +//| theoretically approximate the normal distribution function to | +//| at least 18 significant decimal digits. The accuracy achieved | +//| depends on the arithmetic system, the compiler, the intrinsic | +//| functions, and proper selection of the machine-dependent | +//| constants. | +//| | +//| Author: | +//| W. J. Cody, Mathematics and Computer Science Division | +//| Argonne National Laboratory, Argonne, IL 60439 | +//+------------------------------------------------------------------+ +double MathCumulativeDistributionNormal(const double x,const double mu,const double sigma,const bool tail,const bool log_mode,int &error_code) + { +//--- check NaN + if(!MathIsValidNumber(x) || !MathIsValidNumber(mu) || !MathIsValidNumber(sigma)) + { + error_code=ERR_ARGUMENTS_NAN; + return QNaN; + } +//--- check sigma + if(sigma<=0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } + + error_code=ERR_OK; +//--- prepare argument + double xx=(x-mu)/sigma; +//--- mathematical constants +//--- sqrpi = 1 / sqrt(2*pi), root32 = sqrt(32), and +//--- thrsh is the argument for which anorm = 0.75. + const double sqrpi=1.0/MathSqrt(2*M_PI); + const double thrsh = 0.66291e0; + const double root32= MathSqrt(32); +//--- machine-dependent constants +//--- data eps/5.96e-8/,xlow/-12.949e0/,xuppr/5.768e0/ + const double eps=1.11e-16; + const double xlow=-37.519; + const double xuppr=8.572; + int k; +//--- + double xsq=0.0; + double y=MathAbs(xx); + double xnum=0.0; + double xden=0.0; + double cdf=0.0; + double del=0.0; +//--- + if(y<=thrsh) + { + //--- evaluate for |x| <= 0.66291 + if(y>eps) + xsq=xx*xx; + + xnum = normal_cdf_a[4] * xsq; + xden = xsq; + for(k=0; k<3; k++) + { + xnum=(xnum+normal_cdf_a[k])*xsq; + xden=(xden+normal_cdf_b[k])*xsq; + } + cdf = xx*(xnum+normal_cdf_a[3])/(xden+normal_cdf_b[3]); + cdf = 0.5 + cdf; + } + else + if(y<=root32) + { + //--- evaluate for 0.66291 <= |x| <= sqrt(32) + xnum = normal_cdf_c[8]*y; + xden = y; + for(k=0; k<7; k++) + { + xnum=(xnum+normal_cdf_c[k])*y; + xden=(xden+normal_cdf_d[k])*y; + } + cdf=(xnum+normal_cdf_c[7])/(xden+normal_cdf_d[7]); + xsq=int(y*16)/16; + del=(y-xsq)*(y+xsq); + cdf=MathExp(-xsq*xsq*0.5)*MathExp(-del*0.5)*cdf; + if(xx>0.0) cdf=1.0-cdf; + } +//--- evaluate for |x| > sqrt(32) + else + { + cdf=0.0; + if((xx>=xlow) && (xx0.0) cdf=1.0-cdf; + } +//--- take into account round-off errors for probability + return TailLogValue(MathMin(cdf,1.0),tail,log_mode); + } +//+------------------------------------------------------------------+ +//| Normal cumulative distribution function (CDF) | +//+------------------------------------------------------------------+ +//| The function returns the probability that an observation | +//| from the Normal distribution with parameters mu and sigma | +//| is less than or equal to x. | +//| | +//| Arguments: | +//| x : The desired quantile | +//| mu : Mean | +//| sigma : Standard deviation (must be positive) | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The value of the Normal cumulative distribution function with | +//| parameters mu and sigma, evaluated at x. | +//+------------------------------------------------------------------+ +double MathCumulativeDistributionNormal(const double x,const double mu,const double sigma,int &error_code) + { + return MathCumulativeDistributionNormal(x,mu,sigma,true,false,error_code); + } +//+------------------------------------------------------------------+ +//| Normal cumulative distribution function (CDF) | +//+------------------------------------------------------------------+ +//| The function calculates the cumulative distribution function of | +//| the Normal distribution with parameters mu and sigma | +//| for values in x[] array. | +//| | +//| Arguments: | +//| x : Array with random variables | +//| mu : Mean | +//| sigma : Standard deviation (must be positive) | +//| tail : Flag to calculate lower tail | +//| log_mode : Logarithm mode, if true it calculates Log values | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathCumulativeDistributionNormal(const double &x[],const double mu,const double sigma,const bool tail,const bool log_mode,double &result[]) + { +//--- check NaN + if(!MathIsValidNumber(mu) || !MathIsValidNumber(sigma)) + return false; +//--- check sigma + if(sigma<=0) + return false; + + int data_count=ArraySize(x); + if(data_count==0) + return false; + + int error_code=0; + ArrayResize(result,data_count); + for(int i=0; ieps) + xsq=xx*xx; + + xnum = normal_cdf_a[4] * xsq; + xden = xsq; + for(k=0; k<3; k++) + { + xnum=(xnum+normal_cdf_a[k])*xsq; + xden=(xden+normal_cdf_b[k])*xsq; + } + cdf = xx*(xnum+normal_cdf_a[3])/(xden+normal_cdf_b[3]); + cdf = 0.5 + cdf; + } + else + if(y<=root32) + { + //--- evaluate for 0.66291 <= |x| <= sqrt(32) + xnum = normal_cdf_c[8]*y; + xden = y; + for(k=0; k<7; k++) + { + xnum=(xnum+normal_cdf_c[k])*y; + xden=(xden+normal_cdf_d[k])*y; + } + cdf=(xnum+normal_cdf_c[7])/(xden+normal_cdf_d[7]); + xsq=int(y*16)/16; + del=(y-xsq)*(y+xsq); + cdf=MathExp(-xsq*xsq*0.5)*MathExp(-del*0.5)*cdf; + if(xx>0.0) cdf=1.0-cdf; + } + //--- evaluate for |x| > sqrt(32) + else + { + cdf=0.0; + if((xx>=xlow) && (xx0.0) cdf=1.0-cdf; + } + //--- take into account round-off errors for probability + result[i]=TailLogValue(MathMin(cdf,1.0),tail,log_mode); + } + return true; + } +//+------------------------------------------------------------------+ +//| Normal cumulative distribution function (CDF) | +//+------------------------------------------------------------------+ +//| The function calculates the cumulative distribution function of | +//| the Normal distribution with parameters mu and sigma | +//| for values in x[] array. | +//| | +//| Arguments: | +//| x : Array with random variables | +//| mu : Mean | +//| sigma : Standard deviation (must be positive) | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathCumulativeDistributionNormal(const double &x[],const double mu,const double sigma,double &result[]) + { + return MathCumulativeDistributionNormal(x,mu,sigma,true,false,result); + } +//+------------------------------------------------------------------+ +//| Normal distribution quantile function (inverse CDF) | +//+------------------------------------------------------------------+ +//| The function returns the inverse cumulative distribution | +//| function of the Normal distribution with parameters mu and sigma | +//| for the desired probability. | +//| | +//| Arguments: | +//| probability : The desired probability | +//| mu : Mean | +//| sigma : Standard deviation (must be positive) | +//| tail : Flag to calculate lower tail | +//| log_mode : Logarithm mode,if true it calculates for Log values| +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The value of the inverse cumulative distribution function | +//| of the Normal distribution with parameters mu and sigma. | +//+------------------------------------------------------------------+ +//| Comment from original FORTRAN code | +//| https://www1.fpl.fs.fed.us/ni241.f | +//| Produces the normal deviate Z corresponding to a given lower | +//| tail area of P; Z is accurate to about 1 part in 10**16. | +//| Wichura, M.J. (1988). Algorithm AS 241: The Percentage Points of | +//| the Normal Distribution. Applied Statistics, v.37, N3, 477-484. | +//+------------------------------------------------------------------+ +double MathQuantileNormal(const double probability,const double mu,const double sigma,const bool tail,const bool log_mode,int &error_code) + { +//--- check NaN + if(!MathIsValidNumber(probability) || !MathIsValidNumber(mu) || !MathIsValidNumber(sigma)) + { + error_code=ERR_ARGUMENTS_NAN; + return QNaN; + } +//--- check sigma + if(sigma<=0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } + +//--- calculate real probability + double prob=TailLogProbability(probability,tail,log_mode); +//--- check probability range + if(prob<0.0 || prob>1.0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } +//--- f(0)=-infinity + if(prob==0.0) + { + error_code=ERR_RESULT_INFINITE; + return QNEGINF; + } +//--- f(1)=+infinity + if(prob==1.0) + { + error_code=ERR_RESULT_INFINITE; + return QPOSINF; + } + + error_code=ERR_OK; + + double q=prob-0.5; + double r=0; + double ppnd16=0.0; +//--- + if(MathAbs(q)<=0.425) + { + r=0.180625-q*q; + ppnd16=q*(((((((normal_q_a7*r+normal_q_a6)*r+normal_q_a5)*r+normal_q_a4)*r+normal_q_a3)*r+normal_q_a2)*r+normal_q_a1)*r+normal_q_a0)/ + (((((((normal_q_b7*r+normal_q_b6)*r+normal_q_b5)*r+normal_q_b4)*r+normal_q_b3)*r+normal_q_b2)*r+normal_q_b1)*r+1.0); + //--- + error_code=ERR_OK; + return mu+sigma*ppnd16; + } + else + { + if(q<0.0) + r=prob; + else + r=1.0-prob; + //--- + r=MathSqrt(-MathLog(r)); + //--- + if(r<=5.0) + { + r=r-1.6; + ppnd16=(((((((normal_q_c7*r+normal_q_c6)*r+normal_q_c5)*r+normal_q_c4)*r+normal_q_c3)*r+normal_q_c2)*r+normal_q_c1)*r+normal_q_c0)/ + (((((((normal_q_d7*r+normal_q_d6)*r+normal_q_d5)*r+normal_q_d4)*r+normal_q_d3)*r+normal_q_d2)*r+normal_q_d1)*r+1.0); + } + else + { + r=r-5.0; + ppnd16=(((((((normal_q_e7*r+normal_q_e6)*r+normal_q_e5)*r+normal_q_e4)*r+normal_q_e3)*r+normal_q_e2)*r+normal_q_e1)*r+normal_q_e0)/ + (((((((normal_q_f7*r+normal_q_f6)*r+normal_q_f5)*r+normal_q_f4)*r+normal_q_f3)*r+normal_q_f2)*r+normal_q_f1)*r+1.0); + } + //--- + if(q<0.0) + ppnd16=-ppnd16; + } +//--- return rescaled/shifted value + return mu+sigma*ppnd16; + } +//+------------------------------------------------------------------+ +//| Normal distribution quantile function (inverse CDF) | +//+------------------------------------------------------------------+ +//| The function returns the inverse cumulative distribution | +//| function of Normal distribution with parameters mu and sigma | +//| for the desired probability. | +//| | +//| Arguments: | +//| probability : The desired probability | +//| mu : Mean | +//| sigma : Standard deviation (must be positive) | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The value of the inverse cumulative distribution function | +//| of the Normal distribution with parameters mu and sigma. | +//+------------------------------------------------------------------+ +double MathQuantileNormal(const double probability,const double mu,const double sigma,int &error_code) + { + return MathQuantileNormal(probability,mu,sigma,true,false,error_code); + } +//+------------------------------------------------------------------+ +//| Normal distribution quantile function (inverse CDF) | +//+------------------------------------------------------------------+ +//| The function calculates the inverse cumulative distribution | +//| function of the Normal distribution with parameters mu and sigma | +//| for the probability values from array. | +//| | +//| Arguments: | +//| probability : Array with probabilities | +//| mu : Mean | +//| sigma : Standard deviation (must be positive) | +//| tail : Flag to calculate lower tail | +//| log_mode : Logarithm mode, if true it calculates Log values | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathQuantileNormal(const double &probability[],const double mu,const double sigma,const bool tail,const bool log_mode,double &result[]) + { +//--- check NaN + if(!MathIsValidNumber(mu) || !MathIsValidNumber(sigma)) + return false; +//--- check sigma + if(sigma<0) + return false; + + int data_count=ArraySize(probability); + if(data_count==0) + return false; + + int error_code=0; + ArrayResize(result,data_count); + +//--- case sigma==0 + if(sigma==0.0) + { + for(int i=0; i1.0) + return false; + + //--- f(0)=-infinity, f(1)=+infinity + if(prob==0.0 || prob==1.0) + { + if(prob==0.0) + result[i]=QNEGINF; + else + result[i]=QPOSINF; + } + else + { + double q=prob-0.5; + double r=0; + double ppnd16=0.0; + //--- + if(MathAbs(q)<=0.425) + { + r=0.180625-q*q; + ppnd16=q*(((((((normal_q_a7*r+normal_q_a6)*r+normal_q_a5)*r+normal_q_a4)*r+normal_q_a3)*r+normal_q_a2)*r+normal_q_a1)*r+normal_q_a0)/ + (((((((normal_q_b7*r+normal_q_b6)*r+normal_q_b5)*r+normal_q_b4)*r+normal_q_b3)*r+normal_q_b2)*r+normal_q_b1)*r+1.0); + //--- set rescaled/shifted value + result[i]=mu+sigma*ppnd16; + } + else + { + if(q<0.0) + r=prob; + else + r=1.0-prob; + //--- + r=MathSqrt(-MathLog(r)); + //--- + if(r<=5.0) + { + r=r-1.6; + ppnd16=(((((((normal_q_c7*r+normal_q_c6)*r+normal_q_c5)*r+normal_q_c4)*r+normal_q_c3)*r+normal_q_c2)*r+normal_q_c1)*r+normal_q_c0)/ + (((((((normal_q_d7*r+normal_q_d6)*r+normal_q_d5)*r+normal_q_d4)*r+normal_q_d3)*r+normal_q_d2)*r+normal_q_d1)*r+1.0); + } + else + { + r=r-5.0; + ppnd16=(((((((normal_q_e7*r+normal_q_e6)*r+normal_q_e5)*r+normal_q_e4)*r+normal_q_e3)*r+normal_q_e2)*r+normal_q_e1)*r+normal_q_e0)/ + (((((((normal_q_f7*r+normal_q_f6)*r+normal_q_f5)*r+normal_q_f4)*r+normal_q_f3)*r+normal_q_f2)*r+normal_q_f1)*r+1.0); + } + //--- + if(q<0.0) + ppnd16=-ppnd16; + } + //--- set rescaled/shifted value + result[i]=mu+sigma*ppnd16; + } + } + return true; + } +//+------------------------------------------------------------------+ +//| Normal distribution quantile function (inverse CDF) | +//+------------------------------------------------------------------+ +//| The function calculates the inverse cumulative distribution | +//| function of the Normal distribution with parameters mu and sigma | +//| for the probability values from array. | +//| | +//| Arguments: | +//| probability : Array with probabilities | +//| mu : Mean | +//| sigma : Standard deviation (must be positive) | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathQuantileNormal(const double &probability[],const double mu,const double sigma,double &result[]) + { + return MathQuantileNormal(probability,mu,sigma,true,false,result); + } +//+------------------------------------------------------------------+ +//| Random variate from the Normal distribution | +//+------------------------------------------------------------------+ +//| Compute the random variable from the Normal distribution | +//| with given mean mu and standard deviation sigma. | +//| | +//| Arguments: | +//| mu : Mean | +//| sigma : Standard deviation (must be positive) | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The random value with Normal distribution. | +//+------------------------------------------------------------------+ +double MathRandomNormal(const double mu,const double sigma,int &error_code) + { +//--- check NaN + if(!MathIsValidNumber(mu) || !MathIsValidNumber(sigma)) + { + error_code=ERR_ARGUMENTS_NAN; + return QNaN; + } +//--- check sigma + if(sigma<0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } + + error_code=ERR_OK; +//--- + if(sigma==0.0) + return mu; +//--- generate random number + double rnd=MathRandomNonZero(); +//--- return normal random using quantile + return MathQuantileNormal(rnd,mu,sigma,true,false,error_code); + } +//+------------------------------------------------------------------+ +//| Random variate from the Normal distribution | +//+------------------------------------------------------------------+ +//| Generates random variables from the Normal distribution with | +//| parameters mu and sigma. | +//| | +//| Arguments: | +//| mu : Mean | +//| sigma : Standard deviation (must be positive) | +//| data_count : Number of values needed | +//| result : Output array with random values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathRandomNormal(const double mu,const double sigma,const int data_count,double &result[]) + { +//--- check NaN + if(!MathIsValidNumber(mu) || !MathIsValidNumber(sigma)) + return false; +//--- check sigma + if(sigma<0) + return false; +//--- prepare output array and calculate random values + ArrayResize(result,data_count); + if(sigma==0.0) + { + for(int i=0; i0) | +//| mean : Variable for mean value (1st moment) | +//| variance : Variable for variance value (2nd moment) | +//| skewness : Variable for skewness value (3rd moment) | +//| kurtosis : Variable for kurtosis value (4th moment) | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| true if moments calculated successfully, otherwise false. | +//+------------------------------------------------------------------+ +bool MathMomentsNormal(const double mu,const double sigma,double &mean,double &variance,double &skewness,double &kurtosis,int &error_code) + { +//--- default values + mean =QNaN; + variance=QNaN; + skewness=QNaN; + kurtosis=QNaN; +//--- check NaN + if(!MathIsValidNumber(mu) || !MathIsValidNumber(sigma)) + { + error_code=ERR_ARGUMENTS_NAN; + return false; + } +//--- check sigma + if(sigma<=0) + { + error_code=ERR_ARGUMENTS_INVALID; + return false; + } + + error_code=ERR_OK; +//--- calculate moments + mean =mu; + variance=MathPow(sigma,2); + skewness=0; + kurtosis=0; +//--- successful + return true; + } +//+------------------------------------------------------------------+ diff --git a/Math/Stat/Poisson.mqh b/Math/Stat/Poisson.mqh new file mode 100644 index 0000000..afefa04 --- /dev/null +++ b/Math/Stat/Poisson.mqh @@ -0,0 +1,791 @@ +//+------------------------------------------------------------------+ +//| Poisson.mqh | +//| Copyright 2000-2024, MetaQuotes Ltd. | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#include "Math.mqh" +#include "Gamma.mqh" + +//+------------------------------------------------------------------+ +//| Poisson probability mass function (PDF) | +//+------------------------------------------------------------------+ +//| The function returns the probability mass function | +//| of the Poisson distribution with parameter lambda. | +//| | +//| Arguments: | +//| x : Random variable | +//| lambda : Mean | +//| log_mode : Logarithm mode flag, if true it returns Log values | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The probability mass evaluated at x. | +//+------------------------------------------------------------------+ +double MathProbabilityDensityPoisson(const double x,const double lambda,const bool log_mode,int &error_code) + { +//--- check NaN + if(!MathIsValidNumber(x) || !MathIsValidNumber(lambda)) + { + error_code=ERR_ARGUMENTS_NAN; + return QNaN; + } +//--- lambda must be positive, x must be integer + if(lambda<=0.0 || x!=MathRound(x)) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } + + error_code=ERR_OK; +//--- check x + if(x<0.0) + return TailLog0(true,log_mode); + +//--- calculate log pdf using LogGamma + double log_pdf=-lambda+x*MathLog(lambda)-MathGammaLog(x+1.0); + if(log_mode) + return log_pdf; +//--- return density + return MathExp(log_pdf); + } +//+------------------------------------------------------------------+ +//| Poisson probability mass function (PDF) | +//+------------------------------------------------------------------+ +//| The function returns the probability mass function | +//| of the Poisson distribution with parameter lambda. | +//| | +//| Arguments: | +//| x : Random variable | +//| lambda : Mean | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The probability mass evaluated at x. | +//+------------------------------------------------------------------+ +double MathProbabilityDensityPoisson(const double x,const double lambda,int &error_code) + { + return MathProbabilityDensityPoisson(x,lambda,false,error_code); + } +//+------------------------------------------------------------------+ +//| Poisson probability mass function (PDF) | +//+------------------------------------------------------------------+ +//| The function calculates the probability density function of | +//| the Poisson distribution with parameter lambda for values in x[].| +//| | +//| Arguments: | +//| x : Array with random variables | +//| lambda : Mean | +//| log_mode : Logarithm mode flag, if true it returns Log values | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathProbabilityDensityPoisson(const double &x[],const double lambda,const bool log_mode,double &result[]) + { +//--- check NaN + if(!MathIsValidNumber(lambda)) + return false; +//--- lambda must be positive + if(lambda<=0.0) + return false; + + int data_count=ArraySize(x); + if(data_count==0) + return false; + + ArrayResize(result,data_count); + for(int i=0; i1.0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } +//--- check + if(prob==1.0) + { + error_code=ERR_RESULT_INFINITE; + return QPOSINF; + } + error_code=ERR_OK; + if(prob==0.0) + return 0.0; + + prob*=1-1000*DBL_EPSILON; + int err_code=0; + int j=0; + const int max_terms=500; + double coef_lambda=MathExp(-lambda); + double pwr_lambda=1.0; + double inverse_fact=1.0; + double sum=0; +//--- direct calculation of the quantile + while(sum0) + { + pwr_lambda*=lambda; + inverse_fact/=j; + } + sum+=coef_lambda*pwr_lambda*inverse_fact; + j++; + } +//--- check convergence + if(j1.0) + return false; + else + if(prob==1.0) + result[i]=QPOSINF; + if(prob==0.0) + result[i]=0; + else + { + prob*=1-1000*DBL_EPSILON; + int err_code=0; + int j=0; + double sum=0.0; + const int max_terms=500; + double pwr_lambda=1.0; + double inverse_fact=1.0; + //--- direct calculation + while(sum0) + { + pwr_lambda*=lambda; + inverse_fact/=j; + } + sum+=coef_lambda*pwr_lambda*inverse_fact; + j++; + } + //--- check convergence + if(j=1.0 || r2==0.0); + //--- Box-Muller transform + f=MathSqrt(-2.0*MathLog(r2)/r2); + double snorm=f*x2; + //--- normal sample + g=lambda+s*snorm; + + if(0.0<=g) + { + value=(int)(g); + //--- immediate acceptance if large enough + if(l<=value) + return value; + //--- squeeze acceptance + fk=(double)(value); + difmuk=lambda-fk; + u=MathRandomNonZero(); + //--- + if(difmuk*difmuk*difmuk<=d*u) + return value; + } + //--- preparation for steps P and Q + double omega=0.3989423/s; + double b1 = 0.04166667/lambda; + double b2 = 0.3*b1*b1; + double c3 = 0.1428571*b1*b2; + double c2 = b2 - 15.0*c3; + double c1 = b1 - 6.0*b2 + 45.0*c3; + double c0 = 1.0 - b1 + 3.0*b2 - 15.0*c3; + double c=0.1069/lambda; + double del=0; + + if(0.0<=g) + { + kflag=0; + + if(value<10) + { + px = -lambda; + py = MathPow(lambda,value)/MathFactorial(value); + } + else + { + del = 0.8333333E-01/fk; + del = del - 4.8*del*del*del; + v=difmuk/fk; + + if(0.25 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include \ No newline at end of file diff --git a/Math/Stat/T.mqh b/Math/Stat/T.mqh new file mode 100644 index 0000000..9bd1d87 --- /dev/null +++ b/Math/Stat/T.mqh @@ -0,0 +1,654 @@ +//+------------------------------------------------------------------+ +//| T.mqh | +//| Copyright 2000-2024, MetaQuotes Ltd. | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#include "Math.mqh" +#include "Gamma.mqh" + +//+------------------------------------------------------------------+ +//| T probability density function (PDF) | +//+------------------------------------------------------------------+ +//| The function returns the probability density function | +//| of the T-distribution with parameter nu. | +//| | +//| Arguments: | +//| x : Random variable | +//| nu : Degrees of freedom | +//| log_mode : Logarithm mode, if true it calculates Log values | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The probability density evaluated at x. | +//+------------------------------------------------------------------+ +double MathProbabilityDensityT(const double x,const double nu,const bool log_mode,int &error_code) + { +//--- check NaN + if(!MathIsValidNumber(x) || !MathIsValidNumber(nu)) + { + error_code=ERR_ARGUMENTS_NAN; + return QNaN; + } +//--- check nu + if(nu!=MathRound(nu) || nu<=0.0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } + + error_code=ERR_OK; +//--- calculate T density + double pdf=MathExp(MathGammaLog((nu+1.0)*0.5)-MathGammaLog(nu*0.5)); + pdf=pdf/(MathSqrt(nu*M_PI)*MathPow(1+x*x/nu,(nu+1.0)*0.5)); +//--- return density + return TailLogValue(pdf,true,log_mode); + } +//+------------------------------------------------------------------+ +//| T probability density function (PDF) | +//+------------------------------------------------------------------+ +//| The function returns the probability density function | +//| of the T-distribution with parameter nu. | +//| | +//| Arguments: | +//| x : Random variable | +//| nu : Degrees of freedom | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The probability density evaluated at x. | +//+------------------------------------------------------------------+ +double MathProbabilityDensityT(const double x,const double nu,int &error_code) + { + return MathProbabilityDensityT(x,nu,false,error_code); + } +//+------------------------------------------------------------------+ +//| T probability density function (PDF) | +//+------------------------------------------------------------------+ +//| The function calculates the probability density function of | +//| the T distribution with parameter nu for values in x[] array. | +//| | +//| Arguments: | +//| x : Array with random variables | +//| nu : Degrees of freedom | +//| log_mode : Logarithm mode flag, if true it returns Log values | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathProbabilityDensityT(const double &x[],const double nu,const bool log_mode,double &result[]) + { +//--- check NaN + if(!MathIsValidNumber(nu)) + return false; +//--- check nu + if(nu!=MathRound(nu) || nu<=0.0) + return false; + + int data_count=ArraySize(x); + if(data_count==0) + return false; + + int error_code=0; + ArrayResize(result,data_count); + for(int i=0; i0.0) + cdf=1.0-cdf; +//--- take into account round-off errors for probability + return TailLogValue(MathMin(cdf,1.0),tail,log_mode); + } +//+------------------------------------------------------------------+ +//| T cumulative distribution function (CDF) | +//+------------------------------------------------------------------+ +//| The function returns the probability that an observation from | +//| T-distribution with parameter nu is less than or equal to x. | +//| | +//| Arguments: | +//| x : The desired quantile | +//| nu : Degrees of freedom | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The value of T cumulative distribution function with parameter | +//| nu, evaluated at x. | +//+------------------------------------------------------------------+ +double MathCumulativeDistributionT(const double x,const double nu,int &error_code) + { + return MathCumulativeDistributionT(x,nu,true,false,error_code); + } +//+------------------------------------------------------------------+ +//| T cumulative distribution function (CDF) | +//+------------------------------------------------------------------+ +//| The function calculates the cumulative distribution function of | +//| the T distribution with parameter nu for values in x. | +//| | +//| Arguments: | +//| x : Array with random variables | +//| nu : Degrees of freedom | +//| tail : Flag to calculate lower tail | +//| log_mode : Logarithm mode, if true it calculates Log values | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathCumulativeDistributionT(const double &x[],const double nu,const bool tail,const bool log_mode,double &result[]) + { +//--- check NaN + if(!MathIsValidNumber(nu)) + return false; +//--- check nu (must be positive integer) + if(nu!=MathRound(nu) || nu<=0.0) + return false; + + int data_count=ArraySize(x); + if(data_count==0) + return false; + + int error_code=0; + ArrayResize(result,data_count); + for(int i=0; i0.0) + cdf=1.0-cdf; + //--- take into account round-off errors for probability + result[i]=TailLogValue(MathMin(cdf,1.0),tail,log_mode); + } + } + return true; + } +//+------------------------------------------------------------------+ +//| T cumulative distribution function (CDF) | +//+------------------------------------------------------------------+ +//| The function calculates the cumulative distribution function of | +//| the T distribution with parameter nu for values in x[] array. | +//| | +//| Arguments: | +//| x : Array with random variables | +//| nu : Degrees of freedom | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathCumulativeDistributionT(const double &x[],const double nu,double &result[]) + { + return MathCumulativeDistributionT(x,nu,true,false,result); + } +//+------------------------------------------------------------------+ +//| T distribution quantile function (inverse CDF) | +//+------------------------------------------------------------------+ +//| The function returns the inverse cumulative distribution | +//| function of the T distribution with parameter nu for the desired | +//| probability. | +//| | +//| Arguments: | +//| probability : The desired probability | +//| nu : Degrees of freedom | +//| tail : Flag to calculate lower tail | +//| log_mode : Logarithm mode, if true it calculates Log values | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The value of the inverse cumulative distribution function | +//| of the T-distribution with parameter nu. | +//+------------------------------------------------------------------+ +double MathQuantileT(const double probability,const double nu,const bool tail,const bool log_mode,int &error_code) + { +//--- check NaN + if(!MathIsValidNumber(probability) || !MathIsValidNumber(nu)) + { + error_code=ERR_ARGUMENTS_NAN; + return QNaN; + } +//--- check nu + if(nu!=MathRound(nu) || nu<0.0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } +//--- calculate real probability + double prob=TailLogProbability(probability,tail,log_mode); +//--- check probability range + if(prob<0.0 || prob>1.0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } + +//--- check cases when probability==0 or 1 + if(prob==0.0 || prob==1.0) + { + error_code=ERR_RESULT_INFINITE; + //--- + if(prob==0.0) + return(QNEGINF); + else + return(QPOSINF); + } + + error_code=ERR_OK; +//--- special case nu=1 + if(nu==1.0) + return MathTan(M_PI*(prob-0.5)); +//--- special case + if(prob==0.5) + return 0.0; +//--- + int max_iterations=50; + int iterations=0; +//--- initial values + double h=1.0; + double h_min=10E-20; + double x=0.5; + int err_code=0; +//--- Newton iterations + while(iterationsh_min && MathAbs(h)>MathAbs(h_min*x))==false) + break; + //--- calculate pdf and cdf + double pdf=MathProbabilityDensityT(x,nu,err_code); + double cdf=MathCumulativeDistributionT(x,nu,err_code); + //--- calculate ratio + h=(cdf-prob)/pdf; + //--- + double x_new=x-h; + //--- check x + if(x_new<0.0) + x_new=x*0.1; + else + if(x_new>1.0) + x_new=1.0-(1.0-x)*0.1; + + x=x_new; + + iterations++; + } +//--- check convergence + if(iterations1.0) + return false; + + //--- special case p=0.5 + if(prob==0.5) + result[i]=0.0; + else + if(prob==0.0) + result[i]=QNEGINF; + else + if(prob==1.0) + result[i]=QPOSINF; + else + { + //--- special case nu=1 + if(nu==1.0) + result[i]=MathTan(M_PI*(prob-0.5)); + else + { + int max_iterations=50; + int iterations=0; + //--- initial values + double h=1.0; + double h_min=10E-18; + double x=0.5; + int err_code=0; + //--- Newton iterations + while(iterationsh_min && MathAbs(h)>MathAbs(h_min*x))==false) + break; + //--- calculate pdf and cdf + double pdf=MathProbabilityDensityT(x,nu,err_code); + double cdf=MathCumulativeDistributionT(x,nu,err_code); + //--- calculate ratio + h=(cdf-prob)/pdf; + //--- + double x_new=x-h; + //--- check x + if(x_new<0.0) + x_new=x*0.1; + else + if(x_new>1.0) + x_new=1.0-(1.0-x)*0.1; + + if (MathAbs(x_new-x)<10E-15) + break; + + x=x_new; + + iterations++; + } + //--- check convergence + if(iterations=1.0 || r2==0.0); +//--- generate normal and gamma random variables + double rnd_normal=x2*MathSqrt(-2.0*MathLog(r2)/r2); + double rnd_gamma=MathRandomGamma(nu*0.5,1,error_code); +//--- calculate ratio + double result=0; + if(rnd_gamma!=0) + result=MathSqrt(nu*0.5)*rnd_normal/MathSqrt(rnd_gamma); + return(result); + } +//+------------------------------------------------------------------+ +//| Random variate from the T distribution | +//+------------------------------------------------------------------+ +//| Generates random variables from the T distribution with | +//| parameter nu. | +//| | +//| Arguments: | +//| nu : Degrees of freedom | +//| data_count : Number of values needed | +//| result : Output array with random values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathRandomT(const double nu,const int data_count,double &result[]) + { +//--- check NaN + if(!MathIsValidNumber(nu)) + return false; +//--- check arguments + if(nu!=MathRound(nu) || nu<=0.0) + return false; + + int error_code=0; +//--- prepare output array and calculate random values + ArrayResize(result,data_count); + for(int i=0; i=1.0 || r2==0.0); + //--- generate normal and gamma random variables + double rnd_normal=x2*MathSqrt(-2.0*MathLog(r2)/r2); + double rnd_gamma=MathRandomGamma(nu*0.5,1,error_code); + //--- calculate ratio + double rnd=0; + if(rnd_gamma!=0) + rnd=MathSqrt(nu*0.5)*rnd_normal/MathSqrt(rnd_gamma); + result[i]=rnd; + } + return true; + } +//+------------------------------------------------------------------+ +//| T distribution moments | +//+------------------------------------------------------------------+ +//| The function calculates 4 first moments of the T distribution | +//| with parameter nu. | +//| | +//| Arguments: | +//| nu : Degrees of freedom | +//| mean : Variable for mean value (1st moment) | +//| variance : Variable for variance value (2nd moment) | +//| skewness : Variable for skewness value (3rd moment) | +//| kurtosis : Variable for kurtosis value (4th moment) | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| true if moments calculated successfully, otherwise false. | +//+------------------------------------------------------------------+ +double MathMomentsT(const double nu,double &mean,double &variance,double &skewness,double &kurtosis,int &error_code) + { +//--- default values + mean =QNaN; + variance=QNaN; + skewness=QNaN; + kurtosis=QNaN; +//--- check NaN + if(!MathIsValidNumber(nu)) + { + error_code=ERR_ARGUMENTS_NAN; + return QNaN; + } +//--- check nu + if(nu!=MathRound(nu) || nu<0.0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } + + error_code=ERR_OK; +//--- calculate moments + mean=0; + if(nu>2) + variance=nu/(nu-2); + skewness=0; + if(nu>4) + kurtosis=6/(nu-4); +//--- successful + return true; + } +//+------------------------------------------------------------------+ diff --git a/Math/Stat/Uniform.mqh b/Math/Stat/Uniform.mqh new file mode 100644 index 0000000..26b0473 --- /dev/null +++ b/Math/Stat/Uniform.mqh @@ -0,0 +1,539 @@ +//+------------------------------------------------------------------+ +//| Uniform.mqh | +//| Copyright 2000-2024, MetaQuotes Ltd. | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#include "Math.mqh" + +//+------------------------------------------------------------------+ +//| Uniform probability density function (PDF) | +//+------------------------------------------------------------------+ +//| The function returns the probability density function of the | +//| Uniform distribution with parameters a and b. | +//| | +//| Arguments: | +//| x : Random variable | +//| a : Lower endpoint (minimum) | +//| b : Upper endpoint (maximum) | +//| log_mode : Logarithm mode flag, if true it returns Log values | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The probability density evaluated at x. | +//+------------------------------------------------------------------+ +double MathProbabilityDensityUniform(const double x,const double a,const double b,const bool log_mode,int &error_code) + { +//--- check NaN + if(!MathIsValidNumber(x) || !MathIsValidNumber(a) || !MathIsValidNumber(b)) + { + error_code=ERR_ARGUMENTS_NAN; + return QNaN; + } +//--- check range + if(b<=a) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } + + error_code=ERR_OK; +//--- check ranges + if(x>=a && x<=b) + return TailLogValue(1.0/(b-a),true,log_mode); +//--- otherwise 0 + return TailLog0(true,log_mode); + } +//+------------------------------------------------------------------+ +//| Uniform probability density function (PDF) | +//+------------------------------------------------------------------+ +//| The function returns the probability density function of the | +//| Uniform distribution with parameters a and b. | +//| | +//| Arguments: | +//| x : Random variable | +//| a : Lower endpoint (minimum) | +//| b : Upper endpoint (maximum) | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The probability density evaluated at x. | +//+------------------------------------------------------------------+ +double MathProbabilityDensityUniform(const double x,const double a,const double b,int &error_code) + { + return MathProbabilityDensityUniform(x,a,b,false,error_code); + } +//+------------------------------------------------------------------+ +//| Uniform probability density function (PDF) | +//+------------------------------------------------------------------+ +//| The function calculates the probability density function of the | +//| Uniform distribution with parameters a and b for values in x[]. | +//| | +//| Arguments: | +//| x : Array with random variables | +//| a : Lower endpoint (minimum) | +//| b : Upper endpoint (maximum) | +//| log_mode : Logarithm mode flag, if true it returns Log values | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathProbabilityDensityUniform(const double &x[],const double a,const double b,const bool log_mode,double &result[]) + { +//--- check NaN + if(!MathIsValidNumber(a) || !MathIsValidNumber(b)) + return false; +//--- check range + if(b<=a) + return false; + + int data_count=ArraySize(x); + if(data_count==0) + return false; + + int error_code=0; + ArrayResize(result,data_count); + for(int i=0; i=a && x_arg<=b) + result[i]=TailLogValue(1.0/(b-a),true,log_mode); + else + result[i]=TailLog0(true,log_mode); + } + return true; + } +//+------------------------------------------------------------------+ +//| Uniform probability density function (PDF) | +//+------------------------------------------------------------------+ +//| The function calculates the probability density function of the | +//| Uniform distribution with parameters a and b for values in x[]. | +//| | +//| Arguments: | +//| x : Array with random variables | +//| mu : Mean | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathProbabilityDensityUniform(const double &x[],const double a,const double b,double &result[]) + { + return MathProbabilityDensityUniform(x,a,b,false,result); + } +//+------------------------------------------------------------------+ +//| Uniform cumulative distribution function (CDF) | +//+------------------------------------------------------------------+ +//| The function returns the cumulative distribution function | +//| of the Uniform distribution with parameters a and b. | +//| | +//| Arguments: | +//| x : The desired quantile | +//| a : Lower endpoint (minimum) | +//| b : Upper endpoint (maximum) | +//| tail : Flag to calculate lower tail | +//| log_mode : Logarithm mode flag,if true it calculates Log values| +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The value of the Uniform cumulative distribution function with | +//| parameters a and b, evaluated at x. | +//+------------------------------------------------------------------+ +double MathCumulativeDistributionUniform(const double x,const double a,const double b,const bool tail,const bool log_mode,int &error_code) + { +//--- check parameters + if(!MathIsValidNumber(x) || !MathIsValidNumber(a) || !MathIsValidNumber(b)) + { + error_code=ERR_ARGUMENTS_NAN; + return QNaN; + } +//--- check ranges + if(b=a && x<=b) + return TailLogValue(MathMin((x-a)/(b-a),1.0),tail,log_mode); + + if(x>b) + return TailLog1(tail,log_mode); + return TailLog0(tail,log_mode); + } +//+------------------------------------------------------------------+ +//| Uniform cumulative distribution function (CDF) | +//+------------------------------------------------------------------+ +//| The function returns the cumulative distribution function of | +//| the Uniform distribution with parameters a and b. | +//| | +//| Arguments: | +//| x : The desired quantile | +//| a : Lower endpoint (minimum) | +//| b : Upper endpoint (maximum) | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The value of the Uniform cumulative distribution function with | +//| parameters a and b, evaluated at x. | +//+------------------------------------------------------------------+ +double MathCumulativeDistributionUniform(const double x,const double a,const double b,int &error_code) + { + return MathCumulativeDistributionUniform(x,a,b,true,false,error_code); + } +//+------------------------------------------------------------------+ +//| Uniform cumulative distribution function (CDF) | +//+------------------------------------------------------------------+ +//| The function calculates the cumulative distribution function of | +//| the Uniform distribution with parameters a and b for values in x.| +//| | +//| Arguments: | +//| x : Array with random variables | +//| a : Mean | +//| b : Scale | +//| tail : Flag to calculate lower tail | +//| log_mode : Logarithm mode flag,if true it calculates Log values| +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathCumulativeDistributionUniform(const double &x[],const double a,const double b,const bool tail,const bool log_mode,double &result[]) + { +//--- check parameters + if(!MathIsValidNumber(a) || !MathIsValidNumber(b)) + return false; +//--- check ranges + if(b=a && x_arg<=b) + result[i]=TailLogValue(MathMin((x_arg-a)/(b-a),1.0),tail,log_mode); + else + { + if(x_arg>b) + result[i]=TailLog1(tail,log_mode); + else + result[i]=TailLog0(tail,log_mode); + } + } + return true; + } +//+------------------------------------------------------------------+ +//| Uniform cumulative distribution function (CDF) | +//+------------------------------------------------------------------+ +//| The function calculates the cumulative distribution function of | +//| the Uniform distribution with parameters a and b for values in x.| +//| | +//| Arguments: | +//| x : Array with random variables | +//| a : Mean | +//| b : Scale | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathCumulativeDistributionUniform(const double &x[],const double a,const double b,double &result[]) + { + return MathCumulativeDistributionUniform(x,a,b,true,false,result); + } +//+------------------------------------------------------------------+ +//| Uniform distribution quantile function (inverse CDF) | +//+------------------------------------------------------------------+ +//| The function returns the inverse cumulative distribution | +//| function of the Uniform distribution with parameters a and b | +//| for the desired probability. | +//| | +//| Arguments: | +//| probability : The desired probability | +//| a : Lower endpoint (minimum) | +//| b : Upper endpoint (maximum) | +//| tail : Flag to calculate lower tail | +//| log_mode : Logarithm mode,if true it calculates for Log values| +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The value of the inverse cumulative distribution function | +//| of Uniform distribution with parameters a and b. | +//+------------------------------------------------------------------+ +double MathQuantileUniform(const double probability,const double a,const double b,const bool tail,const bool log_mode,int &error_code) + { + if(log_mode==true) + { + if(probability==QNEGINF) + return 0.0; + } +//--- check parameters + if(!MathIsValidNumber(a) || !MathIsValidNumber(b)) + { + error_code=ERR_ARGUMENTS_NAN; + return QNaN; + } +//--- check bounds + if(b1.0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } + + error_code=ERR_OK; + + if(prob==0.0) + return a; + else + if(prob==1.0) + return b; + +//--- return quantile + return a+prob*(b-a); + } +//+------------------------------------------------------------------+ +//| Uniform distribution quantile function (inverse CDF) | +//+------------------------------------------------------------------+ +//| The function returns the inverse cumulative distribution | +//| function of the Uniform distribution with parameters a and b | +//| for the desired probability. | +//| | +//| Arguments: | +//| probability : The desired probability | +//| a : Lower endpoint (minimum) | +//| b : Upper endpoint (maximum) | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The value of the inverse cumulative distribution function | +//| of Uniform distribution with parameters a and b. | +//+------------------------------------------------------------------+ +double MathQuantileUniform(const double probability,const double a,const double b,int &error_code) + { + return MathQuantileUniform(probability,a,b,true,false,error_code); + } +//+------------------------------------------------------------------+ +//| Uniform distribution quantile function (inverse CDF) | +//+------------------------------------------------------------------+ +//| The function calculates the inverse cumulative distribution | +//| function of Uniform distribution with parameters a and b | +//| for values from the probability[] array. | +//| | +//| Arguments: | +//| probability : Array with probabilities | +//| a : Lower endpoint (minimum) | +//| b : Upper endpoint (maximum) | +//| tail : Flag to calculate lower tail | +//| log_mode : Logarithm mode, if true it calculates Log values | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathQuantileUniform(const double &probability[],const double a,const double b,const bool tail,const bool log_mode,double &result[]) + { +//--- check parameters + if(!MathIsValidNumber(a) || !MathIsValidNumber(b)) + return false; +//--- check ranges + if(b1.0) + return false; + + //--- check bounds + if(b==a) + result[i]=a; + else + if(prob==0.0) + result[i]=a; + else + if(prob==1.0) + result[i]=b; + else + //--- quantile + result[i]=(a+prob*(b-a)); + } + } + return true; + } +//+------------------------------------------------------------------+ +//| Uniform distribution quantile function (inverse CDF) | +//+------------------------------------------------------------------+ +//| The function calculates the inverse cumulative distribution | +//| function of Uniform distribution with parameters a and b | +//| for values from the probability[] array. | +//| | +//| Arguments: | +//| probability : Array with probabilities | +//| a : Lower endpoint (minimum) | +//| b : Upper endpoint (maximum) | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathQuantileUniform(const double &probability[],const double a,const double b,double &result[]) + { + return MathQuantileUniform(probability,a,b,true,false,result); + } +//+------------------------------------------------------------------+ +//| Random variate from the Uniform distribution | +//+------------------------------------------------------------------+ +//| Computes the random variable from the Uniform distribution | +//| with parameters a and b. | +//| | +//| Arguments: | +//| a : Lower endpoint (minimum) | +//| b : Upper endpoint (maximum) | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The random value with uniform distribution. | +//+------------------------------------------------------------------+ +double MathRandomUniform(const double a,const double b,int &error_code) + { +//--- check NaN + if(!MathIsValidNumber(a) || !MathIsValidNumber(b)) + { + error_code=ERR_ARGUMENTS_NAN; + return QNaN; + } +//--- check upper bound + if(b0) | +//| b : Scale parameter of the distribution (b>0) | +//| log_mode : Logarithm mode flag, if true it returns Log values | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The probability density evaluated at x. | +//+------------------------------------------------------------------+ +double MathProbabilityDensityWeibull(const double x,const double a,const double b,const bool log_mode,int &error_code) + { +//--- f(-infinity)=f(infinity)=0 + if(x==QPOSINF || x==QNEGINF) + { + error_code=ERR_OK; + return TailLog0(true,log_mode); + } +//--- check parameters + if(!MathIsValidNumber(x) || !MathIsValidNumber(a) || !MathIsValidNumber(b)) + { + error_code=ERR_ARGUMENTS_NAN; + return QNaN; + } +//--- a and b must be positive + if(a<=0 || b<=0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } + + error_code=ERR_OK; +//--- check x + if(x<=0) + return TailLog0(true,log_mode); +//--- calculate factor + double pwr=MathPow(x/b,a-1); + double pdf=(a/b)*pwr*MathExp(-(x/b)*pwr); + if(log_mode==true) + return MathLog(pdf); +//--- return density + return pdf; + } +//+------------------------------------------------------------------+ +//| Weibull probability density function (PDF) | +//+------------------------------------------------------------------+ +//| The function returns the probability density function | +//| of the Weibull distribution with parameters a and b. | +//| f(x,a,b)=[(a/b)*(x/b)^(a-1)]*exp(-(x/b)^a) | +//| Arguments: | +//| x : Random variable | +//| a : Shape parameter of the distribution (a>0) | +//| b : Scale parameter of the distribution (b>0) | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The probability density evaluated at x. | +//+------------------------------------------------------------------+ +double MathProbabilityDensityWeibull(const double x,const double a,const double b,int &error_code) + { + return MathProbabilityDensityWeibull(x,a,b,false,error_code); + } +//+------------------------------------------------------------------+ +//| Weibull probability density function (PDF) | +//+------------------------------------------------------------------+ +//| The function calculates the probability density function of the | +//| Weibull distribution with parameters a and b for values in x[]. | +//| | +//| Arguments: | +//| x : Array with random variables | +//| a : Shape parameter of the distribution (a>0) | +//| b : Scale parameter of the distribution (b>0) | +//| log_mode : Logarithm mode flag, if true it returns Log values | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathProbabilityDensityWeibull(const double &x[],const double a,const double b,const bool log_mode,double &result[]) + { +//--- check NaN + if(!MathIsValidNumber(a) || !MathIsValidNumber(b)) + return false; +//--- a and b must be positive + if(a<=0 || b<=0) + return false; + + int data_count=ArraySize(x); + if(data_count==0) + return false; + + int error_code=0; + ArrayResize(result,data_count); + for(int i=0; i0) | +//| b : Scale parameter of the distribution (b>0) | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathProbabilityDensityWeibull(const double &x[],const double a,const double b,double &result[]) + { + return MathProbabilityDensityWeibull(x,a,b,false,result); + } +//+------------------------------------------------------------------+ +//| Weibull cumulative distribution function (CDF) | +//+------------------------------------------------------------------+ +//| The function returns the probability that an observation | +//| from the Weibull distribution with parameters a and b | +//| is less than or equal to x. | +//| | +//| Arguments: | +//| x : The desired quantile | +//| a : Shape parameter of the distribution (a>0) | +//| b : Scale parameter of the distribution (b>0) | +//| tail : Flag to calculate lower tail | +//| log_mode : Logarithm mode, if true it calculates Log values | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The value of the Weibull cumulative distribution function | +//| F(a,b)=1-exp(-(x/b)^a) | +//| with parameters a and b, evaluated at x. | +//+------------------------------------------------------------------+ +double MathCumulativeDistributionWeibull(const double x,const double a,const double b,const bool tail,const bool log_mode,int &error_code) + { +//--- f(-infinity)=0 + if(x==QNEGINF) + { + error_code=ERR_OK; + return TailLog0(tail,log_mode); + } +//--- f(+infinity)=1 + if(x==QPOSINF) + { + error_code=ERR_OK; + return TailLog1(tail,log_mode); + } +//--- check parameters + if(!MathIsValidNumber(x) || !MathIsValidNumber(a) || !MathIsValidNumber(b)) + { + error_code=ERR_ARGUMENTS_NAN; + return QNaN; + } +//--- a and b must be positive + if(a<=0 || b<=0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } + + error_code=ERR_OK; +//--- check x + if(x<=0) + return TailLog0(tail,log_mode); +//--- calculate probability and take into account round-off errors + double cdf=MathMin(1.0-MathExp(-MathPow(x/b,a)),1.0); + return TailLogValue(cdf,tail,log_mode); + } +//+------------------------------------------------------------------+ +//| Weibull cumulative distribution function (CDF) | +//+------------------------------------------------------------------+ +//| The function returns the probability that an observation | +//| from the Weibull distribution with parameters a and b | +//| is less than or equal to x. | +//| | +//| Arguments: | +//| x : The desired quantile | +//| a : Shape parameter of the distribution (a>0) | +//| b : Scale parameter of the distribution (b>0) | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The value of the Weibull cumulative distribution function | +//| F(a,b)=1-exp(-(x/b)^a) | +//| with parameters a and b, evaluated at x. | +//+------------------------------------------------------------------+ +double MathCumulativeDistributionWeibull(const double x,const double a,const double b,int &error_code) + { + return MathCumulativeDistributionWeibull(x,a,b,true,false,error_code); + } +//+------------------------------------------------------------------+ +//| Weibull cumulative distribution function (CDF) | +//+------------------------------------------------------------------+ +//| The function calculates the cumulative distribution function of | +//| the Weibull distribution with parameters a and b for values in x.| +//| | +//| Arguments: | +//| x : Array with random variables | +//| a : Shape parameter of the distribution (a>0) | +//| b : Scale parameter of the distribution (b>0) | +//| tail : Flag to calculate lower tail | +//| log_mode : Logarithm mode, if true it calculates Log values | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathCumulativeDistributionWeibull(const double &x[],const double a,const double b,const bool tail,const bool log_mode,double &result[]) + { +//--- check NaN + if(!MathIsValidNumber(a) || !MathIsValidNumber(b)) + return false; +//--- a and b must be positive + if(a<=0 || b<=0) + return false; + + int data_count=ArraySize(x); + if(data_count==0) + return false; + + int error_code=0; + ArrayResize(result,data_count); + for(int i=0; i0) | +//| b : Scale parameter of the distribution (b>0) | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathCumulativeDistributionWeibull(const double &x[],const double a,const double b,double &result[]) + { + return MathCumulativeDistributionWeibull(x,a,b,true,false,result); + } +//+------------------------------------------------------------------+ +//| Weibull distribution quantile function (inverse CDF) | +//+------------------------------------------------------------------+ +//| The function returns the inverse cumulative distribution | +//| function of Weibull distribution | +//| Q(p,a,b)=b*((-ln(1-p)))^(1/a) | +//| with parameters a and b for the desired probability. | +//| | +//| Arguments: | +//| probability : The desired probability | +//| a : Shape parameter of the distribution (a>0) | +//| b : Scale parameter of the distribution (b>0) | +//| tail : Flag to calculate for lower tail | +//| log_mode : Logarithm mode,if true it calculates for Log values| +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The value of the inverse cumulative distribution function | +//| of the Weibull distribution with parameters a and b. | +//+------------------------------------------------------------------+ +double MathQuantileWeibull(const double probability,const double a,const double b,const bool tail,const bool log_mode,int &error_code) + { +//--- check NaN + if(!MathIsValidNumber(a) || !MathIsValidNumber(b)) + { + error_code=ERR_ARGUMENTS_NAN; + return QNaN; + } +//--- a and b must be positive + if(a<=0 || b<=0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } + +//--- calculate real probability + double prob=TailLogProbability(probability,tail,log_mode); +//--- check probability range + if(prob<0.0 || prob>1.0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } +//--- f(1)=+infinity + if(prob==1.0) + { + error_code=ERR_RESULT_INFINITE; + return QPOSINF; + } + + error_code=ERR_OK; +//--- f(0)=0 + if(prob==0.0) + return 0.0; +//--- return quantile + return b*MathPow(-MathLog(1.0-prob),1.0/a); + } +//+------------------------------------------------------------------+ +//| Weibull distribution quantile function (inverse CDF) | +//+------------------------------------------------------------------+ +//| The function returns the inverse cumulative distribution | +//| function of the Weibull distribution | +//| Q(p,a,b)=b*((-ln(1-p)))^(1/a) | +//| with parameters a and b for the desired probability. | +//| | +//| Arguments: | +//| probability : The desired probability | +//| a : Shape parameter of the distribution (a>0) | +//| b : Scale parameter of the distribution (b>0) | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The value of the inverse cumulative distribution function | +//| of the Weibull distribution with parameters a and b. | +//+------------------------------------------------------------------+ +double MathQuantileWeibull(const double probability,const double a,const double b,int &error_code) + { + return MathQuantileWeibull(probability,a,b,true,false,error_code); + } +//+------------------------------------------------------------------+ +//| Weibull distribution quantile function (inverse CDF) | +//+------------------------------------------------------------------+ +//| The function calculates the inverse cumulative distribution | +//| function of the Weibull distribution with parameters a and b | +//| for the probability values from array. | +//| | +//| Arguments: | +//| probability : Array with probabilities | +//| a : Shape parameter of the distribution (a>0) | +//| b : Scale parameter of the distribution (b>0) | +//| tail : Flag to calculate lower tail | +//| log_mode : Logarithm mode, if true it calculates Log values | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathQuantileWeibull(const double &probability[],const double a,const double b,const bool tail,const bool log_mode,double &result[]) + { +//--- check NaN + if(!MathIsValidNumber(a) || !MathIsValidNumber(b)) + return false; +//--- a and b must be positive + if(a<=0 || b<=0) + return false; + + int data_count=ArraySize(probability); + if(data_count==0) + return false; + + int error_code=0; + ArrayResize(result,data_count); + for(int i=0; i1.0) + return false; + + //--- f(1)=+infinity + if(prob==1.0) + result[i]=QPOSINF; + //--- f(0)=0 + if(prob==0.0) + result[i]=0.0; + else + //--- calc quantile + result[i]=b*MathPow(-MathLog(1.0-prob),1.0/a); + } + return true; + } +//+------------------------------------------------------------------+ +//| Weibull distribution quantile function (inverse CDF) | +//+------------------------------------------------------------------+ +//| The function calculates the inverse cumulative distribution | +//| function of the Weibull distribution with parameters a and b | +//| for values from the probability[] array. | +//| | +//| Arguments: | +//| probability : Array with probabilities | +//| a : Shape parameter of the distribution (a>0) | +//| b : Scale parameter of the distribution (b>0) | +//| result : Array with calculated values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathQuantileWeibull(const double &probability[],const double a,const double b,double &result[]) + { + return MathQuantileWeibull(probability,a,b,true,false,result); + } +//+------------------------------------------------------------------+ +//| Random variate from the Weibull distribution | +//+------------------------------------------------------------------+ +//| Computes the random variable from the Weibull distribution | +//| with shape a and scale b. | +//| | +//| Arguments: | +//| a : Shape parameter of the distribution (a>0) | +//| b : Scale parameter of the distribution (b>0) | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| The random value with Weibull distribution. | +//+------------------------------------------------------------------+ +double MathRandomWeibull(const double a,const double b,int &error_code) + { +//--- check NaN + if(!MathIsValidNumber(a) || !MathIsValidNumber(b)) + { + error_code=ERR_ARGUMENTS_NAN; + return QNaN; + } +//--- a and b must be positive + if(a<=0 || b<=0) + { + error_code=ERR_ARGUMENTS_INVALID; + return QNaN; + } + + error_code=ERR_OK; +//--- generate random number + double rnd=MathRandomNonZero(); + return b*MathPow(-MathLog(rnd),1.0/a); + } +//+------------------------------------------------------------------+ +//| Random variate from the Weibull distribution | +//+------------------------------------------------------------------+ +//| Generates random variables from the Weibull distribution with | +//| parameters a and b. | +//| | +//| Arguments: | +//| a : Shape parameter of the distribution (a>0) | +//| b : Scale parameter of the distribution (b>0) | +//| data_count : Number of values needed | +//| result : Output array with random values | +//| | +//| Return value: | +//| true if successful, otherwise false. | +//+------------------------------------------------------------------+ +bool MathRandomWeibull(const double a,const double b,const int data_count,double &result[]) + { +//--- check NaN + if(!MathIsValidNumber(a) || !MathIsValidNumber(b)) + return false; +//--- a and b must be positive + if(a<=0 || b<=0) + return false; + +//--- prepare output array and calculate random values + ArrayResize(result,data_count); + for(int i=0; i0) | +//| b : Scale parameter of the distribution (b>0) | +//| mean : Variable for mean value (1st moment) | +//| variance : Variable for variance value (2nd moment) | +//| skewness : Variable for skewness value (3rd moment) | +//| kurtosis : Variable for kurtosis value (4th moment) | +//| error_code : Variable for error code | +//| | +//| Return value: | +//| true if moments calculated successfully, otherwise false. | +//+------------------------------------------------------------------+ +bool MathMomentsWeibull(const double a,const double b,double &mean,double &variance,double &skewness,double &kurtosis,int &error_code) + { +//--- default values + mean =QNaN; + variance=QNaN; + skewness=QNaN; + kurtosis=QNaN; +//--- check NaN + if(!MathIsValidNumber(a) || !MathIsValidNumber(b)) + { + error_code=ERR_ARGUMENTS_NAN; + return false; + } +//--- a and b must be positive + if(a<=0 || b<=0) + { + error_code=ERR_ARGUMENTS_INVALID; + return false; + } + + error_code=ERR_OK; +//--- Gamma function values + double g1 = MathGamma(1+1.0/a); + double g2 = MathGamma(1+2.0/a); + double g3 = MathGamma(1+3.0/a); + double g4 = MathGamma(1+4.0/a); +//--- calculate moments + mean =b*g1; + variance=b*b*g2-MathPow(g1,2); + skewness=(2*g1*g1*g1-3*g1*g2+g3)*MathPow(g2-g1*g1,-1.5); + kurtosis=(-6*MathPow(g1,4)+12*MathPow(g1,2)*g2-3*MathPow(g2,2)-4*g1*g3+g4)*MathPow(g2-g1*g1,-2); +//--- successful + return true; + } +//+------------------------------------------------------------------+ diff --git a/MyScr/HistoryDealGetXXXX/HistoryDealGetTicket.ex5 b/MyScr/HistoryDealGetXXXX/HistoryDealGetTicket.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..9c75198e877957e6cb63b26564a58104fe1c0ca4 GIT binary patch literal 10864 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 literal 0 HcmV?d00001 diff --git a/MyScr/HistoryDealGetXXXX/HistoryDealGetTicket.mq5 b/MyScr/HistoryDealGetXXXX/HistoryDealGetTicket.mq5 new file mode 100644 index 0000000000000000000000000000000000000000..d3b307f3b3f137ca816523c7c618cc66b745f835 GIT binary patch literal 11944 zcmds7Yfl?T6rB(KRH^@A>j(ve8E9=`xDHfzb(Pm?hm<6RF5OJrx^VR$Kv&0qP-uUMTzAyXv69G zzl$^TFKtWbe}d~pd~E)^>hoG|N3v@kA3~$M&~Anu8bsTpCwT{pJjG~g-uB(|>t@&H zWA2hof4~~MU{n@1vFg@P53^w|@`Y>teR!2YH^)&chqy1t0oX}@zY{g4zW&+pcO9o^ zG9=55CEI0=tW*-?3rF@QlqHgEZhJn%S}(BkdvP|}p01^6b^0_{N4A_sFKz6QRntOc z#YLHBzkY2+9hwF>-xc_&^QqQ~=TSNGl&z&qMhENQdakZf7iX96MH%)~h8UXxqt22= z-^FO_@0~%%gBXK*xUb%{Y`G6JEjJ6?r8X$zYM(h5dGM%{YIC>kNBF zd(Y2Br1XU3;Sol2EOmYw?;b|XC%DI~f%ENS7RAA_oP9r90ui1f3sGs8n2+O+uIFZE zWV=gwXE+$I&M_yWsO=cN5Tl07$2~Ci@ybUP@l9!M-YjNQrYFfqicgt_%U0G$gxE*BlrdC%C0Ub2dmtL}j~Sz3%-0Pqj3(pgTW7&nW|}_RX~sD$ zJDCIaA`b7>)gqOnsIUzhgchZ&oK@^ zr(eH}nvE7u$z4c%h}pW~dxwJG=W$p(7C!o@T(na9DviXRy?VU_Y3a3%R&B(mYt-j? zRz2;&vzt%wBlNmT+A5w`e>3am^{Z&Y_pgQJu#VXO2D!?5_$h4QPC2ra4^dP+*Ntoi z$To1iLMGM1-_7v40-^Z~kISy>M%W5JLyKD#sJu@xEOu2ls;#gMUA=(D+7-yEvM?ee zhw^#cTq)aMMa%CXiZgGRgn?}!9mhV)GV>X+X-}`Jv^YJkP3Vz!vR$b~$rcq!@mxQ$ zc6bZcRoSc09*daxy?$J4u+TR2^|nG|KKk7RSqt$(bGu0x)&io9@H~3DavxXBZ6!}O zjP>hm3#jPbXa)3eBC#ALqs3_cx^&$o)X2*7=qRr*V@NX>DTL4do{viYekvw3T~=b6 ztK-U|qxr1r$;Z71-P?9FDe65d4=X3S*=gjtK$4D_YE zFLjCLHmO`ot0`TzWmlrhd{)ZUOV%ZwF+TMhY~0(*i@18?WLDS+Gr;vVcD{icEuEM6 z^+^RP9XHAU{F=1CBiVWt_N^h>SyTxr8`8qc5 zYyCX=arOG%@p8=9jvtfvy?$I?yLn&i$C(!Ml}dVycxa84>KT0%mzQho9$%xEMJU?Q zI2%z`+q(z#&zG>30e1Qb-c~EqImeRfDwMslKAy;2#b#L+*Z(?tNyTpKT!J551235= zu~Wd}zD+nIUfAC2$}K6}xdQWyJJHSgSv5r%99F>MW2!OVFwT;6^S z8Q(2-5dEmddT_mjzP6EzPpYqRxQ?K+UaX_*!Nq!(I$Igm8dZ8r?IitiFY3(R+th*Y zIlPM4SvA9SL=oQ}GMuYhGphw1t>dWDj-ueXh=hKD-OAgtoHgrfXr?sR?!^pSS}LvJ4-xK8AZK)a-|KfmHuvqxgp8 z-^02Q+0aJ+ErmCQmG9k{104M)c$cFWWKSri=M-MA+ui8<Q80yFx(4jlvescmBXwRqaa#QP4x)}`5$nLaTI$b=D4CH;=0Kmy zXwB@3zFs^p{YD*Dr=EWrw3A@fXfPdG>n`~CQq|F6buSepJ@O1J&^)T$(VEWg_zKSM z&VUho2Vh+@_F-nQ1I)24qt%`O|Eqvf56}T-PsK7-A1%jUn>IPW9#z$sj+^A1udek8 zlOQq3kK&kV*OBs9P1KNDMUIbj(@N5v^!m~_`8R*Fu6ijyd(N2r;wt^9=~riO*T+ln zU4>~SJ-r^cO|9!7^T4}y-p|W(h{vZE$W2-8=%J)(kd9*tz?