last ...
This commit is contained in:
@@ -0,0 +1,383 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| ZigZag Analyzer.mq5|
|
||||||
|
//| Copyright 2025, MetaQuotes Ltd.|
|
||||||
|
//| https://www.mql5.com/en/users/lynnchris|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
#property copyright "Copyright 2025, MetaQuotes Ltd."
|
||||||
|
#property link "https://www.mql5.com/en/users/lynnchris"
|
||||||
|
#property version "1.0"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
//
|
||||||
|
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||||
|
|
||||||
|
// Input parameters
|
||||||
|
input ENUM_TIMEFRAMES InpTimeFrame = PERIOD_CURRENT; // Timeframe to analyze
|
||||||
|
input int ZZ_Depth = 12; // ZigZag depth
|
||||||
|
input int ZZ_Deviation = 5; // ZigZag deviation
|
||||||
|
input int ZZ_Backstep = 3; // ZigZag backstep
|
||||||
|
input int LookBackBars = 500; // Bars to search for pivots
|
||||||
|
input int ExtendFutureBars = 100; // Bars to extend trendlines into the future
|
||||||
|
|
||||||
|
// Global indicator handle for ZigZag
|
||||||
|
int zzHandle;
|
||||||
|
|
||||||
|
// Arrays for ZigZag data and pivot storage
|
||||||
|
double zzBuffer[];
|
||||||
|
bool pivotIsPeak[];
|
||||||
|
double pivotPrices[];
|
||||||
|
datetime pivotTimes[];
|
||||||
|
|
||||||
|
// Variable to detect new bars
|
||||||
|
datetime lastBarTime = 0;
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
zzHandle = iCustom(
|
||||||
|
_Symbol,
|
||||||
|
InpTimeFrame,
|
||||||
|
"x-saherelm.xzg",
|
||||||
|
"",
|
||||||
|
ZZ_Depth,
|
||||||
|
ZZ_Deviation,
|
||||||
|
ZZ_Backstep,
|
||||||
|
X_PRICE_HIGH,
|
||||||
|
X_PRICE_LOW,
|
||||||
|
"",
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
159,
|
||||||
|
159 //
|
||||||
|
);
|
||||||
|
if (zzHandle == INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
Print("Error creating ZigZag handle");
|
||||||
|
return (INIT_FAILED);
|
||||||
|
}
|
||||||
|
return (INIT_SUCCEEDED);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Deinitialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnDeinit(const int reason)
|
||||||
|
{
|
||||||
|
ObjectDelete(0, "Downtrend_HighLine");
|
||||||
|
ObjectDelete(0, "Downtrend_LowLine");
|
||||||
|
ObjectDelete(0, "Major_Resistance");
|
||||||
|
ObjectDelete(0, "Major_Support");
|
||||||
|
ObjectDelete(0, "Minor_Resistance");
|
||||||
|
ObjectDelete(0, "Minor_Support");
|
||||||
|
IndicatorRelease(zzHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Tick function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnTick()
|
||||||
|
{
|
||||||
|
datetime currentBarTime = iTime(_Symbol, InpTimeFrame, 0);
|
||||||
|
if (currentBarTime == lastBarTime)
|
||||||
|
return;
|
||||||
|
lastBarTime = currentBarTime;
|
||||||
|
|
||||||
|
// Remove previous objects
|
||||||
|
ObjectDelete(0, "Downtrend_HighLine");
|
||||||
|
ObjectDelete(0, "Downtrend_LowLine");
|
||||||
|
ObjectDelete(0, "Major_Resistance");
|
||||||
|
ObjectDelete(0, "Major_Support");
|
||||||
|
ObjectDelete(0, "Minor_Resistance");
|
||||||
|
ObjectDelete(0, "Minor_Support");
|
||||||
|
|
||||||
|
if (CopyBuffer(zzHandle, 0, 0, LookBackBars, zzBuffer) <= 0)
|
||||||
|
{
|
||||||
|
Print("Failed to copy ZigZag data");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ArraySetAsSeries(zzBuffer, true);
|
||||||
|
|
||||||
|
DrawZigZagTrendlines();
|
||||||
|
DrawSupportResistance();
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Draw ZigZag-based Trendlines |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void DrawZigZagTrendlines()
|
||||||
|
{
|
||||||
|
double highPrices[10], lowPrices[10];
|
||||||
|
datetime highTimes[10], lowTimes[10];
|
||||||
|
int highCount = 0, lowCount = 0;
|
||||||
|
|
||||||
|
// Extract swing points from the ZigZag buffer
|
||||||
|
for (int i = 0; i < LookBackBars - 1; i++)
|
||||||
|
{
|
||||||
|
if (zzBuffer[i] != 0)
|
||||||
|
{
|
||||||
|
if (iHigh(_Symbol, InpTimeFrame, i) == zzBuffer[i] && highCount < 10)
|
||||||
|
{
|
||||||
|
highPrices[highCount] = zzBuffer[i];
|
||||||
|
highTimes[highCount] = iTime(_Symbol, InpTimeFrame, i);
|
||||||
|
highCount++;
|
||||||
|
}
|
||||||
|
else if (iLow(_Symbol, InpTimeFrame, i) == zzBuffer[i] && lowCount < 10)
|
||||||
|
{
|
||||||
|
lowPrices[lowCount] = zzBuffer[i];
|
||||||
|
lowTimes[lowCount] = iTime(_Symbol, InpTimeFrame, i);
|
||||||
|
lowCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exclude the most recent swing if possible
|
||||||
|
int usedHighCount = (highCount >= 4) ? highCount - 1 : highCount;
|
||||||
|
int usedLowCount = (lowCount >= 4) ? lowCount - 1 : lowCount;
|
||||||
|
|
||||||
|
double mHigh = 0, bHigh = 0, mLow = 0, bLow = 0;
|
||||||
|
bool validHigh = false, validLow = false;
|
||||||
|
|
||||||
|
// Regression for highs
|
||||||
|
if (usedHighCount >= 3)
|
||||||
|
{
|
||||||
|
double sumT = 0, sumP = 0, sumTP = 0, sumT2 = 0;
|
||||||
|
for (int i = 0; i < usedHighCount; i++)
|
||||||
|
{
|
||||||
|
double t = (double)highTimes[i];
|
||||||
|
double p = highPrices[i];
|
||||||
|
sumT += t;
|
||||||
|
sumP += p;
|
||||||
|
sumTP += t * p;
|
||||||
|
sumT2 += t * t;
|
||||||
|
}
|
||||||
|
int N = usedHighCount;
|
||||||
|
double denominator = N * sumT2 - sumT * sumT;
|
||||||
|
if (denominator != 0)
|
||||||
|
{
|
||||||
|
mHigh = (N * sumTP - sumT * sumP) / denominator;
|
||||||
|
bHigh = (sumP - mHigh * sumT) / N;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bHigh = sumP / N;
|
||||||
|
validHigh = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Regression for lows
|
||||||
|
if (usedLowCount >= 3)
|
||||||
|
{
|
||||||
|
double sumT = 0, sumP = 0, sumTP = 0, sumT2 = 0;
|
||||||
|
for (int i = 0; i < usedLowCount; i++)
|
||||||
|
{
|
||||||
|
double t = (double)lowTimes[i];
|
||||||
|
double p = lowPrices[i];
|
||||||
|
sumT += t;
|
||||||
|
sumP += p;
|
||||||
|
sumTP += t * p;
|
||||||
|
sumT2 += t * t;
|
||||||
|
}
|
||||||
|
int N = usedLowCount;
|
||||||
|
double denominator = N * sumT2 - sumT * sumT;
|
||||||
|
if (denominator != 0)
|
||||||
|
{
|
||||||
|
mLow = (N * sumTP - sumT * sumP) / denominator;
|
||||||
|
bLow = (sumP - mLow * sumT) / N;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bLow = sumP / N;
|
||||||
|
validLow = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define time limits for trendlines
|
||||||
|
datetime pastTime = iTime(_Symbol, InpTimeFrame, LookBackBars - 1);
|
||||||
|
datetime futureTime = lastBarTime + ExtendFutureBars * PeriodSeconds();
|
||||||
|
|
||||||
|
// Draw trendlines if both regressions are valid
|
||||||
|
if (validHigh && validLow)
|
||||||
|
{
|
||||||
|
// When slopes have the same sign, use average slope
|
||||||
|
if (mHigh * mLow > 0)
|
||||||
|
{
|
||||||
|
double mParallel = (mHigh + mLow) / 2.0;
|
||||||
|
double bHighParallel = highPrices[0] - mParallel * (double)highTimes[0];
|
||||||
|
double bLowParallel = lowPrices[0] - mParallel * (double)lowTimes[0];
|
||||||
|
|
||||||
|
datetime highStartTime = pastTime;
|
||||||
|
double highStartPrice = mParallel * (double)highStartTime + bHighParallel;
|
||||||
|
double highEndPrice = mParallel * (double)futureTime + bHighParallel;
|
||||||
|
if (!ObjectCreate(0, "Downtrend_HighLine", OBJ_TREND, 0, highStartTime, highStartPrice, futureTime, highEndPrice))
|
||||||
|
Print("Failed to create High Trendline");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_COLOR, clrRed);
|
||||||
|
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_LEFT, true);
|
||||||
|
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_RIGHT, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
datetime lowStartTime = pastTime;
|
||||||
|
double lowStartPrice = mParallel * (double)lowStartTime + bLowParallel;
|
||||||
|
double lowEndPrice = mParallel * (double)futureTime + bLowParallel;
|
||||||
|
if (!ObjectCreate(0, "Downtrend_LowLine", OBJ_TREND, 0, lowStartTime, lowStartPrice, futureTime, lowEndPrice))
|
||||||
|
Print("Failed to create Low Trendline");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_COLOR, clrGreen);
|
||||||
|
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_RAY_LEFT, true);
|
||||||
|
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_RAY_RIGHT, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
datetime highStartTime = pastTime;
|
||||||
|
double highStartPrice = mHigh * (double)highStartTime + bHigh;
|
||||||
|
double highEndPrice = mHigh * (double)futureTime + bHigh;
|
||||||
|
if (!ObjectCreate(0, "Downtrend_HighLine", OBJ_TREND, 0, highStartTime, highStartPrice, futureTime, highEndPrice))
|
||||||
|
Print("Failed to create High Trendline");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_COLOR, clrRed);
|
||||||
|
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_LEFT, true);
|
||||||
|
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_RIGHT, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
datetime lowStartTime = pastTime;
|
||||||
|
double lowStartPrice = mLow * (double)lowStartTime + bLow;
|
||||||
|
double lowEndPrice = mLow * (double)futureTime + bLow;
|
||||||
|
if (!ObjectCreate(0, "Downtrend_LowLine", OBJ_TREND, 0, lowStartTime, lowStartPrice, futureTime, lowEndPrice))
|
||||||
|
Print("Failed to create Low Trendline");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_COLOR, clrGreen);
|
||||||
|
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_RAY_LEFT, true);
|
||||||
|
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_RAY_RIGHT, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (validHigh)
|
||||||
|
{
|
||||||
|
datetime highStartTime = pastTime;
|
||||||
|
double highStartPrice = mHigh * (double)highStartTime + bHigh;
|
||||||
|
double highEndPrice = mHigh * (double)futureTime + bHigh;
|
||||||
|
if (!ObjectCreate(0, "Downtrend_HighLine", OBJ_TREND, 0, highStartTime, highStartPrice, futureTime, highEndPrice))
|
||||||
|
Print("Failed to create High Trendline");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_COLOR, clrRed);
|
||||||
|
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_LEFT, true);
|
||||||
|
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_RIGHT, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (validLow)
|
||||||
|
{
|
||||||
|
datetime lowStartTime = pastTime;
|
||||||
|
double lowStartPrice = mLow * (double)lowStartTime + bLow;
|
||||||
|
double lowEndPrice = mLow * (double)futureTime + bLow;
|
||||||
|
if (!ObjectCreate(0, "Downtrend_LowLine", OBJ_TREND, 0, lowStartTime, lowStartPrice, futureTime, lowEndPrice))
|
||||||
|
Print("Failed to create Low Trendline");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_COLOR, clrGreen);
|
||||||
|
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_RAY_LEFT, true);
|
||||||
|
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_RAY_RIGHT, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Draw Support and Resistance Levels |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void DrawSupportResistance()
|
||||||
|
{
|
||||||
|
double confirmedHighs[10], confirmedLows[10];
|
||||||
|
int confHighCount = 0, confLowCount = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < LookBackBars - 1; i++)
|
||||||
|
{
|
||||||
|
if (zzBuffer[i] != 0)
|
||||||
|
{
|
||||||
|
if (iHigh(_Symbol, InpTimeFrame, i) == zzBuffer[i] && confHighCount < 10)
|
||||||
|
{
|
||||||
|
confirmedHighs[confHighCount] = zzBuffer[i];
|
||||||
|
confHighCount++;
|
||||||
|
}
|
||||||
|
else if (iLow(_Symbol, InpTimeFrame, i) == zzBuffer[i] && confLowCount < 10)
|
||||||
|
{
|
||||||
|
confirmedLows[confLowCount] = zzBuffer[i];
|
||||||
|
confLowCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int usedHighCount = (confHighCount >= 4) ? confHighCount - 1 : confHighCount;
|
||||||
|
int usedLowCount = (confLowCount >= 4) ? confLowCount - 1 : confLowCount;
|
||||||
|
|
||||||
|
double majorResistance = -1e9, majorSupport = 1e9;
|
||||||
|
double minorResistance = -1e9, minorSupport = 1e9;
|
||||||
|
double tempHigh = -1e9, tempLow = -1e9;
|
||||||
|
for (int i = 0; i < usedHighCount; i++)
|
||||||
|
{
|
||||||
|
if (confirmedHighs[i] > majorResistance)
|
||||||
|
{
|
||||||
|
tempHigh = majorResistance;
|
||||||
|
majorResistance = confirmedHighs[i];
|
||||||
|
}
|
||||||
|
else if (confirmedHighs[i] > tempHigh)
|
||||||
|
{
|
||||||
|
tempHigh = confirmedHighs[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tempHigh > -1e9)
|
||||||
|
minorResistance = tempHigh;
|
||||||
|
for (int i = 0; i < usedLowCount; i++)
|
||||||
|
{
|
||||||
|
if (confirmedLows[i] < majorSupport)
|
||||||
|
{
|
||||||
|
tempLow = majorSupport;
|
||||||
|
majorSupport = confirmedLows[i];
|
||||||
|
}
|
||||||
|
else if (confirmedLows[i] < tempLow)
|
||||||
|
{
|
||||||
|
tempLow = confirmedLows[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tempLow < 1e9)
|
||||||
|
minorSupport = tempLow;
|
||||||
|
|
||||||
|
if (usedHighCount > 0)
|
||||||
|
{
|
||||||
|
if (!ObjectCreate(0, "Major_Resistance", OBJ_HLINE, 0, 0, majorResistance))
|
||||||
|
Print("Failed to create Major Resistance");
|
||||||
|
else
|
||||||
|
ObjectSetInteger(0, "Major_Resistance", OBJPROP_COLOR, clrMagenta);
|
||||||
|
|
||||||
|
if (minorResistance > -1e9 && minorResistance < majorResistance)
|
||||||
|
{
|
||||||
|
if (!ObjectCreate(0, "Minor_Resistance", OBJ_HLINE, 0, 0, minorResistance))
|
||||||
|
Print("Failed to create Minor Resistance");
|
||||||
|
else
|
||||||
|
ObjectSetInteger(0, "Minor_Resistance", OBJPROP_COLOR, clrFuchsia);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (usedLowCount > 0)
|
||||||
|
{
|
||||||
|
if (!ObjectCreate(0, "Major_Support", OBJ_HLINE, 0, 0, majorSupport))
|
||||||
|
Print("Failed to create Major Support");
|
||||||
|
else
|
||||||
|
ObjectSetInteger(0, "Major_Support", OBJPROP_COLOR, clrAqua);
|
||||||
|
|
||||||
|
if (minorSupport < 1e9 && minorSupport > majorSupport)
|
||||||
|
{
|
||||||
|
if (!ObjectCreate(0, "Minor_Support", OBJ_HLINE, 0, 0, minorSupport))
|
||||||
|
Print("Failed to create Minor Support");
|
||||||
|
else
|
||||||
|
ObjectSetInteger(0, "Minor_Support", OBJPROP_COLOR, clrBlue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
+198
-15
@@ -99,6 +99,7 @@ input bool showMAFast = true; // Show MA Fast
|
|||||||
input bool showMASlow = true; // Show MA Slow
|
input bool showMASlow = true; // Show MA Slow
|
||||||
input bool showMABand = true; // Show MA Band
|
input bool showMABand = true; // Show MA Band
|
||||||
input bool showZigZag = true; // Show ZigZag
|
input bool showZigZag = true; // Show ZigZag
|
||||||
|
input bool showZigZagPV = true; // Show ZigZag PV
|
||||||
input bool showFiboZone = true; // Show Fibo Zone
|
input bool showFiboZone = true; // Show Fibo Zone
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -133,8 +134,8 @@ input int valeArrowCode = 159; // Vales Arrow Code
|
|||||||
#property indicator_chart_window
|
#property indicator_chart_window
|
||||||
|
|
||||||
//
|
//
|
||||||
#property indicator_buffers 29
|
#property indicator_buffers 31
|
||||||
#property indicator_plots 11
|
#property indicator_plots 13
|
||||||
|
|
||||||
//
|
//
|
||||||
// Plot Buffers ...
|
// Plot Buffers ...
|
||||||
@@ -277,39 +278,67 @@ double zigzagBuffer[];
|
|||||||
#property indicator_color9 clrYellow
|
#property indicator_color9 clrYellow
|
||||||
#property indicator_width9 2
|
#property indicator_width9 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// ZG Peak ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define zigzagPeakBufferIndex 12
|
||||||
|
#define zigzagPeakBufferPlotIndex 9
|
||||||
|
double zigzagPeakBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_label10 "XZG Peak"
|
||||||
|
#property indicator_type10 DRAW_ARROW
|
||||||
|
#property indicator_color10 clrYellow
|
||||||
|
#property indicator_width10 3
|
||||||
|
|
||||||
|
//
|
||||||
|
// ZG Vale ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define zigzagValeBufferIndex 13
|
||||||
|
#define zigzagValeBufferPlotIndex 10
|
||||||
|
double zigzagValeBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_label11 "XZG Peak"
|
||||||
|
#property indicator_type11 DRAW_ARROW
|
||||||
|
#property indicator_color11 clrDarkOrange
|
||||||
|
#property indicator_width11 3
|
||||||
|
|
||||||
//
|
//
|
||||||
// MA Upper Boundary ...
|
// MA Upper Boundary ...
|
||||||
|
|
||||||
//
|
//
|
||||||
#define maUpperBufferIndex 12
|
#define maUpperBufferIndex 14
|
||||||
#define maUpperBufferPlotIndex 9
|
#define maUpperBufferPlotIndex 11
|
||||||
double maUpperBuffer[];
|
double maUpperBuffer[];
|
||||||
|
|
||||||
//
|
//
|
||||||
#property indicator_label10 "UpperMA"
|
#property indicator_label12 "UpperMA"
|
||||||
#property indicator_type10 DRAW_LINE
|
#property indicator_type12 DRAW_LINE
|
||||||
#property indicator_color10 clrAqua
|
#property indicator_color12 clrAqua
|
||||||
#property indicator_width10 3
|
#property indicator_width12 3
|
||||||
|
|
||||||
//
|
//
|
||||||
// MA Lower Boundary ...
|
// MA Lower Boundary ...
|
||||||
|
|
||||||
//
|
//
|
||||||
#define maLowerBufferIndex 13
|
#define maLowerBufferIndex 15
|
||||||
#define maLowerBufferPlotIndex 10
|
#define maLowerBufferPlotIndex 12
|
||||||
double maLowerBuffer[];
|
double maLowerBuffer[];
|
||||||
|
|
||||||
//
|
//
|
||||||
#property indicator_label11 "LowerMA"
|
#property indicator_label13 "LowerMA"
|
||||||
#property indicator_type11 DRAW_LINE
|
#property indicator_type13 DRAW_LINE
|
||||||
#property indicator_color11 clrMagenta
|
#property indicator_color13 clrMagenta
|
||||||
#property indicator_width11 3
|
#property indicator_width13 3
|
||||||
|
|
||||||
//
|
//
|
||||||
// Data Buffers ...
|
// Data Buffers ...
|
||||||
|
|
||||||
//
|
//
|
||||||
#define mLastBufferIndex 13
|
#define mLastBufferIndex 15
|
||||||
|
|
||||||
//
|
//
|
||||||
// MA ...
|
// MA ...
|
||||||
@@ -446,6 +475,14 @@ int zigzagLowersCount = 0;
|
|||||||
int zigzagUppersCount = 0;
|
int zigzagUppersCount = 0;
|
||||||
int zigzagRecalc = 3; // Number of last extremes for recalculation
|
int zigzagRecalc = 3; // Number of last extremes for recalculation
|
||||||
|
|
||||||
|
//
|
||||||
|
double lastZigZagPeak = 0;
|
||||||
|
datetime lastZigZagPeakTime = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
double lastZigZagVale = 0;
|
||||||
|
datetime lastZigZagValeTime = NULL;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Event Handlers ...
|
// Event Handlers ...
|
||||||
|
|
||||||
@@ -585,6 +622,32 @@ int OnCalculate(
|
|||||||
return prev_calculated;
|
return prev_calculated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculating Limit ...
|
||||||
|
limit = prev_calculated == 0
|
||||||
|
? rates_total - 1
|
||||||
|
: rates_total - prev_calculated;
|
||||||
|
if (limit <= 0)
|
||||||
|
{
|
||||||
|
limit = rates_total - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Main Loop ...
|
||||||
|
for (int i = limit; i < rates_total - 1 && !IsStopped(); i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
Print("Calculating Bar Index: ", i);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculate Peaks and Vales ...
|
||||||
|
CalculateZigZagPV(
|
||||||
|
i,
|
||||||
|
prev_calculated,
|
||||||
|
rates_total //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Prepare Buffers ...
|
// Prepare Buffers ...
|
||||||
ArraySetAsSeries(time, true);
|
ArraySetAsSeries(time, true);
|
||||||
@@ -921,6 +984,38 @@ void DefineBuffers()
|
|||||||
PlotIndexSetInteger(zigzagBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
|
PlotIndexSetInteger(zigzagBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
|
||||||
PlotIndexSetDouble(zigzagBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
|
PlotIndexSetDouble(zigzagBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// ZigZag PV ...
|
||||||
|
|
||||||
|
//
|
||||||
|
ENUM_DRAW_TYPE zigzagPVDrawType = showZigZagPV ? DRAW_ARROW : DRAW_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// ZG Peak ...
|
||||||
|
|
||||||
|
//
|
||||||
|
SetIndexBuffer(zigzagPeakBufferIndex, zigzagPeakBuffer, INDICATOR_DATA);
|
||||||
|
|
||||||
|
//
|
||||||
|
PlotIndexSetInteger(zigzagPeakBufferPlotIndex, PLOT_SHOW_DATA, showZigZagPV);
|
||||||
|
PlotIndexSetInteger(zigzagPeakBufferPlotIndex, PLOT_DRAW_TYPE, zigzagPVDrawType);
|
||||||
|
|
||||||
|
PlotIndexSetInteger(zigzagPeakBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
|
||||||
|
PlotIndexSetDouble(zigzagPeakBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// ZG Vale ...
|
||||||
|
|
||||||
|
//
|
||||||
|
SetIndexBuffer(zigzagValeBufferIndex, zigzagValeBuffer, INDICATOR_DATA);
|
||||||
|
|
||||||
|
//
|
||||||
|
PlotIndexSetInteger(zigzagValeBufferPlotIndex, PLOT_SHOW_DATA, showZigZagPV);
|
||||||
|
PlotIndexSetInteger(zigzagValeBufferPlotIndex, PLOT_DRAW_TYPE, zigzagPVDrawType);
|
||||||
|
|
||||||
|
PlotIndexSetInteger(zigzagValeBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
|
||||||
|
PlotIndexSetDouble(zigzagValeBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
|
||||||
|
|
||||||
//
|
//
|
||||||
// MA Band ...
|
// MA Band ...
|
||||||
|
|
||||||
@@ -1912,6 +2007,94 @@ int CalculateZigZag(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate Peaks and Vales ...
|
||||||
|
*
|
||||||
|
* @param barIndex: Integer, Represent Current Bar ...
|
||||||
|
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
|
||||||
|
* @param ratesTotal: Integer, Represents All Available Bars ...
|
||||||
|
* @param open: Double Array, History of Open Prices ...
|
||||||
|
* @param high: Double Array, History of High Prices ...
|
||||||
|
* @param close: Double Array, History of Close Prices ...
|
||||||
|
* @param low: Double Array, History of Low Prices ...
|
||||||
|
* @param tickVolume: Long, History of Tick Volumes on Bar ...
|
||||||
|
*/
|
||||||
|
void CalculateZigZagPV(
|
||||||
|
int barIndex,
|
||||||
|
const int prevCalculated,
|
||||||
|
const int ratesTotal //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double iZigZagValue = zigzagBuffer[barIndex];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Print("Calculate Bar Index: ", barIndex, ", ZG: ", iZigZagValue, ", ", prevCalculated, ", ", ratesTotal);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Peak ...
|
||||||
|
double iHighValue = highsBuffer[barIndex];
|
||||||
|
double iHighTimeDouble = highsTimeBuffer[barIndex];
|
||||||
|
datetime iHighTime = (datetime)((int)iHighTimeDouble);
|
||||||
|
if (iHighValue != 0 && iHighValue != EMPTY_VALUE && iZigZagValue == iHighValue)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
peakBuffer[barIndex] = iHighValue;
|
||||||
|
|
||||||
|
//
|
||||||
|
lastZigZagPeak = iHighValue;
|
||||||
|
lastZigZagPeakTime = iHighTime;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double iValue = emptyValue;
|
||||||
|
if (
|
||||||
|
lastZigZagPeak != emptyValue &&
|
||||||
|
lastZigZagPeak != EMPTY_VALUE &&
|
||||||
|
IsSpecifiedValid(lastZigZagPeakTime))
|
||||||
|
{
|
||||||
|
iValue = lastZigZagPeak;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
peakBuffer[barIndex] = iValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Vale ...
|
||||||
|
double iLowValue = lowsBuffer[barIndex];
|
||||||
|
double iLowTimeDouble = lowsTimeBuffer[barIndex];
|
||||||
|
datetime iLowTime = (datetime)((int)iLowTimeDouble);
|
||||||
|
if (iLowValue != 0 && iLowValue != EMPTY_VALUE && iZigZagValue == iLowValue)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
valeBuffer[barIndex] = iLowValue;
|
||||||
|
|
||||||
|
//
|
||||||
|
lastZigZagVale = iLowValue;
|
||||||
|
lastZigZagValeTime = iLowTime;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double iValue = emptyValue;
|
||||||
|
if (
|
||||||
|
lastZigZagVale != emptyValue &&
|
||||||
|
lastZigZagVale != EMPTY_VALUE &&
|
||||||
|
IsSpecifiedValid(lastZigZagValeTime))
|
||||||
|
{
|
||||||
|
iValue = lastZigZagVale;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
valeBuffer[barIndex] = iValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ChartRedraw();
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
void CalculateCycleRanges(
|
void CalculateCycleRanges(
|
||||||
int barIndex,
|
int barIndex,
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -246,6 +246,42 @@ class XCXFIMAPOIDetector : public XCBase
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool AnalyseMarketUsingZigZag(
|
||||||
|
XOHCL &bar,
|
||||||
|
ENUM_TIMEFRAMES forPeriod,
|
||||||
|
XZigZagAnalysis &analysis //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Prepare ...
|
||||||
|
analysis.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate ...
|
||||||
|
result = bar.IsValid();
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Normalize ...
|
||||||
|
if (!IsSpecifiedValid(forPeriod))
|
||||||
|
{
|
||||||
|
forPeriod = bar.period;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reading XZigZag Points ...
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Implementing Patrren Detector ...
|
// Implementing Patrren Detector ...
|
||||||
|
|
||||||
|
|||||||
@@ -411,4 +411,199 @@ struct XZigZagPoint
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specified ZigZag based Market Analysis ...
|
||||||
|
**/
|
||||||
|
struct XZigZagAnalysis
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
string symbol; // Symbol ...
|
||||||
|
datetime time; // Time ...
|
||||||
|
ENUM_TIMEFRAMES period; // Period ...
|
||||||
|
XZigZagPoint pivots[]; // ZigZag Pivots ...
|
||||||
|
|
||||||
|
//
|
||||||
|
ENUM_X_DIRECTION dir; // Direction ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Constructor ...
|
||||||
|
XZigZagAnalysis()
|
||||||
|
{
|
||||||
|
Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tools ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleanup Model ...
|
||||||
|
*/
|
||||||
|
void Clean()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
time = NULL;
|
||||||
|
symbol = NULL;
|
||||||
|
period = NULL;
|
||||||
|
dir = X_DIRECTION_NONE;
|
||||||
|
SpecifiedClean(pivots);
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate Model ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool IsValid()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
HasChild(pivots) &&
|
||||||
|
HasDirection(dir) &&
|
||||||
|
IsSpecifiedValid(time) &&
|
||||||
|
IsSpecifiedValid(symbol) &&
|
||||||
|
IsSpecifiedValid(period);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate Analysis Age, based on Specified Time Frame ...
|
||||||
|
*
|
||||||
|
* @param forPeriod: ENUM_TIMEFRAMES, Specified Period ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int GetAge(
|
||||||
|
ENUM_TIMEFRAMES forPeriod = NULL //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = -1;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate ...
|
||||||
|
if (!IsValid())
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Normalize ...
|
||||||
|
if (!IsSpecifiedValid(forPeriod))
|
||||||
|
{
|
||||||
|
forPeriod = period;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
result = GetBarIndex(
|
||||||
|
symbol,
|
||||||
|
forPeriod,
|
||||||
|
time //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check two item is Same or not ...
|
||||||
|
*
|
||||||
|
* @param item: XZigZagAnalysis, dest model for Checking ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool IsSameAs(XZigZagAnalysis &item)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
IsValid() &&
|
||||||
|
item.IsValid() &&
|
||||||
|
time == item.time &&
|
||||||
|
IsSameMarketAs(item);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check to model Has Same Symbol ...
|
||||||
|
*
|
||||||
|
* @param item: XZigZagAnalysis, dest model for Checking ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool IsSameSymbolAs(XZigZagAnalysis &item)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
IsValid() &&
|
||||||
|
item.IsValid() &&
|
||||||
|
symbol == item.symbol;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check to model Has Same Period ...
|
||||||
|
*
|
||||||
|
* @param item: XZigZagAnalysis, dest model for Checking ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool IsSamePeriodAs(XZigZagAnalysis &item)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
IsValid() &&
|
||||||
|
item.IsValid() &&
|
||||||
|
period == item.period;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check to model Has Same Symbol/Period ...
|
||||||
|
*
|
||||||
|
* @param item: XZigZagAnalysis, dest model for Checking ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool IsSameMarketAs(XZigZagAnalysis &item)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
IsValid() &&
|
||||||
|
item.IsValid() &&
|
||||||
|
IsSameSymbolAs(item) &&
|
||||||
|
IsSamePeriodAs(item);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user