Complete Test Linear Regression and Required to Apply Works on Real Project ...
This commit is contained in:
@@ -1,186 +1,641 @@
|
||||
// //
|
||||
// // Detect At lease Two PEAK and Two Vale ...
|
||||
// XZigZagPoint tmpPoints[];
|
||||
// Copy(
|
||||
// points,
|
||||
// tmpPoints //
|
||||
// );
|
||||
// //
|
||||
// // Detect At lease Two PEAK and Two Vale ...
|
||||
// XZigZagPoint tmpPoints[];
|
||||
// Copy(
|
||||
// points,
|
||||
// tmpPoints //
|
||||
// );
|
||||
|
||||
// //
|
||||
// // Detect Highs ...
|
||||
// //
|
||||
// // Detect Highs ...
|
||||
|
||||
// //
|
||||
// // Highest High ...
|
||||
// //
|
||||
// // Highest High ...
|
||||
|
||||
// //
|
||||
// XZigZagPoint iZGPeak1;
|
||||
// XZigZagPoint iZGPeak2;
|
||||
// //
|
||||
// XZigZagPoint iZGPeak1;
|
||||
// XZigZagPoint iZGPeak2;
|
||||
|
||||
// //
|
||||
// // First ...
|
||||
// int idx = GetHighest(
|
||||
// tmpPoints,
|
||||
// X_ZIGZAG_POINT_TYPE_PEAK //
|
||||
// );
|
||||
// result = IsValidIndex(idx);
|
||||
// if (!result)
|
||||
// {
|
||||
// //
|
||||
// Clean();
|
||||
// iZGPeak1.Clean();
|
||||
// iZGPeak2.Clean();
|
||||
// SpecifiedClean(tmpPoints);
|
||||
// //
|
||||
// // First ...
|
||||
// int idx = GetHighest(
|
||||
// tmpPoints,
|
||||
// X_ZIGZAG_POINT_TYPE_PEAK //
|
||||
// );
|
||||
// result = IsValidIndex(idx);
|
||||
// if (!result)
|
||||
// {
|
||||
// //
|
||||
// Clean();
|
||||
// iZGPeak1.Clean();
|
||||
// iZGPeak2.Clean();
|
||||
// SpecifiedClean(tmpPoints);
|
||||
|
||||
// //
|
||||
// return result;
|
||||
// }
|
||||
// iZGPeak1 = tmpPoints[idx];
|
||||
// ArrayRemove(
|
||||
// tmpPoints,
|
||||
// idx,
|
||||
// 1 //
|
||||
// );
|
||||
// //
|
||||
// return result;
|
||||
// }
|
||||
// iZGPeak1 = tmpPoints[idx];
|
||||
// ArrayRemove(
|
||||
// tmpPoints,
|
||||
// idx,
|
||||
// 1 //
|
||||
// );
|
||||
|
||||
// //
|
||||
// // Second ...
|
||||
// idx = GetHighest(
|
||||
// tmpPoints,
|
||||
// X_ZIGZAG_POINT_TYPE_PEAK //
|
||||
// );
|
||||
// result = IsValidIndex(idx);
|
||||
// if (!result)
|
||||
// {
|
||||
// //
|
||||
// Clean();
|
||||
// iZGPeak1.Clean();
|
||||
// iZGPeak2.Clean();
|
||||
// SpecifiedClean(tmpPoints);
|
||||
// //
|
||||
// // Second ...
|
||||
// idx = GetHighest(
|
||||
// tmpPoints,
|
||||
// X_ZIGZAG_POINT_TYPE_PEAK //
|
||||
// );
|
||||
// result = IsValidIndex(idx);
|
||||
// if (!result)
|
||||
// {
|
||||
// //
|
||||
// Clean();
|
||||
// iZGPeak1.Clean();
|
||||
// iZGPeak2.Clean();
|
||||
// SpecifiedClean(tmpPoints);
|
||||
|
||||
// //
|
||||
// return result;
|
||||
// }
|
||||
// iZGPeak2 = tmpPoints[idx];
|
||||
// ArrayRemove(
|
||||
// tmpPoints,
|
||||
// idx,
|
||||
// 1 //
|
||||
// );
|
||||
// //
|
||||
// return result;
|
||||
// }
|
||||
// iZGPeak2 = tmpPoints[idx];
|
||||
// ArrayRemove(
|
||||
// tmpPoints,
|
||||
// idx,
|
||||
// 1 //
|
||||
// );
|
||||
|
||||
// //
|
||||
// // Detect Lows ...
|
||||
// //
|
||||
// // Detect Lows ...
|
||||
|
||||
// //
|
||||
// XZigZagPoint iZGVale1;
|
||||
// XZigZagPoint iZGVale2;
|
||||
// //
|
||||
// XZigZagPoint iZGVale1;
|
||||
// XZigZagPoint iZGVale2;
|
||||
|
||||
// //
|
||||
// // First ...
|
||||
// idx = GetLowest(
|
||||
// tmpPoints,
|
||||
// X_ZIGZAG_POINT_TYPE_VALE //
|
||||
// );
|
||||
// result = IsValidIndex(idx);
|
||||
// if (!result)
|
||||
// {
|
||||
// //
|
||||
// Clean();
|
||||
// iZGPeak1.Clean();
|
||||
// iZGPeak2.Clean();
|
||||
// iZGVale1.Clean();
|
||||
// iZGVale2.Clean();
|
||||
// SpecifiedClean(tmpPoints);
|
||||
// //
|
||||
// // First ...
|
||||
// idx = GetLowest(
|
||||
// tmpPoints,
|
||||
// X_ZIGZAG_POINT_TYPE_VALE //
|
||||
// );
|
||||
// result = IsValidIndex(idx);
|
||||
// if (!result)
|
||||
// {
|
||||
// //
|
||||
// Clean();
|
||||
// iZGPeak1.Clean();
|
||||
// iZGPeak2.Clean();
|
||||
// iZGVale1.Clean();
|
||||
// iZGVale2.Clean();
|
||||
// SpecifiedClean(tmpPoints);
|
||||
|
||||
// //
|
||||
// return result;
|
||||
// }
|
||||
// iZGVale1 = tmpPoints[idx];
|
||||
// ArrayRemove(
|
||||
// tmpPoints,
|
||||
// idx,
|
||||
// 1 //
|
||||
// );
|
||||
// //
|
||||
// return result;
|
||||
// }
|
||||
// iZGVale1 = tmpPoints[idx];
|
||||
// ArrayRemove(
|
||||
// tmpPoints,
|
||||
// idx,
|
||||
// 1 //
|
||||
// );
|
||||
|
||||
// //
|
||||
// // Second ...
|
||||
// idx = GetLowest(
|
||||
// tmpPoints,
|
||||
// X_ZIGZAG_POINT_TYPE_VALE //
|
||||
// );
|
||||
// result = IsValidIndex(idx);
|
||||
// if (!result)
|
||||
// {
|
||||
// //
|
||||
// Clean();
|
||||
// iZGPeak1.Clean();
|
||||
// iZGPeak2.Clean();
|
||||
// iZGVale1.Clean();
|
||||
// iZGVale2.Clean();
|
||||
// SpecifiedClean(tmpPoints);
|
||||
// //
|
||||
// // Second ...
|
||||
// idx = GetLowest(
|
||||
// tmpPoints,
|
||||
// X_ZIGZAG_POINT_TYPE_VALE //
|
||||
// );
|
||||
// result = IsValidIndex(idx);
|
||||
// if (!result)
|
||||
// {
|
||||
// //
|
||||
// Clean();
|
||||
// iZGPeak1.Clean();
|
||||
// iZGPeak2.Clean();
|
||||
// iZGVale1.Clean();
|
||||
// iZGVale2.Clean();
|
||||
// SpecifiedClean(tmpPoints);
|
||||
|
||||
// //
|
||||
// return result;
|
||||
// }
|
||||
// iZGVale2 = tmpPoints[idx];
|
||||
// ArrayRemove(
|
||||
// tmpPoints,
|
||||
// idx,
|
||||
// 1 //
|
||||
// );
|
||||
// //
|
||||
// return result;
|
||||
// }
|
||||
// iZGVale2 = tmpPoints[idx];
|
||||
// ArrayRemove(
|
||||
// tmpPoints,
|
||||
// idx,
|
||||
// 1 //
|
||||
// );
|
||||
|
||||
// //
|
||||
// // Check Directions ...
|
||||
// bool isBullish =
|
||||
// //
|
||||
// (iZGPeak1.time > iZGPeak2.time &&
|
||||
// iZGVale1.time < iZGVale2.time)
|
||||
// //
|
||||
// ;
|
||||
// bool isBearish =
|
||||
// //
|
||||
// (iZGPeak1.time < iZGPeak2.time &&
|
||||
// iZGVale1.time > iZGVale2.time)
|
||||
// //
|
||||
// ;
|
||||
// result =
|
||||
// (isBullish && !isBearish) ||
|
||||
// (isBearish && !isBullish);
|
||||
// if (!result)
|
||||
// {
|
||||
// //
|
||||
// Clean();
|
||||
// iZGPeak1.Clean();
|
||||
// iZGPeak2.Clean();
|
||||
// iZGVale1.Clean();
|
||||
// iZGVale2.Clean();
|
||||
// SpecifiedClean(tmpPoints);
|
||||
// //
|
||||
// // Check Directions ...
|
||||
// bool isBullish =
|
||||
// //
|
||||
// (iZGPeak1.time > iZGPeak2.time &&
|
||||
// iZGVale1.time < iZGVale2.time)
|
||||
// //
|
||||
// ;
|
||||
// bool isBearish =
|
||||
// //
|
||||
// (iZGPeak1.time < iZGPeak2.time &&
|
||||
// iZGVale1.time > iZGVale2.time)
|
||||
// //
|
||||
// ;
|
||||
// result =
|
||||
// (isBullish && !isBearish) ||
|
||||
// (isBearish && !isBullish);
|
||||
// if (!result)
|
||||
// {
|
||||
// //
|
||||
// Clean();
|
||||
// iZGPeak1.Clean();
|
||||
// iZGPeak2.Clean();
|
||||
// iZGVale1.Clean();
|
||||
// iZGVale2.Clean();
|
||||
// SpecifiedClean(tmpPoints);
|
||||
|
||||
// //
|
||||
// return result;
|
||||
// }
|
||||
// //
|
||||
// return result;
|
||||
// }
|
||||
|
||||
// //
|
||||
// // Setting Direction ...
|
||||
// dir =
|
||||
// isBullish
|
||||
// ? X_DIRECTION_BULLISH
|
||||
// : isBearish
|
||||
// ? X_DIRECTION_BEARISH
|
||||
// : X_DIRECTION_NONE;
|
||||
// //
|
||||
// // Setting Direction ...
|
||||
// dir =
|
||||
// isBullish
|
||||
// ? X_DIRECTION_BULLISH
|
||||
// : isBearish
|
||||
// ? X_DIRECTION_BEARISH
|
||||
// : X_DIRECTION_NONE;
|
||||
|
||||
// //
|
||||
// // Setting Points ...
|
||||
// Copy(
|
||||
// points,
|
||||
// pivots //
|
||||
// );
|
||||
// //
|
||||
// // Setting Points ...
|
||||
// Copy(
|
||||
// points,
|
||||
// pivots //
|
||||
// );
|
||||
|
||||
//
|
||||
// Cleanup Resources ...
|
||||
// iZGPeak1.Clean();
|
||||
// iZGPeak2.Clean();
|
||||
// iZGVale1.Clean();
|
||||
// iZGVale2.Clean();
|
||||
// SpecifiedClean(tmpPoints);
|
||||
|
||||
/**
|
||||
* Analyse Market Structure ...
|
||||
*
|
||||
* @param bar: XOHCL, Specified Bar ...
|
||||
* @param _pivots: XZigZagPivot, Specified ZigZag Points Collection ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool Analyse(
|
||||
XOHCL &bar,
|
||||
XZigZagPivot &_pivots[] //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = bar.IsValid() &&
|
||||
HasChild(_pivots) &&
|
||||
bar.symbol == _pivots[0].symbol;
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
Clean();
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// AssignSymbol and Period ...
|
||||
time = bar.time;
|
||||
symbol = bar.symbol;
|
||||
period = bar.period;
|
||||
Copy(_pivots, pivots);
|
||||
|
||||
//
|
||||
// Calculate Peaks and Vales Regressions ...
|
||||
|
||||
//
|
||||
// Peaks Processing ...
|
||||
double mPeak = 0;
|
||||
double bPeak = 0;
|
||||
result = ValidateZigZagPivots(
|
||||
mPeak,
|
||||
bPeak,
|
||||
_pivots,
|
||||
X_ZIGZAG_PIVOT_TYPE_PEAK //
|
||||
);
|
||||
|
||||
//
|
||||
// Vales Processing ...
|
||||
double mVale = 0;
|
||||
double bVale = 0;
|
||||
result =
|
||||
result &&
|
||||
ValidateZigZagPivots(
|
||||
mVale,
|
||||
bVale,
|
||||
_pivots,
|
||||
X_ZIGZAG_PIVOT_TYPE_VALE //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
Clean();
|
||||
// SpecifiedClean(recentPeaks);
|
||||
// SpecifiedClean(recentVales);
|
||||
|
||||
//
|
||||
// Cleanup Resources ...
|
||||
// iZGPeak1.Clean();
|
||||
// iZGPeak2.Clean();
|
||||
// iZGVale1.Clean();
|
||||
// iZGVale2.Clean();
|
||||
// SpecifiedClean(tmpPoints);
|
||||
return result;
|
||||
}
|
||||
|
||||
// //
|
||||
// // Extracting Pivots ...
|
||||
// int numberOfPivots = 2;
|
||||
|
||||
// //
|
||||
// // Reading Recent Peaks ...
|
||||
// XZigZagPivot recentPeaks[];
|
||||
// int recentPeaksCount = GetRecent(
|
||||
// _pivots,
|
||||
// recentPeaks,
|
||||
// numberOfPivots,
|
||||
// X_ZIGZAG_PIVOT_TYPE_PEAK //
|
||||
// );
|
||||
|
||||
// //
|
||||
// // Reading Recent Vales ...
|
||||
// XZigZagPivot recentVales[];
|
||||
// int recentValesCount = GetRecent(
|
||||
// _pivots,
|
||||
// recentVales,
|
||||
// numberOfPivots,
|
||||
// X_ZIGZAG_PIVOT_TYPE_VALE //
|
||||
// );
|
||||
|
||||
// //
|
||||
// // Validate Pivots ...
|
||||
// result =
|
||||
// recentPeaksCount >= numberOfPivots &&
|
||||
// recentValesCount >= numberOfPivots;
|
||||
// if (!result)
|
||||
// {
|
||||
// //
|
||||
// Clean();
|
||||
// SpecifiedClean(recentPeaks);
|
||||
// SpecifiedClean(recentVales);
|
||||
|
||||
// //
|
||||
// return result;
|
||||
// }
|
||||
|
||||
// //
|
||||
// // Detect Direction ...
|
||||
|
||||
// //
|
||||
// int zIdx = 0;
|
||||
// int pIdx = numberOfPivots - 1;
|
||||
|
||||
// //
|
||||
// bool isBullish =
|
||||
// recentPeaks[zIdx].value > recentPeaks[pIdx].value &&
|
||||
// recentVales[zIdx].value > recentVales[pIdx].value;
|
||||
|
||||
// //
|
||||
// bool isBearish =
|
||||
// recentPeaks[zIdx].value < recentPeaks[pIdx].value &&
|
||||
// recentVales[zIdx].value < recentVales[pIdx].value;
|
||||
|
||||
// //
|
||||
// result = isBullish || isBearish;
|
||||
// if (!result)
|
||||
// {
|
||||
// //
|
||||
// Clean();
|
||||
// SpecifiedClean(recentPeaks);
|
||||
// SpecifiedClean(recentVales);
|
||||
|
||||
// //
|
||||
// return result;
|
||||
// }
|
||||
|
||||
// //
|
||||
// dir =
|
||||
// isBullish
|
||||
// ? X_DIRECTION_BULLISH
|
||||
// : X_DIRECTION_BEARISH;
|
||||
|
||||
//
|
||||
// Calculate Support and Resistance ...
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = IsValid();
|
||||
if (!result)
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// SpecifiedClean(recentPeaks);
|
||||
// SpecifiedClean(recentVales);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ValidateZigZagPivots(
|
||||
double &_pivot,
|
||||
double &_processed,
|
||||
XZigZagPivot &_pivots[],
|
||||
ENUM_X_ZIGZAG_POINT_TYPE _type //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Prepare ...
|
||||
_pivot = 0;
|
||||
_processed = 0;
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = HasChild(_pivots);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Required Variables for Calculations ...
|
||||
double sumT = 0;
|
||||
double sumP = 0;
|
||||
double sumTP = 0;
|
||||
double sumT2 = 0;
|
||||
bool has = false;
|
||||
int typeCount = 0;
|
||||
|
||||
//
|
||||
// Loop Through Pivots to Calculate Specified
|
||||
// Type Pivots Summaries ...
|
||||
int count = ArraySize(_pivots);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
// Check Type Passed ...
|
||||
has =
|
||||
!IsXValid(_type)
|
||||
? true
|
||||
: _type == _pivots[i].type;
|
||||
if (!has)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
typeCount++;
|
||||
double iP = _pivots[i].value;
|
||||
double iT = (double)_pivots[i].time;
|
||||
|
||||
//
|
||||
sumT += iT;
|
||||
sumP += iP;
|
||||
sumTP += iT * iP;
|
||||
sumT2 += iT * iP;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Process Values ...
|
||||
double denominator = typeCount * sumT2 - sumT * sumT;
|
||||
if (denominator != 0)
|
||||
{
|
||||
//
|
||||
_pivot = (typeCount * sumTP - sumT * sumP) / denominator;
|
||||
_processed = (sumP - _pivot * sumT) / typeCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
_processed = sumP / typeCount;
|
||||
}
|
||||
|
||||
//
|
||||
// Validating Result ...
|
||||
result = _pivot > 0 &&
|
||||
_processed > 0;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyse Market Structure ...
|
||||
*
|
||||
* @param bar: XOHCL, Specified Bar ...
|
||||
* @param _pivots: XZigZagPivot, Specified ZigZag Points Collection ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool Analyse(
|
||||
XOHCL &bar,
|
||||
XZigZagPivot &_pivots[] //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = bar.IsValid() &&
|
||||
HasChild(_pivots) &&
|
||||
bar.symbol == _pivots[0].symbol;
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
Clean();
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Assign Requirements ...
|
||||
|
||||
//
|
||||
time = bar.time;
|
||||
symbol = bar.symbol;
|
||||
period = bar.period;
|
||||
Copy(_pivots, pivots);
|
||||
|
||||
//
|
||||
int oldestPeakIdx = GetOldest(pivots, X_ZIGZAG_PIVOT_TYPE_PEAK);
|
||||
int oldestValeIdx = GetOldest(pivots, X_ZIGZAG_PIVOT_TYPE_VALE);
|
||||
int youngestPeakIdx = GetYoungest(pivots, X_ZIGZAG_PIVOT_TYPE_PEAK);
|
||||
int youngestValeIdx = GetYoungest(pivots, X_ZIGZAG_PIVOT_TYPE_VALE);
|
||||
|
||||
//
|
||||
// Calculate Peaks and Vales Regressions ...
|
||||
|
||||
//
|
||||
// Peaks Processing ...
|
||||
double mPeak = 0;
|
||||
double bPeak = 0;
|
||||
bool hasPeak = ValidateZigZagPivots(
|
||||
mPeak,
|
||||
bPeak,
|
||||
pivots,
|
||||
X_ZIGZAG_PIVOT_TYPE_PEAK //
|
||||
);
|
||||
|
||||
//
|
||||
// Vales Processing ...
|
||||
double mVale = 0;
|
||||
double bVale = 0;
|
||||
bool hasVale = ValidateZigZagPivots(
|
||||
mVale,
|
||||
bVale,
|
||||
pivots,
|
||||
X_ZIGZAG_PIVOT_TYPE_VALE //
|
||||
);
|
||||
|
||||
//
|
||||
// Validate Calculated requirements ...
|
||||
result =
|
||||
(hasPeak || hasVale) &&
|
||||
(IsValidIndex(oldestPeakIdx) &&
|
||||
IsValidIndex(oldestValeIdx) &&
|
||||
IsValidIndex(youngestPeakIdx) &&
|
||||
IsValidIndex(youngestValeIdx));
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
Clean();
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculating Values ...
|
||||
|
||||
//
|
||||
peakToTime = pivots[youngestPeakIdx].time;
|
||||
peakFromTime = pivots[oldestPeakIdx].time;
|
||||
|
||||
//
|
||||
valeToTime = pivots[youngestValeIdx].time;
|
||||
valeFromTime = pivots[oldestValeIdx].time;
|
||||
|
||||
//
|
||||
// Check Different Senarios ...
|
||||
// 1-Valid Peak and Valid Vale Exists ...
|
||||
if (hasPeak && hasVale)
|
||||
{
|
||||
//
|
||||
// When Slopes Have same Sign, Use Average Slope for Parallel Lines ...
|
||||
if (mPeak * mVale > 0)
|
||||
{
|
||||
//
|
||||
// Calculating Parallel Slopes ...
|
||||
double slopeParallel = (mPeak + mVale) / 2;
|
||||
double bParallelPeak = pivots[youngestPeakIdx].value - slopeParallel * (double)peakToTime;
|
||||
double bParallelVale = pivots[youngestValeIdx].value - slopeParallel * (double)valeToTime;
|
||||
|
||||
//
|
||||
// Peak ...
|
||||
peakTo = slopeParallel * (double)peakToTime + bParallelPeak;
|
||||
peakFrom = slopeParallel * (double)peakFromTime + bParallelPeak;
|
||||
|
||||
//
|
||||
// Vale ...
|
||||
valeTo = slopeParallel * (double)valeToTime + bParallelVale;
|
||||
valeFrom = slopeParallel * (double)valeFromTime + bParallelVale;
|
||||
}
|
||||
else
|
||||
//
|
||||
// separate trendlines if slopes differ ...
|
||||
{
|
||||
//
|
||||
// Peak ...
|
||||
peakTo = mPeak * (double)peakToTime + bPeak;
|
||||
peakFrom = mPeak * (double)peakFromTime + bPeak;
|
||||
|
||||
//
|
||||
// Vale ...
|
||||
valeTo = mVale * (double)valeToTime + bVale;
|
||||
valeFrom = mVale * (double)valeFromTime + bVale;
|
||||
}
|
||||
}
|
||||
else
|
||||
//
|
||||
// Only one of them Exists ...
|
||||
{
|
||||
//
|
||||
// Valid Peak ...
|
||||
if (hasPeak)
|
||||
{
|
||||
//
|
||||
// Peak ...
|
||||
peakTo = mPeak * (double)peakToTime + bPeak;
|
||||
peakFrom = mPeak * (double)peakFromTime + bPeak;
|
||||
}
|
||||
|
||||
//
|
||||
// Valid Vale ...
|
||||
if (hasVale)
|
||||
{
|
||||
//
|
||||
// Vale ...
|
||||
valeTo = mVale * (double)valeToTime + bVale;
|
||||
valeFrom = mVale * (double)valeFromTime + bVale;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Detecting Direction ...
|
||||
|
||||
//
|
||||
bool isBullish =
|
||||
valeTo > valeFrom ||
|
||||
(valeTo > valeFrom &&
|
||||
peakTo > peakFrom);
|
||||
|
||||
//
|
||||
bool isBearish =
|
||||
peakTo < peakFrom ||
|
||||
(peakTo < peakFrom &&
|
||||
valeTo < valeFrom);
|
||||
|
||||
//
|
||||
// Validate When Only One Direction Exists ...
|
||||
result =
|
||||
(isBullish && !isBearish) ||
|
||||
(isBearish && !isBullish);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
Clean();
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
dir =
|
||||
isBullish
|
||||
? X_DIRECTION_BULLISH
|
||||
: X_DIRECTION_BEARISH;
|
||||
|
||||
//
|
||||
// Calculate Support and Resistance ...
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = IsValid();
|
||||
if (!result)
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,294 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| 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;
|
||||
|
||||
//
|
||||
// Variables ...
|
||||
double mSumX = 0;
|
||||
double mSumY = 0;
|
||||
double mSumXY = 0;
|
||||
double mSumX2 = 0;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
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;
|
||||
|
||||
//
|
||||
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();
|
||||
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;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -1147,34 +1147,175 @@ void DetectPatterns()
|
||||
{
|
||||
//
|
||||
// ZIGZAG Pattern ...
|
||||
if (detectZIGZAGPatterns)
|
||||
// if (detectZIGZAGPatterns)
|
||||
// {
|
||||
// //
|
||||
// // Detect Market Analysis ...
|
||||
// XZigZagAnalysis zAnalysis;
|
||||
// has = fima2Signaller.fimaPOIDetector.AnalyseMarketUsingZigZag(
|
||||
// cBar,
|
||||
// cBar.period,
|
||||
// fima2Signaller.fimaHelper,
|
||||
// zAnalysis,
|
||||
// 15 //
|
||||
// );
|
||||
// if (has)
|
||||
// {
|
||||
// //
|
||||
// Print(ShortName + zAnalysis.GetMessage());
|
||||
|
||||
// //
|
||||
// XCZigZagAnalysisObject *iObj;
|
||||
// has = fima2Signaller.fimaPOIDrawer.DrawZigZagMarketAnalysisByPV(
|
||||
// iObj,
|
||||
// zAnalysis //
|
||||
// );
|
||||
// if (has)
|
||||
// {
|
||||
// draws.Add(iObj);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
//
|
||||
// Reading Pivots ...
|
||||
double iLows[];
|
||||
double iHighs[];
|
||||
double lowTo = 0;
|
||||
double highTo = 0;
|
||||
double lowFrom = 0;
|
||||
double highFrom = 0;
|
||||
datetime lowToTime = NULL;
|
||||
datetime highToTime = NULL;
|
||||
datetime lowFromTime = NULL;
|
||||
datetime highFromTime = NULL;
|
||||
double lowsSlope = EMPTY_VALUE;
|
||||
double highsSlope = EMPTY_VALUE;
|
||||
double lowsIntercept = EMPTY_VALUE;
|
||||
double highsIntercept = EMPTY_VALUE;
|
||||
|
||||
//
|
||||
int iLoopbackLength = 50;
|
||||
for (int i = 0; i < iLoopbackLength; i++)
|
||||
{
|
||||
//
|
||||
// Detect Market Analysis ...
|
||||
XZigZagAnalysis zAnalysis;
|
||||
has = fima2Signaller.fimaPOIDetector.AnalyseMarketUsingZigZag(
|
||||
cBar,
|
||||
cBar.period,
|
||||
fima2Signaller.fimaHelper,
|
||||
zAnalysis,
|
||||
15 //
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
Print(ShortName + zAnalysis.GetMessage());
|
||||
double iLowPrice = iLow(_Symbol, _Period, i);
|
||||
double iHighPrice = iHigh(_Symbol, _Period, i);
|
||||
|
||||
//
|
||||
XCZigZagAnalysisObject *iObj;
|
||||
has = fima2Signaller.fimaPOIDrawer.DrawZigZagMarketAnalysis(
|
||||
iObj,
|
||||
zAnalysis //
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
draws.Add(iObj);
|
||||
}
|
||||
}
|
||||
//
|
||||
Add(
|
||||
iLowPrice,
|
||||
iLows //
|
||||
);
|
||||
Add(
|
||||
iHighPrice,
|
||||
iHighs //
|
||||
);
|
||||
}
|
||||
has = CalculateLinearRegression(
|
||||
lowsSlope,
|
||||
lowsIntercept,
|
||||
iLows,
|
||||
0,
|
||||
0 //
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
lowToTime = GetBarTime(
|
||||
_Symbol,
|
||||
_Period,
|
||||
0 //
|
||||
);
|
||||
lowTo = CalculateValueBySlopeIntercept(
|
||||
lowsSlope,
|
||||
lowsIntercept,
|
||||
0 //
|
||||
);
|
||||
|
||||
//
|
||||
lowFromTime = GetBarTime(
|
||||
_Symbol,
|
||||
_Period,
|
||||
iLoopbackLength //
|
||||
);
|
||||
lowFrom = CalculateValueBySlopeIntercept(
|
||||
lowsSlope,
|
||||
lowsIntercept,
|
||||
iLoopbackLength //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
has = CalculateLinearRegression(
|
||||
highsSlope,
|
||||
highsIntercept,
|
||||
iHighs,
|
||||
0,
|
||||
0 //
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
highToTime = GetBarTime(
|
||||
_Symbol,
|
||||
_Period,
|
||||
0 //
|
||||
);
|
||||
highTo = CalculateValueBySlopeIntercept(
|
||||
highsSlope,
|
||||
highsIntercept,
|
||||
0 //
|
||||
);
|
||||
|
||||
//
|
||||
highFromTime = GetBarTime(
|
||||
_Symbol,
|
||||
_Period,
|
||||
iLoopbackLength //
|
||||
);
|
||||
highFrom = CalculateValueBySlopeIntercept(
|
||||
highsSlope,
|
||||
highsIntercept,
|
||||
iLoopbackLength //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Try to Draw ...
|
||||
|
||||
//
|
||||
// Low ...
|
||||
CChartObjectTrend *iLowTrend;
|
||||
has = fima2Signaller.fimaPOIDrawer.DrawTrendLine(
|
||||
lowFrom,
|
||||
lowFromTime,
|
||||
lowTo,
|
||||
lowToTime,
|
||||
iLowTrend,
|
||||
"LOW_TREMD",
|
||||
true // Ray Right ...
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
draws.Add(iLowTrend);
|
||||
}
|
||||
|
||||
//
|
||||
// High ...
|
||||
CChartObjectTrend *iHighTrend;
|
||||
has = fima2Signaller.fimaPOIDrawer.DrawTrendLine(
|
||||
highFrom,
|
||||
highFromTime,
|
||||
highTo,
|
||||
highToTime,
|
||||
iHighTrend,
|
||||
"HIGH_TREMD",
|
||||
true // Ray Right ...
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
draws.Add(iHighTrend);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6654,9 +6654,9 @@ int GetPriceBoundary(
|
||||
int GetAppliedPrice(
|
||||
ENUM_X_PRICE mType,
|
||||
double &dest[],
|
||||
const double &mOpen[], // Open Prices
|
||||
const double &mHigh[], // High Preices
|
||||
const double &mLow[], // Low Prices
|
||||
const double &mOpen[], // Open Prices
|
||||
const double &mHigh[], // High Preices
|
||||
const double &mLow[], // Low Prices
|
||||
const double &mClose[] // Close Prices
|
||||
)
|
||||
{
|
||||
@@ -7061,3 +7061,135 @@ bool SetChartVolumesColor(
|
||||
//
|
||||
|
||||
//
|
||||
// START Linear Regression ...
|
||||
//
|
||||
|
||||
/**
|
||||
* Linear Regression Based Calculate Data ...
|
||||
* int this Senario X Axis is Buffer Index ...
|
||||
*
|
||||
* @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 ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool CalculateLinearRegression(
|
||||
double &_slope,
|
||||
double &_intercept,
|
||||
double &_source[],
|
||||
int _start = 0,
|
||||
int _count = 0 //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Prepare ...
|
||||
_slope = EMPTY_VALUE;
|
||||
_intercept = EMPTY_VALUE;
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
int count = ArraySize(_source);
|
||||
result = IsValidSize(count);
|
||||
if (!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 sumY = 0;
|
||||
double sumXY = 0;
|
||||
double sumX2 = 0;
|
||||
|
||||
//
|
||||
// Looping Through Source Buffer to Cellect Data ...
|
||||
for (int i = _start; i < _end; i++)
|
||||
{
|
||||
//
|
||||
double x = i + 1;
|
||||
double y = _source[i];
|
||||
|
||||
//
|
||||
sumX += x;
|
||||
sumY += y;
|
||||
sumXY += x * y;
|
||||
sumX2 += x * x;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Slope and Intercept ...
|
||||
int n = _count;
|
||||
_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;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
double CalculateValueBySlopeIntercept(
|
||||
double _slope,
|
||||
double _intercept,
|
||||
int _index //
|
||||
)
|
||||
{
|
||||
//
|
||||
double result = EMPTY_VALUE;
|
||||
|
||||
//
|
||||
// Normalize Index ...
|
||||
_index = NormalizeInt(_index, 1);
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
if (
|
||||
!NotEmpty(_slope) ||
|
||||
!NotEmpty(_intercept) ||
|
||||
!IsValidIndex(_index))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = (_intercept + _slope * _index);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// END Linear Regression ...
|
||||
//
|
||||
|
||||
//
|
||||
|
||||
@@ -44,7 +44,7 @@ class XCXFIMAPOIDrawer : public XCPOIDrawer
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool DrawZigZagMarketAnalysis(
|
||||
bool DrawZigZagMarketAnalysisByPV(
|
||||
XCZigZagAnalysisObject *&object,
|
||||
XZigZagAnalysis &model,
|
||||
bool rayRight = false,
|
||||
@@ -69,7 +69,78 @@ class XCXFIMAPOIDrawer : public XCPOIDrawer
|
||||
|
||||
//
|
||||
object = new XCZigZagAnalysisObject();
|
||||
result = object.Create(
|
||||
result = object.CreateByPV(
|
||||
ChartIdentification(),
|
||||
SubWindowIdentification(),
|
||||
model //
|
||||
);
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
// Apply Style ...
|
||||
bool isBullish = model.IsBullish();
|
||||
|
||||
//
|
||||
XPOIStyle style;
|
||||
if (isBullish)
|
||||
{
|
||||
style = defaultBullishStyle;
|
||||
}
|
||||
else
|
||||
{
|
||||
style = defaultBearishStyle;
|
||||
}
|
||||
|
||||
//
|
||||
ApplyZigZagMarketAnalysisStyle(
|
||||
object,
|
||||
style,
|
||||
true, // Ray Right ...
|
||||
false // Ray Left ...
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw Specified XZigZagMarketStyle on Chart ...
|
||||
*
|
||||
* @param object: XCZigZagAnalysisObject, pointer reference to Drawn Object ...
|
||||
* @param model: XZigZagAnalysis, reference to Model ...
|
||||
* @param numberOfPivots: int, required number of pivots for Draw Trends ...
|
||||
* @param rayRight: bool, Ray To Right ...
|
||||
* @param rayLeft: bool, Ray To Left ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool DrawZigZagMarketAnalysisByRecent(
|
||||
XCZigZagAnalysisObject *&object,
|
||||
XZigZagAnalysis &model,
|
||||
bool rayRight = false,
|
||||
bool rayLeft = false,
|
||||
int numberOfPivots = 2 //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Prepare ...
|
||||
object = NULL;
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = model.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
object = new XCZigZagAnalysisObject();
|
||||
result = object.CreateByRecent(
|
||||
ChartIdentification(),
|
||||
SubWindowIdentification(),
|
||||
model,
|
||||
@@ -96,8 +167,8 @@ class XCXFIMAPOIDrawer : public XCPOIDrawer
|
||||
ApplyZigZagMarketAnalysisStyle(
|
||||
object,
|
||||
style,
|
||||
false, // Ray Right ...
|
||||
true // Ray Left ...
|
||||
true, // Ray Right ...
|
||||
false // Ray Left ...
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -570,7 +570,20 @@ struct XZigZagAnalysis
|
||||
XZigZagPivot pivots[]; // ZigZag Pivots ...
|
||||
|
||||
//
|
||||
ENUM_X_DIRECTION dir; // Direction ...
|
||||
// Calculated Values ...
|
||||
double peakTo; // Recent Peak ..
|
||||
double valeTo; // Recent Vale ...
|
||||
double peakFrom; // Previous Peak ...
|
||||
double valeFrom; // Previous Vale ...
|
||||
double peakSlope; // Calculated Slope for Peak ...
|
||||
double valeSlope; // Calculated Slope for Vale ...
|
||||
datetime peakToTime; // Recent Peak Time ...
|
||||
datetime valeToTime; // Recent Vale Time ...
|
||||
double peakIntercept; // Calculated Intercept for Peak ...
|
||||
double valeIntercept; // Calculated Intercept for Vale ...
|
||||
ENUM_X_DIRECTION dir; // Direction ...
|
||||
datetime peakFromTime; // Previous Peak Time ...
|
||||
datetime valeFromTime; // Previous Vale Time ...
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
@@ -611,78 +624,191 @@ struct XZigZagAnalysis
|
||||
}
|
||||
|
||||
//
|
||||
// AssignSymbol and Period ...
|
||||
// Assign Requirements ...
|
||||
|
||||
//
|
||||
time = bar.time;
|
||||
symbol = bar.symbol;
|
||||
period = bar.period;
|
||||
Copy(_pivots, pivots);
|
||||
|
||||
//
|
||||
// Extracting Pivots ...
|
||||
int numberOfPivots = 2;
|
||||
int oldestPeakIdx = GetOldest(pivots, X_ZIGZAG_PIVOT_TYPE_PEAK);
|
||||
int oldestValeIdx = GetOldest(pivots, X_ZIGZAG_PIVOT_TYPE_VALE);
|
||||
int youngestPeakIdx = GetYoungest(pivots, X_ZIGZAG_PIVOT_TYPE_PEAK);
|
||||
int youngestValeIdx = GetYoungest(pivots, X_ZIGZAG_PIVOT_TYPE_VALE);
|
||||
|
||||
//
|
||||
// Reading Recent Peaks ...
|
||||
XZigZagPivot recentPeaks[];
|
||||
int recentPeaksCount = GetRecent(
|
||||
_pivots,
|
||||
recentPeaks,
|
||||
numberOfPivots,
|
||||
X_ZIGZAG_PIVOT_TYPE_PEAK //
|
||||
);
|
||||
// Calculate Peaks and Vales Regressions ...
|
||||
|
||||
//
|
||||
// Reading Recent Vales ...
|
||||
XZigZagPivot recentVales[];
|
||||
int recentValesCount = GetRecent(
|
||||
_pivots,
|
||||
recentVales,
|
||||
numberOfPivots,
|
||||
X_ZIGZAG_PIVOT_TYPE_VALE //
|
||||
);
|
||||
// Peak Time ...
|
||||
peakToTime = pivots[youngestPeakIdx].time;
|
||||
peakFromTime = pivots[oldestPeakIdx].time;
|
||||
|
||||
//
|
||||
// Validate Pivots ...
|
||||
// Vale Time ...
|
||||
valeToTime = pivots[youngestValeIdx].time;
|
||||
valeFromTime = pivots[oldestValeIdx].time;
|
||||
|
||||
//
|
||||
// Validating Calculated Peaks and Vales Times ...
|
||||
result =
|
||||
recentPeaksCount >= numberOfPivots &&
|
||||
recentValesCount >= numberOfPivots;
|
||||
(IsSpecifiedValid(valeToTime) &&
|
||||
IsSpecifiedValid(valeFromTime)) ||
|
||||
(IsSpecifiedValid(peakToTime) &&
|
||||
IsSpecifiedValid(peakFromTime));
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
Clean();
|
||||
SpecifiedClean(recentPeaks);
|
||||
SpecifiedClean(recentVales);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Detect Direction ...
|
||||
// Calculate Slope and Intercepts ...
|
||||
|
||||
//
|
||||
int zIdx = 0;
|
||||
int pIdx = numberOfPivots - 1;
|
||||
|
||||
//
|
||||
bool isBullish =
|
||||
recentPeaks[zIdx].value > recentPeaks[pIdx].value &&
|
||||
recentVales[zIdx].value > recentVales[pIdx].value;
|
||||
|
||||
//
|
||||
bool isBearish =
|
||||
recentPeaks[zIdx].value < recentPeaks[pIdx].value &&
|
||||
recentVales[zIdx].value < recentVales[pIdx].value;
|
||||
|
||||
//
|
||||
result = isBullish || isBearish;
|
||||
// Peaks ...
|
||||
result = CalculateZigZagLinearRegression(
|
||||
peakSlope,
|
||||
peakIntercept,
|
||||
pivots,
|
||||
X_ZIGZAG_PIVOT_TYPE_PEAK //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
Clean();
|
||||
SpecifiedClean(recentPeaks);
|
||||
SpecifiedClean(recentVales);
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Vales ...
|
||||
result = CalculateZigZagLinearRegression(
|
||||
valeSlope,
|
||||
valeIntercept,
|
||||
pivots,
|
||||
X_ZIGZAG_PIVOT_TYPE_VALE //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
Clean();
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Peaks and Vales ...
|
||||
|
||||
//
|
||||
// Peaks ...
|
||||
|
||||
//
|
||||
int iPeakToIDX = GetBarIndex(
|
||||
symbol,
|
||||
period,
|
||||
peakToTime //
|
||||
);
|
||||
if (IsValidIndex(iPeakToIDX))
|
||||
{
|
||||
//
|
||||
peakTo = CalculateValueBySlopeIntercept(
|
||||
peakSlope,
|
||||
peakIntercept,
|
||||
iPeakToIDX //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
int iPeakFromIDX = GetBarIndex(
|
||||
symbol,
|
||||
period,
|
||||
peakFromTime //
|
||||
);
|
||||
if (IsValidIndex(iPeakFromIDX))
|
||||
{
|
||||
//
|
||||
peakFrom = CalculateValueBySlopeIntercept(
|
||||
peakSlope,
|
||||
peakIntercept,
|
||||
iPeakFromIDX //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Vales ...
|
||||
|
||||
//
|
||||
int iValeToIDX = GetBarIndex(
|
||||
symbol,
|
||||
period,
|
||||
valeToTime //
|
||||
);
|
||||
if (IsValidIndex(iValeToIDX))
|
||||
{
|
||||
//
|
||||
valeTo = CalculateValueBySlopeIntercept(
|
||||
valeSlope,
|
||||
valeIntercept,
|
||||
iValeToIDX //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
int iValeFromIDX = GetBarIndex(
|
||||
symbol,
|
||||
period,
|
||||
valeFromTime //
|
||||
);
|
||||
if (IsValidIndex(iValeFromIDX))
|
||||
{
|
||||
//
|
||||
valeFrom = CalculateValueBySlopeIntercept(
|
||||
valeSlope,
|
||||
valeIntercept,
|
||||
iValeFromIDX //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Validating Calculated Peaks and Vales ...
|
||||
result =
|
||||
(NotEmpty(valeTo) &&
|
||||
NotEmpty(valeFrom) > 0) ||
|
||||
(NotEmpty(peakTo) > 0 &&
|
||||
NotEmpty(peakFrom) > 0);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
Clean();
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Detecting Direction ...
|
||||
|
||||
//
|
||||
bool isBullish =
|
||||
valeTo > valeFrom ||
|
||||
(valeTo > valeFrom &&
|
||||
peakTo > peakFrom);
|
||||
|
||||
//
|
||||
bool isBearish =
|
||||
peakTo < peakFrom ||
|
||||
(peakTo < peakFrom &&
|
||||
valeTo < valeFrom);
|
||||
|
||||
//
|
||||
// Validate When Only One Direction Exists ...
|
||||
result =
|
||||
(isBullish && !isBearish) ||
|
||||
(isBearish && !isBullish);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
Clean();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -692,9 +818,6 @@ struct XZigZagAnalysis
|
||||
? X_DIRECTION_BULLISH
|
||||
: X_DIRECTION_BEARISH;
|
||||
|
||||
//
|
||||
Copy(_pivots, pivots);
|
||||
|
||||
//
|
||||
// Calculate Support and Resistance ...
|
||||
|
||||
@@ -706,10 +829,6 @@ struct XZigZagAnalysis
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
SpecifiedClean(recentPeaks);
|
||||
SpecifiedClean(recentVales);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
@@ -729,6 +848,16 @@ struct XZigZagAnalysis
|
||||
dir = X_DIRECTION_NONE;
|
||||
SpecifiedClean(pivots);
|
||||
|
||||
//
|
||||
peakTo = 0;
|
||||
valeTo = 0;
|
||||
peakFrom = 0;
|
||||
valeFrom = 0;
|
||||
peakToTime = NULL;
|
||||
valeToTime = NULL;
|
||||
peakFromTime = NULL;
|
||||
valeFromTime = NULL;
|
||||
|
||||
//
|
||||
ZeroMemory(this);
|
||||
}
|
||||
@@ -752,6 +881,30 @@ struct XZigZagAnalysis
|
||||
IsSpecifiedValid(symbol) &&
|
||||
IsSpecifiedValid(period)
|
||||
//
|
||||
&&
|
||||
//
|
||||
(
|
||||
//
|
||||
// Validate Peak ...
|
||||
(peakTo > 0 &&
|
||||
peakFrom > 0 &&
|
||||
peakSlope != EMPTY_VALUE &&
|
||||
peakIntercept != EMPTY_VALUE &&
|
||||
IsSpecifiedValid(peakToTime) &&
|
||||
IsSpecifiedValid(peakFromTime))
|
||||
//
|
||||
||
|
||||
//
|
||||
// Validate Vale ...
|
||||
(valeTo > 0 &&
|
||||
valeFrom > 0 &&
|
||||
valeSlope != EMPTY_VALUE &&
|
||||
valeIntercept != EMPTY_VALUE &&
|
||||
IsSpecifiedValid(valeToTime) &&
|
||||
IsSpecifiedValid(valeFromTime))
|
||||
//
|
||||
)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
@@ -1337,7 +1490,7 @@ class XCZigZagAnalysisObject : public XCBaseObject
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool Create(
|
||||
bool CreateByRecent(
|
||||
long chart_id,
|
||||
int window,
|
||||
XZigZagAnalysis &model,
|
||||
@@ -1392,10 +1545,10 @@ class XCZigZagAnalysisObject : public XCBaseObject
|
||||
chart_id,
|
||||
upperName,
|
||||
window,
|
||||
rPeaks[0].time,
|
||||
rPeaks[0].value,
|
||||
rPeaks[numberOfPivots - 1].time,
|
||||
rPeaks[numberOfPivots - 1].value //
|
||||
rPeaks[numberOfPivots - 1].value,
|
||||
rPeaks[0].time,
|
||||
rPeaks[0].value //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
@@ -1408,10 +1561,93 @@ class XCZigZagAnalysisObject : public XCBaseObject
|
||||
chart_id,
|
||||
lowerName,
|
||||
window,
|
||||
rVales[0].time,
|
||||
rVales[0].value,
|
||||
rVales[numberOfPivots - 1].time,
|
||||
rVales[numberOfPivots - 1].value //
|
||||
rVales[numberOfPivots - 1].value,
|
||||
rVales[0].time,
|
||||
rVales[0].value //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
mUpper.Detach();
|
||||
mUpper.Delete();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Setting Object Name ...
|
||||
if (result)
|
||||
{
|
||||
ObjName(objID);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Object ...
|
||||
*
|
||||
* @param chart_id: Long, Specified Chart ID ...
|
||||
* @param window: Integer, Specified Chart Window ID ...
|
||||
* @param model: XZigZagAnalysis, reference model ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool CreateByPV(
|
||||
long chart_id,
|
||||
int window,
|
||||
XZigZagAnalysis &model //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = model.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Generate Object ID ...
|
||||
string objID = model.GetObjectID();
|
||||
string upperName = "Upper_" + objID;
|
||||
string lowerName = "Lower_" + objID;
|
||||
|
||||
//
|
||||
// Extract Recent Pivots ...
|
||||
|
||||
//
|
||||
// Creating Upper ...
|
||||
result = mUpper.Create(
|
||||
chart_id,
|
||||
upperName,
|
||||
window,
|
||||
model.peakFromTime,
|
||||
model.peakFrom,
|
||||
model.peakToTime,
|
||||
model.peakTo //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Create Lower ...
|
||||
result = mLower.Create(
|
||||
chart_id,
|
||||
lowerName,
|
||||
window,
|
||||
model.valeFromTime,
|
||||
model.valeFrom,
|
||||
model.valeToTime,
|
||||
model.valeTo //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
@@ -1974,4 +2210,105 @@ int GetRecent(
|
||||
return result;
|
||||
}
|
||||
|
||||
bool CalculateZigZagLinearRegression(
|
||||
double &_slope,
|
||||
double &_intercept,
|
||||
XZigZagPivot &_pivots[],
|
||||
ENUM_X_ZIGZAG_POINT_TYPE _type //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Prepare ...
|
||||
_slope = EMPTY_VALUE;
|
||||
_intercept = EMPTY_VALUE;
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result =
|
||||
IsXValid(_type) &&
|
||||
HasChild(_pivots);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Extracted Type Specific Valus ...
|
||||
double values[];
|
||||
XZigZagPivot tmp[];
|
||||
XZigZagPivot iPivot;
|
||||
Copy(
|
||||
_pivots,
|
||||
tmp //
|
||||
);
|
||||
int count = ArraySize(tmp);
|
||||
while (HasChild(tmp))
|
||||
{
|
||||
//
|
||||
// Get Model ...
|
||||
iPivot = tmp[0];
|
||||
|
||||
//
|
||||
// Remove Model ...
|
||||
ArrayRemove(
|
||||
tmp,
|
||||
0,
|
||||
1 //
|
||||
);
|
||||
|
||||
//
|
||||
// Validate Type ...
|
||||
result = _type == iPivot.type;
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
// Add Value if Type Passed ...
|
||||
Add(
|
||||
iPivot.value,
|
||||
values //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
iPivot.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Validation Valus ...
|
||||
result = HasChild(values);
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
// Calculate Slope / Intercept ...
|
||||
result = CalculateLinearRegression(
|
||||
_slope,
|
||||
_intercept,
|
||||
values //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Validate Result ...
|
||||
result =
|
||||
_slope != EMPTY_VALUE &&
|
||||
_intercept != EMPTY_VALUE;
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
_slope = EMPTY_VALUE;
|
||||
_intercept = EMPTY_VALUE;
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup Resources ...
|
||||
iPivot.Clean();
|
||||
SpecifiedClean(tmp);
|
||||
SpecifiedClean(values);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
//
|
||||
Reference in New Issue
Block a user