537 lines
11 KiB
Plaintext
537 lines
11 KiB
Plaintext
//+------------------------------------------------------------------+
|
|
//| 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 ...
|
|
|
|
//
|
|
// Calculation ...
|
|
input int zigzagDepth = 12; // Depth
|
|
input int zigzagDeviation = 5; // Deviation
|
|
input int zigzagBackStep = 3; // Back Step
|
|
|
|
//
|
|
input int mLoopbackLength = 200;
|
|
input int mExtendFutureLength = 100; // Bars to extend trendlines into the future
|
|
|
|
//
|
|
// Variables ...
|
|
|
|
//
|
|
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 |
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
//
|
|
// Initialize Bar Tracker ...
|
|
mBarTracker.Init(
|
|
_Symbol,
|
|
_Period //
|
|
);
|
|
|
|
//
|
|
double xData[];
|
|
double yData[];
|
|
int xDataCount = CollectData(
|
|
xData,
|
|
yData //
|
|
);
|
|
|
|
//
|
|
// Initialize ZigZag Handler ...
|
|
mZigZagHandler = iCustom(
|
|
_Symbol,
|
|
_Period,
|
|
"ZigZag",
|
|
zigzagDepth,
|
|
zigzagDeviation,
|
|
zigzagBackStep //
|
|
);
|
|
if (mZigZagHandler == INVALID_HANDLE)
|
|
{
|
|
Print("Error creating ZigZag handle");
|
|
return (INIT_FAILED);
|
|
}
|
|
|
|
//
|
|
return (INIT_SUCCEEDED);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Expert deinitialization function |
|
|
//+------------------------------------------------------------------+
|
|
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("");
|
|
|
|
//
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
|
|
//
|
|
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 ReadZigZagValues(int barIndex = 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;
|
|
double iZigZag = 0;
|
|
bool isIZigZagPeak = false;
|
|
int count = ArraySize(mZigZagBuffer);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
// 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();
|
|
}
|
|
|
|
//
|
|
// 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);
|
|
}
|
|
}
|
|
|
|
// |