1108 lines
22 KiB
Plaintext
1108 lines
22 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 "../Classes/x-saherelm.x-cobject.class.mq5"
|
|
#include "../Libraries/x-saherelm.common.lib.mq5"
|
|
#include "../Libraries/x-saherelm.x-poi.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; // Loopback Length for Calculation
|
|
input int mRequiredPivots = 50; // Required Peaks for Calculation (0 > use loopback )
|
|
|
|
//
|
|
// 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[];
|
|
|
|
//
|
|
datetime mToTime;
|
|
datetime mFromTime;
|
|
|
|
//
|
|
// Predictions ...
|
|
|
|
//
|
|
double mPeakTo;
|
|
double mValeTo;
|
|
double mPeakFrom;
|
|
double mValeFrom;
|
|
|
|
//
|
|
ENUM_X_DIRECTION mUpperTrendDir;
|
|
ENUM_X_DIRECTION mLowerTrendDir;
|
|
|
|
//
|
|
// Support and Resistances ...
|
|
|
|
//
|
|
XBoxZone mSupportBox;
|
|
double mMinorSupport;
|
|
double mMajorSupport;
|
|
XCBoxObject *mSupportObj;
|
|
|
|
//
|
|
XBoxZone mResistanceBox;
|
|
double mMinorResistance;
|
|
double mMajorResistance;
|
|
XCBoxObject *mResistanceObj;
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert initialization function |
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
//
|
|
// Initialize Bar Tracker ...
|
|
mBarTracker.Init(
|
|
_Symbol,
|
|
_Period //
|
|
);
|
|
|
|
//
|
|
// 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 = 0;
|
|
bool readZigZagsBasedOnPivots = mRequiredPivots > 0;
|
|
|
|
//
|
|
// Reading ZigZag Values Based on Loopback Length ...
|
|
if (!readZigZagsBasedOnPivots)
|
|
{
|
|
readedZigZagsCount = ReadZigZagValues();
|
|
}
|
|
//
|
|
// Reading ZigZag Pivots based on required Pivots ...
|
|
else
|
|
{
|
|
//
|
|
readedZigZagsCount = ReadingZigZagPivots(
|
|
0, // BarIndex ...
|
|
mRequiredPivots, // Required Pivots ...
|
|
1500 // Max Allowed Loopback Length ...
|
|
);
|
|
}
|
|
|
|
//
|
|
// Validate Reading Succeed ...
|
|
if (readedZigZagsCount <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Try to Detect ZigZag Peaks and Vales ...
|
|
ProcessZigZagsPeaksAndVales();
|
|
|
|
//
|
|
// Try to Calculate ZigZag Supports and Resistances ...
|
|
ProcessZigZagsSupportsAnsResistances();
|
|
|
|
//
|
|
// Try to Calculate Peaks and Vales Linear Regression Based
|
|
// Slope and Intercept (s) and also Detect From and To Times then
|
|
// Predict Peaks and Vales Values for them then ...
|
|
// Prepare Support and Resistance Boxes based on Calculated Support
|
|
// and Resistances ...
|
|
if (!CalculateZigZagLinearRegressionParameters())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Draw Peaks and Vales Based Trend Lines ...
|
|
DrawAnalysis();
|
|
|
|
//
|
|
// Process ZigZag Values ...
|
|
Print("");
|
|
|
|
//
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
|
|
//
|
|
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);
|
|
|
|
//
|
|
if (result <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Filling ZigZag Pivots ...
|
|
|
|
//
|
|
// 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();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int ReadingZigZagPivots(
|
|
int barIndex = 0,
|
|
int requiredPivots = 15,
|
|
int maxAllowedLoopback = 1500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
SpecifiedClean(mZigZagPivotTimes);
|
|
SpecifiedClean(mZigZagPivotPrices);
|
|
SpecifiedClean(mZigZagPivotIsPeaks);
|
|
SpecifiedClean(mZigZagPivotIndexes);
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeInt(barIndex, 0);
|
|
requiredPivots = NormalizeInt(requiredPivots, 2);
|
|
maxAllowedLoopback = NormalizeInt(maxAllowedLoopback, 100);
|
|
|
|
//
|
|
XOHCL iBar;
|
|
bool has = false;
|
|
double iZigZag = 0;
|
|
bool isPeak = false;
|
|
int idx = barIndex - 1;
|
|
double tmpZigZagBuffer[];
|
|
int maxAllowed = barIndex + maxAllowedLoopback;
|
|
while (idx < maxAllowed &&
|
|
ArraySize(mZigZagPivotPrices) < requiredPivots)
|
|
{
|
|
//
|
|
idx++;
|
|
|
|
//
|
|
// Initializing Bar ...
|
|
has = iBar.Init(
|
|
_Symbol,
|
|
_Period,
|
|
idx //
|
|
);
|
|
if (!has)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Reading ZigZag Value ...
|
|
if (CopyBuffer(mZigZagHandler, MAIN_LINE, idx, 1, tmpZigZagBuffer) < 1)
|
|
{
|
|
//
|
|
iBar.Clean();
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Read ZigZag Value and Validate it ...
|
|
iZigZag = tmpZigZagBuffer[0];
|
|
has = NotEmptyZero(iZigZag);
|
|
if (!has)
|
|
{
|
|
//
|
|
iBar.Clean();
|
|
SpecifiedClean(tmpZigZagBuffer);
|
|
|
|
//
|
|
continue;
|
|
}
|
|
|
|
//
|
|
isPeak = iZigZag == iBar.high;
|
|
|
|
//
|
|
// Validate ZigZag Value for Ignore Zero ...
|
|
if (iBar.Index() == barIndex)
|
|
{
|
|
//
|
|
iBar.Clean();
|
|
SpecifiedClean(tmpZigZagBuffer);
|
|
|
|
//
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Filling Pivots ...
|
|
|
|
//
|
|
Add(
|
|
iZigZag,
|
|
mZigZagPivotPrices //
|
|
);
|
|
|
|
//
|
|
Add(
|
|
isPeak,
|
|
mZigZagPivotIsPeaks //
|
|
);
|
|
|
|
//
|
|
Add(
|
|
iBar.time,
|
|
mZigZagPivotTimes //
|
|
);
|
|
|
|
//
|
|
Add(
|
|
(double)iBar.Index(),
|
|
mZigZagPivotIndexes //
|
|
);
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
iBar.Clean();
|
|
SpecifiedClean(tmpZigZagBuffer);
|
|
|
|
//
|
|
// Check Can Break Loop ...
|
|
has = idx >= maxAllowed ||
|
|
ArraySize(mZigZagPivotPrices) == requiredPivots;
|
|
if (has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
SpecifiedClean(tmpZigZagBuffer);
|
|
|
|
//
|
|
result = ArraySize(mZigZagPivotPrices);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
void ProcessZigZagsPeaksAndVales()
|
|
{
|
|
//
|
|
// Here we Parse ZigZag Values to Detect Peak or Vale ...
|
|
|
|
//
|
|
int count = 0;
|
|
bool has = false;
|
|
|
|
//
|
|
// 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 iZigZag = 0;
|
|
double iZigZagIDX = -1;
|
|
bool isIZigZagPeak = false;
|
|
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 //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
void ProcessZigZagsSupportsAnsResistances()
|
|
{
|
|
//
|
|
int count = 0;
|
|
bool has = false;
|
|
double iValue = EMPTY_VALUE;
|
|
double tmpValue = EMPTY_VALUE;
|
|
|
|
//
|
|
// Support ...
|
|
// Supports Calculated based on Vales ...
|
|
|
|
//
|
|
tmpValue = EMPTY_VALUE;
|
|
mMinorSupport = EMPTY_VALUE;
|
|
mMajorSupport = EMPTY_VALUE;
|
|
count = ArraySize(mZigZagVales);
|
|
has = IsValidSize(count);
|
|
if (has)
|
|
{
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
// Reading Indexed Value ...
|
|
iValue = mZigZagVales[i];
|
|
|
|
//
|
|
// Check Can Change Major Support ...
|
|
has = !NotEmpty(mMajorSupport) ||
|
|
mMajorSupport > iValue;
|
|
if (has)
|
|
{
|
|
//
|
|
tmpValue = mMajorSupport;
|
|
mMajorSupport = iValue;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Check Minor Support ...
|
|
has = !NotEmpty(tmpValue) ||
|
|
tmpValue > iValue;
|
|
if (has)
|
|
{
|
|
tmpValue = iValue;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
has = NotEmpty(tmpValue);
|
|
if (has)
|
|
{
|
|
mMinorSupport = tmpValue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Resistance ...
|
|
// Resistances Calculated based on Peaks ...
|
|
|
|
//
|
|
tmpValue = EMPTY_VALUE;
|
|
mMinorResistance = EMPTY_VALUE;
|
|
mMajorResistance = EMPTY_VALUE;
|
|
count = ArraySize(mZigZagPeaks);
|
|
has = IsValidSize(count);
|
|
if (has)
|
|
{
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
// Reading Indexed Value ...
|
|
iValue = mZigZagPeaks[i];
|
|
|
|
//
|
|
// Check Can Change Major Resistance ...
|
|
has = !NotEmpty(mMajorResistance) ||
|
|
mMajorResistance < iValue;
|
|
if (has)
|
|
{
|
|
//
|
|
tmpValue = mMajorResistance;
|
|
mMajorResistance = iValue;
|
|
}
|
|
elsetmp
|
|
{
|
|
//
|
|
// Check Minor Resistance ...
|
|
has = !NotEmpty(tmpValue) ||
|
|
tmpValue < iValue;
|
|
if (has)
|
|
{
|
|
tmpValue = iValue;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
has = NotEmpty(tmpValue);
|
|
if (has)
|
|
{
|
|
mMinorResistance = tmpValue;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
bool CalculateZigZagLinearRegressionParameters()
|
|
{
|
|
//
|
|
bool result = false;
|
|
mUpperTrendDir = X_DIRECTION_NONE;
|
|
mLowerTrendDir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Peaks ...
|
|
CalculateSlopeAndIntercept(
|
|
mPeakSlope,
|
|
mPeakIntercept,
|
|
mZigZagPeakIndexes,
|
|
mZigZagPeaks //
|
|
);
|
|
|
|
//
|
|
// Vales ...
|
|
CalculateSlopeAndIntercept(
|
|
mValeSlope,
|
|
mValeIntercept,
|
|
mZigZagValeIndexes,
|
|
mZigZagVales //
|
|
);
|
|
|
|
//
|
|
result =
|
|
(NotEmpty(mPeakSlope) &&
|
|
NotEmpty(mPeakIntercept)) ||
|
|
(NotEmpty(mValeSlope) &&
|
|
NotEmpty(mValeIntercept));
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detect Oldest and Youngest Time of Pivots ...
|
|
|
|
//
|
|
int idx = -1;
|
|
bool has = false;
|
|
|
|
//
|
|
// Oldest ...
|
|
has = FindOldestIndex(
|
|
idx,
|
|
mZigZagPivotTimes //
|
|
);
|
|
if (has)
|
|
{
|
|
mFromTime = mZigZagPivotTimes[idx];
|
|
}
|
|
|
|
//
|
|
// Youngest ...
|
|
has = FindYoungesttIndex(
|
|
idx,
|
|
mZigZagPivotTimes //
|
|
);
|
|
if (has)
|
|
{
|
|
mToTime = mZigZagPivotTimes[idx];
|
|
}
|
|
|
|
//
|
|
// Validate Extracted Times ...
|
|
result =
|
|
IsSpecifiedValid(mToTime) &&
|
|
IsSpecifiedValid(mFromTime);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detect Extracted Times Bar Indexes ...
|
|
|
|
//
|
|
int mToIDX = iBarShift(
|
|
_Symbol,
|
|
_Period,
|
|
mToTime //
|
|
);
|
|
int mFromIDX = iBarShift(
|
|
_Symbol,
|
|
_Period,
|
|
mFromTime //
|
|
);
|
|
|
|
//
|
|
// Validate Detected Bar Indexes ...
|
|
result =
|
|
IsValidIndex(mToIDX) &&
|
|
IsValidIndex(mFromIDX);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Calculate Predictions ...
|
|
|
|
//
|
|
// Peak ...
|
|
mPeakTo = PredictValue(
|
|
mPeakSlope,
|
|
mPeakIntercept,
|
|
mToIDX //
|
|
);
|
|
mPeakFrom = PredictValue(
|
|
mPeakSlope,
|
|
mPeakIntercept,
|
|
mFromIDX //
|
|
);
|
|
|
|
//
|
|
// Vale ...
|
|
mValeTo = PredictValue(
|
|
mValeSlope,
|
|
mValeIntercept,
|
|
mToIDX //
|
|
);
|
|
mValeFrom = PredictValue(
|
|
mValeSlope,
|
|
mValeIntercept,
|
|
mFromIDX //
|
|
);
|
|
|
|
//
|
|
mUpperTrendDir =
|
|
mPeakFrom < mPeakTo
|
|
? X_DIRECTION_BULLISH
|
|
: mPeakFrom > mPeakTo
|
|
? X_DIRECTION_BEARISH
|
|
: X_DIRECTION_NONE;
|
|
mLowerTrendDir =
|
|
mValeFrom < mValeTo
|
|
? X_DIRECTION_BULLISH
|
|
: mValeFrom > mValeTo
|
|
? X_DIRECTION_BEARISH
|
|
: X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Prepare Support and Resistance Boxes ...
|
|
|
|
//
|
|
// Support ...
|
|
|
|
//
|
|
mSupportBox.Clean();
|
|
has = NotEmptyZero(mMinorSupport) &&
|
|
NotEmptyZero(mMajorSupport);
|
|
if (has)
|
|
{
|
|
//
|
|
mSupportBox.to = mToTime;
|
|
mSupportBox.from = mFromTime;
|
|
mSupportBox.symbol = _Symbol;
|
|
mSupportBox.period = _Period;
|
|
mSupportBox.type = "Support";
|
|
mSupportBox.upper = mMinorSupport;
|
|
mSupportBox.lower = mMajorSupport;
|
|
mSupportBox.dir = X_DIRECTION_BULLISH;
|
|
}
|
|
|
|
//
|
|
// Resistance ...
|
|
|
|
//
|
|
mResistanceBox.Clean();
|
|
has = NotEmptyZero(mMinorResistance) &&
|
|
NotEmptyZero(mMajorResistance);
|
|
if (has)
|
|
{
|
|
//
|
|
mResistanceBox.to = mToTime;
|
|
mResistanceBox.from = mFromTime;
|
|
mResistanceBox.symbol = _Symbol;
|
|
mResistanceBox.period = _Period;
|
|
mResistanceBox.type = "Resistance";
|
|
mResistanceBox.upper = mMajorResistance;
|
|
mResistanceBox.lower = mMinorResistance;
|
|
mResistanceBox.dir = X_DIRECTION_BEARISH;
|
|
}
|
|
|
|
//
|
|
result =
|
|
mSupportBox.IsValid() ||
|
|
mResistanceBox.IsValid();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
void DrawAnalysis()
|
|
{
|
|
//
|
|
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,
|
|
mFromTime,
|
|
mPeakFrom,
|
|
mToTime,
|
|
mPeakTo //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
// Apply Styles ...
|
|
|
|
//
|
|
color upperColor =
|
|
IsSpecifiedBullish(mUpperTrendDir)
|
|
? clrAqua
|
|
: IsSpecifiedBearish(mUpperTrendDir)
|
|
? clrMagenta
|
|
: clrGray; // Neutural ...
|
|
|
|
//
|
|
mUpperTrend.Width(2);
|
|
mUpperTrend.RayRight(true);
|
|
mUpperTrend.Color(upperColor);
|
|
}
|
|
|
|
//
|
|
// Vale ...
|
|
|
|
//
|
|
// Cleanup Lower Object ...
|
|
if (mLowerTrend != NULL)
|
|
{
|
|
//
|
|
mLowerTrend.Delete();
|
|
mLowerTrend.Detach();
|
|
delete mLowerTrend;
|
|
ZeroMemory(mLowerTrend);
|
|
}
|
|
|
|
//
|
|
mLowerTrend = new CChartObjectTrend();
|
|
isCreated = mLowerTrend.Create(
|
|
ChartID(),
|
|
"LowerTrend",
|
|
0,
|
|
mFromTime,
|
|
mValeFrom,
|
|
mToTime,
|
|
mValeTo //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
// Apply Styles ...
|
|
|
|
//
|
|
color lowerColor =
|
|
IsSpecifiedBullish(mLowerTrendDir)
|
|
? clrAqua
|
|
: IsSpecifiedBearish(mLowerTrendDir)
|
|
? clrMagenta
|
|
: clrGray; // Neutural ...
|
|
|
|
//
|
|
mLowerTrend.Width(2);
|
|
mLowerTrend.RayRight(true);
|
|
mLowerTrend.Color(lowerColor);
|
|
}
|
|
|
|
//
|
|
// Support ...
|
|
|
|
//
|
|
// Cleanup Support Object ...
|
|
if (mSupportObj != NULL)
|
|
{
|
|
//
|
|
mSupportObj.Delete();
|
|
mSupportObj.Detach();
|
|
delete mSupportObj;
|
|
ZeroMemory(mSupportObj);
|
|
}
|
|
|
|
//
|
|
isCreated = mSupportBox.IsValid();
|
|
if (isCreated)
|
|
{
|
|
//
|
|
datetime to = TimeCurrent();
|
|
mSupportObj = new XCBoxObject();
|
|
isCreated = mSupportObj.Create(
|
|
ChartID(),
|
|
0,
|
|
"Support",
|
|
mSupportBox.upper,
|
|
mSupportBox.lower,
|
|
mSupportBox.from,
|
|
to //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
// Apply Style ...
|
|
mSupportObj.BoxWidth(2);
|
|
mSupportObj.BoxColor(clrAqua);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Resistance ...
|
|
|
|
//
|
|
// Cleanup Resistance Object ...
|
|
if (mResistanceObj != NULL)
|
|
{
|
|
//
|
|
mResistanceObj.Delete();
|
|
mResistanceObj.Detach();
|
|
delete mResistanceObj;
|
|
ZeroMemory(mResistanceObj);
|
|
}
|
|
|
|
//
|
|
isCreated = mResistanceBox.IsValid();
|
|
if (isCreated)
|
|
{
|
|
//
|
|
datetime to = TimeCurrent();
|
|
mResistanceObj = new XCBoxObject();
|
|
isCreated = mResistanceObj.Create(
|
|
ChartID(),
|
|
0,
|
|
"Resistance",
|
|
mResistanceBox.upper,
|
|
mResistanceBox.lower,
|
|
mResistanceBox.from,
|
|
to //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
// Apply Style ...
|
|
mResistanceObj.BoxWidth(2);
|
|
mResistanceObj.BoxColor(clrMagenta);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
int FindOldestIndex(
|
|
int &index,
|
|
datetime ×[] //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Validate ...
|
|
if (!HasChild(times))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool has = false;
|
|
datetime tmpTime = NULL;
|
|
for (int i = 0; i < ArraySize(times); i++)
|
|
{
|
|
//
|
|
has =
|
|
!IsSpecifiedValid(tmpTime)
|
|
? true
|
|
: tmpTime > times[i];
|
|
if (has)
|
|
{
|
|
//
|
|
index = i;
|
|
tmpTime = times[i];
|
|
}
|
|
}
|
|
|
|
//
|
|
// Validate result ...
|
|
result =
|
|
IsValidIndex(index) &&
|
|
IsSpecifiedValid(tmpTime);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int FindYoungesttIndex(
|
|
int &index,
|
|
datetime ×[] //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Validate ...
|
|
if (!HasChild(times))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool has = false;
|
|
datetime tmpTime = NULL;
|
|
for (int i = 0; i < ArraySize(times); i++)
|
|
{
|
|
//
|
|
has =
|
|
!IsSpecifiedValid(tmpTime)
|
|
? true
|
|
: tmpTime < times[i];
|
|
if (has)
|
|
{
|
|
//
|
|
index = i;
|
|
tmpTime = times[i];
|
|
}
|
|
}
|
|
|
|
//
|
|
// Validate result ...
|
|
result =
|
|
IsValidIndex(index) &&
|
|
IsSpecifiedValid(tmpTime);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
// |