700 lines
22 KiB
MQL5
700 lines
22 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| Curve.mqh |
|
|
//| Copyright 2000-2025, MetaQuotes Ltd. |
|
|
//| https://www.mql5.com |
|
|
//+------------------------------------------------------------------+
|
|
#include <Object.mqh>
|
|
#include <Canvas\Canvas.mqh>
|
|
//--- 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; i<m_size; i++)
|
|
{
|
|
m_x[i]=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_ymax<y[i])
|
|
m_ymax=y[i];
|
|
else
|
|
if(m_ymin>y[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; i<m_size; i++)
|
|
{
|
|
if(MathIsValidNumber(m_x[i]))
|
|
{
|
|
if(!xvalid)
|
|
{
|
|
m_xmax = x[i];
|
|
m_xmin = x[i];
|
|
xvalid=true;
|
|
}
|
|
else
|
|
{
|
|
//--- find max and min of x
|
|
if(m_xmax<x[i])
|
|
m_xmax=x[i];
|
|
else
|
|
if(m_xmin>x[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_ymax<y[i])
|
|
m_ymax=y[i];
|
|
else
|
|
if(m_ymin>y[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; i<m_size; i++)
|
|
{
|
|
m_x[i] = points[i].x;
|
|
m_y[i] = points[i].y;
|
|
if(MathIsValidNumber(m_x[i]))
|
|
{
|
|
if(!xvalid)
|
|
{
|
|
m_xmax = m_x[i];
|
|
m_xmin = m_x[i];
|
|
xvalid=true;
|
|
}
|
|
else
|
|
{
|
|
//--- find max and min of x
|
|
if(m_xmax<m_x[i])
|
|
m_xmax=m_x[i];
|
|
else
|
|
if(m_xmin>m_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_ymax<m_y[i])
|
|
m_ymax=m_y[i];
|
|
else
|
|
if(m_ymin>m_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; i<m_size; i++)
|
|
{
|
|
m_x[i]=from+(i*step);
|
|
m_y[i]=function(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_ymax<m_y[i])
|
|
m_ymax=m_y[i];
|
|
else if(m_ymin>m_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; i<m_size; i++)
|
|
{
|
|
m_x[i]=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_ymax<y[i])
|
|
m_ymax=y[i];
|
|
else
|
|
if(m_ymin>y[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; i<m_size; i++)
|
|
{
|
|
if(MathIsValidNumber(m_x[i]))
|
|
{
|
|
if(!xvalid)
|
|
{
|
|
m_xmax = x[i];
|
|
m_xmin = x[i];
|
|
xvalid=true;
|
|
}
|
|
else
|
|
{
|
|
//--- find max and min of x
|
|
if(m_xmax<x[i])
|
|
m_xmax=x[i];
|
|
else
|
|
if(m_xmin>x[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_ymax<y[i])
|
|
m_ymax=y[i];
|
|
else
|
|
if(m_ymin>y[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; i<m_size; i++)
|
|
{
|
|
m_x[i] = points[i].x;
|
|
m_y[i] = points[i].y;
|
|
if(MathIsValidNumber(m_x[i]))
|
|
{
|
|
if(!xvalid)
|
|
{
|
|
m_xmax = m_x[i];
|
|
m_xmin = m_x[i];
|
|
xvalid=true;
|
|
}
|
|
else
|
|
{
|
|
//--- find max and min of x
|
|
if(m_xmax<m_x[i])
|
|
m_xmax=m_x[i];
|
|
else
|
|
if(m_xmin>m_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_ymax<m_y[i])
|
|
m_ymax=m_y[i];
|
|
else
|
|
if(m_ymin>m_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; i<m_size; i++)
|
|
{
|
|
m_x[i]=from+(i*step);
|
|
m_y[i]=function(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_ymax<m_y[i])
|
|
m_ymax=m_y[i];
|
|
else if(m_ymin>m_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; i<m_size; i++)
|
|
{
|
|
xmean+=m_x[i];
|
|
ymean+=m_y[i];
|
|
sum_xy+=m_x[i]*m_y[i];
|
|
sum_xx+=m_x[i]*m_x[i];
|
|
}
|
|
xmean/=m_size;
|
|
ymean/=m_size;
|
|
//--- calculate intercept
|
|
m_trend_coeff[0]=(sum_xy -(m_size*xmean*ymean))/(sum_xx -(m_size*xmean*xmean));
|
|
//--- calculate slope
|
|
m_trend_coeff[1]=ymean-m_trend_coeff[0]*xmean;
|
|
}
|
|
//+------------------------------------------------------------------+
|