Add Support For ZigZag Swing Prediction to TestRegression Expert ...
This commit is contained in:
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
+402
-159
@@ -14,15 +14,44 @@
|
|||||||
|
|
||||||
//
|
//
|
||||||
// Inputs ...
|
// Inputs ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculation ...
|
||||||
|
input int zigzagDepth = 12; // Depth
|
||||||
|
input int zigzagDeviation = 5; // Deviation
|
||||||
|
input int zigzagBackStep = 3; // Back Step
|
||||||
|
|
||||||
|
//
|
||||||
input int mLoopbackLength = 200;
|
input int mLoopbackLength = 200;
|
||||||
input ENUM_X_PRICE mPriceType = X_PRICE_HIGH;
|
input int mExtendFutureLength = 100; // Bars to extend trendlines into the future
|
||||||
|
|
||||||
//
|
//
|
||||||
// Variables ...
|
// Variables ...
|
||||||
double mSumX = 0;
|
|
||||||
double mSumY = 0;
|
//
|
||||||
double mSumXY = 0;
|
double mZigZagBuffer[]; // ZigZag Values Buffer ...
|
||||||
double mSumX2 = 0;
|
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 |
|
//| Expert initialization function |
|
||||||
@@ -30,28 +59,11 @@ double mSumX2 = 0;
|
|||||||
int OnInit()
|
int OnInit()
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
for (int i = 0; i < mLoopbackLength; i++)
|
// Initialize Bar Tracker ...
|
||||||
{
|
mBarTracker.Init(
|
||||||
//
|
|
||||||
double iY = GetAppliedPrice(
|
|
||||||
_Symbol,
|
_Symbol,
|
||||||
_Period,
|
_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 xData[];
|
||||||
@@ -60,71 +72,21 @@ int OnInit()
|
|||||||
xData,
|
xData,
|
||||||
yData //
|
yData //
|
||||||
);
|
);
|
||||||
double _cSlope;
|
|
||||||
double _cIntercept;
|
//
|
||||||
int calculatedCount = CalculateSlopeandIntercept(
|
// Initialize ZigZag Handler ...
|
||||||
_cSlope,
|
mZigZagHandler = iCustom(
|
||||||
_cIntercept,
|
_Symbol,
|
||||||
xData,
|
_Period,
|
||||||
yData //
|
"ZigZag",
|
||||||
|
zigzagDepth,
|
||||||
|
zigzagDeviation,
|
||||||
|
zigzagBackStep //
|
||||||
);
|
);
|
||||||
|
if (mZigZagHandler == INVALID_HANDLE)
|
||||||
//
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
//
|
Print("Error creating ZigZag handle");
|
||||||
// Styling Trend Line ...
|
return (INIT_FAILED);
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
CChartObjectTrend *iCTrend = new CChartObjectTrend();
|
|
||||||
isCreated = iCTrend.Create(
|
|
||||||
ChartID(),
|
|
||||||
cName,
|
|
||||||
0,
|
|
||||||
time1,
|
|
||||||
cPrice1,
|
|
||||||
time2,
|
|
||||||
cPrice2 //
|
|
||||||
);
|
|
||||||
if (isCreated)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Styling Trend Line ...
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -135,14 +97,35 @@ int OnInit()
|
|||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
void OnDeinit(const int reason)
|
void OnDeinit(const int reason)
|
||||||
{
|
{
|
||||||
//---
|
//
|
||||||
|
IndicatorRelease(mZigZagHandler);
|
||||||
}
|
}
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
//| Expert tick function |
|
//| Expert tick function |
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
void OnTick()
|
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(
|
int ReadZigZagValues(int barIndex = 0)
|
||||||
double &_slope,
|
|
||||||
double &_intercept,
|
|
||||||
double &xData[],
|
|
||||||
double &yData[] //
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
// Normalize ...
|
||||||
|
barIndex = NormalizeInt(barIndex, 0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate ...
|
||||||
|
if (mZigZagHandler == INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copy ZigZag Values to Buffers ...
|
||||||
|
result = CopyBuffer(mZigZagHandler, MAIN_LINE, 0, mLoopbackLength, mZigZagBuffer);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set ZigZag Buffers as Series ...
|
||||||
|
ArraySetAsSeries(mZigZagBuffer, true);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void ProcessZigZagsPeaksAndVales()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Here we Parse ZigZag Values to Detect Peak or Vale ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Clean Buffers ...
|
||||||
|
SpecifiedClean(mZigZagPivotTimes);
|
||||||
|
SpecifiedClean(mZigZagPivotPrices);
|
||||||
|
SpecifiedClean(mZigZagPivotIsPeaks);
|
||||||
|
SpecifiedClean(mZigZagPivotIndexes);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Looping Through ZigZag Buffers ...
|
||||||
|
XOHCL iBar;
|
||||||
bool has = false;
|
bool has = false;
|
||||||
|
double iZigZag = 0;
|
||||||
//
|
bool isIZigZagPeak = false;
|
||||||
_slope = 0;
|
int count = ArraySize(mZigZagBuffer);
|
||||||
_intercept = 0;
|
for (int i = 0; i < count; i++)
|
||||||
|
|
||||||
//
|
|
||||||
if (!HasChild(xData) ||
|
|
||||||
!HasChild(yData))
|
|
||||||
{
|
{
|
||||||
return result;
|
//
|
||||||
|
// Reading ZigZag Value ...
|
||||||
|
iZigZag = mZigZagBuffer[i];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate ZigZag Values ...
|
||||||
|
if (!NotEmptyZero(iZigZag))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
double sumX = 0;
|
// Check ZigZag Value Is Peak or Vale ...
|
||||||
double sumY = 0;
|
|
||||||
double sumXY = 0;
|
|
||||||
double sumX2 = 0;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
double x = 0;
|
// Initialize iBar ...
|
||||||
double y = 0;
|
has = iBar.Init(
|
||||||
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,
|
_Symbol,
|
||||||
_Period,
|
_Period,
|
||||||
forTime //
|
i //
|
||||||
); // (double)TimeToSeconds(forTime);
|
);
|
||||||
result = (_intercept + _slope * forX);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
return result;
|
// 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
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.
@@ -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);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
@@ -7065,67 +7065,54 @@ bool SetChartVolumesColor(
|
|||||||
//
|
//
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Linear Regression Based Calculate Data ...
|
* Calculate Slope and Intercept for Linear Regression Predictions ...
|
||||||
* int this Senario X Axis is Buffer Index ...
|
|
||||||
*
|
*
|
||||||
* @param _slope: double, refrence for Calculated Slope ...
|
* @param _slope: double, refrence to Hold Calculated Slope ...
|
||||||
* @param _intercept: double, reference for Calculated Intercept ...
|
* @param _intercept: double, reference to Hold Calculated Intercept ...
|
||||||
* @param _source: double, Y Axis Valus Collection ...
|
* @param xData: double, reference Collection to Provides X-Axis Data for Calculations ...
|
||||||
* @param _start: int, start Index ...
|
* @param yData: double, reference Collection to Provides Y-Axis Data for Calculations ...
|
||||||
* @param _count: int, number of Calculations ...
|
|
||||||
*
|
*
|
||||||
* @return ( bool )
|
* @return ( int )
|
||||||
*/
|
*/
|
||||||
bool CalculateLinearRegression(
|
int CalculateSlopeAndIntercept(
|
||||||
double &_slope,
|
double &_slope,
|
||||||
double &_intercept,
|
double &_intercept,
|
||||||
double &_source[],
|
double &xData[],
|
||||||
int _start = 0,
|
double &yData[] //
|
||||||
int _count = 0 //
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
bool result = false;
|
int result = 0;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Prepare ...
|
bool has = false;
|
||||||
_slope = EMPTY_VALUE;
|
|
||||||
_intercept = EMPTY_VALUE;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Validate ...
|
_slope = 0;
|
||||||
int count = ArraySize(_source);
|
_intercept = 0;
|
||||||
result = IsValidSize(count);
|
|
||||||
if (!result)
|
//
|
||||||
|
if (!HasChild(xData) ||
|
||||||
|
!HasChild(yData))
|
||||||
{
|
{
|
||||||
return result;
|
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 sumX = 0;
|
||||||
double sumY = 0;
|
double sumY = 0;
|
||||||
double sumXY = 0;
|
double sumXY = 0;
|
||||||
double sumX2 = 0;
|
double sumX2 = 0;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Looping Through Source Buffer to Cellect Data ...
|
double x = 0;
|
||||||
for (int i = _start; i < _end; i++)
|
double y = 0;
|
||||||
|
int end = MathMin(ArraySize(xData), ArraySize(yData));
|
||||||
|
for (int i = 0; i < end; i++)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
double x = i + 1;
|
double x = xData[i];
|
||||||
double y = _source[i];
|
double y = yData[i];
|
||||||
|
|
||||||
//
|
//
|
||||||
sumX += x;
|
sumX += x;
|
||||||
@@ -7135,54 +7122,46 @@ bool CalculateLinearRegression(
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Calculate Slope and Intercept ...
|
int n = end;
|
||||||
int n = _count;
|
_slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
|
||||||
_slope = ((n * sumXY) - (sumX * sumY)) / ((n * sumX2) - (sumX * sumX));
|
_intercept = (sumY - _slope * sumX) / n;
|
||||||
_intercept = ((sumY - _slope) * sumX) / n;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
result = sumX > 0 &&
|
result = n;
|
||||||
sumY > 0 &&
|
|
||||||
sumXY > 0 &&
|
|
||||||
sumX2 > 0 &&
|
|
||||||
NotEmpty(_slope) &&
|
|
||||||
NotEmpty(_intercept);
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
_slope = EMPTY_VALUE;
|
|
||||||
_intercept = EMPTY_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
return result;
|
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 _slope,
|
||||||
double _intercept,
|
double _intercept,
|
||||||
int _index //
|
double _forX //
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
double result = EMPTY_VALUE;
|
double result = 0;
|
||||||
|
|
||||||
//
|
|
||||||
// Normalize Index ...
|
|
||||||
_index = NormalizeInt(_index, 1);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Validate ...
|
// Validate ...
|
||||||
if (
|
if (!NotEmpty(_forX) ||
|
||||||
!NotEmpty(_slope) ||
|
!NotEmpty(_slope) ||
|
||||||
!NotEmpty(_intercept) ||
|
!NotEmpty(_intercept))
|
||||||
!IsValidIndex(_index))
|
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
result = (_intercept + _slope * _index);
|
result = (_intercept + (_slope * _forX));
|
||||||
|
|
||||||
//
|
//
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
Reference in New Issue
Block a user