1150 lines
22 KiB
Plaintext
1150 lines
22 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 Library
|
|
// -------------------------------------------------
|
|
// Name: XCXFIMAEALib ...
|
|
// Description: XFIMAEA Library ...
|
|
//
|
|
//
|
|
// Maintainer:
|
|
// ------------
|
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
|
//
|
|
//////////////////////////////////////////////////////
|
|
//
|
|
// Global Properties ...
|
|
#property library
|
|
#property copyright "Copyright 2023, SaherElm IT Center"
|
|
#property link "https://saherelm.ir"
|
|
#property version "1.00"
|
|
#property description "SaherElm XFIMAEA Library"
|
|
#property strict
|
|
|
|
//
|
|
// Imports ...
|
|
#include "../../Helpers/x-saherelm.xfima.helper.mq5"
|
|
|
|
//
|
|
// Definitions ...
|
|
|
|
//
|
|
// Enumerations ...
|
|
|
|
//
|
|
// ZigZag Point Type ...
|
|
enum ENUM_X_ZIGZAG_POINT_TYPE
|
|
{
|
|
X_ZIGZAG_POINT_TYPE_NONE = 0, // None
|
|
X_ZIGZAG_POINT_TYPE_PEAK = 1, // PEAK
|
|
X_ZIGZAG_POINT_TYPE_VALE = 2, // VALE
|
|
};
|
|
|
|
/**
|
|
* Validate ...
|
|
*
|
|
* @param value: ENUM_X_ZIGZAG_POINT_TYPE ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsXValid(ENUM_X_ZIGZAG_POINT_TYPE value)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = value != X_ZIGZAG_POINT_TYPE_NONE;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Represent Specified ZigZag Point Type as String ...
|
|
*
|
|
* @param value: ENUM_X_ZIGZAG_POINT_TYPE ...
|
|
*
|
|
* @return ( string )
|
|
*/
|
|
string ToXString(ENUM_X_ZIGZAG_POINT_TYPE value)
|
|
{
|
|
return EnumToString(value);
|
|
}
|
|
|
|
//
|
|
// Structs ...
|
|
|
|
/**
|
|
* Specified ZigZag Point ...
|
|
**/
|
|
struct XZigZagPoint
|
|
{
|
|
//
|
|
// Props ...
|
|
double value; // Value
|
|
datetime time; // Time
|
|
string symbol; // Symbol
|
|
ENUM_X_DIRECTION dir; // Direction
|
|
ENUM_TIMEFRAMES period; // Period
|
|
ENUM_X_ZIGZAG_POINT_TYPE type; // Type
|
|
|
|
//
|
|
// Constructor ...
|
|
XZigZagPoint()
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
// Init ...
|
|
|
|
/**
|
|
* Initialize Structure ...
|
|
*
|
|
* @param _value: double, value of point ...
|
|
* @param _time: datetime, time of point ...
|
|
* @param _symbol: string, Symbol ...
|
|
* @param _dir: ENUM_X_DIRECTION, direction of point ...
|
|
* @param _period: ENUM_TIMEFRAMES, period ...
|
|
* @param _type: ENUM_X_ZIGZAG_POINT_TYPE, point type ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool Init(
|
|
double _value,
|
|
datetime _time,
|
|
string _symbol,
|
|
ENUM_X_DIRECTION _dir,
|
|
ENUM_TIMEFRAMES _period,
|
|
ENUM_X_ZIGZAG_POINT_TYPE _type //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
dir = _dir;
|
|
time = _time;
|
|
type = _type;
|
|
value = _value;
|
|
symbol = _symbol;
|
|
period = _period;
|
|
|
|
//
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
/**
|
|
* Cleanup Model ...
|
|
*/
|
|
void Clean()
|
|
{
|
|
//
|
|
value = 0;
|
|
time = NULL;
|
|
symbol = NULL;
|
|
period = NULL;
|
|
dir = X_DIRECTION_NONE;
|
|
type = X_ZIGZAG_POINT_TYPE_NONE;
|
|
|
|
//
|
|
ZeroMemory(this);
|
|
}
|
|
|
|
/**
|
|
* Validate Model ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsValid()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
value > 0 &&
|
|
IsXValid(type) &&
|
|
HasDirection(dir) &&
|
|
IsSpecifiedValid(time) &&
|
|
IsSpecifiedValid(symbol) &&
|
|
IsSpecifiedValid(period);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Point is Bullish or not ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsBullish()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = IsValid() &&
|
|
IsSpecifiedBullish(dir);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Point is Bearish or not ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsBearish()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = IsValid() &&
|
|
IsSpecifiedBearish(dir);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check two Struct are Same or not ...
|
|
*
|
|
* @param item: XZigZagPoint ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSameAs(XZigZagPoint &item)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
IsValid() &&
|
|
item.IsValid() &&
|
|
dir == item.dir &&
|
|
type == item.type &&
|
|
time == item.time &&
|
|
value == item.value &&
|
|
symbol == item.symbol &&
|
|
period == item.period;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Structure Exists in Specified Collection or not ...
|
|
*
|
|
* @param items: XZigZagPoint, reference Array ...
|
|
* @param index: int, reference to Holds Founded Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsExists(
|
|
XZigZagPoint &items[],
|
|
int &index //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Validate ...
|
|
result =
|
|
IsValid() &&
|
|
HasChild(items);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(items);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
result = IsSameAs(items[i]);
|
|
if (result)
|
|
{
|
|
//
|
|
index = i;
|
|
|
|
//
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result =
|
|
result &&
|
|
IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Add Structure to Specified Collection only if not Exists ...
|
|
*
|
|
* @param items: XZigZagPoint, reference Array ...
|
|
*/
|
|
void AddIfNotExists(XZigZagPoint &items[])
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
if (!HasChild(items))
|
|
{
|
|
//
|
|
AddRef(
|
|
this,
|
|
items //
|
|
);
|
|
|
|
//
|
|
return;
|
|
}
|
|
|
|
//
|
|
int index = -1;
|
|
bool isExists = IsExists(items, index);
|
|
if (!isExists)
|
|
{
|
|
//
|
|
AddRef(
|
|
this,
|
|
items //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Logging Tools ...
|
|
|
|
/**
|
|
* Extract Specified Token of Struct ...
|
|
*
|
|
* @return ( string )
|
|
*/
|
|
string GetTag()
|
|
{
|
|
return GetToken(this);
|
|
}
|
|
|
|
/**
|
|
* Represent an String Unique Identifier for Chart Objects ...
|
|
*
|
|
* @return ( string )
|
|
*/
|
|
string GetObjectID()
|
|
{
|
|
//
|
|
string result = "";
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = GetTag() + "_" + symbol + "_" + ToXString(period) + "_" + ToXString(dir) + "_" + ToXString(type) + "_" + ToXString(TimeToSeconds(time));
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Represent a Point as String ...
|
|
*
|
|
* @param spacer: string, How to Represent Spaces ...
|
|
*
|
|
* @return ( string )
|
|
*/
|
|
string GetMessage(string spacer = NULL)
|
|
{
|
|
//
|
|
string result = "";
|
|
|
|
//
|
|
// Normalize Spacer ...
|
|
if (!IsSpecifiedValid(spacer))
|
|
{
|
|
spacer = " ";
|
|
}
|
|
|
|
//
|
|
// Validate ...
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result =
|
|
ToXString(dir) + spacer + GetTag() + ":" + spacer +
|
|
"Symbol: " + symbol + spacer +
|
|
"Period: " + ToXString(period) + spacer +
|
|
"Type: " + ToXString(type) + spacer +
|
|
"Direction: " + ToXString(dir) + spacer +
|
|
"Value: " + ToXString(value) + spacer +
|
|
"Time: " + ToXString(time) + spacer;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* 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 ...
|
|
|
|
//
|
|
// Pivots ...
|
|
|
|
//
|
|
XZigZagPoint lastPeak;
|
|
XZigZagPoint recentPeak;
|
|
|
|
//
|
|
XZigZagPoint lastVale;
|
|
XZigZagPoint recentVale;
|
|
|
|
//
|
|
// Constructor ...
|
|
XZigZagAnalysis()
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
// Initialize ...
|
|
|
|
/**
|
|
* Analyse Market Structure ...
|
|
*
|
|
* @param bar: XOHCL, Specified Bar ...
|
|
* @param points: XZigZagPoint, Specified ZigZag Points Collection ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool Analyse(
|
|
XOHCL &bar,
|
|
XZigZagPoint &points[] //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Validate ...
|
|
result = bar.IsValid() &&
|
|
HasChild(points) &&
|
|
bar.symbol == points[0].symbol;
|
|
if (!result)
|
|
{
|
|
//
|
|
Clean();
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// AssignSymbol and Period ...
|
|
time = bar.time;
|
|
symbol = bar.symbol;
|
|
period = bar.period;
|
|
|
|
//
|
|
// Detect At lease Two PEAK and Two Vale ...
|
|
XZigZagPoint tmpPoints[];
|
|
Copy(
|
|
points,
|
|
tmpPoints //
|
|
);
|
|
|
|
//
|
|
// Detect Highs ...
|
|
|
|
//
|
|
// Highest High ...
|
|
|
|
//
|
|
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);
|
|
|
|
//
|
|
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);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
iZGPeak2 = tmpPoints[idx];
|
|
ArrayRemove(
|
|
tmpPoints,
|
|
idx,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
// Detect Lows ...
|
|
|
|
//
|
|
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);
|
|
|
|
//
|
|
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);
|
|
|
|
//
|
|
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);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Setting Direction ...
|
|
dir =
|
|
isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: isBearish
|
|
? X_DIRECTION_BEARISH
|
|
: X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Setting Points ...
|
|
Copy(
|
|
points,
|
|
pivots //
|
|
);
|
|
|
|
//
|
|
// Assigning Peaks and Vales ...
|
|
if (result)
|
|
{
|
|
//
|
|
lastPeak = iZGPeak1;
|
|
lastVale = iZGVale1;
|
|
recentPeak = iZGPeak2;
|
|
recentVale = iZGVale2;
|
|
}
|
|
|
|
//
|
|
// Calculate Support and Resistance ...
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
iZGPeak1.Clean();
|
|
iZGPeak2.Clean();
|
|
iZGVale1.Clean();
|
|
iZGVale2.Clean();
|
|
SpecifiedClean(tmpPoints);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
/**
|
|
* Cleanup Model ...
|
|
*/
|
|
void Clean()
|
|
{
|
|
//
|
|
time = NULL;
|
|
symbol = NULL;
|
|
period = NULL;
|
|
dir = X_DIRECTION_NONE;
|
|
SpecifiedClean(pivots);
|
|
|
|
//
|
|
lastPeak.Clean();
|
|
lastVale.Clean();
|
|
recentPeak.Clean();
|
|
recentVale.Clean();
|
|
|
|
//
|
|
ZeroMemory(this);
|
|
}
|
|
|
|
/**
|
|
* Validate Model ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsValid()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
//
|
|
HasChild(pivots) &&
|
|
HasDirection(dir) &&
|
|
IsSpecifiedValid(time) &&
|
|
IsSpecifiedValid(symbol) &&
|
|
IsSpecifiedValid(period) &&
|
|
//
|
|
lastPeak.IsValid() &&
|
|
lastVale.IsValid() &&
|
|
recentPeak.IsValid() &&
|
|
recentVale.IsValid()
|
|
//
|
|
;
|
|
|
|
//
|
|
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;
|
|
}
|
|
|
|
/**
|
|
* Check to model Has Same Direction ...
|
|
*
|
|
* @param item: XZigZagAnalysis, dest model for Checking ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSameDirectionAs(XZigZagAnalysis &item)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
IsValid() &&
|
|
item.IsValid() &&
|
|
dir == item.dir;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check to model Has Analysis Trend ...
|
|
*
|
|
* @param item: XZigZagAnalysis, dest model for Checking ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSameTrendAs(XZigZagAnalysis &item)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
IsValid() &&
|
|
item.IsValid() &&
|
|
IsSameMarketAs(item) &&
|
|
IsSameDirectionAs(item);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loggint Tools ...
|
|
|
|
/**
|
|
* Extract Specified Token of Struct ...
|
|
*
|
|
* @return ( string )
|
|
*/
|
|
string GetTag()
|
|
{
|
|
return GetToken(this);
|
|
}
|
|
|
|
/**
|
|
* Represent an String Unique Identifier for Chart Objects ...
|
|
*
|
|
* @return ( string )
|
|
*/
|
|
string GetObjectID()
|
|
{
|
|
//
|
|
string result = "";
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = GetTag() + "_" + symbol + "_" + ToXString(period) + "_" + ToXString(dir) + "_" + ToXString(TimeToSeconds(time));
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Represent a Point as String ...
|
|
*
|
|
* @param spacer: string, How to Represent Spaces ...
|
|
*
|
|
* @return ( string )
|
|
*/
|
|
string GetMessage(string spacer = NULL)
|
|
{
|
|
//
|
|
string result = "";
|
|
|
|
//
|
|
// Normalize Spacer ...
|
|
if (!IsSpecifiedValid(spacer))
|
|
{
|
|
spacer = " ";
|
|
}
|
|
|
|
//
|
|
// Validate ...
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result =
|
|
ToXString(dir) + spacer + GetTag() + ":" + spacer +
|
|
"Symbol: " + symbol + spacer +
|
|
"Period: " + ToXString(period) + spacer +
|
|
"Direction: " + ToXString(dir) + spacer +
|
|
"Time: " + ToXString(time) + spacer;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
//
|
|
// Extensions ...
|
|
|
|
/**
|
|
* Get Highest ZigZagPoint Index in Specified Collection ...
|
|
*
|
|
* @param items: XZigZagPoint, Specified Points Collection to Search ...
|
|
* @param type: ENUM_X_ZIGZAG_POINT_TYPE, Specified Points Type ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int GetHighest(
|
|
XZigZagPoint &items[],
|
|
ENUM_X_ZIGZAG_POINT_TYPE type = X_ZIGZAG_POINT_TYPE_NONE //
|
|
)
|
|
{
|
|
//
|
|
int result = -1;
|
|
|
|
//
|
|
// Validate ...
|
|
if (!HasChild(items))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool has = false;
|
|
XZigZagPoint iPoint;
|
|
int count = ArraySize(items);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
// Passed Type ...
|
|
has = !IsXValid(type)
|
|
? true
|
|
: type == items[i].type;
|
|
|
|
//
|
|
// Check Can Assign ...
|
|
has =
|
|
has &&
|
|
(!iPoint.IsValid() ||
|
|
(iPoint.IsValid() &&
|
|
items[i].value > iPoint.value));
|
|
if (has)
|
|
{
|
|
//
|
|
result = i;
|
|
iPoint = items[i];
|
|
}
|
|
}
|
|
|
|
//
|
|
// Validate Result ...
|
|
has =
|
|
iPoint.IsValid() &&
|
|
IsValidIndex(result);
|
|
if (!has)
|
|
{
|
|
//
|
|
result = -1;
|
|
iPoint.Clean();
|
|
return result;
|
|
}
|
|
|
|
//
|
|
iPoint.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Get Lowest ZigZagPoint Index in Specified Collection ...
|
|
*
|
|
* @param items: XZigZagPoint, Specified Points Collection to Search ...
|
|
* @param type: ENUM_X_ZIGZAG_POINT_TYPE, Specified Points Type ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int GetLowest(
|
|
XZigZagPoint &items[],
|
|
ENUM_X_ZIGZAG_POINT_TYPE type = X_ZIGZAG_POINT_TYPE_NONE //
|
|
)
|
|
{
|
|
//
|
|
int result = -1;
|
|
|
|
//
|
|
// Validate ...
|
|
if (!HasChild(items))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool has = false;
|
|
XZigZagPoint iPoint;
|
|
int count = ArraySize(items);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
// Passed Type ...
|
|
has = !IsXValid(type)
|
|
? true
|
|
: type == items[i].type;
|
|
|
|
//
|
|
// Check Can Assign ...
|
|
has =
|
|
has &&
|
|
(!iPoint.IsValid() ||
|
|
(iPoint.IsValid() &&
|
|
items[i].value < iPoint.value));
|
|
if (has)
|
|
{
|
|
//
|
|
result = i;
|
|
iPoint = items[i];
|
|
}
|
|
}
|
|
|
|
//
|
|
// Validate Result ...
|
|
has =
|
|
iPoint.IsValid() &&
|
|
IsValidIndex(result);
|
|
if (!has)
|
|
{
|
|
//
|
|
result = -1;
|
|
iPoint.Clean();
|
|
return result;
|
|
}
|
|
|
|
//
|
|
iPoint.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
// |