diff --git a/Documents/BKP/tmp.poi.mq5 b/Documents/BKP/tmp.poi.mq5 index 919dc816..db780f87 100644 --- a/Documents/BKP/tmp.poi.mq5 +++ b/Documents/BKP/tmp.poi.mq5 @@ -5383,3 +5383,1676 @@ class XCSession : public XCFromToZone // }; + + +// + + + +template +bool ToBox( + T *&source[], + XBoxZone &dest[] // +) +{ + // + bool result = false; + + // + Clean(dest); + + // + int count = ArraySize(source); + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + T *item = source[i]; + + // + if (item != NULL) + { + // + XBoxZone iBox; + bool hasBox = ToBox( + iBox, + item // + ); + + // + if (hasBox) + { + // + AddRef( + iBox, + dest // + ); + } + } + } + + // + int destCount = ArraySize(dest); + result = IsValidSize(destCount); + + // + return result; +} + +template +int GetOldest( + T *&source[] // +) +{ + // + int result = -1; + + // + int count = ArraySize(source); + if (!IsValidSize(count)) + { + return result; + } + + // + XBoxZone boxes[]; + bool isConverted = ToBox( + source, + boxes // + ); + if (!isConverted) + { + return result; + } + + // + int boxesCount = ArraySize(boxes); + + // + if (count != boxesCount) + { + return result; + } + + // + result = GetOldest(boxes); + + // + Clean(boxes); + + // + return result; +} + +template +int GetYoungest( + T *&source[] // +) +{ + // + int result = -1; + + // + int count = ArraySize(source); + if (!IsValidSize(count)) + { + return result; + } + + // + XBoxZone boxes[]; + bool isConverted = ToBox( + source, + boxes // + ); + if (!isConverted) + { + return result; + } + + // + int boxesCount = ArraySize(boxes); + + // + if (count != boxesCount) + { + return result; + } + + // + result = GetYoungest(boxes); + + // + Clean(boxes); + + // + return result; +} + +template +int GetLowest( + T *&source[] // +) +{ + // + int result = -1; + + // + int count = ArraySize(source); + if (!IsValidSize(count)) + { + return result; + } + + // + XBoxZone boxes[]; + bool isConverted = ToBox( + source, + boxes // + ); + if (!isConverted) + { + return result; + } + + // + int boxesCount = ArraySize(boxes); + + // + if (count != boxesCount) + { + return result; + } + + // + result = GetLowest(boxes); + + // + Clean(boxes); + + // + return result; +} + +template +int GetHighest( + T *&source[] // +) +{ + // + int result = -1; + + // + int count = ArraySize(source); + if (!IsValidSize(count)) + { + return result; + } + + // + XBoxZone boxes[]; + bool isConverted = ToBox( + source, + boxes // + ); + if (!isConverted) + { + return result; + } + + // + int boxesCount = ArraySize(boxes); + + // + if (count != boxesCount) + { + return result; + } + + // + result = GetHighest(boxes); + + // + Clean(boxes); + + // + return result; +} + +template +bool IsSame( + T *source, + T *dest // +) +{ + // + bool result = false; + + // + XBoxZone sourceBox; + result = ToBox( + sourceBox, + source // + ); + if (!result) + { + return result; + } + + // + XBoxZone destBox; + result = ToBox( + destBox, + dest // + ); + if (!result) + { + return result; + } + + // + result = sourceBox.IsSameAs(destBox); + + // + return result; +} + +template +bool IsBelow( + T *source, + T *dest, + bool ignoreInside = false // +) +{ + // + bool result = false; + + // + XBoxZone sourceBox; + result = ToBox( + sourceBox, + source // + ); + if (!result) + { + return result; + } + + // + XBoxZone destBox; + result = ToBox( + destBox, + dest // + ); + if (!result) + { + return result; + } + + // + result = IsBoxBelow( + sourceBox, + destBox, + ignoreInside // + ); + + // + return result; +} + +template +bool IsAbove( + T *source, + T *dest, + bool ignoreInside = false // +) +{ + // + bool result = false; + + // + XBoxZone sourceBox; + result = ToBox( + sourceBox, + source // + ); + if (!result) + { + return result; + } + + // + XBoxZone destBox; + result = ToBox( + destBox, + dest // + ); + if (!result) + { + return result; + } + + // + result = IsBoxAbove( + sourceBox, + destBox, + ignoreInside // + ); + + // + return result; +} + +template +bool IsInside( + T *source, + T *dest // +) +{ + // + bool result = false; + + // + XBoxZone sourceBox; + result = ToBox( + sourceBox, + source // + ); + if (!result) + { + return result; + } + + // + XBoxZone destBox; + result = ToBox( + destBox, + dest // + ); + if (!result) + { + return result; + } + + // + result = IsBoxInside( + sourceBox, + destBox // + ); + + // + return result; +} + +template +bool IsInsideOr( + T *source, + T *dest // +) +{ + // + bool result = false; + + // + XBoxZone sourceBox; + result = ToBox( + sourceBox, + source // + ); + if (!result) + { + return result; + } + + // + XBoxZone destBox; + result = ToBox( + destBox, + dest // + ); + if (!result) + { + return result; + } + + // + result = IsBoxInsideOr( + sourceBox, + destBox // + ); + + // + return result; +} + +template +bool FindIndex( + int &index, + T *item, + T *&items[] // +) +{ + // + bool result = false; + + // + index = -1; + + // + XBoxZone itemBox; + result = ToBox( + itemBox, + item // + ); + if (!result) + { + return result; + } + + // + XBoxZone itemsBox[]; + result = ToBox( + items, + itemsBox // + ); + if (!result) + { + return result; + } + + // + result = FindBoxIndex( + index, + itemBox, + itemsBox // + ); + + // + return result; +} + +template +bool IsInside( + double value, + T *source // +) +{ + // + bool result = false; + + // + XBoxZone sourceBox; + result = ToBox( + sourceBox, + source // + ); + if (!result) + { + return result; + } + + // + result = IsInsideBox( + value, + sourceBox // + ); + + // + return result; +} + +template +bool IsAbove( + double value, + T *source // +) +{ + // + bool result = false; + + // + XBoxZone sourceBox; + result = ToBox( + sourceBox, + source // + ); + if (!result) + { + return result; + } + + // + result = IsAboveBox( + value, + sourceBox // + ); + + // + return result; +} + +template +bool IsBelow( + double value, + T *source // +) +{ + // + bool result = false; + + // + XBoxZone sourceBox; + result = ToBox( + sourceBox, + source // + ); + if (!result) + { + return result; + } + + // + result = IsBelowBox( + value, + sourceBox // + ); + + // + return result; +} + +// +// +// + +// +template +void SortZones( + T *&source[], + ENUM_X_DIRECTION forDir, + bool ignoreInside = true // +) +{ + // + int idx = -1; + int count = 0; + bool has = false; + + // + has = HasDirection(forDir); + if (!has) + { + return; + } + + // + bool isBullish = IsBullish(forDir); + + // + count = ArraySize(source); + has = IsValidSize(count); + if (!has) + { + return; + } + + // + T *tmpItems[]; + T *last = NULL; + bool hasLast = false; + while (HasChild(source)) + { + // + if (!hasLast) + { + // + idx = GetOldest(source); + hasLast = IsValidIndex(idx); + if (hasLast) + { + // + last = source[idx]; + ArrayRemove( + source, + idx, + 1 // + ); + + // + Add( + last, + tmpItems // + ); + } + + // + count = ArraySize(source); + has = IsValidSize(count); + if (!has) + { + // + ZeroMemory(last); + break; + } + } + if (!hasLast) + { + // + ZeroMemory(last); + break; + } + + // + T *item = NULL; + idx = GetOldest(source); + has = IsValidIndex(idx); + if (!has) + { + // + ZeroMemory(last); + ZeroMemory(item); + break; + } + item = source[idx]; + ArrayRemove( + source, + idx, + 1 // + ); + + // + bool isAbove = IsAbove( + item, + last, + ignoreInside // + ); + + // + bool isBelow = IsBelow( + item, + last, + ignoreInside // + ); + + // + has = + isBullish + ? isAbove + : isBelow; + if (has) + { + // + Add( + item, + tmpItems // + ); + + // + last = item; + hasLast = item != NULL; + } + } + + // + Clean(source); + Copy( + tmpItems, + source // + ); + + // + Clean(tmpItems); +} + +/** + * Extract all Zones Which provided bar is Inside it ... + * + * @return ( int ) + */ +template +int ExtractInsideZones( + XOHCL &bar, // Bar ... + T *&zones[], // Source of Zones ... + T *&dest[] // Dest (all inside Zones) ... +) +{ + // + int result = 0; + + // + Clean(dest); + + // + int count = ArraySize(zones); + bool isValid = bar.IsValid() && + IsValidSize(count); + if (!isValid) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + T *iZone = zones[i]; + + // + bool isHighInside = IsInside( + bar.high, + iZone // + ); + + // + bool isLowInside = IsInside( + bar.low, + iZone // + ); + + // + bool isInside = + isLowInside && + isHighInside; + + // + if (isInside) + { + // + Add( + iZone, + dest // + ); + } + + // + ZeroMemory(iZone); + } + + // + result = ArraySize(dest); + + // + return result; +} + +/** + * Add Specific Item into a Collection Reference only if it's not Exists ... + * + * @return ( bool ) + */ +template +bool AddIfNotExists( + T *item, + T *&items[] // +) +{ + // + bool result = false; + + // + result = item != NULL; + if (!result) + { + return result; + } + + // + int before = ArraySize(items); + + // + int idx = FindIndex( + item, + items // + ); + bool has = IsValidIndex(idx); + result = !has; + if (!result) + { + return result; + } + + // + Add( + item, + items // + ); + + // + int after = ArraySize(items); + + // + result = after > before; + + // + return result; +} + +/** + * Add items Collection reference Members into source Collection only if it's not Exists ...alignas + * @return ( int ) + */ +template +int AddIfNotExists( + T *&items[], + T *&sources[] // +) +{ + // + int result = 0; + + // + bool has = HasChild(items); + if (!has) + { + return result; + } + + // + int before = ArraySize(sources); + + // + int count = ArraySize(items); + for (int i = 0; i < count; i++) + { + // + has = AddIfNotExists( + items[i], + sources // + ); + } + + // + int after = ArraySize(sources); + + // + result = after > before; + + // + return result; +} + +/** + * Update to Time of Specifiex Collection ... + * + * @param items: XOBFVG instance Collection ... + * @param value: datetime ... + */ +template +void SpecifiedUpdateTo( + T *&items[], + datetime value = NULL // +) +{ + // + value = NormalizeTime(value); + + // + int count = ArraySize(items); + bool has = HasChild(items); + if (!has) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + items[i].To(value); + } +} + + +/** + * Check a Box is Used or not ... + * + * @param box: XBoxZone instance Reference ... + * @param fromIndex: int ... + * @param toIndex: int + * @param forPeriod: Specified Period ... + * + * @return ( bool ) + */ +bool IsBoxUsed( + XBoxZone &box, + int fromIndex, + int toIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // +) +{ + // + bool result = false; + + // + if (toIndex < 0) + { + toIndex = 0; + } + + // + result = + // + box.IsValid() && + fromIndex > 0 && + fromIndex > toIndex + // + ; + if (!result) + { + return result; + } + + // + if (!IsValid(forPeriod)) + { + forPeriod = box.period; + } + + // + ENUM_X_DIRECTION forDir = box.dir; + bool isBullish = IsBullish(forDir); + + // + bool isTouched = false; + for (int i = fromIndex; i >= toIndex; i--) + { + // + XOHCL iBar; + bool isInited = iBar.Init( + box.symbol, + forPeriod, + i // + ); + + // + isTouched = + isInited && + (isBullish + ? iBar.low > box.upper + : iBar.high < box.lower); + if (!isTouched) + { + continue; + } + + // + iBar.Clean(); + break; + } + + // + result = isTouched; + + // + return result; +} + +/** + * Validate Box ... + * + * @param box: XBoxZone instance ... + * @param barIndex: int, Current Bar Index ... + * @param forPeriod: Testing Period ... + * + * @return ( bool ) + */ +bool IsBoxValid( + XBoxZone &box, + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // +) +{ + // + bool result = false; + + // + result = box.IsValid(); + if (!result) + { + return result; + } + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (!IsValid(forPeriod)) + { + forPeriod = box.period; + } + + // + int toIndex = iBarShift( + box.symbol, + forPeriod, + box.to // + ); + result = IsValidIndex(toIndex); + if (!result) + { + return result; + } + + // + XOHCL iBar; + bool isBullish = box.IsBullish(); + for (int i = barIndex; i < toIndex; i++) + { + // + result = iBar.Init( + box.symbol, + forPeriod, + i // + ); + if (!result) + { + break; + } + + // + result = + isBullish + ? iBar.low > box.upper + : iBar.high < box.lower; + if (!result) + { + break; + } + + // + iBar.Clean(); + } + + // + iBar.Clean(); + + // + return result; +} + +/** + * Check Box Breaked ... + * + * @param box: XBoxZone instance ... + * @param barIndex: int, Current Bar Index ... + * @param forPeriod: Testing Period ... + * + * @return ( bool ) + */ +bool IsBoxBreaked( + XBoxZone &box, + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // +) +{ + // + bool result = false; + + // + result = box.IsValid(); + if (!result) + { + return result; + } + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (!IsValid(forPeriod)) + { + forPeriod = box.period; + } + + // + int toIndex = iBarShift( + box.symbol, + forPeriod, + box.to // + ); + result = IsValidIndex(toIndex); + if (!result) + { + return result; + } + + // + XOHCL iBar; + bool isBullish = box.IsBullish(); + for (int i = barIndex; i < toIndex; i++) + { + // + result = iBar.Init( + box.symbol, + forPeriod, + i // + ); + if (!result) + { + break; + } + + // + result = + isBullish + ? iBar.high < box.lower + : iBar.low > box.upper; + if (!result) + { + break; + } + + // + iBar.Clean(); + } + + // + iBar.Clean(); + + // + return result; +} + +/** + * Check a Box is Breaked or not ... + * + * @param box: XBoxZone instance Reference ... + * @param fromIndex: int ... + * @param toIndex: int + * @param forPeriod: Specified Period ... + * + * @return ( bool ) + */ +bool IsBoxBreaked( + XBoxZone &box, + int fromIndex, + int toIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // +) +{ + // + bool result = false; + + // + if (toIndex < 0) + { + toIndex = 0; + } + + // + result = + // + box.IsValid() && + fromIndex > 0 && + fromIndex > toIndex + // + ; + if (!result) + { + return result; + } + + // + if (!IsValid(forPeriod)) + { + forPeriod = box.period; + } + + // + ENUM_X_DIRECTION forDir = box.dir; + bool isBullish = IsBullish(forDir); + + // + bool isBreaked = false; + for (int i = fromIndex; i >= toIndex; i--) + { + // + XOHCL iBar; + bool isInited = iBar.Init( + box.symbol, + forPeriod, + i // + ); + + // + isBreaked = + isInited && + (isBullish + ? iBar.high <= box.lower + : iBar.low >= box.upper); + if (!isBreaked) + { + continue; + } + + // + iBar.Clean(); + break; + } + + // + result = isBreaked; + + // + return result; +} + +/** + * Check a BaxHas Valid Place for Specified Bar ... + * + * @param bar: XOHCL instance reference, Specified Bar ... + * #param box: XBoxZone instance reference, Specified Box ... + * + * @return ( bool ) + */ +bool IsBoxPlaceValidForBar( + XOHCL &bar, + XBoxZone &box // +) +{ + // + bool result = false; + + // + result = bar.IsValid() && + box.IsValid(); + if (!result) + { + return result; + } + + // + result = + box.IsBullish() + ? bar.low > box.upper + : bar.high < box.upper; + + // + return result; +} + + +/** + * Check Source Box is Below Dest ... + * + * @param source: XBoxZone instance Reference ... + * @param dest: XBoxZone instance Reference ... + * @param ignoreInside: bool ... + * + * @return ( bool ) + */ +bool IsBoxBelow( + XBoxZone &source, + XBoxZone &dest, + bool ignoreInside = false // +) +{ + // + bool result = false; + + // + result = source.IsValid() && + dest.IsValid() && + !source.IsSameAs(dest); + if (!result) + { + return result; + } + + // + if (!ignoreInside) + { + result = source.upper < dest.lower; + } + else + { + result = (source.upper < dest.lower || + source.upper >= dest.upper) && + source.lower < dest.lower; + } + + // + return result; +} + +/** + * Check Source Box is Above Dest ... + * + * @param source: XBoxZone instance Reference ... + * @param dest: XBoxZone instance Reference ... + * @param ignoreInside: bool ... + * + * @return ( bool ) + */ +bool IsBoxAbove( + XBoxZone &source, + XBoxZone &dest, + bool ignoreInside = false // +) +{ + // + bool result = false; + + // + result = source.IsValid() && + dest.IsValid() && + !source.IsSameAs(dest); + if (!result) + { + return result; + } + + // + if (!ignoreInside) + { + result = source.lower > dest.upper; + } + else + { + result = (source.lower > dest.upper || + source.lower <= dest.upper) && + source.upper > dest.upper; + } + + // + return result; +} + +/** + * Check Source Box is Inside Dest ... + * + * @param source: XBoxZone instance Reference ... + * @param dest: XBoxZone instance Reference ... + * @param forceSideOut: bool, force check Box has One Side Out ... + * @param ignoreSideOut: bool, Accept if source Box one Side is out of Dest Box ... + * + * @return ( bool ) + */ +bool IsBoxInside( + XBoxZone &source, + XBoxZone &dest, + bool forceSideOut = false, // + bool ignoreSideOut = true // +) +{ + // + bool result = false; + + // + result = source.IsValid() && + dest.IsValid() && + !source.IsSameAs(dest); + if (!result) + { + return result; + } + + // + bool isBullish = IsBullish(dest.dir); + + // + if (!forceSideOut) + { + // + if (ignoreSideOut) + { + // + result = source.lower >= dest.lower && + source.upper <= dest.upper; + } + else + { + result = source.lower >= dest.lower || + source.upper <= dest.upper; + } + } + else + { + // + bool hasSideIn = + isBullish + ? source.lower >= dest.lower + : source.upper <= dest.upper; + bool hasSideOut = + isBullish + ? source.upper >= dest.upper + : source.lower <= dest.lower; + result = + hasSideIn && + hasSideOut; + } + + // + return result; +} + +/** + * Detect source BoX is Inside Dest Box or Have a Side Out on it ... + * + * @param source: XBoxZone instance, source box which checks by dest ... + * @param dest: XBoxZone instance, dest Box which compares source with it ... + * + * @return ( bool ) + */ +bool IsBoxInsideOr( + XBoxZone &source, + XBoxZone &dest, + bool forceInside = false // +) +{ + // + bool result = false; + + // + result = source.IsValid() && + dest.IsValid() && + !source.IsSameAs(dest); + if (!result) + { + return result; + } + + // + bool isInside = + source.upper <= dest.upper && + source.upper >= dest.lower && + source.lower >= dest.lower && + source.lower <= dest.upper; + bool isUpperInside = + source.upper <= dest.upper && + source.upper >= dest.lower; + bool isLowerInside = + source.lower >= dest.lower && + source.lower <= dest.upper; + + // + result = + forceInside + ? isInside + : (isInside || + isLowerInside || + isUpperInside); + + // + return result; +} + +/** + * Check Value is Inside Specified Box ... + * + * @param value: double ... + * @param box: XCBozZone instance Reference ... + * + * @return ( bool ) + */ +bool IsInsideBox( + double value, + XBoxZone &box // +) +{ + // + bool result = false; + + // + result = value > 0 && + box.IsValid() && + value <= box.upper && + value >= box.lower; + + // + return result; +} + +/** + * Check Bar is Inside Specified Box ... + * + * @param bar: XOHCL instance reference, Specified Bar ... + * @param box: XCBozZone instance Reference ... + * + * @return ( bool ) + */ +bool IsInsideBox( + XOHCL &bar, + XBoxZone &box // +) +{ + // + bool result = false; + + // + // Validate Args ... + result = bar.IsValid() && + box.IsValid(); + if (!result) + { + return result; + } + + // + result = + bar.close <= box.upper && + bar.close >= box.lower; + + // + return result; +} + +/** + * Check Value is Above Specified Box ... + * + * @param value: double ... + * @param box: XCBozZone instance Reference ... + * + * @return ( bool ) + */ +bool IsAboveBox( + double value, + XBoxZone &box // +) +{ + // + bool result = false; + + // + result = value > 0 && + box.IsValid() && + value > box.upper; + + // + return result; +} + +/** + * Check Value is Below Specified Box ... + * + * @param value: double ... + * @param box: XCBozZone instance Reference ... + * + * @return ( bool ) + */ +bool IsBelowBox( + double value, + XBoxZone &box // +) +{ + // + bool result = false; + + // + result = value > 0 && + box.IsValid() && + value < box.lower; + + // + return result; +} + +/** + * Find an Inside Box of source in a Collection ... + * + * @param index: int, Founded Index ... + * @param source: XBoxZone instance ... + * @param dest: XBoxZone instance Collection ... + * + * @return ( bool ) + */ +bool HasInsideBox( + int &index, + XBoxZone &source, + XBoxZone &dest[] // +) +{ + // + bool result = false; + + // + index = -1; + + // + result = source.IsValid() && + HasChild(dest); + + // + int count = ArraySize(dest); + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = dest[i]; + + // + bool isInside = !iBox.IsSameAs(source) && + IsBoxInsideOr( + iBox, + source // + ); + if (isInside) + { + // + index = i; + iBox.Clean(); + + // + break; + } + + // + iBox.Clean(); + } + + // + result = IsValidIndex(index); + + // + return result; +} diff --git a/Indicators/x-saherelm.x121.xcatb.v1.mq5 b/Indicators/x-saherelm.x121.xcatb.v1.mq5 new file mode 100644 index 00000000..61aebf42 --- /dev/null +++ b/Indicators/x-saherelm.x121.xcatb.v1.mq5 @@ -0,0 +1,3594 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------------- +// Name: X121 XCATB +// Description: Integrates All Requirements inside +// this indicator for analyse Markets to +// Detect Trigger Blocks ... +// +// - HK Bars; +// - ATR Band; +// - Signal Bars; +// - Parabolic Sar; +// - HK Signal Bars; +// - Peaks and Vales; +// - Peaks and Vales Goldens; +// - Trending Average Prices; +// +// - ATR; +// - RSI; +// - ADX; +// - DELTA; +// - VOLUME; +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121 XCATB Indicator" +#property strict + +// +// Definitions ... + +// +#define ShortName "X121 XCATB" + +// +// Imports ... +#include "../Classes/x-saherelm.x-bar.analyser.class.mq5" +#include "../Classes/x-saherelm.x-poi.drawer.class.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Inputs ... + +// +input group "Market"; + +// +// Short ... +input ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Short Period +input ENUM_TIMEFRAMES scPeriod = NULL; // Short Period + +// +// Medium ... +input ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Medium Period +input ENUM_TIMEFRAMES mcPeriod = NULL; // Medium Period + +// +// Long ... +input ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Long Period +input ENUM_TIMEFRAMES lcPeriod = NULL; // Long Period + +// +// Hind ... +input ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Hind Period +input ENUM_TIMEFRAMES hcPeriod = NULL; // Hind Period + +// +// Select Trending Cycle ... +// this Cycle Used for All Calculations ... +input ENUM_X_MARKET_CYCLES appliedCycle = X_MARKET_CYCLE_HIND; // Applied Cycle + +// +// Presentation ... +input group "Presentation"; +input bool showBars = true; // Show Bars +input bool showKI = false; // Show KI +input bool showPV = false; // Show PV +input bool showPVGolden = false; // Show PV Golden +input bool showSar = false; // Show Sar +input bool showTrend = false; // Show Trend +input bool showATRBand = false; // Show ATR Band +input bool showSignalBars = false; // Show Signal Bars +input bool showHKSignalBars = false; // Show Hiken Ashi Signal Bars + +// +input int startCalculationForLastBars = 1500; // Calculate Last n Bars + +// +// Non Inputs ... +double sarStep = 0.02; // Step +double sarMax = 0.2; // Maximum +double rsiOBLevel = 70.0; // RSI OB Level +double rsiOSLevel = 30.0; // RSI OS Level +double adxThreshold = 25.0; // ADX Threshold +int kiLength = 144; // KI Length +int sarArrowCode = 159; // Parabolic Sar Arrow Code +int peakArrowCode = 159; // Peaks Arrow Code +int valeArrowCode = 159; // Vales Arrow Code +double atrMultiplier = 1.5; // ATR Band Multiplier +bool showShortCycle = false; // Show Short Cycle Range +bool showMediumCycle = false; // Show Medium Cycle Range +bool showLongCycle = false; // Show Long Cycle Range +bool showHindCycle = false; // Show Hind Cycle Range +ENUM_MA_METHOD trendMode = MODE_SMA; // Trend Mode +ENUM_SERIESMODE upperMode = MODE_HIGH; // Peak Method +ENUM_SERIESMODE lowerMode = MODE_LOW; // Vale Method +ENUM_X_PRICE atrUpperPriceType = X_PRICE_HIGH; // ATR Upper Zone Applied To +ENUM_X_PRICE atrLowerPriceType = X_PRICE_LOW; // ATR Lower Zone Applied To +ENUM_APPLIED_PRICE rsiAppliedTo = PRICE_CLOSE; // RSI Applied To +ENUM_APPLIED_PRICE trendAppliedTo = PRICE_MEDIAN; // Trend Applied To +ENUM_X_MA_METHOD atrSignalMethod = X_MA_MODE_EMA; // ATR Signalling Method +ENUM_X_MA_METHOD barsSignalMethod = X_MA_MODE_EMA; // Bars Signalling Method +ENUM_X_MA_METHOD deltaSignalMethod = X_MA_MODE_EMA; // Delta Signalling Method +ENUM_X_MA_METHOD hkSignalBarMethod = X_MA_MODE_EMA; // Hiken Ashi Signal Method +ENUM_X_MA_METHOD volumeSignalMethod = X_MA_MODE_EMA; // Volume Signalling Method + +// +#define hideColorIDX 0 +#define bullishColorIDX 1 +#define bearishColorIDX 2 +#define neuturalColorIDX 3 + +// +#define bullishState 1 +#define neuturalState 0 +#define bearishState -1 + +// +#define emptyValue 0.0 + +// +// Buffers ... + +// +#property indicator_chart_window + +// +// Plot: 18 +// Color: 4 +// Bar: 8 +// Data Buffer: 29 +#property indicator_buffers 50 +#property indicator_plots 19 + +// +// Plot Buffers ... + +// +// SAR ... + +// +#define sarBufferIndex 0 +#define sarBufferPlotIndex 0 +double sarBuffer[]; + +// +#define sarColorBufferIndex 1 +double sarColorBuffer[]; + +// +#property indicator_label1 "SAR" +#property indicator_type1 DRAW_COLOR_ARROW +#property indicator_color1 CLR_NONE, clrLime, clrRed, clrGray +#property indicator_width1 2 + +// +// PEAKS ... + +// +#define peakBufferIndex 2 +#define peakBufferPlotIndex 1 +double peakBuffer[]; + +// +#property indicator_label2 "PEAK" +#property indicator_type2 DRAW_ARROW +#property indicator_color2 clrMagenta +#property indicator_width2 1 + +// +// VALES ... + +// +#define valeBufferIndex 3 +#define valeBufferPlotIndex 2 +double valeBuffer[]; + +// +#property indicator_label3 "VALE" +#property indicator_type3 DRAW_ARROW +#property indicator_color3 clrAqua +#property indicator_width3 1 + +// +// PEAKS Golden ... + +// +#define peakGoldenBufferIndex 4 +#define peakGoldenBufferPlotIndex 3 +double peakGoldenBuffer[]; + +// +#property indicator_label4 "PEAK Golden" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrMagenta +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +// VALE Golden ... + +// +#define valeGoldenBufferIndex 5 +#define valeGoldenBufferPlotIndex 4 +double valeGoldenBuffer[]; + +// +#property indicator_label5 "VALES Golden" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrAqua +#property indicator_style5 STYLE_DOT +#property indicator_width5 1 + +// +// ATR ... + +// +// Upper ... + +// +#define atrUpperBufferIndex 6 +#define atrUpperBufferPlotIndex 5 +double atrUpperBuffer[]; + +// +#property indicator_label6 "XATRU" +#property indicator_type6 DRAW_LINE +#property indicator_color6 clrYellow +#property indicator_style6 STYLE_SOLID +#property indicator_width6 1 + +// +// Lower ... + +// +#define atrLowerBufferIndex 7 +#define atrLowerBufferPlotIndex 6 +double atrLowerBuffer[]; + +// +#property indicator_label7 "XATRL" +#property indicator_type7 DRAW_LINE +#property indicator_color7 clrYellow +#property indicator_style7 STYLE_SOLID +#property indicator_width7 1 + +// +// TREND ... + +// +#define trendBufferIndex 8 +#define trendBufferPlotIndex 7 +double trendBuffer[]; + +// +#define trendColorBufferIndex 9 +double trendColorBuffer[]; + +// +#property indicator_label8 "Trend" +#property indicator_type8 DRAW_COLOR_LINE +#property indicator_color8 CLR_NONE, clrAqua, clrMagenta, clrGray +#property indicator_style8 STYLE_SOLID +#property indicator_width8 2 + +// +// Signal Bar ... + +// +#define sBarOpenBufferIndex 10 +double sBarOpenBuffer[]; + +// +#define sBarHighBufferIndex 11 +double sBarHighBuffer[]; + +// +#define sBarLowBufferIndex 12 +double sBarLowBuffer[]; + +// +#define sBarCloseBufferIndex 13 +double sBarCloseBuffer[]; + +// +#define sBarColorBufferIndex 14 +double sBarColorBuffer[]; + +// +#define sBarBufferPlotIndex 8 +#property indicator_label9 "XSGB Open;XSGB High;XSGB Low;XSGB Close" +#property indicator_type9 DRAW_COLOR_CANDLES +#property indicator_color9 CLR_NONE, clrLime, clrRed + +// +// XHK SIGNAL ... + +// +#define hkSBarOpenBufferIndex 15 +double hkSBarOpenBuffer[]; + +// +#define hkSBarHighBufferIndex 16 +double hkSBarHighBuffer[]; + +// +#define hkSBarLowBufferIndex 17 +double hkSBarLowBuffer[]; + +// +#define hkSBarCloseBufferIndex 18 +double hkSBarCloseBuffer[]; + +// +#define hkSBarColorBufferIndex 19 +double hkSBarColorBuffer[]; + +// +#define hkSBarBufferPlotIndex 9 +#property indicator_label10 "XHKSGB Open;XHKSGB High;XHKSGB Low;XHKSGB Close" +#property indicator_type10 DRAW_COLOR_CANDLES +#property indicator_color10 CLR_NONE, clrAqua, clrMagenta + +// +// CYCLES Range ... + +// +// SHORT ... + +// +#define sHHBufferIndex 20 +#define sHHBufferPlotIndex 10 +double sHHBuffer[]; + +// +#property indicator_label11 "SH" +#property indicator_type11 DRAW_LINE +#property indicator_color11 clrGray +#property indicator_style11 STYLE_DOT +#property indicator_width11 1 + +// +#define sLLBufferIndex 21 +#define sLLBufferPlotIndex 11 +double sLLBuffer[]; + +// +#property indicator_label12 "SL" +#property indicator_type12 DRAW_LINE +#property indicator_color12 clrGray +#property indicator_style12 STYLE_DOT +#property indicator_width12 1 + +// +// MEDIUM ... + +// +#define mHHBufferIndex 22 +#define mHHBufferPlotIndex 12 +double mHHBuffer[]; + +// +#property indicator_label13 "MH" +#property indicator_type13 DRAW_LINE +#property indicator_color13 clrIndigo +#property indicator_style13 STYLE_DOT +#property indicator_width13 1 + +// +#define mLLBufferIndex 23 +#define mLLBufferPlotIndex 13 +double mLLBuffer[]; + +// +#property indicator_label14 "ML" +#property indicator_type14 DRAW_LINE +#property indicator_color14 clrIndigo +#property indicator_style14 STYLE_DOT +#property indicator_width14 1 + +// +// LONG ... + +// +#define lHHBufferIndex 24 +#define lHHBufferPlotIndex 14 +double lHHBuffer[]; + +// +#property indicator_label15 "LH" +#property indicator_type15 DRAW_LINE +#property indicator_color15 clrGoldenrod +#property indicator_style15 STYLE_DOT +#property indicator_width15 1 + +// +#define lLLBufferIndex 25 +#define lLLBufferPlotIndex 15 +double lLLBuffer[]; + +// +#property indicator_label16 "LL" +#property indicator_type16 DRAW_LINE +#property indicator_color16 clrGoldenrod +#property indicator_style16 STYLE_DOT +#property indicator_width16 1 + +// +// HIND ... + +// +#define hHHBufferIndex 26 +#define hHHBufferPlotIndex 16 +double hHHBuffer[]; + +// +#property indicator_label17 "HH" +#property indicator_type17 DRAW_LINE +#property indicator_color17 clrBrown +#property indicator_style17 STYLE_DOT +#property indicator_width17 1 + +// +#define hLLBufferIndex 27 +#define hLLBufferPlotIndex 17 +double hLLBuffer[]; + +// +#property indicator_label18 "HL" +#property indicator_type18 DRAW_LINE +#property indicator_color18 clrBrown +#property indicator_style18 STYLE_DOT +#property indicator_width18 1 + +// +// KI ... + +// +#define kiBufferIndex 28 +#define kiBufferPlotIndex 18 +double kiBuffer[]; + +// +#define kiColorBufferIndex 29 +double kiColorBuffer[]; + +// +#property indicator_label19 "KI" +#property indicator_type19 DRAW_COLOR_LINE +#property indicator_color19 CLR_NONE, clrGreen, clrRed, clrGray +#property indicator_style19 STYLE_DASHDOTDOT +#property indicator_width19 2 + +// +// Data Buffers ... + +// +#define mLastBufferIndex 29 + +// +// SAR ... + +// +#define sarStateBufferIndex mLastBufferIndex + 1 +double sarStateBuffer[]; + +// +// TREND State ... + +// +#define trendStateBufferIndex mLastBufferIndex + 2 +double trendStateBuffer[]; + +// +// RSI ... + +// +#define rsiBufferIndex mLastBufferIndex + 3 +double rsiBuffer[]; + +// +// ADX ... + +// +#define adxBufferIndex mLastBufferIndex + 4 +double adxBuffer[]; + +// +#define adxpBufferIndex mLastBufferIndex + 5 +double adxpBuffer[]; + +// +#define adxnBufferIndex mLastBufferIndex + 6 +double adxnBuffer[]; + +// +// DELTA ... + +// +#define deltaBufferIndex mLastBufferIndex + 7 +double deltaBuffer[]; + +// +#define deltaSignalBufferIndex mLastBufferIndex + 8 +double deltaSignalBuffer[]; + +// +// VOLUMES ... + +// +#define bullishVolumeBufferIndex mLastBufferIndex + 9 +double bullishVolumeBuffer[]; + +// +#define bearishVolumeBufferIndex mLastBufferIndex + 10 +double bearishVolumeBuffer[]; + +// +#define bullishVolumeSignalBufferIndex mLastBufferIndex + 11 +double bullishVolumeSignalBuffer[]; + +// +#define bearishVolumeSignalBufferIndex mLastBufferIndex + 12 +double bearishVolumeSignalBuffer[]; + +// +// ATR ... + +// +#define atrBufferIndex mLastBufferIndex + 13 +double atrBuffer[]; + +// +#define atrUpperRawBufferIndex mLastBufferIndex + 14 +double atrUpperRawBuffer[]; + +// +#define atrLowerRawBufferIndex mLastBufferIndex + 15 +double atrLowerRawBuffer[]; + +// +// HK ... + +// +#define openHKBufferIndex mLastBufferIndex + 16 +double openHKBuffer[]; + +// +#define highHKBufferIndex mLastBufferIndex + 17 +double highHKBuffer[]; + +// +#define lowHKBufferIndex mLastBufferIndex + 18 +double lowHKBuffer[]; + +// +#define closeHKBufferIndex mLastBufferIndex + 19 +double closeHKBuffer[]; + +// +// KI ... + +// +#define kiStateBufferIndex mLastBufferIndex + 20 +double kiStateBuffer[]; + +// +// Variables, Properties and etc ... + +// +int limit; + +// +int maxLength; + +// +int firstBarIndex; + +// +// Bars Color Variables ... +color _upColor = clrLime; +color _downColor = clrRed; +color _lineColor = clrLime; +color _bullishColor = clrLime; +color _bearishColor = clrRed; + +// +// XMarketCycle sc; +int mSCLength = 0; +ENUM_TIMEFRAMES mSCPeriod = NULL; + +// +// XMarketCycle mc; +int mMCLength = 0; +ENUM_TIMEFRAMES mMCPeriod = NULL; + +// +// XMarketCycle lc; +int mLCLength = 0; +ENUM_TIMEFRAMES mLCPeriod = NULL; + +// +// XMarketCycle hc; +int mHCLength = 0; +ENUM_TIMEFRAMES mHCPeriod = NULL; + +// +// Applied Cycle ... +int mAppliedLength; +ENUM_TIMEFRAMES mAppliedPeriod = NULL; + +// +// Handlers ... +int atrHandler = INVALID_HANDLE; +int sarHandler = INVALID_HANDLE; +int rsiHandler = INVALID_HANDLE; +int adxHandler = INVALID_HANDLE; +int trendHandler = INVALID_HANDLE; + +// +CArrayObj mObjects; +XCPOIDrawer *mDrawer; +XCBarAnalyser *mBarAnalyser; + +// +XBoxZone mBullishLiquidities[]; +XBoxZone mBearishLiquidities[]; + +// +// Event Handlers ... + +/** + * Initialize Indicator ... + * + * @return ( int ) + */ +int OnInit() +{ + // + bool has = false; + + // + ReadBarStyle(); + + // + // Validate Inputs ... + has = ValidateInputs(); + if (!has) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + has = InitCycles(); + if (!has) + { + return INIT_FAILED; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Initial Requirements ... + has = InitRequirements(); + if (!has) + { + return INIT_FAILED; + } + + // + if (showBars) + { + ShowBars(); + } + else + { + HideBars(); + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Initial Requirements ... + mDrawer = new XCPOIDrawer(); + mBarAnalyser = new XCBarAnalyser(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; + + // +} + +/** + * De Initialize Indicator ... + * + * @param reason: Integer, De Initialization Reason ... + */ +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + ShowBars(); + + // + // De Initial Requirements ... + mObjects.Clear(); + + // + delete mDrawer; + ZeroMemory(mDrawer); + + delete mBarAnalyser; + ZeroMemory(mBarAnalyser); + + // + // De Initialize all Handlers and etc ... + IndicatorRelease(atrHandler); + IndicatorRelease(sarHandler); + IndicatorRelease(rsiHandler); + IndicatorRelease(adxHandler); + IndicatorRelease(trendHandler); +} + +/** + * Calculate Bars ... + * + * @param rates_total: Integer, Total Bars on Chart ... + * @param prev_calculated: Integer, Total Calculated Bars on Charts ... + * @param time: DateTime Array, History of Open Time ... + * @param open: Double Array, History of Open Prices ... + * @param high: Double Array, History of High Prices ... + * @param low: Double Array, History of Low Prices ... + * @param close: Double Array, History of Close Prices ... + * @param tick_volume: Long, History of Tick Volumes on Bar ... + * @param volume: Long, History of Trade Volumes ... + * @param spread: Double, History of Spread Price ... + * + * @return ( int ) + */ +int OnCalculate( + const int rates_total, + const int prev_calculated, + const datetime &time[], + const double &open[], + const double &high[], + const double &low[], + const double &close[], + const long &tick_volume[], + const long &volume[], + const int &spread[] // +) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // Validate Calculated Bars ... + + // + // ATR ... + int atrCalculatedBars = BarsCalculated(atrHandler); + + // + // SAR ... + int sarCalculatedBars = BarsCalculated(sarHandler); + + // + // RSI ... + int rsiCalculatedBars = BarsCalculated(rsiHandler); + + // + // ADX ... + int adxCalculatedBars = BarsCalculated(adxHandler); + + // + // TREND ... + int trendCalculatedBars = BarsCalculated(trendHandler); + + // + bool isPassedRequiredCalculatedBars = + // + // ATR ... + atrCalculatedBars >= maxLength && + // + // SAR ... + sarCalculatedBars >= maxLength && + // + // RSI ... + rsiCalculatedBars >= maxLength && + // + // ADX ... + adxCalculatedBars >= maxLength && + // + // TREND ... + trendCalculatedBars >= maxLength + // + ; + if (!isPassedRequiredCalculatedBars) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) + ? rates_total + : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + + // + // ATR ... + int copiedAtrs = CopyBuffer(atrHandler, MAIN_LINE, 0, limit, atrBuffer); + + // + // SAR ... + int copiedSars = CopyBuffer(sarHandler, MAIN_LINE, 0, limit, sarBuffer); + + // + // RSI ... + int copiedRSIs = CopyBuffer(rsiHandler, MAIN_LINE, 0, limit, rsiBuffer); + + // + // ADX ... + int copiedADXs = CopyBuffer(adxHandler, MAIN_LINE, 0, limit, adxBuffer); + + // + // ADX Plus ... + int copiedADXPs = CopyBuffer(adxHandler, PLUSDI_LINE, 0, limit, adxpBuffer); + + // + // ADX Negative ... + int copiedADXNs = CopyBuffer(adxHandler, MINUSDI_LINE, 0, limit, adxnBuffer); + + // + // TREND ... + int copiedTrends = CopyBuffer(trendHandler, MAIN_LINE, 0, limit, trendBuffer); + + // + // Validate Copied Items ... + bool isPassedRequiredCopiedItems = + // + // ATR ... + copiedAtrs >= limit && + // + // SAR ... + copiedSars >= limit && + // + // RSI ... + copiedRSIs >= limit && + // + // TREND ... + copiedTrends >= limit + // + ; + if (!isPassedRequiredCopiedItems) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers( + i, + prev_calculated, + rates_total, + // + open, + high, + close, + low, + tick_volume // + ); + } + + // + if (prev_calculated == 0) + { + // + string message = "History Finished ..."; + Print(message); + } + + // + return rates_total; +} + +// +// Custom Functions ... + +/** + * Set Indicator Short Name and also we can define Buffers Labels ... + */ +void SetIndicatorName() +{ + // + IndicatorSetInteger(INDICATOR_DIGITS, _Digits); + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +/** + * Validate Input Args for Initialization ... + * + * @return ( bool ) + */ +bool ValidateInputs() +{ + // + bool result = false; + + // + result = + // + sarMax > 0 && + sarStep > 0 && + rsiOBLevel > 0 && + rsiOSLevel > 0 && + adxThreshold > 0 && + sarMax > sarStep && + atrMultiplier > 0 && + // + IsValid(appliedCycle) && + // + IsValid(atrUpperPriceType) && + IsValid(atrLowerPriceType) && + // + // CYCLES ... + (IsValid(scMethod, scPeriod) && + IsValid(mcMethod, mcPeriod) && + IsValid(lcMethod, lcPeriod) && + IsValid(hcMethod, hcPeriod)) + // + ; + + // + return result; +} + +/** + * Extract Max Length of Inputs ... + * + * @return ( int ) + */ +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(mSCLength, mMCLength); + result = MathMax(result, mLCLength); + result = MathMax(result, mHCLength); + + // + return result; +} + +/** + * Define Required Buffers ... + */ +void DefineBuffers() +{ + // + // Plot Buffers ... + + // + // SAR ... + + // + ArraySetAsSeries(sarBuffer, true); + SetIndexBuffer(sarBufferIndex, sarBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(sarBufferPlotIndex, PLOT_SHOW_DATA, showSar); + PlotIndexSetDouble(sarBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(sarBufferPlotIndex, PLOT_ARROW, sarArrowCode); + + // + ArraySetAsSeries(sarColorBuffer, true); + SetIndexBuffer(sarColorBufferIndex, sarColorBuffer, INDICATOR_COLOR_INDEX); + + // + ArraySetAsSeries(sarStateBuffer, true); + SetIndexBuffer(sarStateBufferIndex, sarStateBuffer, INDICATOR_CALCULATIONS); + + // + // PEAK / VALE ... + + // + ENUM_DRAW_TYPE pvDrawType = showPV ? DRAW_ARROW : DRAW_NONE; + + // + // PEAK ... + + // + ArraySetAsSeries(peakBuffer, true); + SetIndexBuffer(peakBufferIndex, peakBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(peakBufferPlotIndex, PLOT_SHOW_DATA, showPV); + PlotIndexSetInteger(peakBufferPlotIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + PlotIndexSetDouble(peakBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(peakBufferPlotIndex, PLOT_ARROW, peakArrowCode); + + // + // VALE ... + + // + ArraySetAsSeries(valeBuffer, true); + SetIndexBuffer(valeBufferIndex, valeBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(valeBufferPlotIndex, PLOT_SHOW_DATA, showPV); + PlotIndexSetInteger(valeBufferPlotIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + PlotIndexSetDouble(valeBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(valeBufferPlotIndex, PLOT_ARROW, valeArrowCode); + + // + // PV GOLDEN ... + + // + ENUM_DRAW_TYPE pvGoldenDrawType = showPVGolden ? DRAW_LINE : DRAW_NONE; + + // + // PEAK Golden ... + + // + ArraySetAsSeries(peakGoldenBuffer, true); + SetIndexBuffer(peakGoldenBufferIndex, peakGoldenBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(peakGoldenBufferPlotIndex, PLOT_SHOW_DATA, showPVGolden); + PlotIndexSetInteger(peakGoldenBufferPlotIndex, PLOT_DRAW_TYPE, pvGoldenDrawType); + + // + PlotIndexSetDouble(peakGoldenBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // VALE Golden ... + + // + ArraySetAsSeries(valeGoldenBuffer, true); + SetIndexBuffer(valeGoldenBufferIndex, valeGoldenBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(valeGoldenBufferPlotIndex, PLOT_SHOW_DATA, showPVGolden); + PlotIndexSetInteger(valeGoldenBufferPlotIndex, PLOT_DRAW_TYPE, pvGoldenDrawType); + + // + PlotIndexSetDouble(valeGoldenBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // ATR Band ... + + // + // UPPER ... + ENUM_DRAW_TYPE atrUpperDrawType = showATRBand ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(atrUpperBuffer, true); + SetIndexBuffer(atrUpperBufferIndex, atrUpperBuffer, INDICATOR_DATA); + + // + PlotIndexSetDouble(atrUpperBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(atrUpperBufferPlotIndex, PLOT_SHOW_DATA, showATRBand); + PlotIndexSetInteger(atrUpperBufferPlotIndex, PLOT_DRAW_TYPE, atrUpperDrawType); + + // + // LOWER ... + ENUM_DRAW_TYPE atrLowerDrawType = showATRBand ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(atrLowerBuffer, true); + SetIndexBuffer(atrLowerBufferIndex, atrLowerBuffer, INDICATOR_DATA); + + // + PlotIndexSetDouble(atrLowerBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(atrLowerBufferPlotIndex, PLOT_SHOW_DATA, showATRBand); + PlotIndexSetInteger(atrLowerBufferPlotIndex, PLOT_DRAW_TYPE, atrLowerDrawType); + + // + // TREND ... + + // + ArraySetAsSeries(trendBuffer, true); + SetIndexBuffer(trendBufferIndex, trendBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(trendBufferPlotIndex, PLOT_SHOW_DATA, showTrend); + PlotIndexSetDouble(trendBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + ArraySetAsSeries(trendColorBuffer, true); + SetIndexBuffer(trendColorBufferIndex, trendColorBuffer, INDICATOR_COLOR_INDEX); + + // + ArraySetAsSeries(trendStateBuffer, true); + SetIndexBuffer(trendStateBufferIndex, trendStateBuffer, INDICATOR_CALCULATIONS); + + // + // SIGNAL Bar ... + + // + // Signal Bars Color ... + ArraySetAsSeries(sBarColorBuffer, true); + SetIndexBuffer(sBarColorBufferIndex, sBarColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on XHK Bar Buffer ... + PlotIndexSetDouble(sBarBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(sBarBufferPlotIndex, PLOT_SHOW_DATA, false); + + // + // Open ... + ArraySetAsSeries(sBarOpenBuffer, true); + SetIndexBuffer(sBarOpenBufferIndex, sBarOpenBuffer, INDICATOR_DATA); + + // + // High ... + ArraySetAsSeries(sBarHighBuffer, true); + SetIndexBuffer(sBarHighBufferIndex, sBarHighBuffer, INDICATOR_DATA); + + // + // Low ... + ArraySetAsSeries(sBarLowBuffer, true); + SetIndexBuffer(sBarLowBufferIndex, sBarLowBuffer, INDICATOR_DATA); + + // + // Close ... + ArraySetAsSeries(sBarCloseBuffer, true); + SetIndexBuffer(sBarCloseBufferIndex, sBarCloseBuffer, INDICATOR_DATA); + + // + // XHK SIGNAL Bar ... + + // + // HK Bars Color ... + ArraySetAsSeries(hkSBarColorBuffer, true); + SetIndexBuffer(hkSBarColorBufferIndex, hkSBarColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on XHK Bar Buffer ... + PlotIndexSetDouble(hkSBarBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(hkSBarBufferPlotIndex, PLOT_SHOW_DATA, false); + + // + // Open ... + ArraySetAsSeries(hkSBarOpenBuffer, true); + SetIndexBuffer(hkSBarOpenBufferIndex, hkSBarOpenBuffer, INDICATOR_DATA); + + // + // High ... + ArraySetAsSeries(hkSBarHighBuffer, true); + SetIndexBuffer(hkSBarHighBufferIndex, hkSBarHighBuffer, INDICATOR_DATA); + + // + // Low ... + ArraySetAsSeries(hkSBarLowBuffer, true); + SetIndexBuffer(hkSBarLowBufferIndex, hkSBarLowBuffer, INDICATOR_DATA); + + // + // Close ... + ArraySetAsSeries(hkSBarCloseBuffer, true); + SetIndexBuffer(hkSBarCloseBufferIndex, hkSBarCloseBuffer, INDICATOR_DATA); + + // + // CYCLES ... + + // + // SHORT ... + + // + ENUM_DRAW_TYPE sDrawType = showShortCycle ? DRAW_LINE : DRAW_NONE; + + // + // HH ... + + // + ArraySetAsSeries(sHHBuffer, true); + SetIndexBuffer(sHHBufferIndex, sHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(sHHBufferPlotIndex, PLOT_SHOW_DATA, showShortCycle); + PlotIndexSetInteger(sHHBufferPlotIndex, PLOT_DRAW_TYPE, sDrawType); + PlotIndexSetDouble(sHHBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // LL ... + + // + ArraySetAsSeries(sLLBuffer, true); + SetIndexBuffer(sLLBufferIndex, sLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(sLLBufferPlotIndex, PLOT_SHOW_DATA, showShortCycle); + PlotIndexSetInteger(sLLBufferPlotIndex, PLOT_DRAW_TYPE, sDrawType); + PlotIndexSetDouble(sLLBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // MEDIUM ... + + // + ENUM_DRAW_TYPE mDrawType = showMediumCycle ? DRAW_LINE : DRAW_NONE; + + // + // HH ... + + // + ArraySetAsSeries(mHHBuffer, true); + SetIndexBuffer(mHHBufferIndex, mHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mHHBufferPlotIndex, PLOT_SHOW_DATA, showMediumCycle); + PlotIndexSetInteger(mHHBufferPlotIndex, PLOT_DRAW_TYPE, mDrawType); + PlotIndexSetDouble(mHHBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // LL ... + + // + ArraySetAsSeries(mLLBuffer, true); + SetIndexBuffer(mLLBufferIndex, mLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mLLBufferPlotIndex, PLOT_SHOW_DATA, showMediumCycle); + PlotIndexSetInteger(mLLBufferPlotIndex, PLOT_DRAW_TYPE, mDrawType); + PlotIndexSetDouble(mLLBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // LONG ... + + // + ENUM_DRAW_TYPE lDrawType = showLongCycle ? DRAW_LINE : DRAW_NONE; + + // + // HH ... + + // + ArraySetAsSeries(lHHBuffer, true); + SetIndexBuffer(lHHBufferIndex, lHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(lHHBufferPlotIndex, PLOT_SHOW_DATA, showLongCycle); + PlotIndexSetInteger(lHHBufferPlotIndex, PLOT_DRAW_TYPE, lDrawType); + PlotIndexSetDouble(lHHBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // LL ... + + // + ArraySetAsSeries(lLLBuffer, true); + SetIndexBuffer(lLLBufferIndex, lLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(lLLBufferPlotIndex, PLOT_SHOW_DATA, showLongCycle); + PlotIndexSetInteger(lLLBufferPlotIndex, PLOT_DRAW_TYPE, lDrawType); + PlotIndexSetDouble(lLLBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // HIND ... + + // + ENUM_DRAW_TYPE hDrawType = showHindCycle ? DRAW_LINE : DRAW_NONE; + + // + // HH ... + + // + ArraySetAsSeries(hHHBuffer, true); + SetIndexBuffer(hHHBufferIndex, hHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hHHBufferPlotIndex, PLOT_SHOW_DATA, showHindCycle); + PlotIndexSetInteger(hHHBufferPlotIndex, PLOT_DRAW_TYPE, hDrawType); + PlotIndexSetDouble(hHHBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // LL ... + + // + ArraySetAsSeries(hLLBuffer, true); + SetIndexBuffer(hLLBufferIndex, hLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hLLBufferPlotIndex, PLOT_SHOW_DATA, showHindCycle); + PlotIndexSetInteger(hLLBufferPlotIndex, PLOT_DRAW_TYPE, hDrawType); + PlotIndexSetDouble(hLLBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // KI ... + + // + ArraySetAsSeries(kiBuffer, true); + SetIndexBuffer(kiBufferIndex, kiBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(kiBufferPlotIndex, PLOT_SHOW_DATA, showKI); + PlotIndexSetDouble(kiBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + ArraySetAsSeries(kiColorBuffer, true); + SetIndexBuffer(kiColorBufferIndex, kiColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Data Buffers ... + + // + // RSI ... + ArraySetAsSeries(rsiBuffer, true); + SetIndexBuffer(rsiBufferIndex, rsiBuffer, INDICATOR_CALCULATIONS); + + // + // ADX ... + + // + ArraySetAsSeries(adxBuffer, true); + SetIndexBuffer(adxBufferIndex, adxBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(adxpBuffer, true); + SetIndexBuffer(adxpBufferIndex, adxpBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(adxnBuffer, true); + SetIndexBuffer(adxnBufferIndex, adxnBuffer, INDICATOR_CALCULATIONS); + + // + // DELTA ... + + // + ArraySetAsSeries(deltaBuffer, true); + SetIndexBuffer(deltaBufferIndex, deltaBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(deltaSignalBuffer, true); + SetIndexBuffer(deltaSignalBufferIndex, deltaSignalBuffer, INDICATOR_CALCULATIONS); + + // + // VOLUME ... + + // + ArraySetAsSeries(bullishVolumeBuffer, true); + SetIndexBuffer(bullishVolumeBufferIndex, bullishVolumeBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(bearishVolumeBuffer, true); + SetIndexBuffer(bearishVolumeBufferIndex, bearishVolumeBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(bullishVolumeSignalBuffer, true); + SetIndexBuffer(bullishVolumeSignalBufferIndex, bullishVolumeSignalBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(bearishVolumeSignalBuffer, true); + SetIndexBuffer(bearishVolumeSignalBufferIndex, bearishVolumeSignalBuffer, INDICATOR_CALCULATIONS); + + // + // ATR ... + + ArraySetAsSeries(atrBuffer, true); + SetIndexBuffer(atrBufferIndex, atrBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(atrUpperRawBuffer, true); + SetIndexBuffer(atrUpperRawBufferIndex, atrUpperRawBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(atrLowerRawBuffer, true); + SetIndexBuffer(atrLowerRawBufferIndex, atrLowerRawBuffer, INDICATOR_CALCULATIONS); + + // + // XHK ... + + // + ArraySetAsSeries(openHKBuffer, true); + SetIndexBuffer(openHKBufferIndex, openHKBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(highHKBuffer, true); + SetIndexBuffer(highHKBufferIndex, highHKBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(lowHKBuffer, true); + SetIndexBuffer(lowHKBufferIndex, lowHKBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(closeHKBuffer, true); + SetIndexBuffer(closeHKBufferIndex, closeHKBuffer, INDICATOR_CALCULATIONS); + + // + // KI ... + + // + ArraySetAsSeries(kiStateBuffer, true); + SetIndexBuffer(kiStateBufferIndex, kiStateBuffer, INDICATOR_CALCULATIONS); + + // +} + +/** + * Initial Market Cycles ... + * + * @return ( bool ) + */ +bool InitCycles() +{ + // + bool result = false; + + // + int cPeriodSeconds = PeriodSeconds(_Period); + + // + // Find Cycle Period ... + if (scMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mSCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_SHORT, + _Period // + ); + } + else + { + mSCPeriod = scPeriod; + } + + // + if (IsValid(mSCPeriod)) + { + mSCLength = PeriodSeconds(mSCPeriod) / cPeriodSeconds; + } + + // + // Find Cycle Period ... + if (mcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mMCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_MEDIUM, + _Period // + ); + } + else + { + mMCPeriod = mcPeriod; + } + + // + if (IsValid(mMCPeriod)) + { + mMCLength = PeriodSeconds(mMCPeriod) / cPeriodSeconds; + } + + // + // Find Cycle Period ... + if (lcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mLCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_LONG, + _Period // + ); + } + else + { + mLCPeriod = lcPeriod; + } + + // + if (IsValid(mLCPeriod)) + { + mLCLength = PeriodSeconds(mLCPeriod) / cPeriodSeconds; + } + + // + // Find Cycle Period ... + if (hcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mHCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_HIND, + _Period // + ); + } + else + { + mHCPeriod = hcPeriod; + } + + // + if (IsValid(mHCPeriod)) + { + mHCLength = PeriodSeconds(mHCPeriod) / cPeriodSeconds; + } + + // + result = mSCLength > 0 && + mMCLength > mSCLength && + mLCLength > mMCLength && + mHCLength > mLCLength; + + // + // Selecte Applied Cycle ... + if (result) + { + // + switch (appliedCycle) + { + // + case X_MARKET_CYCLE_SHORT: + // + mAppliedLength = mSCLength; + mAppliedPeriod = mSCPeriod; + break; + + // + case X_MARKET_CYCLE_MEDIUM: + // + mAppliedLength = mMCLength; + mAppliedPeriod = mMCPeriod; + break; + + // + case X_MARKET_CYCLE_LONG: + // + mAppliedLength = mLCLength; + mAppliedPeriod = mLCPeriod; + break; + + // + case X_MARKET_CYCLE_HIND: + // + mAppliedLength = mHCLength; + mAppliedPeriod = mHCPeriod; + break; + } + } + + // + return result; +} + +/** + * Initial all Indicator Requirements ... + * + * @return ( false ) + * + */ +bool InitRequirements() +{ + // + bool result = false; + + // + // Handlers ... + + // + // SAR ... + sarHandler = iSAR( + _Symbol, + _Period, + sarStep, + sarMax // + ); + result = sarHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // ATR ... + atrHandler = iATR( + _Symbol, + _Period, + mAppliedLength // + ); + result = atrHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // RSI ... + rsiHandler = iRSI( + _Symbol, + _Period, + mAppliedLength, + rsiAppliedTo // + ); + result = rsiHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // ADX ... + adxHandler = iADX( + _Symbol, + _Period, + mAppliedLength // + ); + result = adxHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // TREND ... + trendHandler = iMA( + _Symbol, + _Period, + mAppliedLength, + 0, + trendMode, + trendAppliedTo // + ); + result = trendHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; +} + +/** + * Calculate Custom Buffers ... + * + * @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 CalculateBuffers( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + int barsLimit = startCalculationForLastBars > 0 + ? startCalculationForLastBars + : 0; + if (barsLimit == 0) + { + // + barsLimit = ratesTotal; + firstBarIndex = barsLimit - 1; + } + else + { + firstBarIndex = startCalculationForLastBars; + } + + // + // bool canCalculate = true; + bool canCalculate = + barIndex <= barsLimit; + if (canCalculate) + { + // + // Calculate Values ... + CalculateValues( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + } + else + { + FillBuffersZero(barIndex); + } +} + +/** + * Fill All Bufers to Zero Vlue for Specified Bar Index ... + * + * @param barIndex: Integer ... + */ +void FillBuffersZero(int barIndex) +{ + // + kiColorBuffer[barIndex] = hideColorIDX; + sarColorBuffer[barIndex] = hideColorIDX; + trendColorBuffer[barIndex] = hideColorIDX; + + // + atrUpperRawBuffer[barIndex] = emptyValue; + atrLowerRawBuffer[barIndex] = emptyValue; +} + +// +// Custom Handlers ... + +/** + * Calculate Values ... + * + * @param barIndex: int, Specified Bar Index ... + * @param prevCalculated: int, Provides Previous Calculated Bars ... + * @param ratesTotal: int, Provides All Availabled Bars ... + * @param open: double Collection, Provides Open Prices Time Series ... + * @param high: double Collection, Provides High Prices Time Series ... + * @param close: double Collection, Provides Close Prices Time Series ... + * @param low: double Collection, Provides Low Prices Time Series ... + * @param tickVolume: long Collection, Provides Ticks Volume Prices Time Series ... + */ +void CalculateValues( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + int lastBarIndex = barIndex + 1; + int maxBarIndex = startCalculationForLastBars > 0 + ? startCalculationForLastBars + : ratesTotal; + bool isFirstBar = + startCalculationForLastBars > 0 + ? barIndex == startCalculationForLastBars + : barIndex == firstBarIndex; + + // + // Cycle Ranges ... + CalculateCycleRanges( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // KI ... + CalculateKI( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // PV ... + CalculatePV( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // SAR ... + CalculateSAR( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // SBAR ... + CalculateSBar( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // HKBAR ... + CalculateHKBar( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // DELTA ... + CalculateDelta( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // TREND ... + CalculateTrend( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // VOLUME ... + CalculateVolume( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // ATR Band ... + CalculateATRBand( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // Do Process on Bars ... + DoProcess( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); +} + +// +void CalculateCycleRanges( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + // SHORT ... + CalculateCycle( + barIndex, + X_MARKET_CYCLE_SHORT, + sHHBuffer, + sLLBuffer // + ); + + // + // MEDIUM ... + CalculateCycle( + barIndex, + X_MARKET_CYCLE_MEDIUM, + mHHBuffer, + mLLBuffer // + ); + + // + // LONG ... + CalculateCycle( + barIndex, + X_MARKET_CYCLE_LONG, + lHHBuffer, + lLLBuffer // + ); + + // + // HIND ... + CalculateCycle( + barIndex, + X_MARKET_CYCLE_HIND, + hHHBuffer, + hLLBuffer // + ); +} + +// +void CalculateKI( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + int lastBarIndex = barIndex + 1; + bool isFirstBar = + startCalculationForLastBars > 0 + ? barIndex == startCalculationForLastBars + : barIndex == firstBarIndex; + + // + XOHCL iBar; + bool isInited = iBar.Init( + _Symbol, + _Period, + barIndex // + ); + + // + double iClose = close[barIndex]; + + // + // Calculate KI / Color ... + double lastKI = + isFirstBar + ? emptyValue + : kiBuffer[lastBarIndex]; + double iKI = lastKI; + if (isInited) + { + // + double iLLKI = iBar.FindLowest(kiLength, MODE_LOW); + double iHHKI = iBar.FindHighest(kiLength, MODE_HIGH); + + // + iKI = (iHHKI + iLLKI) / 2; + if (iLLKI == 0 || iHHKI == 0) + { + iKI = lastKI; + } + } + else + { + iKI = lastKI; + } + kiBuffer[barIndex] = iKI; + + // + double iKIState = neuturalState; + double iKIColor = neuturalColorIDX; + if (iClose > iKI) + { + // + iKIState = bullishState; + iKIColor = + !showKI + ? hideColorIDX + : bullishColorIDX; + } + else if (iClose < iKI) + { + // + iKIState = bearishState; + iKIColor = + !showKI + ? hideColorIDX + : bearishColorIDX; + } + kiStateBuffer[barIndex] = iKIState; + kiColorBuffer[barIndex] = iKIColor; + + // + iBar.Clean(); +} + +// +void CalculatePV( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + int lastBarIndex = barIndex + 1; + bool isFirstBar = + startCalculationForLastBars > 0 + ? barIndex == startCalculationForLastBars + : barIndex == firstBarIndex; + + // + double iSHH = sHHBuffer[barIndex]; + double iSLL = sLLBuffer[barIndex]; + + // + double iMHH = mHHBuffer[barIndex]; + double iMLL = mLLBuffer[barIndex]; + + // + double iLHH = lHHBuffer[barIndex]; + double iLLL = lLLBuffer[barIndex]; + + // + double iHHH = hHHBuffer[barIndex]; + double iHLL = hLLBuffer[barIndex]; + + // + // Calculate VALE ... + bool isVale = iSLL == iMLL && + iMLL == iLLL && + iLLL == iHLL; + double iPVale = + isFirstBar + ? emptyValue + : valeBuffer[lastBarIndex]; + double iVale = + isVale + ? iSLL + : iPVale; + valeBuffer[barIndex] = iVale; + + // + // Calculate PEAK ... + bool isPeak = iSHH == iMHH && + iMHH == iLHH && + iLHH == iHHH; + double iPPeak = + isFirstBar + ? emptyValue + : peakBuffer[lastBarIndex]; + double iPeak = + isPeak + ? iSHH + : iPPeak; + peakBuffer[barIndex] = iPeak; + + // + // GOLDEN ... + + XOHCL iBar; + bool isInited = iBar.Init( + _Symbol, + _Period, + barIndex // + ); + + // + // Calculate PV Gold ... + double lastPeakGold = + isFirstBar + ? emptyValue + : peakGoldenBuffer[lastBarIndex]; + double lastValeGold = + isFirstBar + ? emptyValue + : valeGoldenBuffer[lastBarIndex]; + double iPeakGold = lastPeakGold; + double iValeGold = lastValeGold; + if (isInited) + { + // + iPeakGold = iBar.FindHighest(mHCLength, MODE_CLOSE); + if (iPeakGold == 0) + { + iPeakGold = lastPeakGold; + } + + // + iValeGold = iBar.FindLowest(mHCLength, MODE_CLOSE); + if (iValeGold == 0) + { + iValeGold = lastValeGold; + } + } + else + { + // + iPeakGold = lastPeakGold; + iValeGold = lastValeGold; + } + + // + peakGoldenBuffer[barIndex] = iPeakGold; + valeGoldenBuffer[barIndex] = iValeGold; + + // + iBar.Clean(); +} + +// +void CalculateSAR( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + double iLow = low[barIndex]; + double iHigh = low[barIndex]; + double iSar = sarBuffer[barIndex]; + + // + bool isBullish = iSar < iLow; + bool isBearish = iSar > iHigh; + + // + double iSarState = isBullish + ? 1 + : isBearish + ? -1 + : 0; + double iSarColor = iSarState > 0 + ? bullishColorIDX + : iSarState < 0 + ? bearishColorIDX + : neuturalColorIDX; + sarStateBuffer[barIndex] = iSarState; + sarColorBuffer[barIndex] = showSar + ? iSarColor + : hideColorIDX; +} + +// +void CalculateSBar( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + // Open ... + iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + open, + sBarOpenBuffer, + barsSignalMethod // + ); + + // + // Close ... + iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + close, + sBarCloseBuffer, + barsSignalMethod // + ); + + // + double min = MathMin(sBarCloseBuffer[barIndex], sBarOpenBuffer[barIndex]); + double max = MathMin(sBarCloseBuffer[barIndex], sBarOpenBuffer[barIndex]); + + // + sBarLowBuffer[barIndex] = min; + sBarHighBuffer[barIndex] = max; + + // + // Calculate HK Signal Color ... + double iSignalColorValue = + sBarOpenBuffer[barIndex] < sBarCloseBuffer[barIndex] + ? bullishColorIDX + : bearishColorIDX; + sBarColorBuffer[barIndex] = + showSignalBars + ? iSignalColorValue + : hideColorIDX; +} + +// +void CalculateHKBar( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + int lastBarIndex = barIndex + 1; + bool isFirstBar = + startCalculationForLastBars > 0 + ? barIndex == startCalculationForLastBars + : barIndex == firstBarIndex; + + // + double lastHKOpen = + isFirstBar + ? emptyValue + : openHKBuffer[lastBarIndex]; + double lastHKClose = + isFirstBar + ? emptyValue + : closeHKBuffer[lastBarIndex]; + + // + double iHKOpenValue = (lastHKOpen + lastHKClose) / 2; + double iHKCloseValue = (open[barIndex] + high[barIndex] + close[barIndex] + low[barIndex]) / 4; + double iHKHighValue = MathMax(high[barIndex], MathMax(iHKOpenValue, iHKCloseValue)); + double iHKLowValue = MathMin(low[barIndex], MathMin(iHKOpenValue, iHKCloseValue)); + + // + // Raw HK Buffers ... + openHKBuffer[barIndex] = iHKOpenValue; + highHKBuffer[barIndex] = iHKHighValue; + lowHKBuffer[barIndex] = iHKLowValue; + closeHKBuffer[barIndex] = iHKCloseValue; + + // + // XHK Signal ... + + // + // Open ... + iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + openHKBuffer, + hkSBarOpenBuffer, + hkSignalBarMethod // + ); + + // + // Close ... + iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + closeHKBuffer, + hkSBarCloseBuffer, + hkSignalBarMethod // + ); + + // + double min = MathMin(hkSBarCloseBuffer[barIndex], hkSBarOpenBuffer[barIndex]); + double max = MathMin(hkSBarCloseBuffer[barIndex], hkSBarOpenBuffer[barIndex]); + + // + hkSBarLowBuffer[barIndex] = min; + hkSBarHighBuffer[barIndex] = max; + + // + // Calculate HK Signal Color ... + double iHKSignalColorValue = + hkSBarOpenBuffer[barIndex] < hkSBarCloseBuffer[barIndex] + ? bullishColorIDX + : bearishColorIDX; + hkSBarColorBuffer[barIndex] = + showHKSignalBars + ? iHKSignalColorValue + : hideColorIDX; +} + +// +void CalculateDelta( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + int lastBarIndex = barIndex + 1; + bool isFirstBar = + startCalculationForLastBars > 0 + ? barIndex == startCalculationForLastBars + : barIndex == firstBarIndex; + + // + double iClose = close[barIndex]; + double iOpen = open[barIndex]; + double iVolume = (double)iVolume(_Symbol, _Period, barIndex); + + // + bool isBullish = iClose > iOpen; + bool isBearish = iClose < iOpen; + + // + // DELTA ... + double lastDelta = + isFirstBar + ? emptyValue + : deltaBuffer[lastBarIndex]; + double iAppliedVolume = + isBullish + ? iVolume + : -1 * iVolume; + double iDelta = + lastDelta + iAppliedVolume; + deltaBuffer[barIndex] = iDelta; + + // + // Calculate Delta Signal ... + int deltaSignalsCount = iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + deltaBuffer, + deltaSignalBuffer, + deltaSignalMethod // + ); +} + +// +void CalculateTrend( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + double iLow = low[barIndex]; + double iHigh = high[barIndex]; + double iClose = close[barIndex]; + double iTrend = trendBuffer[barIndex]; + + // + bool isBullish = iTrend < iLow; + bool isBearish = iTrend > iHigh; + + // + double iTrendState = + isBullish + ? 1 + : isBearish + ? -1 + : 0; + double iTrendColor = + iTrendState > 0 + ? bullishColorIDX + : iTrendState < 0 + ? bearishColorIDX + : neuturalColorIDX; + trendStateBuffer[barIndex] = iTrendState; + trendColorBuffer[barIndex] = showTrend + ? iTrendColor + : hideColorIDX; +} + +// +void CalculateVolume( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + double iClose = close[barIndex]; + double iOpen = open[barIndex]; + double iVolume = (double)iVolume(_Symbol, _Period, barIndex); + + // + bool isBullish = iClose > iOpen; + bool isBearish = iClose < iOpen; + + // + double iBullishVolume = emptyValue; + double iBearishVolume = emptyValue; + if (isBullish) + { + iBullishVolume = iVolume; + } + else if (isBearish) + { + iBearishVolume = iVolume; + } + else + { + // + double iHalfVolume = iVolume / 2; + + // + iBullishVolume = iHalfVolume; + iBearishVolume = iHalfVolume; + } + bullishVolumeBuffer[barIndex] = iBullishVolume; + bearishVolumeBuffer[barIndex] = iBearishVolume; + + // + // Calculate Volume Signals ... + + // + int bullishVolumeSignalsCount = iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + bullishVolumeBuffer, + bullishVolumeSignalBuffer, + volumeSignalMethod // + ); + + // + int bearishVolumeSignalsCount = iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + bearishVolumeBuffer, + bearishVolumeSignalBuffer, + volumeSignalMethod // + ); +} + +// +void CalculateATRBand( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + double iATR = atrBuffer[barIndex]; + double iAppliedATR = atrMultiplier * iATR; + double iATRUpperPrice = GetAppliedPrice( + atrUpperPriceType, + open, + high, + low, + close, + barIndex // + ); + double iATRLowerPrice = GetAppliedPrice( + atrLowerPriceType, + open, + high, + low, + close, + barIndex // + ); + double iATRUpper = iATRUpperPrice + iAppliedATR; + double iATRLower = iATRLowerPrice - iAppliedATR; + atrUpperRawBuffer[barIndex] = iATRUpper; + atrLowerRawBuffer[barIndex] = iATRLower; + + // + bool canSignalATR = IsValid(atrSignalMethod); + if (canSignalATR) + { + // + // Upper ... + iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + atrUpperRawBuffer, + atrUpperBuffer, + atrSignalMethod // + ); + + // + // Lower ... + iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + atrLowerRawBuffer, + atrLowerBuffer, + atrSignalMethod // + ); + } + else + { + // + atrUpperBuffer[barIndex] = iATRUpper; + atrLowerBuffer[barIndex] = iATRLower; + } +} + +/** + * Calculate Specified Market Cycle Info ... + * + * @param barIndex: Integer, Bar Index ... + * @param cycle: ENUM_X_MARKET_CYCLES member, Specified Cycle ... + * @param hhBuffer: Highest High Buffer Reference ... + * @param llBuffer: Lowest Low Buffer Reference ... + */ +void CalculateCycle( + int barIndex, + ENUM_X_MARKET_CYCLES cycle, + double &hhBuffer[], + double &llBuffer[] // +) +{ + // + XOHCL bar; + bool isBarInited = bar.Init( + _Symbol, + _Period, + barIndex + // + ); + if (!isBarInited) + { + return; + } + + // + int mLength = 0; + switch (cycle) + { + // + case X_MARKET_CYCLE_SHORT: + mLength = mSCLength; + break; + + // + case X_MARKET_CYCLE_MEDIUM: + mLength = mMCLength; + break; + + // + case X_MARKET_CYCLE_LONG: + mLength = mLCLength; + break; + + // + case X_MARKET_CYCLE_HIND: + mLength = mHCLength; + break; + } + + // + if (mLength == 0) + { + return; + } + + // + // Find Highest High ... + double hhValue = bar.FindHighest( + mLength, + upperMode // + ); + hhBuffer[barIndex] = hhValue; + + // + // Find Lowest Low ... + double llValue = bar.FindLowest( + mLength, + lowerMode // + ); + llBuffer[barIndex] = llValue; + + // + bar.Clean(); +} + +// +void DoProcess( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + // Check Some Requirements ... + int lastBarIndex = barIndex + 1; + int maxBarIndex = startCalculationForLastBars > 0 + ? startCalculationForLastBars + : ratesTotal; + bool isFirstBar = + startCalculationForLastBars > 0 + ? barIndex == startCalculationForLastBars + : barIndex == firstBarIndex; + + // + // Recieve Bar ... + XOHCL iBar; + XOHCL iPBar; + bool has = iBar.Init( + _Symbol, + _Period, + barIndex + // + ); + has = + has && + iBar.GetPreviousBar(iPBar); + if (!has) + { + return; + } + + // + // Do Process ... + + // + // Detecting POI(s) ... + DetectPOIs( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // Validating ... + ValidatePOIs( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // Drawing ... + DrawPOIs( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // Detecting Trigger Bar ... + + // + string namePrefix = NULL; + int triggerBarPushers = 0; + ENUM_X_DIRECTION triggerDir; + + // + // Detecting Trigger Bars ... + + // + bool isCond1Trigger = + mBarAnalyser + .IsValidForTrigger( + iBar, + triggerDir, + true, // Cond 1 ... + false, // Cond 2 ... + false, // Cond 3 ... + false, // Cond 4 ... + false, // Cond 5 ... + false, // Cond 6 ... + false // Cond 7 ... + ); + bool isCond1BullishTrigger = + isCond1Trigger && + IsBullish(triggerDir); + bool isCond1BearishTrigger = + isCond1Trigger && + IsBearish(triggerDir); + if (isCond1Trigger) + { + // + triggerBarPushers++; + namePrefix += "Cond1"; + } + + // + bool isCond2Trigger = + mBarAnalyser + .IsValidForTrigger( + iBar, + triggerDir, + false, // Cond 1 ... + true, // Cond 2 ... + false, // Cond 3 ... + false, // Cond 4 ... + false, // Cond 5 ... + false, // Cond 6 ... + false // Cond 7 ... + ); + bool isCond2BullishTrigger = + isCond2Trigger && + IsBullish(triggerDir); + bool isCond2BearishTrigger = + isCond2Trigger && + IsBearish(triggerDir); + if (isCond2Trigger) + { + // + triggerBarPushers++; + namePrefix += "Cond2"; + } + + // + bool isCond3Trigger = + mBarAnalyser + .IsValidForTrigger( + iBar, + triggerDir, + false, // Cond 1 ... + false, // Cond 2 ... + true, // Cond 3 ... + false, // Cond 4 ... + false, // Cond 5 ... + false, // Cond 6 ... + false // Cond 7 ... + ); + bool isCond3BullishTrigger = + isCond3Trigger && + IsBullish(triggerDir); + bool isCond3BearishTrigger = + isCond3Trigger && + IsBearish(triggerDir); + if (isCond3Trigger) + { + // + triggerBarPushers++; + namePrefix += "Cond3"; + } + + // + bool isCond4Trigger = + mBarAnalyser + .IsValidForTrigger( + iBar, + triggerDir, + false, // Cond 1 ... + false, // Cond 2 ... + false, // Cond 3 ... + true, // Cond 4 ... + false, // Cond 5 ... + false, // Cond 6 ... + false // Cond 7 ... + ); + bool isCond4BullishTrigger = + isCond4Trigger && + IsBullish(triggerDir); + bool isCond4BearishTrigger = + isCond4Trigger && + IsBearish(triggerDir); + if (isCond4Trigger) + { + // + triggerBarPushers++; + namePrefix += "Cond4"; + } + + // + bool isCond5Trigger = + mBarAnalyser + .IsValidForTrigger( + iBar, + triggerDir, + false, // Cond 1 ... + false, // Cond 2 ... + false, // Cond 3 ... + false, // Cond 4 ... + true, // Cond 5 ... + false, // Cond 6 ... + false // Cond 7 ... + ); + bool isCond5BullishTrigger = + isCond5Trigger && + IsBullish(triggerDir); + bool isCond5BearishTrigger = + isCond5Trigger && + IsBearish(triggerDir); + if (isCond5Trigger) + { + // + triggerBarPushers++; + namePrefix += "Cond5"; + } + + // + bool isCond6Trigger = + mBarAnalyser + .IsValidForTrigger( + iBar, + triggerDir, + false, // Cond 1 ... + false, // Cond 2 ... + false, // Cond 3 ... + false, // Cond 4 ... + false, // Cond 5 ... + true, // Cond 6 ... + false // Cond 7 ... + ); + bool isCond6BullishTrigger = + isCond6Trigger && + IsBullish(triggerDir); + bool isCond6BearishTrigger = + isCond6Trigger && + IsBearish(triggerDir); + if (isCond6Trigger) + { + // + triggerBarPushers++; + namePrefix += "Cond6"; + } + + // + bool isCond7Trigger = + mBarAnalyser + .IsValidForTrigger( + iBar, + triggerDir, + false, // Cond 1 ... + false, // Cond 2 ... + false, // Cond 3 ... + false, // Cond 4 ... + false, // Cond 5 ... + false, // Cond 6 ... + true // Cond 7 ... + ); + bool isCond7BullishTrigger = + isCond7Trigger && + IsBullish(triggerDir); + bool isCond7BearishTrigger = + isCond7Trigger && + IsBearish(triggerDir); + if (isCond7Trigger) + { + // + triggerBarPushers++; + namePrefix += "Cond7"; + } + + // + // Summarizing Trigger Bars ... + + // + bool isBullishTriggerBar = + // + isCond1BullishTrigger || + isCond2BullishTrigger || + isCond3BullishTrigger || + isCond4BullishTrigger || + isCond5BullishTrigger || + isCond6BullishTrigger || + isCond7BullishTrigger + // + ; + + // + bool isBearishTriggerBar = + // + isCond1BearishTrigger || + isCond2BearishTrigger || + isCond3BearishTrigger || + isCond4BearishTrigger || + isCond5BearishTrigger || + isCond6BearishTrigger || + isCond7BearishTrigger + // + ; + + // + bool isTriggerBar = + // + triggerBarPushers > 1 && + (isBullishTriggerBar || + isBearishTriggerBar) + // + ; + + // + // Validating Trigger Bar ... + if (isTriggerBar) + { + // + // Reading Required Info ... + + // + double iHKSOpen = hkSBarOpenBuffer[barIndex]; + double iHKSClose = hkSBarCloseBuffer[barIndex]; + + // + double iHKSMax = MathMax(iHKSOpen, iHKSClose); + double iHKSMin = MathMin(iHKSOpen, iHKSClose); + + // + bool isHKSBullish = hkSBarOpenBuffer[barIndex] < hkSBarCloseBuffer[barIndex]; + bool isHKSBearish = hkSBarOpenBuffer[barIndex] > hkSBarCloseBuffer[barIndex]; + bool isHKSSwitchedToBullish = + hkSBarOpenBuffer[barIndex] < hkSBarCloseBuffer[barIndex] && + hkSBarOpenBuffer[barIndex] >= hkSBarCloseBuffer[barIndex]; + bool isHKSSwitchedToBearish = + hkSBarOpenBuffer[barIndex] > hkSBarCloseBuffer[barIndex] && + hkSBarOpenBuffer[barIndex] <= hkSBarCloseBuffer[barIndex]; + + // + double iTrend = trendBuffer[barIndex]; + bool isTrendBullish = trendStateBuffer[barIndex] > 0; + bool isTrendBearish = trendStateBuffer[barIndex] < 0; + bool isTrendSwitchedToBullish = + trendStateBuffer[barIndex] > 0 && + trendStateBuffer[barIndex + 1] <= 0; + bool isTrendSwitchedToBearish = + trendStateBuffer[barIndex] < 0 && + trendStateBuffer[barIndex + 1] >= 0; + + // + bool isTriggerBarOverHKS = + iBar.low > iHKSMax; + bool isTriggerBarUnderHKS = + iBar.high < iHKSMin; + + // + // + // + + // + // Validate Bullish Trigger Bar ... + isBullishTriggerBar = + // + isBullishTriggerBar && + // + ( + // + isHKSBullish && + isTrendBullish + // + ) + // + ; + + // + // Validate Bearish Trigger Bar ... + isBearishTriggerBar = + // + isBearishTriggerBar && + // + ( + // + isHKSBearish && + isTrendBearish + // + ) + // + ; + + // + isTriggerBar = + // + isBullishTriggerBar || + isBearishTriggerBar + // + ; + } + + // + // Draw Trigger Bar ... + if (isTriggerBar) + { + // + int triggerBullishArrowCode = 225; + int triggerBearishArrowCode = 226; + + // + color triggerBarBullishColor = clrLime; + color triggerBarBearishColor = clrRed; + + // + ENUM_ARROW_ANCHOR triggerBullishAnchor = ANCHOR_TOP; + ENUM_ARROW_ANCHOR triggerBearishAnchor = ANCHOR_BOTTOM; + + // + int arrowWidth = 3; + int arrowCode = + isBullishTriggerBar + ? triggerBullishArrowCode + : triggerBearishArrowCode; + ENUM_X_PRICE arrowPriceType = + isBullishTriggerBar + ? X_PRICE_LOW + : X_PRICE_HIGH; + color arrowColor = + isBullishTriggerBar + ? triggerBarBullishColor + : triggerBarBearishColor; + ENUM_ARROW_ANCHOR arrowAnchor = + isBullishTriggerBar + ? triggerBullishAnchor + : triggerBearishAnchor; + + // + XCBarArrowObject *iObj; + has = mDrawer.CreateBarArrow( + iBar, + iObj, + arrowPriceType, + arrowCode, + arrowColor, + arrowWidth, + arrowAnchor, + namePrefix // + ); + if (has) + { + mObjects.Add(iObj); + } + + // + // Converts to Box ... + XBoxZone iBox; + iBox.type = "XTRB"; + iBox.to = iBar.time; + iBox.symbol = _Symbol; + iBox.period = _Period; + iBox.lower = iPBar.low; + iBox.from = iPBar.time; + iBox.upper = iPBar.high; + iBox.dir = + isBullishTriggerBar + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + if (iBox.IsValid()) + { + // + // XCBoxObject *iObj; + // has = mDrawer.DrawBox( + // iBox, + // iObj // + // ); + // if (has) + // { + // mObjects.Add(iObj); + // } + + // + XSignal iSignal; + double iRewardRatios[] = { + 1, + 1.5, + 2 // + }; + has = ToSignal( + iBox, + iSignal, + iRewardRatios, + 0 // Additional SL ... + ); + if (has) + { + // + XCSignalObject *iObj; + has = mDrawer.DrawSignal( + iSignal, + iObj, + 4 // + ); + if (has) + { + mObjects.Add(iObj); + } + } + } + + // + } + + // + // Cleanup Resources ... + + // + iBar.Clean(); + iPBar.Clean(); +} + +// +// +// + +// +void ReadBarStyle() +{ + // + long chartId = ChartID(); + + // + _upColor = GetChartUpColor(chartId); + _downColor = GetChartDownColor(chartId); + _lineColor = GetChartLineColor(chartId); + _bullishColor = GetChartBullishColor(chartId); + _bearishColor = GetChartBearishColor(chartId); +} + +// +void ShowBars() +{ + // + long chartId = ChartID(); + + // + SetChartUpColor(_upColor, chartId); + SetChartDownColor(_downColor, chartId); + SetChartLineColor(_lineColor, chartId); + SetChartBullishColor(_bullishColor, chartId); + SetChartBearishColor(_bearishColor, chartId); +} + +// +void HideBars() +{ + // + long chartId = ChartID(); + + // + SetChartUpColor(CLR_NONE, chartId); + SetChartDownColor(CLR_NONE, chartId); + SetChartLineColor(CLR_NONE, chartId); + SetChartBullishColor(CLR_NONE, chartId); + SetChartBearishColor(CLR_NONE, chartId); +} + +// +void DetectPOIs( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + // Check Some Requirements ... + int lastBarIndex = barIndex + 1; + int maxBarIndex = startCalculationForLastBars > 0 + ? startCalculationForLastBars + : ratesTotal; + bool isFirstBar = + startCalculationForLastBars > 0 + ? barIndex == startCalculationForLastBars + : barIndex == firstBarIndex; + + // + // Recieve Bar ... + XOHCL iBar; + XOHCL iPBar; + bool has = iBar.Init( + _Symbol, + _Period, + barIndex + // + ); + has = + has && + iBar.GetPreviousBar(iPBar); + if (!has) + { + return; + } + + // + int maxAllowedPOIs = 50; + + // + ENUM_X_DIRECTION iDir; + bool isLiquidity = + mBarAnalyser + .IsRejected( + iBar, + iDir, + true, + true // + ); + bool isBullishLiquiditySweeped = + isLiquidity && + IsBullish(iDir); + bool isBearishLiquiditySweeped = + isLiquidity && + IsBearish(iDir); + if (isLiquidity) + { + // + XBoxZone iLiq; + + // + iLiq.dir = iDir; + iLiq.type = "XLIQ"; + iLiq.upper = + isBullishLiquiditySweeped + ? iBar.GetDown() + : iBar.high; + iLiq.lower = + isBullishLiquiditySweeped + ? iBar.low + : iBar.GetUp(); + iLiq.from = iBar.time; + iLiq.symbol = _Symbol; + iLiq.period = _Period; + iLiq.to = ((datetime)((int)iBar.time + (PeriodSeconds(_Period)))); + + // + if (iLiq.IsValid()) + { + // + if (isBullishLiquiditySweeped) + { + // + has = AddBoxIfNotExists( + iLiq, + mBullishLiquidities // + ); + if (has) + { + // + SortBoxes( + mBullishLiquidities, + maxAllowedPOIs // + ); + } + } + else + { + // + has = AddBoxIfNotExists( + iLiq, + mBearishLiquidities // + ); + if (has) + { + // + SortBoxes( + mBearishLiquidities, + maxAllowedPOIs // + ); + } + } + } + + // + iLiq.Clean(); + } +} + +// +void ValidatePOIs( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + int count = 0; + XBoxZone tmp[]; + bool has = false; + datetime to = GetBarTime( + _Symbol, + _Period, + barIndex // + ); + + // + // Liquidities ... + + // + count = ArraySize(mBullishLiquidities); + has = IsValidSize(count); + if (has) + { + // + Clean(tmp); + for (int i = 0; i < count; i++) + { + // + has = IsBoxValid( + mBullishLiquidities[i], + barIndex // + ); + if (!has) + { + // + AddRef( + mBullishLiquidities[i], + tmp // + ); + } + } + + // + has = HasChild(tmp); + if (has) + { + // + RemoveBoxes( + tmp, + mBullishLiquidities // + ); + + // + SortBoxes(mBullishLiquidities); + } + + // + Clean(tmp); + } + + // + count = ArraySize(mBearishLiquidities); + has = IsValidSize(count); + if (has) + { + // + Clean(tmp); + for (int i = 0; i < count; i++) + { + // + mBearishLiquidities[i].to = to; + + // + has = IsBoxValid( + mBearishLiquidities[i], + barIndex // + ); + if (!has) + { + // + AddRef( + mBearishLiquidities[i], + tmp // + ); + } + } + + // + has = HasChild(tmp); + if (has) + { + // + RemoveBoxes( + tmp, + mBearishLiquidities // + ); + + // + SortBoxes(mBearishLiquidities); + } + + // + Clean(tmp); + } +} + +// +void DrawPOIs( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + int count = 0; + XBoxZone iBox; + bool has = false; + datetime to = GetBarTime( + _Symbol, + _Period, + barIndex // + ); + + // + // Liquidities ... + + // + count = ArraySize(mBullishLiquidities); + has = IsValidSize(count); + if (has) + { + // + for (int i = 0; i < count; i++) + { + // + iBox = mBullishLiquidities[i]; + iBox.to = to; + + // + XCBoxObject *iObj; + has = mDrawer.DrawBox( + iBox, + iObj // + ); + if (has) + { + mObjects.Add(iObj); + } + + // + iBox.Clean(); + } + } + + // + count = ArraySize(mBearishLiquidities); + has = IsValidSize(count); + if (has) + { + // + for (int i = 0; i < count; i++) + { + // + iBox = mBearishLiquidities[i]; + iBox.to = to; + + // + XCBoxObject *iObj; + has = mDrawer.DrawBox( + iBox, + iObj // + ); + if (has) + { + mObjects.Add(iObj); + } + + // + iBox.Clean(); + } + } +} + +// \ No newline at end of file diff --git a/Libraries/x-saherelm.common.lib.mq5 b/Libraries/x-saherelm.common.lib.mq5 index cad150f6..6b97b5d5 100644 --- a/Libraries/x-saherelm.common.lib.mq5 +++ b/Libraries/x-saherelm.common.lib.mq5 @@ -28,130 +28,4 @@ // // Models ... -// -// Consolidation Zone ... -struct XConsolidationZone -{ - // - // Props ... - - // - string symbol; // Symbol ... - ENUM_TIMEFRAMES period; // Period ... - - // - double upper; // Upper ... - double lower; // Lower ... - - // - datetime from; // Start Date - datetime to; // Breake Date - - // - ENUM_X_DIRECTION dir; // Break Direction ... - - // - // Constructor ... - XConsolidationZone() - { - Clean(); - } - - // - // Tools ... - - /** - * Cleanup ... - */ - void Clean() - { - // - upper = 0; - lower = 0; - - // - to = NULL; - from = NULL; - symbol = NULL; - period = NULL; - dir = X_DIRECTION_NONE; - - // - ZeroMemory(this); - } - - /** - * Validate ... - * - * @return ( bool ) - */ - bool IsValid() - { - // - bool result = false; - - // - result = - // - upper > 0 && - lower > 0 && - IsValid(to) && - IsValid(from) && - IsValid(symbol) && - IsValid(period) && - HasDirection(dir) - // - ; - - // - return result; - } - - bool IsSameAs( - XConsolidationZone &item // - ) - { - // - bool result = false; - - // - result = IsValid() && - item.IsValid() && - dir == item.dir && - from == item.from && - upper == item.upper && - lower == item.lower && - symbol == item.symbol && - period == item.period; - - // - return result; - } - - /** - * Retrieve Unique Identifier ... - * - * @return ( string ) - */ - string GetTag() - { - // - string result = - // - "XCZONE" + "_" + - ToString(dir) + "_" + - symbol + "_" + - ToString(period) + "_" + - ToString(upper) + "_" + - ToString(lower) - // - ; - - // - return result; - } - - // -}; - // \ No newline at end of file diff --git a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 index 6651461a..22dc931c 100644 --- a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 @@ -26,1427 +26,6 @@ // // Extensions ... -template -bool ToBox( - T *&source[], - XBoxZone &dest[] // -) -{ - // - bool result = false; - - // - Clean(dest); - - // - int count = ArraySize(source); - result = IsValidSize(count); - if (!result) - { - return result; - } - - // - for (int i = 0; i < count; i++) - { - // - T *item = source[i]; - - // - if (item != NULL) - { - // - XBoxZone iBox; - bool hasBox = ToBox( - iBox, - item // - ); - - // - if (hasBox) - { - // - AddRef( - iBox, - dest // - ); - } - } - } - - // - int destCount = ArraySize(dest); - result = IsValidSize(destCount); - - // - return result; -} - -template -int GetOldest( - T *&source[] // -) -{ - // - int result = -1; - - // - int count = ArraySize(source); - if (!IsValidSize(count)) - { - return result; - } - - // - XBoxZone boxes[]; - bool isConverted = ToBox( - source, - boxes // - ); - if (!isConverted) - { - return result; - } - - // - int boxesCount = ArraySize(boxes); - - // - if (count != boxesCount) - { - return result; - } - - // - result = GetOldest(boxes); - - // - Clean(boxes); - - // - return result; -} - -template -int GetYoungest( - T *&source[] // -) -{ - // - int result = -1; - - // - int count = ArraySize(source); - if (!IsValidSize(count)) - { - return result; - } - - // - XBoxZone boxes[]; - bool isConverted = ToBox( - source, - boxes // - ); - if (!isConverted) - { - return result; - } - - // - int boxesCount = ArraySize(boxes); - - // - if (count != boxesCount) - { - return result; - } - - // - result = GetYoungest(boxes); - - // - Clean(boxes); - - // - return result; -} - -template -int GetLowest( - T *&source[] // -) -{ - // - int result = -1; - - // - int count = ArraySize(source); - if (!IsValidSize(count)) - { - return result; - } - - // - XBoxZone boxes[]; - bool isConverted = ToBox( - source, - boxes // - ); - if (!isConverted) - { - return result; - } - - // - int boxesCount = ArraySize(boxes); - - // - if (count != boxesCount) - { - return result; - } - - // - result = GetLowest(boxes); - - // - Clean(boxes); - - // - return result; -} - -template -int GetHighest( - T *&source[] // -) -{ - // - int result = -1; - - // - int count = ArraySize(source); - if (!IsValidSize(count)) - { - return result; - } - - // - XBoxZone boxes[]; - bool isConverted = ToBox( - source, - boxes // - ); - if (!isConverted) - { - return result; - } - - // - int boxesCount = ArraySize(boxes); - - // - if (count != boxesCount) - { - return result; - } - - // - result = GetHighest(boxes); - - // - Clean(boxes); - - // - return result; -} - -template -bool IsSame( - T *source, - T *dest // -) -{ - // - bool result = false; - - // - XBoxZone sourceBox; - result = ToBox( - sourceBox, - source // - ); - if (!result) - { - return result; - } - - // - XBoxZone destBox; - result = ToBox( - destBox, - dest // - ); - if (!result) - { - return result; - } - - // - result = sourceBox.IsSameAs(destBox); - - // - return result; -} - -template -bool IsBelow( - T *source, - T *dest, - bool ignoreInside = false // -) -{ - // - bool result = false; - - // - XBoxZone sourceBox; - result = ToBox( - sourceBox, - source // - ); - if (!result) - { - return result; - } - - // - XBoxZone destBox; - result = ToBox( - destBox, - dest // - ); - if (!result) - { - return result; - } - - // - result = IsBoxBelow( - sourceBox, - destBox, - ignoreInside // - ); - - // - return result; -} - -template -bool IsAbove( - T *source, - T *dest, - bool ignoreInside = false // -) -{ - // - bool result = false; - - // - XBoxZone sourceBox; - result = ToBox( - sourceBox, - source // - ); - if (!result) - { - return result; - } - - // - XBoxZone destBox; - result = ToBox( - destBox, - dest // - ); - if (!result) - { - return result; - } - - // - result = IsBoxAbove( - sourceBox, - destBox, - ignoreInside // - ); - - // - return result; -} - -template -bool IsInside( - T *source, - T *dest // -) -{ - // - bool result = false; - - // - XBoxZone sourceBox; - result = ToBox( - sourceBox, - source // - ); - if (!result) - { - return result; - } - - // - XBoxZone destBox; - result = ToBox( - destBox, - dest // - ); - if (!result) - { - return result; - } - - // - result = IsBoxInside( - sourceBox, - destBox // - ); - - // - return result; -} - -template -bool IsInsideOr( - T *source, - T *dest // -) -{ - // - bool result = false; - - // - XBoxZone sourceBox; - result = ToBox( - sourceBox, - source // - ); - if (!result) - { - return result; - } - - // - XBoxZone destBox; - result = ToBox( - destBox, - dest // - ); - if (!result) - { - return result; - } - - // - result = IsBoxInsideOr( - sourceBox, - destBox // - ); - - // - return result; -} - -template -bool FindIndex( - int &index, - T *item, - T *&items[] // -) -{ - // - bool result = false; - - // - index = -1; - - // - XBoxZone itemBox; - result = ToBox( - itemBox, - item // - ); - if (!result) - { - return result; - } - - // - XBoxZone itemsBox[]; - result = ToBox( - items, - itemsBox // - ); - if (!result) - { - return result; - } - - // - result = FindBoxIndex( - index, - itemBox, - itemsBox // - ); - - // - return result; -} - -template -bool IsInside( - double value, - T *source // -) -{ - // - bool result = false; - - // - XBoxZone sourceBox; - result = ToBox( - sourceBox, - source // - ); - if (!result) - { - return result; - } - - // - result = IsInsideBox( - value, - sourceBox // - ); - - // - return result; -} - -template -bool IsAbove( - double value, - T *source // -) -{ - // - bool result = false; - - // - XBoxZone sourceBox; - result = ToBox( - sourceBox, - source // - ); - if (!result) - { - return result; - } - - // - result = IsAboveBox( - value, - sourceBox // - ); - - // - return result; -} - -template -bool IsBelow( - double value, - T *source // -) -{ - // - bool result = false; - - // - XBoxZone sourceBox; - result = ToBox( - sourceBox, - source // - ); - if (!result) - { - return result; - } - - // - result = IsBelowBox( - value, - sourceBox // - ); - - // - return result; -} - -/** - * Find Specified Box Index inside a Collection of Boxes ... - * - * @param box: XBoxZone instance Reference ... - * @param boxes: XBoxZone instance Reference Collection ... - * - * @return ( int ) - */ -bool FindBoxIndex( - int &index, - XBoxZone &box, - XBoxZone &boxes[] // -) -{ - // - bool result = false; - - // - index = -1; - - // - int count = ArraySize(boxes); - result = box.IsValid() && - IsValidSize(count); - if (!result) - { - return result; - } - - // - for (int i = 0; i < count; i++) - { - // - XBoxZone iBox = boxes[i]; - - // - bool isSame = box.IsSameAs(iBox); - if (isSame) - { - // - index = i; - break; - } - } - - // - result = IsValidIndex(index); - - // - return result; -} - -/** - * Check a BaxHas Valid Place for Specified Bar ... - * - * @param bar: XOHCL instance reference, Specified Bar ... - * #param box: XBoxZone instance reference, Specified Box ... - * - * @return ( bool ) - */ -bool IsBoxPlaceValidForBar( - XOHCL &bar, - XBoxZone &box // -) -{ - // - bool result = false; - - // - result = bar.IsValid() && - box.IsValid(); - if (!result) - { - return result; - } - - // - result = - box.IsBullish() - ? bar.low > box.upper - : bar.high < box.upper; - - // - return result; -} - -/** - * Check Source Box is Below Dest ... - * - * @param source: XBoxZone instance Reference ... - * @param dest: XBoxZone instance Reference ... - * @param ignoreInside: bool ... - * - * @return ( bool ) - */ -bool IsBoxBelow( - XBoxZone &source, - XBoxZone &dest, - bool ignoreInside = false // -) -{ - // - bool result = false; - - // - result = source.IsValid() && - dest.IsValid() && - !source.IsSameAs(dest); - if (!result) - { - return result; - } - - // - if (!ignoreInside) - { - result = source.upper < dest.lower; - } - else - { - result = (source.upper < dest.lower || - source.upper >= dest.upper) && - source.lower < dest.lower; - } - - // - return result; -} - -/** - * Check Source Box is Above Dest ... - * - * @param source: XBoxZone instance Reference ... - * @param dest: XBoxZone instance Reference ... - * @param ignoreInside: bool ... - * - * @return ( bool ) - */ -bool IsBoxAbove( - XBoxZone &source, - XBoxZone &dest, - bool ignoreInside = false // -) -{ - // - bool result = false; - - // - result = source.IsValid() && - dest.IsValid() && - !source.IsSameAs(dest); - if (!result) - { - return result; - } - - // - if (!ignoreInside) - { - result = source.lower > dest.upper; - } - else - { - result = (source.lower > dest.upper || - source.lower <= dest.upper) && - source.upper > dest.upper; - } - - // - return result; -} - -/** - * Check Source Box is Inside Dest ... - * - * @param source: XBoxZone instance Reference ... - * @param dest: XBoxZone instance Reference ... - * @param forceSideOut: bool, force check Box has One Side Out ... - * @param ignoreSideOut: bool, Accept if source Box one Side is out of Dest Box ... - * - * @return ( bool ) - */ -bool IsBoxInside( - XBoxZone &source, - XBoxZone &dest, - bool forceSideOut = false, // - bool ignoreSideOut = true // -) -{ - // - bool result = false; - - // - result = source.IsValid() && - dest.IsValid() && - !source.IsSameAs(dest); - if (!result) - { - return result; - } - - // - bool isBullish = IsBullish(dest.dir); - - // - if (!forceSideOut) - { - // - if (ignoreSideOut) - { - // - result = source.lower >= dest.lower && - source.upper <= dest.upper; - } - else - { - result = source.lower >= dest.lower || - source.upper <= dest.upper; - } - } - else - { - // - bool hasSideIn = - isBullish - ? source.lower >= dest.lower - : source.upper <= dest.upper; - bool hasSideOut = - isBullish - ? source.upper >= dest.upper - : source.lower <= dest.lower; - result = - hasSideIn && - hasSideOut; - } - - // - return result; -} - -/** - * Detect source BoX is Inside Dest Box or Have a Side Out on it ... - * - * @param source: XBoxZone instance, source box which checks by dest ... - * @param dest: XBoxZone instance, dest Box which compares source with it ... - * - * @return ( bool ) - */ -bool IsBoxInsideOr( - XBoxZone &source, - XBoxZone &dest, - bool forceInside = false // -) -{ - // - bool result = false; - - // - result = source.IsValid() && - dest.IsValid() && - !source.IsSameAs(dest); - if (!result) - { - return result; - } - - // - bool isInside = - source.upper <= dest.upper && - source.upper >= dest.lower && - source.lower >= dest.lower && - source.lower <= dest.upper; - bool isUpperInside = - source.upper <= dest.upper && - source.upper >= dest.lower; - bool isLowerInside = - source.lower >= dest.lower && - source.lower <= dest.upper; - - // - result = - forceInside - ? isInside - : (isInside || - isLowerInside || - isUpperInside); - - // - return result; -} - -/** - * Check Value is Inside Specified Box ... - * - * @param value: double ... - * @param box: XCBozZone instance Reference ... - * - * @return ( bool ) - */ -bool IsInsideBox( - double value, - XBoxZone &box // -) -{ - // - bool result = false; - - // - result = value > 0 && - box.IsValid() && - value <= box.upper && - value >= box.lower; - - // - return result; -} - -/** - * Check Bar is Inside Specified Box ... - * - * @param bar: XOHCL instance reference, Specified Bar ... - * @param box: XCBozZone instance Reference ... - * - * @return ( bool ) - */ -bool IsInsideBox( - XOHCL &bar, - XBoxZone &box // -) -{ - // - bool result = false; - - // - // Validate Args ... - result = bar.IsValid() && - box.IsValid(); - if (!result) - { - return result; - } - - // - result = - bar.close <= box.upper && - bar.close >= box.lower; - - // - return result; -} - -/** - * Check Value is Above Specified Box ... - * - * @param value: double ... - * @param box: XCBozZone instance Reference ... - * - * @return ( bool ) - */ -bool IsAboveBox( - double value, - XBoxZone &box // -) -{ - // - bool result = false; - - // - result = value > 0 && - box.IsValid() && - value > box.upper; - - // - return result; -} - -/** - * Check Value is Below Specified Box ... - * - * @param value: double ... - * @param box: XCBozZone instance Reference ... - * - * @return ( bool ) - */ -bool IsBelowBox( - double value, - XBoxZone &box // -) -{ - // - bool result = false; - - // - result = value > 0 && - box.IsValid() && - value < box.lower; - - // - return result; -} - -/** - * Check a Box is Used or not ... - * - * @param box: XBoxZone instance Reference ... - * @param fromIndex: int ... - * @param toIndex: int - * @param forPeriod: Specified Period ... - * - * @return ( bool ) - */ -bool IsBoxUsed( - XBoxZone &box, - int fromIndex, - int toIndex = 0, - ENUM_TIMEFRAMES forPeriod = NULL // -) -{ - // - bool result = false; - - // - if (toIndex < 0) - { - toIndex = 0; - } - - // - result = - // - box.IsValid() && - fromIndex > 0 && - fromIndex > toIndex - // - ; - if (!result) - { - return result; - } - - // - if (!IsValid(forPeriod)) - { - forPeriod = box.period; - } - - // - ENUM_X_DIRECTION forDir = box.dir; - bool isBullish = IsBullish(forDir); - - // - bool isTouched = false; - for (int i = fromIndex; i >= toIndex; i--) - { - // - XOHCL iBar; - bool isInited = iBar.Init( - box.symbol, - forPeriod, - i // - ); - - // - isTouched = - isInited && - (isBullish - ? iBar.low > box.upper - : iBar.high < box.lower); - if (!isTouched) - { - continue; - } - - // - iBar.Clean(); - break; - } - - // - result = isTouched; - - // - return result; -} - -/** - * Validate Box ... - * - * @param box: XBoxZone instance ... - * @param barIndex: int, Current Bar Index ... - * @param forPeriod: Testing Period ... - * - * @return ( bool ) - */ -bool IsBoxValid( - XBoxZone &box, - int barIndex = 0, - ENUM_TIMEFRAMES forPeriod = NULL // -) -{ - // - bool result = false; - - // - result = box.IsValid(); - if (!result) - { - return result; - } - - // - if (barIndex < 0) - { - barIndex = 0; - } - - // - if (!IsValid(forPeriod)) - { - forPeriod = box.period; - } - - // - int toIndex = iBarShift( - box.symbol, - forPeriod, - box.to // - ); - result = IsValidIndex(toIndex); - if (!result) - { - return result; - } - - // - XOHCL iBar; - bool isBullish = box.IsBullish(); - for (int i = barIndex; i < toIndex; i++) - { - // - result = iBar.Init( - box.symbol, - forPeriod, - i // - ); - if (!result) - { - break; - } - - // - result = - isBullish - ? iBar.low > box.upper - : iBar.high < box.lower; - if (!result) - { - break; - } - - // - iBar.Clean(); - } - - // - iBar.Clean(); - - // - return result; -} - -/** - * Check Box Breaked ... - * - * @param box: XBoxZone instance ... - * @param barIndex: int, Current Bar Index ... - * @param forPeriod: Testing Period ... - * - * @return ( bool ) - */ -bool IsBoxBreaked( - XBoxZone &box, - int barIndex = 0, - ENUM_TIMEFRAMES forPeriod = NULL // -) -{ - // - bool result = false; - - // - result = box.IsValid(); - if (!result) - { - return result; - } - - // - if (barIndex < 0) - { - barIndex = 0; - } - - // - if (!IsValid(forPeriod)) - { - forPeriod = box.period; - } - - // - int toIndex = iBarShift( - box.symbol, - forPeriod, - box.to // - ); - result = IsValidIndex(toIndex); - if (!result) - { - return result; - } - - // - XOHCL iBar; - bool isBullish = box.IsBullish(); - for (int i = barIndex; i < toIndex; i++) - { - // - result = iBar.Init( - box.symbol, - forPeriod, - i // - ); - if (!result) - { - break; - } - - // - result = - isBullish - ? iBar.high < box.lower - : iBar.low > box.upper; - if (!result) - { - break; - } - - // - iBar.Clean(); - } - - // - iBar.Clean(); - - // - return result; -} - -/** - * Check a Box is Breaked or not ... - * - * @param box: XBoxZone instance Reference ... - * @param fromIndex: int ... - * @param toIndex: int - * @param forPeriod: Specified Period ... - * - * @return ( bool ) - */ -bool IsBoxBreaked( - XBoxZone &box, - int fromIndex, - int toIndex = 0, - ENUM_TIMEFRAMES forPeriod = NULL // -) -{ - // - bool result = false; - - // - if (toIndex < 0) - { - toIndex = 0; - } - - // - result = - // - box.IsValid() && - fromIndex > 0 && - fromIndex > toIndex - // - ; - if (!result) - { - return result; - } - - // - if (!IsValid(forPeriod)) - { - forPeriod = box.period; - } - - // - ENUM_X_DIRECTION forDir = box.dir; - bool isBullish = IsBullish(forDir); - - // - bool isBreaked = false; - for (int i = fromIndex; i >= toIndex; i--) - { - // - XOHCL iBar; - bool isInited = iBar.Init( - box.symbol, - forPeriod, - i // - ); - - // - isBreaked = - isInited && - (isBullish - ? iBar.high <= box.lower - : iBar.low >= box.upper); - if (!isBreaked) - { - continue; - } - - // - iBar.Clean(); - break; - } - - // - result = isBreaked; - - // - return result; -} - -/** - * Find an Inside Box of source in a Collection ... - * - * @param index: int, Founded Index ... - * @param source: XBoxZone instance ... - * @param dest: XBoxZone instance Collection ... - * - * @return ( bool ) - */ -bool HasInsideBox( - int &index, - XBoxZone &source, - XBoxZone &dest[] // -) -{ - // - bool result = false; - - // - index = -1; - - // - result = source.IsValid() && - HasChild(dest); - - // - int count = ArraySize(dest); - for (int i = 0; i < count; i++) - { - // - XBoxZone iBox = dest[i]; - - // - bool isInside = !iBox.IsSameAs(source) && - IsBoxInsideOr( - iBox, - source // - ); - if (isInside) - { - // - index = i; - iBox.Clean(); - - // - break; - } - - // - iBox.Clean(); - } - - // - result = IsValidIndex(index); - - // - return result; -} - -/** - * Remove Specified Box from Collection ... - */ -bool RemoveBox( - XBoxZone &box, - XBoxZone &boxes[] // -) -{ - // - bool result = false; - - // - result = - box.IsValid() && - HasChild(boxes); - if (!result) - { - return result; - } - - // - int idx = -1; - result = FindBoxIndex( - idx, - box, - boxes // - ); - if (!result) - { - return result; - } - - // - result = ArrayRemove( - boxes, - idx, - 1 // - ); - - // - return result; -} - /** * Get Oldest Box Index ... * @@ -1486,7 +65,7 @@ int GetOldest( result = i; selected = iBox; } - + // iBox.Clean(); } @@ -1598,7 +177,7 @@ int GetYoungest( result = i; selected = iBox; } - + // iBox.Clean(); } @@ -1659,7 +238,7 @@ int GetYoungest( result = i; selected = iBox; } - + // iBox.Clean(); } @@ -1710,7 +289,7 @@ int GetHighest( result = i; selected = iBox; } - + // iBox.Clean(); } @@ -1771,7 +350,7 @@ int GetHighest( result = i; selected = iBox; } - + // iBox.Clean(); } @@ -1822,7 +401,7 @@ int GetLowest( result = i; selected = iBox; } - + // iBox.Clean(); } @@ -1883,7 +462,7 @@ int GetLowest( result = i; selected = iBox; } - + // iBox.Clean(); } @@ -1895,173 +474,124 @@ int GetLowest( return result; } - -// -// -// - -// -template -void SortZones( - T *&source[], - ENUM_X_DIRECTION forDir, - bool ignoreInside = true // +/** + * Validate Boxes ... + * @param box: XBoxZone instance reference for Validate ... + * @param barIndex: int, Bar Index ... + * @param barsLength: int, Bars Length for Validation ... + * + * @return ( bool ) + */ +bool IsBoxValid( + XBoxZone &box, + int barIndex = 0, + int barsLength = 3 // ) { // - int idx = -1; - int count = 0; - bool has = false; + bool result = false; // - has = HasDirection(forDir); - if (!has) + // Normalize Bar Index ... + barIndex = NormalizeInt(barIndex, 0); + barsLength = NormalizeInt(barsLength, 1); + + // + // Ceck Input Box is Valid ... + result = box.IsValid(); + if (!result) { - return; + return result; } // - bool isBullish = IsBullish(forDir); - - // - count = ArraySize(source); - has = IsValidSize(count); - if (!has) + // Check Input Box is Breaked or not ... + // Breaktion Found using Counting Over/Under Close Bars ... + bool isBullish = box.IsBullish(); + double appliedPrice = box.GetInDirectionalPrice(); + result = NotEmptyZero(appliedPrice); + if (!result) { - return; + return result; } // - T *tmpItems[]; - T *last = NULL; - bool hasLast = false; - while (HasChild(source)) + int toIDX = box.ToIndex(); + + // + XOHCL iBar; + int edgeBreakes = 0; + for (int i = barIndex; i <= toIDX; i++) { // - if (!hasLast) + result = iBar.Init( + box.symbol, + box.period, + i // + ); + + // + result = + result && + (isBullish + ? iBar.close < appliedPrice + : iBar.close > appliedPrice); + if (result) { - // - idx = GetOldest(source); - hasLast = IsValidIndex(idx); - if (hasLast) - { - // - last = source[idx]; - ArrayRemove( - source, - idx, - 1 // - ); - - // - Add( - last, - tmpItems // - ); - } - - // - count = ArraySize(source); - has = IsValidSize(count); - if (!has) - { - // - ZeroMemory(last); - break; - } + edgeBreakes++; } - if (!hasLast) + else + { + edgeBreakes = 0; + } + + // + result = edgeBreakes >= barsLength; + if (result) { - // - ZeroMemory(last); break; } // - T *item = NULL; - idx = GetOldest(source); - has = IsValidIndex(idx); - if (!has) - { - // - ZeroMemory(last); - ZeroMemory(item); - break; - } - item = source[idx]; - ArrayRemove( - source, - idx, - 1 // - ); - - // - bool isAbove = IsAbove( - item, - last, - ignoreInside // - ); - - // - bool isBelow = IsBelow( - item, - last, - ignoreInside // - ); - - // - has = - isBullish - ? isAbove - : isBelow; - if (has) - { - // - Add( - item, - tmpItems // - ); - - // - last = item; - hasLast = item != NULL; - } + iBar.Clean(); } // - Clean(source); - Copy( - tmpItems, - source // - ); + // return true; // - Clean(tmpItems); + result = + edgeBreakes >= barsLength; + + // + return result; } /** - * Extract all Zones Which provided bar is Inside it ... + * Find Specified Box Index inside a Collection of Boxes ... + * + * @param box: XBoxZone instance Reference ... + * @param boxes: XBoxZone instance Reference Collection ... * * @return ( int ) */ -template -int ExtractInsideZones( - XOHCL &bar, // Bar ... - T *&zones[], // Source of Zones ... - T *&dest[] // Dest (all inside Zones) ... +bool FindBoxIndex( + int &index, + XBoxZone &box, + XBoxZone &boxes[] // ) { // - int result = 0; + bool result = false; // - Clean(dest); + index = -1; // - int count = ArraySize(zones); - bool isValid = bar.IsValid() && - IsValidSize(count); - if (!isValid) + int count = ArraySize(boxes); + result = box.IsValid() && + IsValidSize(count); + if (!result) { return result; } @@ -2070,106 +600,137 @@ int ExtractInsideZones( for (int i = 0; i < count; i++) { // - T *iZone = zones[i]; + XBoxZone iBox = boxes[i]; // - bool isHighInside = IsInside( - bar.high, - iZone // - ); - - // - bool isLowInside = IsInside( - bar.low, - iZone // - ); - - // - bool isInside = - isLowInside && - isHighInside; - - // - if (isInside) + bool isSame = box.IsSameAs(iBox); + if (isSame) { // - Add( - iZone, - dest // - ); + index = i; + break; } - - // - ZeroMemory(iZone); } // - result = ArraySize(dest); + result = IsValidIndex(index); // return result; } /** - * Add Specific Item into a Collection Reference only if it's not Exists ... - * - * @return ( bool ) + * Remove Specified Box from Collection ... */ -template -bool AddIfNotExists( - T *item, - T *&items[] // +bool RemoveBox( + XBoxZone &box, + XBoxZone &boxes[] // ) { // bool result = false; // - result = item != NULL; + result = + box.IsValid() && + HasChild(boxes); if (!result) { return result; } // - int before = ArraySize(items); - - // - int idx = FindIndex( - item, - items // + int idx = -1; + result = FindBoxIndex( + idx, + box, + boxes // ); - bool has = IsValidIndex(idx); - result = !has; if (!result) { return result; } // - Add( - item, - items // + result = ArrayRemove( + boxes, + idx, + 1 // ); - // - int after = ArraySize(items); - - // - result = after > before; - // return result; } -bool AddIfNotExists( - XConsolidationZone &item, - XConsolidationZone &items[] // + +/** + * Remove Specified Box from Collection ... + */ +int RemoveBoxes( + XBoxZone &items[], + XBoxZone &sources[] // +) +{ + // + int result = 0; + + // + bool has = HasChild(items) && + HasChild(sources); + if (!has) + { + return result; + } + + // + int count = ArraySize(items); + for (int i = 0; i < count; i++) + { + // + int idx = -1; + has = FindBoxIndex( + idx, + items[i], + sources // + ); + if (has) + { + // + has = ArrayRemove( + sources, + idx, + 1 // + ); + + // + if (has) + { + result++; + } + } + } + + // + return result; +} + +/** + * Add items reference into source Collection only if it's not Exists ...alignas + * + * @param item: XBoxZone instance Reference, Specified Item to Add ... + * @param sources: XBoxZone instance Reference Collection, Source Items Collection ... + * + * @return ( bool ) + */ +bool AddBoxIfNotExists( + XBoxZone &item, + XBoxZone &sources[] // ) { // bool result = false; // + // Validate Args ... result = item.IsValid(); if (!result) { @@ -2177,15 +738,14 @@ bool AddIfNotExists( } // - int before = ArraySize(items); - - // - int idx = FindIndex( + // Check Item Exists or not ... + int idx = -1; + bool isExists = FindBoxIndex( + idx, item, - items // + sources // ); - bool has = IsValidIndex(idx); - result = !has; + result = !isExists; if (!result) { return result; @@ -2194,27 +754,24 @@ bool AddIfNotExists( // AddRef( item, - items // + sources //; ); - // - int after = ArraySize(items); - - // - result = after > before; - // return result; } /** * Add items Collection reference Members into source Collection only if it's not Exists ...alignas + * + * @param items: XBoxZone instance Reference Collection, Specified Items to Add ... + * @param sources: XBoxZone instance Reference Collection, Source Items Collection ... + * * @return ( int ) */ -template -int AddIfNotExists( - T *&items[], - T *&sources[] // +int AddBoxIfNotExists( + XBoxZone &items[], + XBoxZone &sources[] // ) { // @@ -2235,45 +792,7 @@ int AddIfNotExists( for (int i = 0; i < count; i++) { // - has = AddIfNotExists( - items[i], - sources // - ); - } - - // - int after = ArraySize(sources); - - // - result = after > before; - - // - return result; -} -int AddIfNotExists( - XConsolidationZone &items[], - XConsolidationZone &sources[] // -) -{ - // - int result = 0; - - // - bool has = HasChild(items); - if (!has) - { - return result; - } - - // - int before = ArraySize(sources); - - // - int count = ArraySize(items); - for (int i = 0; i < count; i++) - { - // - has = AddIfNotExists( + has = AddBoxIfNotExists( items[i], sources // ); @@ -2289,34 +808,103 @@ int AddIfNotExists( return result; } -/** - * Update to Time of Specifiex Collection ... - * - * @param items: XOBFVG instance Collection ... - * @param value: datetime ... - */ -template -void SpecifiedUpdateTo( - T *&items[], - datetime value = NULL // +// +void SortBoxes( + XBoxZone &items[], + int maxAllowed = 0 // ) { // - value = NormalizeTime(value); + int idx = -1; + bool has = false; // - int count = ArraySize(items); - bool has = HasChild(items); + has = HasChild(items); if (!has) { return; } // - for (int i = 0; i < count; i++) + XBoxZone tmp[]; + Copy( + items, + tmp // + ); + Clean(items); + + // + while (HasChild(tmp)) { - items[i].To(value); + // + idx = GetOldest(tmp); + has = IsValidIndex(idx); + if (!has) + { + break; + } + + // + XBoxZone iBox = tmp[idx]; + ArrayRemove( + tmp, + idx, + 1 // + ); + + // + AddRef( + iBox, + items // + ); } + + // + if (maxAllowed > 0) + { + // + CleanupArray( + items, + maxAllowed // + ); + } + + // + Clean(tmp); +} + +/** + * Check a BaxHas Valid Place for Specified Bar ... + * + * @param bar: XOHCL instance reference, Specified Bar ... + * #param box: XBoxZone instance reference, Specified Box ... + * + * @return ( bool ) + */ +bool IsBoxPlaceValidForBar( + XOHCL &bar, + XBoxZone &box // +) +{ + // + bool result = false; + + // + result = bar.IsValid() && + box.IsValid(); + if (!result) + { + return result; + } + + // + result = + box.IsBullish() + ? bar.low > box.upper + : bar.high < box.upper; + + // + return result; } // \ No newline at end of file diff --git a/Libraries/x-saherelm.x-poi.lib.mq5 b/Libraries/x-saherelm.x-poi.lib.mq5 index 35d90e79..c655d3ae 100644 --- a/Libraries/x-saherelm.x-poi.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.lib.mq5 @@ -309,11 +309,11 @@ struct XBoxZone } /** - * Extract Rejection Price based on Box Direction ... - * + * Retrieve Box Applied Price ... + * * @return ( double ) */ - double GetRejection() + double GetDirectionalPrice() { // double result = 0; @@ -334,6 +334,32 @@ struct XBoxZone return result; } + /** + * Retrieve Box Breaked Price ... + * + * @return ( double ) + */ + double GetInDirectionalPrice() + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = + IsBullish() + ? lower + : upper; + + // + return result; + } + /** * To Bar Index ... * diff --git a/XCATBEA/Classes/xcatbea.x-poi.detector.class.mq5 b/XCATBEA/Classes/xcatbea.x-poi.detector.class.mq5 index 7f9d7448..d789c4b2 100644 --- a/XCATBEA/Classes/xcatbea.x-poi.detector.class.mq5 +++ b/XCATBEA/Classes/xcatbea.x-poi.detector.class.mq5 @@ -2458,7 +2458,7 @@ class XCXCATBEAPOIDetector : public XCBase has = HasInvalidPivots(); if (has) { - ApplySortOnBoxes(invalidPivots); + SortBoxes(invalidPivots); } // @@ -2469,7 +2469,7 @@ class XCXCATBEAPOIDetector : public XCBase has = HasPeakPivots(); if (has) { - ApplySortOnBoxes(peakPivots); + SortBoxes(peakPivots); } // @@ -2477,7 +2477,7 @@ class XCXCATBEAPOIDetector : public XCBase has = HasValePivots(); if (has) { - ApplySortOnBoxes(valePivots); + SortBoxes(valePivots); } // @@ -2485,7 +2485,7 @@ class XCXCATBEAPOIDetector : public XCBase has = HasMTBullishPivots(); if (has) { - ApplySortOnBoxes(mtBullishPivots); + SortBoxes(mtBullishPivots); } // @@ -2493,7 +2493,7 @@ class XCXCATBEAPOIDetector : public XCBase has = HasMTBearishPivots(); if (has) { - ApplySortOnBoxes(mtBearishPivots); + SortBoxes(mtBearishPivots); } // @@ -2501,7 +2501,7 @@ class XCXCATBEAPOIDetector : public XCBase has = HasOBBullishPivots(); if (has) { - ApplySortOnBoxes(obBullishPivots); + SortBoxes(obBullishPivots); } // @@ -2509,70 +2509,10 @@ class XCXCATBEAPOIDetector : public XCBase has = HasOBBearishPivots(); if (has) { - ApplySortOnBoxes(obBearishPivots); + SortBoxes(obBearishPivots); } } - // - void ApplySortOnBoxes( - XBoxZone &items[] // - ) - { - // - int idx = -1; - bool has = false; - - // - has = HasChild(items); - if (!has) - { - return; - } - - // - XBoxZone tmp[]; - Copy( - items, - tmp // - ); - Clean(items); - - // - while (HasChild(tmp)) - { - // - idx = GetOldest(tmp); - has = IsValidIndex(idx); - if (!has) - { - break; - } - - // - XBoxZone iBox = tmp[idx]; - ArrayRemove( - tmp, - idx, - 1 // - ); - - // - AddRef( - iBox, - items // - ); - } - - // - CleanupArray( - items, - maxAllowedPivots // - ); - - // - Clean(tmp); - } - // void ApplyValidationOnBoxes( XBoxZone &items[],