last ...
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1040,6 +1040,7 @@ struct XOHCL
|
||||
// also zBar Open must be Above Price Line ...
|
||||
result =
|
||||
//
|
||||
pBar.high > price &&
|
||||
pBar.low < price &&
|
||||
cBar.close > price &&
|
||||
this.close > price &&
|
||||
@@ -1088,6 +1089,7 @@ struct XOHCL
|
||||
// also zBar Open must be Below Price Line ...
|
||||
result =
|
||||
//
|
||||
pBar.high > price &&
|
||||
pBar.low < price &&
|
||||
cBar.close < price &&
|
||||
this.close < price &&
|
||||
@@ -1137,6 +1139,7 @@ struct XOHCL
|
||||
result =
|
||||
//
|
||||
pBar.high > price &&
|
||||
pBar.low < price &&
|
||||
cBar.close < price &&
|
||||
this.close < price &&
|
||||
this.open < price
|
||||
@@ -1184,6 +1187,7 @@ struct XOHCL
|
||||
// also zBar Open must be Pver Price Line ...
|
||||
result =
|
||||
//
|
||||
pBar.low < price &&
|
||||
pBar.high > price &&
|
||||
cBar.close > price &&
|
||||
this.close > price &&
|
||||
@@ -1238,7 +1242,7 @@ struct XOHCL
|
||||
//
|
||||
// Check Bar has Strongest Body in a Range ...
|
||||
bool HasStrongestBody(
|
||||
int loopback = 3 // loopback candles to compare it ...
|
||||
int mLoopback = 3 // loopback candles to compare it ...
|
||||
)
|
||||
{
|
||||
//
|
||||
@@ -1254,7 +1258,7 @@ struct XOHCL
|
||||
//
|
||||
double body = GetBody();
|
||||
XOHCL prev = this;
|
||||
for (int i = 0; i < loopback; i++)
|
||||
for (int i = 0; i < mLoopback; i++)
|
||||
{
|
||||
//
|
||||
bool isValid = prev.GetPreviousBar(prev);
|
||||
@@ -1285,7 +1289,7 @@ struct XOHCL
|
||||
//
|
||||
// Check Bar has Weakest Body in a Range ...
|
||||
bool HasWeakestBody(
|
||||
int loopback = 3 // loopback candles to compare it ...
|
||||
int mLoopback = 3 // loopback candles to compare it ...
|
||||
)
|
||||
{
|
||||
//
|
||||
@@ -1301,7 +1305,7 @@ struct XOHCL
|
||||
//
|
||||
double body = GetBody();
|
||||
XOHCL prev = this;
|
||||
for (int i = 0; i < loopback; i++)
|
||||
for (int i = 0; i < mLoopback; i++)
|
||||
{
|
||||
//
|
||||
bool isValid = prev.GetPreviousBar(prev);
|
||||
@@ -1696,6 +1700,312 @@ struct XOHCL
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
struct XPivot
|
||||
{
|
||||
//
|
||||
double pivot; // Pivot Price ...
|
||||
int breaks; // Number of Breaks ...
|
||||
int rejects; // Number of Rejects ...
|
||||
|
||||
//
|
||||
void XPivot()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
pivot = 0;
|
||||
breaks = 0;
|
||||
rejects = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
bool IsValid()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = pivot > 0;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
struct XPivotTracker
|
||||
{
|
||||
//
|
||||
XPivot pivots[];
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
void XPivotTracker()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
Clean(pivots);
|
||||
}
|
||||
|
||||
//
|
||||
int Count()
|
||||
{
|
||||
return ArraySize(pivots);
|
||||
}
|
||||
|
||||
//
|
||||
double Get(int index)
|
||||
{
|
||||
//
|
||||
double result = 0;
|
||||
|
||||
//
|
||||
NormalizeIndex(index, pivots);
|
||||
|
||||
//
|
||||
XPivot iPivot = pivots[index];
|
||||
|
||||
//
|
||||
result = iPivot.pivot;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
XPivot GetPivot(int index)
|
||||
{
|
||||
//
|
||||
XPivot result;
|
||||
|
||||
//
|
||||
NormalizeIndex(index, pivots);
|
||||
|
||||
//
|
||||
result = pivots[index];
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool Add(double mPivot)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = mPivot > 0 && !Has(mPivot);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
XPivot pivot;
|
||||
pivot.pivot = mPivot;
|
||||
|
||||
//
|
||||
AddRef(
|
||||
pivot,
|
||||
pivots //
|
||||
);
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int Adds(double &mPivots[])
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
int pivotsCount = ArraySize(mPivots);
|
||||
if (!IsValidSize(pivotsCount))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
for (int i = 0; i < pivotsCount; i++)
|
||||
{
|
||||
//
|
||||
double iPivot = mPivots[i];
|
||||
|
||||
//
|
||||
bool isAdded = Add(iPivot);
|
||||
if (isAdded)
|
||||
{
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int FindIndex(double mPivot)
|
||||
{
|
||||
//
|
||||
int result = -1;
|
||||
|
||||
//
|
||||
if (mPivot <= 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int count = Count();
|
||||
if (!IsValidSize(count))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
XPivot iPivot = pivots[i];
|
||||
|
||||
//
|
||||
if (iPivot.pivot == mPivot)
|
||||
{
|
||||
//
|
||||
result = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double Has(double mPivot)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
int pivotIDX = FindIndex(mPivot);
|
||||
result = pivotIDX >= 0;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int Reject(double mPivot)
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
int pivotIDX = FindIndex(mPivot);
|
||||
if (pivotIDX < 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
pivots[pivotIDX].rejects++;
|
||||
|
||||
//
|
||||
result = pivots[pivotIDX].rejects;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int Break(double mPivot)
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
int pivotIDX = FindIndex(mPivot);
|
||||
if (pivotIDX < 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
pivots[pivotIDX].breaks++;
|
||||
|
||||
//
|
||||
result = pivots[pivotIDX].breaks;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool Remove(double mPivot)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
int pivotIDX = FindIndex(mPivot);
|
||||
result = pivotIDX >= 0;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = ArrayRemove(
|
||||
pivots,
|
||||
pivotIDX,
|
||||
1 //
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool HasChild()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
int count = Count();
|
||||
result = IsValidSize(count);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Model Support and Resistance
|
||||
// for Specific Bar ...
|
||||
@@ -3553,6 +3863,52 @@ void NormalizeIndex(
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Normalize Start and Count based on Specified Buffer ...
|
||||
template <typename T>
|
||||
void NormalizeCount(
|
||||
int &start,
|
||||
int &count,
|
||||
T &buffer[] //
|
||||
)
|
||||
{
|
||||
//
|
||||
// Validate Buffer Size ...
|
||||
int bufferSize = ArraySize(buffer);
|
||||
if (!IsValidSize(bufferSize))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Normalization Start ...
|
||||
NormalizeIndex(
|
||||
start,
|
||||
buffer //
|
||||
);
|
||||
|
||||
//
|
||||
if (count < start)
|
||||
{
|
||||
count = (start - count);
|
||||
}
|
||||
|
||||
//
|
||||
// Normalization Count ...
|
||||
|
||||
//
|
||||
if (count < 0)
|
||||
{
|
||||
count = start;
|
||||
}
|
||||
|
||||
//
|
||||
if (count > bufferSize)
|
||||
{
|
||||
count = bufferSize;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Normalize a give Volume ...
|
||||
double NormalizeVolume(
|
||||
@@ -4051,8 +4407,8 @@ void CalculateTPSL(
|
||||
|
||||
//
|
||||
mSL = isLong
|
||||
? mEntry - reward
|
||||
: mEntry + reward;
|
||||
? mEntry - risk
|
||||
: mEntry + risk;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -4939,6 +5295,177 @@ double GetFibonacciLevel(
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Method 1
|
||||
// Normalize between 1 and 0 ...
|
||||
template <typename T>
|
||||
double GetNormalizedValueMethod1(
|
||||
T &buffer[], // Array which required to Normalize
|
||||
int mLength, // Length of Normalization
|
||||
int mStart = 0, // start index
|
||||
int digits = 5 // Normalization Digits
|
||||
)
|
||||
{
|
||||
//
|
||||
double result = 0;
|
||||
|
||||
//
|
||||
if (digits <= 5)
|
||||
{
|
||||
digits = 5;
|
||||
}
|
||||
|
||||
//
|
||||
int bufferSize = ArraySize(buffer);
|
||||
if (!IsValidSize(bufferSize))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Normalize Count ...
|
||||
NormalizeCount(
|
||||
mStart,
|
||||
mLength,
|
||||
buffer //
|
||||
);
|
||||
|
||||
//
|
||||
T max = 0;
|
||||
T min = 0;
|
||||
|
||||
//
|
||||
if (bufferSize != mLength)
|
||||
{
|
||||
//
|
||||
T tmp[];
|
||||
Copy(
|
||||
mStart,
|
||||
mLength,
|
||||
buffer,
|
||||
tmp //
|
||||
);
|
||||
|
||||
//
|
||||
max = GetMax(tmp);
|
||||
min = GetMin(tmp);
|
||||
}
|
||||
|
||||
//
|
||||
if (bufferSize == mLength)
|
||||
{
|
||||
//
|
||||
max = GetMax(buffer);
|
||||
min = GetMin(buffer);
|
||||
}
|
||||
|
||||
//
|
||||
T iValue = buffer[mStart];
|
||||
|
||||
//
|
||||
double minMaxDiff = (max - min);
|
||||
if (minMaxDiff <= 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = (iValue - min) / minMaxDiff;
|
||||
|
||||
//
|
||||
result = NormalizeDouble(result, digits);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Method 2
|
||||
// Normalize Between Specified Upper and Lower ...
|
||||
template <typename T>
|
||||
double GetNormalizedValueMethod2(
|
||||
T &buffer[], // Array which required to Normalize
|
||||
int mLength, // Length of Normalization
|
||||
int mUpper, // Specified Upper Value
|
||||
int mLower, // Specified Lower Value
|
||||
int mStart = 0, // start index
|
||||
int digits = 5 // Normalization Digits
|
||||
)
|
||||
{
|
||||
//
|
||||
double result = 0;
|
||||
|
||||
//
|
||||
if (digits <= 5)
|
||||
{
|
||||
digits = 5;
|
||||
}
|
||||
|
||||
//
|
||||
int bufferSize = ArraySize(buffer);
|
||||
if (!IsValidSize(bufferSize))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Normalize Count ...
|
||||
NormalizeCount(
|
||||
mStart,
|
||||
mLength,
|
||||
buffer //
|
||||
);
|
||||
|
||||
//
|
||||
T max = 0;
|
||||
T min = 0;
|
||||
|
||||
//
|
||||
if (bufferSize != mLength)
|
||||
{
|
||||
//
|
||||
T tmp[];
|
||||
Copy(
|
||||
mStart,
|
||||
mLength,
|
||||
buffer,
|
||||
tmp //
|
||||
);
|
||||
|
||||
//
|
||||
max = GetMax(tmp);
|
||||
min = GetMin(tmp);
|
||||
}
|
||||
|
||||
//
|
||||
if (bufferSize == mLength)
|
||||
{
|
||||
//
|
||||
max = GetMax(buffer);
|
||||
min = GetMin(buffer);
|
||||
}
|
||||
|
||||
//
|
||||
T iValue = buffer[mStart];
|
||||
|
||||
//
|
||||
double minMaxDiff = (max - min);
|
||||
double boundaryDiff = (mUpper - mLower);
|
||||
if (minMaxDiff <= 0 || boundaryDiff <= 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = boundaryDiff / (minMaxDiff * (iValue - max) + max);
|
||||
|
||||
//
|
||||
result = NormalizeDouble(result, digits);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Templates ...
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
//
|
||||
// Imports ...
|
||||
#include <Trade/Trade.mqh>
|
||||
#include "../Libraries/x-saherelm.draw.lib.mq5"
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||
#include "../Classes/x-saherelm.xdata-collector.class.mq5"
|
||||
|
||||
@@ -1109,6 +1110,16 @@ struct XSignal
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int GetAge()
|
||||
{
|
||||
//
|
||||
return GetAge(
|
||||
this,
|
||||
this.period //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve Entry Price ...
|
||||
double GetEntry()
|
||||
@@ -1480,6 +1491,162 @@ struct XSignal
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Draw Signal on Chart ...
|
||||
bool Draw(
|
||||
long chartID,
|
||||
int subWindow = 0,
|
||||
string prefix = NULL,
|
||||
color entryColor = clrGold,
|
||||
color bullishColor = clrSpringGreen,
|
||||
color bearishColor = clrTomato //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool isLong = IsLong(this.type);
|
||||
|
||||
//
|
||||
prefix =
|
||||
//
|
||||
(!IsValid(prefix) ? "" : prefix) +
|
||||
this.symbol + "_" +
|
||||
ToString(this.period) + "_" +
|
||||
this.provider
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
int age = this.GetAge();
|
||||
|
||||
//
|
||||
// Retrieve Time ...
|
||||
datetime time0 = iTime(
|
||||
this.symbol,
|
||||
this.period,
|
||||
age //
|
||||
);
|
||||
|
||||
//
|
||||
// Retrieve 3 Time ...
|
||||
datetime time3 = iTime(
|
||||
this.symbol,
|
||||
this.period,
|
||||
age + 3 //
|
||||
);
|
||||
|
||||
//
|
||||
color posColor = isLong
|
||||
? bullishColor
|
||||
: bearishColor;
|
||||
color tpColor = bullishColor;
|
||||
color slColor = bearishColor;
|
||||
|
||||
//
|
||||
ENUM_LINE_STYLE vLineStyle = STYLE_DOT;
|
||||
ENUM_LINE_STYLE tpLineStyle = STYLE_SOLID;
|
||||
ENUM_LINE_STYLE slLineStyle = STYLE_SOLID;
|
||||
ENUM_LINE_STYLE entryLineStyle = STYLE_SOLID;
|
||||
|
||||
//
|
||||
int lineWidth = 2;
|
||||
|
||||
//
|
||||
// Vertical Line ...
|
||||
string vlName = prefix + "_" + (string)time;
|
||||
|
||||
//
|
||||
result = DrawVerticalLine(
|
||||
chartID,
|
||||
vlName,
|
||||
subWindow,
|
||||
time0,
|
||||
posColor,
|
||||
vLineStyle,
|
||||
lineWidth //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// TP ...
|
||||
double profit = (MathAbs(this.tp - this.entry)) * this.volume;
|
||||
string tpName = prefix + "_TP_" + (string)profit;
|
||||
|
||||
//
|
||||
result = DrawTrendLine(
|
||||
chartID,
|
||||
tpName,
|
||||
subWindow,
|
||||
time3,
|
||||
this.tp,
|
||||
time0,
|
||||
this.tp,
|
||||
tpColor,
|
||||
tpLineStyle,
|
||||
lineWidth //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// SL ...
|
||||
double lost = (MathAbs(this.sl - this.entry)) * this.volume;
|
||||
string slName = prefix + "_SL_" + (string)lost;
|
||||
|
||||
//
|
||||
result = DrawTrendLine(
|
||||
chartID,
|
||||
slName,
|
||||
subWindow,
|
||||
time3,
|
||||
this.sl,
|
||||
time0,
|
||||
this.sl,
|
||||
slColor,
|
||||
slLineStyle,
|
||||
lineWidth //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// ENTRY ...
|
||||
string entryName = prefix + "_ENTRY_" + (string)lost;
|
||||
|
||||
//
|
||||
result = DrawTrendLine(
|
||||
chartID,
|
||||
entryName,
|
||||
subWindow,
|
||||
time3,
|
||||
this.entry,
|
||||
time,
|
||||
this.entry,
|
||||
entryColor,
|
||||
entryLineStyle,
|
||||
lineWidth //
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
@@ -2888,6 +3055,32 @@ bool IsValid(ENUM_X_ORDER_MODES value)
|
||||
//
|
||||
// Ages ...
|
||||
|
||||
//
|
||||
// Retrieve a Position Age ...
|
||||
int GetAge(
|
||||
XSignal &signal, // Selected Signal ...
|
||||
ENUM_TIMEFRAMES period = NULL // Dest Time Frame ...
|
||||
)
|
||||
{
|
||||
//
|
||||
int result = -1;
|
||||
|
||||
//
|
||||
if (period == NULL)
|
||||
{
|
||||
period = _Period;
|
||||
}
|
||||
|
||||
//
|
||||
result = iBarShift(
|
||||
signal.symbol,
|
||||
period,
|
||||
signal.time);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve a Position Age ...
|
||||
int GetAge(
|
||||
|
||||
Reference in New Issue
Block a user