Complete Test Linear Regression and Required to Apply Works on Real Project ...

This commit is contained in:
2025-09-21 17:49:39 +03:30
parent 84dc311c72
commit 7a4f1aa48b
6 changed files with 1688 additions and 258 deletions
+620 -165
View File
@@ -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)
{
//
// Cleanup Resources ...
// iZGPeak1.Clean();
// iZGPeak2.Clean();
// iZGVale1.Clean();
// iZGVale2.Clean();
// SpecifiedClean(tmpPoints);
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);
//
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;
}
+294
View File
@@ -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;
}
//
+166 -25
View File
@@ -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);
}
}
+137 -5
View File
@@ -6641,22 +6641,22 @@ int GetPriceBoundary(
/**
* Get Applied Price Buffer ...
*
*
* @param mType: ENUM_X_PRICE, Specified Price Type ...
* @param dest: double, Holds Destination Prices ...
* @param mOpen: double collection, Open Prices ...
* @param mHigh: double collection, High Prices ...
* @param mLow: double collection, Low Prices ...
* @param mClose: double collection, Close Prices ...
*
*
* @return ( int )
*/
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 ...
);
}
+396 -59
View File
@@ -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;
}
//