Add Support For ZigZag Swing Prediction to TestRegression Expert ...

This commit is contained in:
2025-09-22 13:35:43 +03:30
parent 7a4f1aa48b
commit 0a102fb01b
5 changed files with 1064 additions and 210 deletions
+344
View File
@@ -0,0 +1,344 @@
//+------------------------------------------------------------------+
//| TestRegresser.mq5 |
//| SaherElm IT Center |
//| https://www.saherelm.ir |
//+------------------------------------------------------------------+
#property copyright "SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
//
// Imports ...
#include "../Libraries/x-saherelm.common.lib.mq5"
#include <ChartObjects/ChartObjectsLines.mqh>
//
// Inputs ...
input int mLoopbackLength = 200;
input ENUM_X_PRICE mPriceType = X_PRICE_HIGH;
//
// Calculation ...
input group "Calculation";
input int zigzagDepth = 12; // Depth
input int zigzagDeviation = 5; // Deviation
input int zigzagBackStep = 3; // Back Step
//
// Variables ...
//
int mZigZagHandler = INVALID_HANDLE;
//
// double mSumX = 0;
// double mSumY = 0;
// double mSumXY = 0;
// double mSumX2 = 0;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//
double xData[];
double yData[];
int xDataCount = CollectData(
xData,
yData //
);
//
// Initialize ZigZag Handler ...
mZigZagHandler = iCustom(
_Symbol,
_Period,
"ZigZagColor",
zigzagDepth,
zigzagDeviation,
zigzagBackStep //
);
if (mZigZagHandler == INVALID_HANDLE)
{
Print("Error creating ZigZag handle");
return (INIT_FAILED);
}
// //
// for (int i = 0; i < mLoopbackLength; i++)
// {
// //
// double iY = yData[i];
// double iX = xData[i];
// //
// mSumX += iX;
// mSumY += iY;
// mSumXY += (iX * iY);
// mSumX2 += (iX * iX);
// }
// //
// for (int i = 0; i < mLoopbackLength; i++)
// {
// //
// double iY = GetAppliedPrice(
// _Symbol,
// _Period,
// i,
// mPriceType //
// );
// double iX = i + 1;
// //
// mSumX += iX;
// mSumY += iY;
// mSumXY += (iX * iY);
// mSumX2 += (iX * iX);
// }
//
// int n = mLoopbackLength;
// double slope = (n * mSumXY - mSumX * mSumY) / (n * mSumX2 - mSumX * mSumX);
// double intercept = (mSumY - slope * mSumX) / n;
// //
// double xData[];
// double yData[];
// int xDataCount = CollectData(
// xData,
// yData //
// );
double _cSlope;
double _cIntercept;
int calculatedCount = CalculateSlopeandIntercept(
_cSlope,
_cIntercept,
xData,
yData //
);
//
datetime time1 = iTime(_Symbol, _Period, mLoopbackLength);
datetime time2 = iTime(_Symbol, _Period, 0);
// //
// double price1 = (intercept + slope * mLoopbackLength);
// double price2 = (intercept + slope);
//
double cPrice1 = PredictValue(
_cSlope,
_cIntercept,
time1 //
);
double cPrice2 = PredictValue(
_cSlope,
_cIntercept,
time2 //
);
//
string name = "TrendLine";
string cName = "cTrendLine";
//
// CChartObjectTrend *iTrend = new CChartObjectTrend();
// bool isCreated = iTrend.Create(
// ChartID(),
// name,
// 0,
// time1,
// price1,
// time2,
// price2 //
// );
// if (isCreated)
// {
// //
// // Styling Trend Line ...
// }
//
CChartObjectTrend *iCTrend = new CChartObjectTrend();
bool isCreated = iCTrend.Create(
ChartID(),
cName,
0,
time1,
cPrice1,
time2,
cPrice2 //
);
if (isCreated)
{
//
// Styling Trend Line ...
}
//
return (INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
}
//+------------------------------------------------------------------+
//
int CollectData(
double &xData[],
double &yData[],
int barIndex = 0 //
)
{
//
int result = false;
//
SpecifiedClean(xData);
SpecifiedClean(yData);
//
barIndex = NormalizeInt(barIndex, 0);
//
int start = barIndex;
int end = start + mLoopbackLength;
for (int i = start; i < end; i++)
{
//
double iY = GetAppliedPrice(
_Symbol,
_Period,
i //
);
//
datetime iTime = iTime(
_Symbol,
_Period,
i //
);
double iX = i + 1; // (double)TimeToSeconds(iTime);
//
Add(
iX,
xData //
);
//
Add(
iY,
yData //
);
}
//
result = ArraySize(xData);
//
return result;
}
//
int CalculateSlopeandIntercept(
double &_slope,
double &_intercept,
double &xData[],
double &yData[] //
)
{
//
int result = 0;
//
bool has = false;
//
_slope = 0;
_intercept = 0;
//
if (!HasChild(xData) ||
!HasChild(yData))
{
return result;
}
//
double sumX = 0;
double sumY = 0;
double sumXY = 0;
double sumX2 = 0;
//
double x = 0;
double y = 0;
int end = MathMin(ArraySize(xData), ArraySize(yData));
for (int i = 0; i < end; i++)
{
//
double x = xData[i];
double y = yData[i];
//
sumX += x;
sumY += y;
sumXY += x * y;
sumX2 += x * x;
}
//
int n = end;
_slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
_intercept = (sumY - _slope * sumX) / n;
//
result = n;
//
return result;
}
//
double PredictValue(
double &_slope,
double &_intercept,
datetime forTime //
)
{
//
double result = 0;
//
if (!IsSpecifiedValid(forTime))
{
return result;
}
//
double forX = iBarShift(
_Symbol,
_Period,
forTime //
); // (double)TimeToSeconds(forTime);
result = (_intercept + _slope * forX);
//
return result;
}
//
+390 -147
View File
@@ -14,15 +14,44 @@
//
// Inputs ...
//
// Calculation ...
input int zigzagDepth = 12; // Depth
input int zigzagDeviation = 5; // Deviation
input int zigzagBackStep = 3; // Back Step
//
input int mLoopbackLength = 200;
input ENUM_X_PRICE mPriceType = X_PRICE_HIGH;
input int mExtendFutureLength = 100; // Bars to extend trendlines into the future
//
// Variables ...
double mSumX = 0;
double mSumY = 0;
double mSumXY = 0;
double mSumX2 = 0;
//
double mZigZagBuffer[]; // ZigZag Values Buffer ...
XBarTracker mBarTracker; // Bar Tracker ...
bool mZigZagPivotIsPeaks[]; // Check ZigZag Pivot Peak or Vale ...
double mZigZagPivotPrices[]; // ZigZag Pivot Prices ...
double mZigZagPivotIndexes[]; // ZigZag Pivot Indexes ...
datetime mZigZagPivotTimes[]; // ZigZag Pivot Times ...
CChartObjectTrend *mUpperTrend; // Trend Line Upper ...
CChartObjectTrend *mLowerTrend; // Trend Line Lower ...
int mZigZagHandler = INVALID_HANDLE; // ZigZag Indicator Handler ...
//
double mPeakSlope;
double mPeakIntercept;
double mZigZagPeaks[];
double mZigZagPeakIndexes[];
datetime mZigZagPeakTimes[];
//
double mValeSlope;
double mValeIntercept;
double mZigZagVales[];
double mZigZagValeIndexes[];
datetime mZigZagValeTimes[];
//+------------------------------------------------------------------+
//| Expert initialization function |
@@ -30,28 +59,11 @@ double mSumX2 = 0;
int OnInit()
{
//
for (int i = 0; i < mLoopbackLength; i++)
{
//
double iY = GetAppliedPrice(
_Symbol,
_Period,
i,
mPriceType //
);
double iX = i + 1;
//
mSumX += iX;
mSumY += iY;
mSumXY += (iX * iY);
mSumX2 += (iX * iX);
}
//
int n = mLoopbackLength;
double slope = (n * mSumXY - mSumX * mSumY) / (n * mSumX2 - mSumX * mSumX);
double intercept = (mSumY - slope * mSumX) / n;
// Initialize Bar Tracker ...
mBarTracker.Init(
_Symbol,
_Period //
);
//
double xData[];
@@ -60,71 +72,21 @@ int OnInit()
xData,
yData //
);
double _cSlope;
double _cIntercept;
int calculatedCount = CalculateSlopeandIntercept(
_cSlope,
_cIntercept,
xData,
yData //
//
// Initialize ZigZag Handler ...
mZigZagHandler = iCustom(
_Symbol,
_Period,
"ZigZag",
zigzagDepth,
zigzagDeviation,
zigzagBackStep //
);
//
datetime time1 = iTime(_Symbol, _Period, mLoopbackLength);
datetime time2 = iTime(_Symbol, _Period, 0);
//
double price1 = (intercept + slope * mLoopbackLength);
double price2 = (intercept + slope);
//
double cPrice1 = PredictValue(
_cSlope,
_cIntercept,
time1 //
);
double cPrice2 = PredictValue(
_cSlope,
_cIntercept,
time2 //
);
//
string name = "TrendLine";
string cName = "cTrendLine";
//
CChartObjectTrend *iTrend = new CChartObjectTrend();
bool isCreated = iTrend.Create(
ChartID(),
name,
0,
time1,
price1,
time2,
price2 //
);
if (isCreated)
if (mZigZagHandler == INVALID_HANDLE)
{
//
// Styling Trend Line ...
}
//
CChartObjectTrend *iCTrend = new CChartObjectTrend();
isCreated = iCTrend.Create(
ChartID(),
cName,
0,
time1,
cPrice1,
time2,
cPrice2 //
);
if (isCreated)
{
//
// Styling Trend Line ...
Print("Error creating ZigZag handle");
return (INIT_FAILED);
}
//
@@ -135,14 +97,35 @@ int OnInit()
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
//
IndicatorRelease(mZigZagHandler);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
//
if (!mBarTracker.IsNewBar())
{
return;
}
//
int readedZigZagsCount = ReadZigZagValues();
if (readedZigZagsCount <= 0)
{
return;
}
ProcessZigZagsPeaksAndVales();
CalculateZigZagLinearRegressionParameters();
DrawZigZagPredictedTrendLines();
//
// Process ZigZag Values ...
Print("");
//
}
//+------------------------------------------------------------------+
@@ -204,91 +187,351 @@ int CollectData(
}
//
int CalculateSlopeandIntercept(
double &_slope,
double &_intercept,
double &xData[],
double &yData[] //
)
int ReadZigZagValues(int barIndex = 0)
{
//
int result = 0;
//
bool has = false;
// Normalize ...
barIndex = NormalizeInt(barIndex, 0);
//
_slope = 0;
_intercept = 0;
//
if (!HasChild(xData) ||
!HasChild(yData))
// Validate ...
if (mZigZagHandler == INVALID_HANDLE)
{
return result;
}
//
double sumX = 0;
double sumY = 0;
double sumXY = 0;
double sumX2 = 0;
// Copy ZigZag Values to Buffers ...
result = CopyBuffer(mZigZagHandler, MAIN_LINE, 0, mLoopbackLength, mZigZagBuffer);
//
double x = 0;
double y = 0;
int end = MathMin(ArraySize(xData), ArraySize(yData));
for (int i = 0; i < end; i++)
{
//
double x = xData[i];
double y = yData[i];
//
sumX += x;
sumY += y;
sumXY += x * y;
sumX2 += x * x;
}
//
int n = end;
_slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
_intercept = (sumY - _slope * sumX) / n;
//
result = n;
// Set ZigZag Buffers as Series ...
ArraySetAsSeries(mZigZagBuffer, true);
//
return result;
}
//
double PredictValue(
double &_slope,
double &_intercept,
datetime forTime //
)
void ProcessZigZagsPeaksAndVales()
{
//
double result = 0;
// Here we Parse ZigZag Values to Detect Peak or Vale ...
//
if (!IsSpecifiedValid(forTime))
// Clean Buffers ...
SpecifiedClean(mZigZagPivotTimes);
SpecifiedClean(mZigZagPivotPrices);
SpecifiedClean(mZigZagPivotIsPeaks);
SpecifiedClean(mZigZagPivotIndexes);
//
// Looping Through ZigZag Buffers ...
XOHCL iBar;
bool has = false;
double iZigZag = 0;
bool isIZigZagPeak = false;
int count = ArraySize(mZigZagBuffer);
for (int i = 0; i < count; i++)
{
return result;
//
// Reading ZigZag Value ...
iZigZag = mZigZagBuffer[i];
//
// Validate ZigZag Values ...
if (!NotEmptyZero(iZigZag))
{
continue;
}
//
// Check ZigZag Value Is Peak or Vale ...
//
// Initialize iBar ...
has = iBar.Init(
_Symbol,
_Period,
i //
);
//
// Validate Bar and also Exclude Most Recent Swing ...
if (!has || iBar.Index() == 0)
{
//
iBar.Clean();
continue;
}
//
isIZigZagPeak = iZigZag == iBar.high;
//
// Filling Buffers ...
Add(
iBar.time,
mZigZagPivotTimes //
);
Add(
iZigZag,
mZigZagPivotPrices //
);
Add(
isIZigZagPeak,
mZigZagPivotIsPeaks //
);
Add(
(double)iBar.Index(),
mZigZagPivotIndexes //
);
//
// Cleanup Resources ...
iBar.Clean();
}
//
double forX = iBarShift(
_Symbol,
_Period,
forTime //
); // (double)TimeToSeconds(forTime);
result = (_intercept + _slope * forX);
// Extract mZigZag Peaks and Vales ...
SpecifiedClean(mZigZagPeaks);
SpecifiedClean(mZigZagVales);
SpecifiedClean(mZigZagPeakTimes);
SpecifiedClean(mZigZagValeTimes);
SpecifiedClean(mZigZagPeakIndexes);
SpecifiedClean(mZigZagValeIndexes);
count = ArraySize(mZigZagPivotPrices);
has = IsValidSize(count);
if (!has)
{
return;
}
//
return result;
double iZigZagIDX = -1;
datetime iZigZagTime = NULL;
for (int i = 0; i < count; i++)
{
//
// Reading Required Values ...
iZigZag = mZigZagPivotPrices[i];
iZigZagTime = mZigZagPivotTimes[i];
iZigZagIDX = mZigZagPivotIndexes[i];
isIZigZagPeak = mZigZagPivotIsPeaks[i];
//
if (isIZigZagPeak)
{
//
Add(
iZigZag,
mZigZagPeaks //
);
//
Add(
iZigZagTime,
mZigZagPeakTimes //
);
//
Add(
iZigZagIDX,
mZigZagPeakIndexes //
);
}
else
{
//
Add(
iZigZag,
mZigZagVales //
);
//
Add(
iZigZagTime,
mZigZagValeTimes //
);
//
Add(
iZigZagIDX,
mZigZagValeIndexes //
);
}
}
//
// TODO:
// - [] Add Support for Reading Specified Number of Swings instead of Specified Loopback ...
}
//
void CalculateZigZagLinearRegressionParameters()
{
//
// Peaks ...
CalculateSlopeAndIntercept(
mPeakSlope,
mPeakIntercept,
mZigZagPeakIndexes,
mZigZagPeaks //
);
//
// Vales ...
CalculateSlopeAndIntercept(
mValeSlope,
mValeIntercept,
mZigZagValeIndexes,
mZigZagVales //
);
}
//
void DrawZigZagPredictedTrendLines()
{
//
// This Variables are Same in Peaks and Vales ...
//
// TODO:
// - [] Add Support for Extending Lines betwen Oldest and Youngest Pivots ...
// - [] Add Support for Styling Lines ...
//
// FromTime ...
datetime fromTime = iTime(
_Symbol,
_Period,
mLoopbackLength - 1 //
);
int fromIDX = iBarShift(
_Symbol,
_Period,
fromTime //
);
//
// To Time ...
// this time Calculated using From Time and mExtendFutureLength ...
datetime toTime = fromTime + (mExtendFutureLength * PeriodSeconds(_Period));
int toIDX = iBarShift(
_Symbol,
_Period,
toTime //
);
//
// Predict Values ...
//
// Peak ...
double mPeakTo = PredictValue(
mPeakSlope,
mPeakIntercept,
toIDX //
);
double mPeakFrom = PredictValue(
mPeakSlope,
mPeakIntercept,
fromIDX //
);
//
// Vale ...
double mValeTo = PredictValue(
mValeSlope,
mValeIntercept,
toIDX //
);
double mValeFrom = PredictValue(
mValeSlope,
mValeIntercept,
fromIDX //
);
//
// Draw Predicted Lines ...
//
bool isCreated = false;
//
// Peak ...
//
// Cleanup Upper Object ...
if (mUpperTrend != NULL)
{
//
mUpperTrend.Delete();
mUpperTrend.Detach();
delete mUpperTrend;
ZeroMemory(mUpperTrend);
}
//
mUpperTrend = new CChartObjectTrend();
isCreated = mUpperTrend.Create(
ChartID(),
"UpperTrend",
0,
fromTime,
mPeakFrom,
toTime,
mPeakTo //
);
if (isCreated)
{
//
// Apply Styles ...
//
mUpperTrend.Width(2);
mUpperTrend.RayRight(true);
mUpperTrend.Color(clrAqua);
}
//
// Vale ...
//
// Cleanup Lower Object ...
if (mLowerTrend != NULL)
{
//
mLowerTrend.Delete();
mLowerTrend.Detach();
delete mLowerTrend;
ZeroMemory(mLowerTrend);
}
//
mLowerTrend = new CChartObjectTrend();
isCreated = mLowerTrend.Create(
ChartID(),
"LowerTrend",
0,
fromTime,
mValeFrom,
toTime,
mValeTo //
);
if (isCreated)
{
//
// Apply Styles ...
//
mLowerTrend.Width(2);
mLowerTrend.RayRight(true);
mLowerTrend.Color(clrMagenta);
}
}
//
Binary file not shown.
+288
View File
@@ -0,0 +1,288 @@
//+------------------------------------------------------------------+
//| ZigzagColor.mq5 |
//| Copyright 2000-2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2025, MetaQuotes Ltd."
#property link "https://www.mql5.com"
//--- indicator settings
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots 1
#property indicator_type1 DRAW_COLOR_ZIGZAG
#property indicator_width1 3
#property indicator_color1 clrAqua, clrMagenta
//--- input parameters
input int InpDepth =12; // Depth
input int InpDeviation=5; // Deviation
input int InpBackstep =3; // Back Step
//--- indicator buffers
double ZigzagPeakBuffer[];
double ZigzagBottomBuffer[];
double HighMapBuffer[];
double LowMapBuffer[];
double ColorBuffer[];
int ExtRecalc=3; // recounting's depth
enum EnSearchMode
{
Extremum=0, // searching for the first extremum
Peak=1, // searching for the next ZigZag peak
Bottom=-1 // searching for the next ZigZag bottom
};
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,ZigzagPeakBuffer,INDICATOR_DATA);
SetIndexBuffer(1,ZigzagBottomBuffer,INDICATOR_DATA);
SetIndexBuffer(2,ColorBuffer,INDICATOR_COLOR_INDEX);
SetIndexBuffer(3,HighMapBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(4,LowMapBuffer,INDICATOR_CALCULATIONS);
//--- set accuracy
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//--- name for DataWindow and indicator subwindow label
string short_name=StringFormat("ZigZagColor(%d,%d,%d)",InpDepth,InpDeviation,InpBackstep);
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
PlotIndexSetString(0,PLOT_LABEL,short_name);
//--- set an empty value
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
}
//+------------------------------------------------------------------+
//| ZigZag calculation |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
if(rates_total<100)
return(0);
//---
int i,start=0;
int extreme_counter=0,extreme_search=Extremum;
int shift,back=0,last_high_pos=0,last_low_pos=0;
double val=0,res=0;
double cur_low=0,cur_high=0,last_high=0,last_low=0;
//--- initializing
if(prev_calculated==0)
{
ArrayInitialize(ZigzagPeakBuffer,0.0);
ArrayInitialize(ZigzagBottomBuffer,0.0);
ArrayInitialize(HighMapBuffer,0.0);
ArrayInitialize(LowMapBuffer,0.0);
//--- start calculation from bar number InpDepth
start=InpDepth-1;
}
//--- ZigZag was already calculated before
if(prev_calculated>0)
{
i=rates_total-1;
//--- searching for the third extremum from the last uncompleted bar
while(extreme_counter<ExtRecalc && i>rates_total -100)
{
res=(ZigzagPeakBuffer[i]+ZigzagBottomBuffer[i]);
//---
if(res!=0)
extreme_counter++;
i--;
}
i++;
start=i;
//--- what type of exremum we search for
if(LowMapBuffer[i]!=0)
{
cur_low=LowMapBuffer[i];
extreme_search=Peak;
}
else
{
cur_high=HighMapBuffer[i];
extreme_search=Bottom;
}
//--- clear indicator values
for(i=start+1; i<rates_total && !IsStopped(); i++)
{
ZigzagPeakBuffer[i] =0.0;
ZigzagBottomBuffer[i]=0.0;
LowMapBuffer[i] =0.0;
HighMapBuffer[i] =0.0;
}
}
//--- searching for high and low extremes
for(shift=start; shift<rates_total && !IsStopped(); shift++)
{
//--- low
val=Lowest(low,InpDepth,shift);
if(val==last_low)
val=0.0;
else
{
last_low=val;
if((low[shift]-val)>(InpDeviation*_Point))
val=0.0;
else
{
for(back=InpBackstep; back>=1; back--)
{
res=LowMapBuffer[shift-back];
//---
if((res!=0) && (res>val))
LowMapBuffer[shift-back]=0.0;
}
}
}
if(low[shift]==val)
LowMapBuffer[shift]=val;
else
LowMapBuffer[shift]=0.0;
//--- high
val=Highest(high,InpDepth,shift);
if(val==last_high)
val=0.0;
else
{
last_high=val;
if((val-high[shift])>(InpDeviation*_Point))
val=0.0;
else
{
for(back=InpBackstep; back>=1; back--)
{
res=HighMapBuffer[shift-back];
//---
if((res!=0) && (res<val))
HighMapBuffer[shift-back]=0.0;
}
}
}
if(high[shift]==val)
HighMapBuffer[shift]=val;
else
HighMapBuffer[shift]=0.0;
}
//--- set last values
if(extreme_search==0) // undefined values
{
last_low=0;
last_high=0;
}
else
{
last_low=cur_low;
last_high=cur_high;
}
//--- final selection of extreme points for ZigZag
for(shift=start; shift<rates_total && !IsStopped(); shift++)
{
res=0.0;
switch(extreme_search)
{
case Extremum:
if(last_low==0 && last_high==0)
{
if(HighMapBuffer[shift]!=0)
{
last_high=high[shift];
last_high_pos=shift;
extreme_search=-1;
ZigzagPeakBuffer[shift]=last_high;
ColorBuffer[shift]=0;
res=1;
}
if(LowMapBuffer[shift]!=0)
{
last_low=low[shift];
last_low_pos=shift;
extreme_search=1;
ZigzagBottomBuffer[shift]=last_low;
ColorBuffer[shift]=1;
res=1;
}
}
break;
case Peak:
if(LowMapBuffer[shift]!=0.0 && LowMapBuffer[shift]<last_low &&
HighMapBuffer[shift]==0.0)
{
ZigzagBottomBuffer[last_low_pos]=0.0;
last_low_pos=shift;
last_low=LowMapBuffer[shift];
ZigzagBottomBuffer[shift]=last_low;
ColorBuffer[shift]=1;
res=1;
}
if(HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]==0.0)
{
last_high=HighMapBuffer[shift];
last_high_pos=shift;
ZigzagPeakBuffer[shift]=last_high;
ColorBuffer[shift]=0;
extreme_search=Bottom;
res=1;
}
break;
case Bottom:
if(HighMapBuffer[shift]!=0.0 &&
HighMapBuffer[shift]>last_high &&
LowMapBuffer[shift]==0.0)
{
ZigzagPeakBuffer[last_high_pos]=0.0;
last_high_pos=shift;
last_high=HighMapBuffer[shift];
ZigzagPeakBuffer[shift]=last_high;
ColorBuffer[shift]=0;
}
if(LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]==0.0)
{
last_low=LowMapBuffer[shift];
last_low_pos=shift;
ZigzagBottomBuffer[shift]=last_low;
ColorBuffer[shift]=1;
extreme_search=Peak;
}
break;
default:
return(rates_total);
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Get highest value for range |
//+------------------------------------------------------------------+
double Highest(const double&array[],int count,int start)
{
double res=array[start];
//---
for(int i=start-1; i>start-count && i>=0; i--)
if(res<array[i])
res=array[i];
//---
return(res);
}
//+------------------------------------------------------------------+
//| Get lowest value for range |
//+------------------------------------------------------------------+
double Lowest(const double&array[],int count,int start)
{
double res=array[start];
//---
for(int i=start-1; i>start-count && i>=0; i--)
if(res>array[i])
res=array[i];
//---
return(res);
}
//+------------------------------------------------------------------+
+42 -63
View File
@@ -7065,67 +7065,54 @@ bool SetChartVolumesColor(
//
/**
* Linear Regression Based Calculate Data ...
* int this Senario X Axis is Buffer Index ...
* Calculate Slope and Intercept for Linear Regression Predictions ...
*
* @param _slope: double, refrence for Calculated Slope ...
* @param _intercept: double, reference for Calculated Intercept ...
* @param _source: double, Y Axis Valus Collection ...
* @param _start: int, start Index ...
* @param _count: int, number of Calculations ...
* @param _slope: double, refrence to Hold Calculated Slope ...
* @param _intercept: double, reference to Hold Calculated Intercept ...
* @param xData: double, reference Collection to Provides X-Axis Data for Calculations ...
* @param yData: double, reference Collection to Provides Y-Axis Data for Calculations ...
*
* @return ( bool )
* @return ( int )
*/
bool CalculateLinearRegression(
int CalculateSlopeAndIntercept(
double &_slope,
double &_intercept,
double &_source[],
int _start = 0,
int _count = 0 //
double &xData[],
double &yData[] //
)
{
//
bool result = false;
int result = 0;
//
// Prepare ...
_slope = EMPTY_VALUE;
_intercept = EMPTY_VALUE;
bool has = false;
//
// Validate ...
int count = ArraySize(_source);
result = IsValidSize(count);
if (!result)
_slope = 0;
_intercept = 0;
//
if (!HasChild(xData) ||
!HasChild(yData))
{
return result;
}
//
// Normalize ...
_start = NormalizeInt(_start, 0, count - 1);
if (_count == 0 || _count + _start >= count)
{
//
// Get Whole Array ...
_count = count - 1 - _start;
}
int _end = _start + _count;
//
// Define Requirements ...
double sumX = 0;
double sumY = 0;
double sumXY = 0;
double sumX2 = 0;
//
// Looping Through Source Buffer to Cellect Data ...
for (int i = _start; i < _end; i++)
double x = 0;
double y = 0;
int end = MathMin(ArraySize(xData), ArraySize(yData));
for (int i = 0; i < end; i++)
{
//
double x = i + 1;
double y = _source[i];
double x = xData[i];
double y = yData[i];
//
sumX += x;
@@ -7135,54 +7122,46 @@ bool CalculateLinearRegression(
}
//
// Calculate Slope and Intercept ...
int n = _count;
_slope = ((n * sumXY) - (sumX * sumY)) / ((n * sumX2) - (sumX * sumX));
_intercept = ((sumY - _slope) * sumX) / n;
int n = end;
_slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
_intercept = (sumY - _slope * sumX) / n;
//
result = sumX > 0 &&
sumY > 0 &&
sumXY > 0 &&
sumX2 > 0 &&
NotEmpty(_slope) &&
NotEmpty(_intercept);
if (!result)
{
//
_slope = EMPTY_VALUE;
_intercept = EMPTY_VALUE;
}
result = n;
//
return result;
}
double CalculateValueBySlopeIntercept(
/**
* Predict Value for Specified X ...
*
* @param _sllope: double, Provided Slope ...
* @param _intercept: double, Provided Intercept ...
* @param _forX: double, Specified XValue ...
*
* @return ( double )
*/
double PredictValue(
double _slope,
double _intercept,
int _index //
double _forX //
)
{
//
double result = EMPTY_VALUE;
//
// Normalize Index ...
_index = NormalizeInt(_index, 1);
double result = 0;
//
// Validate ...
if (
if (!NotEmpty(_forX) ||
!NotEmpty(_slope) ||
!NotEmpty(_intercept) ||
!IsValidIndex(_index))
!NotEmpty(_intercept))
{
return result;
}
//
result = (_intercept + _slope * _index);
result = (_intercept + (_slope * _forX));
//
return result;