diff --git a/MQLTestWorkspace/XBEEA/14030224/Experts/x-donchain.ea.mq5 b/MQLTestWorkspace/XBEEA/14030224/Experts/x-donchain.ea.mq5 new file mode 100644 index 0000000..a529c33 --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Experts/x-donchain.ea.mq5 @@ -0,0 +1,558 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center RSIMA MQL5 Expert Advisor +// ------------------------------------------------- +// Name: XDONCHAINEA +// Description: an Exper Advisor which used RSI and MA +// to Analyse Market ... +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +//////////////////////////////////////////////////////x +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XDONCHAINEA" +#property strict + +// +#include + +// +#define ShortName "XDONCHAINEA" + +// +// Inputs ... +long magicNumber = 78692110; +double lotSize = 0.01; + +// +double stopLoss = 200; +double takeProfit = 400; + +// +// +// + +// +int xdonHandler; +double xdonUpperBuffer[]; +double xdonLowerBuffer[]; + +// +int ma20Handler; +double ma20Buffer[]; + +// +int ma50Handler; +double ma50Buffer[]; + +// +int ma100Handler; +double ma100Buffer[]; + +// +CTrade trade; + +// +ENUM_TIMEFRAMES scPeriod = NULL; +ENUM_TIMEFRAMES mcPeriod = NULL; +ENUM_TIMEFRAMES lcPeriod = NULL; +ENUM_TIMEFRAMES hcPeriod = NULL; + +// +MqlTick currentTick; +MqlRates rates[]; +MqlRates scRates[]; +MqlRates mcRates[]; +MqlRates lcRates[]; +MqlRates hcRates[]; + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + trade.SetExpertMagicNumber(magicNumber); + + // + xdonHandler = iCustom( + // + _Symbol, + _Period, + "x-saherelm.xdon", + // + // Inputs ... + 52, + 0 + // + ); + + // + ma20Handler = iMA( + _Symbol, + _Period, + 20, + 0, + MODE_SMA, + PRICE_OPEN); + + // + ma50Handler = iMA( + _Symbol, + _Period, + 50, + 0, + MODE_SMA, + PRICE_OPEN); + + // + ma100Handler = iMA( + _Symbol, + _Period, + 100, + 0, + MODE_SMA, + PRICE_OPEN); + + // + if (xdonHandler == INVALID_HANDLE || + ma20Handler == INVALID_HANDLE || + ma50Handler == INVALID_HANDLE || + ma100Handler == INVALID_HANDLE) + { + return INIT_FAILED; + } + + // + ArraySetAsSeries(rates, true); + ArraySetAsSeries(ma20Buffer, true); + ArraySetAsSeries(ma50Buffer, true); + ArraySetAsSeries(ma100Buffer, true); + ArraySetAsSeries(xdonUpperBuffer, true); + ArraySetAsSeries(xdonLowerBuffer, true); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +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 + + // + // De Initialize XEA Providers ... + IndicatorRelease(ma20Handler); + IndicatorRelease(ma50Handler); + IndicatorRelease(ma100Handler); + IndicatorRelease(xdonHandler); +} + +// +// On Tick Handler ... +void OnTick() +{ + // + if (!IsNewBar()) + { + return; + } + + // + // Reading Tick ... + if (!SymbolInfoTick(_Symbol, currentTick)) + { + return; + } + + // + // if (scPeriod == NULL) { + // scPeriod = GetNearest + // } + + // + // Prepare Rates ... + int ratesCopied = CopyRates( + _Symbol, + _Period, + 0, + 15, + rates); + + // + int xdonUpperCopied = CopyBuffer( + xdonHandler, + 0, + 0, + 15, + xdonUpperBuffer); + int xdonLowerCopied = CopyBuffer( + xdonHandler, + 1, + 0, + 15, + xdonLowerBuffer); + if (xdonUpperCopied <= 0 || xdonLowerCopied <= 0) + { + return; + } + + // + int ma20Copied = CopyBuffer( + ma20Handler, + 0, + 0, + 15, + ma20Buffer); + int ma50Copied = CopyBuffer( + ma50Handler, + 0, + 0, + 15, + ma50Buffer); + int ma100Copied = CopyBuffer( + ma100Handler, + 0, + 0, + 15, + ma100Buffer); + if (ma20Copied <= 0 || ma50Copied <= 0 || ma100Copied <= 0) + { + return; + } + + // + // BUY ... + bool buyConditions = + // + // First Condition ... + // ma20Buffer[1] < MathMin(ma50Buffer[1], ma100Buffer[1]) + // // + // && + // + // Donchain Condition ... + // Candle Must Shadow Hunt ... + (rates[1].low < xdonLowerBuffer[1] && + MathMin(rates[1].open, rates[1].close) > xdonLowerBuffer[1]) + // + || + // + (rates[1].low < xdonLowerBuffer[1] && + rates[2].low < xdonLowerBuffer[2]) + // + ; + if (buyConditions) + { + // + + // + double sl = + stopLoss <= 0 + ? 0 + : currentTick.bid - (stopLoss * _Point); + if (!NormalizePrice(sl)) + { + return; + } + + // + double tp = + takeProfit <= 0 + ? 0 + : currentTick.bid + (takeProfit * _Point); + if (!NormalizePrice(tp)) + { + return; + } + + // + trade.PositionOpen( + _Symbol, + ORDER_TYPE_BUY, + lotSize, + currentTick.ask, + sl, + tp, + ShortName); + } + + // + // SELL ... + bool sellConditions = + // + // First Condition ... + // ma20Buffer[1] > MathMax(ma50Buffer[1], ma100Buffer[1]) + // // + // && + // + // Donchain Condition ... + // Candle Must Shadow Hunt ... + (rates[1].high > xdonUpperBuffer[1] && + MathMax(rates[1].open, rates[1].close) < xdonUpperBuffer[1]) + // + || + // + (rates[1].high > xdonUpperBuffer[1] && + rates[2].high > xdonUpperBuffer[2]) + // + ; + if (sellConditions) + { + // + double sl = + stopLoss <= 0 + ? 0 + : currentTick.ask - (stopLoss * _Point); + if (!NormalizePrice(sl)) + { + return; + } + + // + double tp = + takeProfit <= 0 + ? 0 + : currentTick.ask + (takeProfit * _Point); + if (!NormalizePrice(tp)) + { + return; + } + + // + trade.PositionOpen( + _Symbol, + ORDER_TYPE_SELL, + lotSize, + currentTick.bid, + sl, + tp, + ShortName); + } +} + +// +// TOOLS ... +bool IsNewBar() +{ + // + static datetime prevTime = 0; + datetime currentTime = iTime(_Symbol, _Period, 0); + + // + if (prevTime != currentTime) + { + // + prevTime = currentTime; + return true; + } + + // + return false; +} + +// +bool ValidateInputs() +{ + // + bool result = true; + + // + return result; +} + +// +bool NormalizePrice( + double &price // What to Normal +) +{ + // + bool result = false; + + // + double tickSize = 0; + result = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE, tickSize); + if (!result) + { + return result; + } + + // + price = NormalizeDouble(MathRound(price / tickSize) * tickSize, _Digits); + + // + return result; +} + +// +bool CountOpenPositions( + int &buyCount, // Buys + int &sellCount // Sells +) +{ + // + bool result = false; + + // + buyCount = 0; + sellCount = 0; + + // + int total = PositionsTotal(); + if (total <= 0) + { + return true; + } + + // + for (int i = total - 1; i >= 0; i--) + { + // + ulong ticket = PositionGetTicket(i); + if (ticket <= 0) + { + continue; + } + + // + bool isSelected = PositionSelectByTicket(ticket); + if (!isSelected) + { + continue; + } + + // + long magic; + bool isMagicSelected = PositionGetInteger(POSITION_MAGIC, magic); + if (!isMagicSelected || (isMagicSelected && magic != magicNumber)) + { + continue; + } + + // + long typeInt; + ENUM_POSITION_TYPE type; + bool isTypeSelected = PositionGetInteger(POSITION_TYPE, typeInt); + if (!isTypeSelected) + { + continue; + } + + // + type = (ENUM_POSITION_TYPE)typeInt; + + // + if (type == POSITION_TYPE_BUY) + { + buyCount++; + } + else if (type == POSITION_TYPE_SELL) + { + sellCount++; + } + } + + // + result = true; + + // + return result; +} + +// +bool ClosePositions(ENUM_POSITION_TYPE type) +{ + // + bool result = false; + + // + int total = PositionsTotal(); + if (total <= 0) + { + return true; + } + + // + for (int i = total - 1; i >= 0; i--) + { + // + ulong ticket = PositionGetTicket(i); + if (ticket <= 0) + { + continue; + } + + // + bool isSelected = PositionSelectByTicket(ticket); + if (!isSelected) + { + continue; + } + + // + long magic; + bool isMagicSelected = PositionGetInteger(POSITION_MAGIC, magic); + if (!isMagicSelected || (isMagicSelected && magic != magicNumber)) + { + continue; + } + + // + long typeInt; + ENUM_POSITION_TYPE pType; + bool isTypeSelected = PositionGetInteger(POSITION_TYPE, typeInt); + if (!isTypeSelected) + { + continue; + } + + // + pType = (ENUM_POSITION_TYPE)typeInt; + + // + if (type != pType) + { + continue; + } + + // + trade.PositionClose(ticket); + } + + // + result = true; + + // + return result; +} + +// +template +string ToString(const T value) +{ + // + return (string)value; +} \ No newline at end of file diff --git a/MQLTestWorkspace/XBEEA/14030224/Experts/x-rsima.ea.mq5 b/MQLTestWorkspace/XBEEA/14030224/Experts/x-rsima.ea.mq5 new file mode 100644 index 0000000..47292a0 --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Experts/x-rsima.ea.mq5 @@ -0,0 +1,494 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center RSIMA MQL5 Expert Advisor +// ------------------------------------------------- +// Name: XRSIMAEA +// Description: an Exper Advisor which used RSI and MA +// to Analyse Market ... +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +//////////////////////////////////////////////////////x +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XRSIMAEA" +#property strict + +// +#include + +// +#define ShortName "XRSIMAEA" + +// +// Inputs ... +long magicNumber = 78692110; +double lotSize = 0.01; + +// +int rsiLength = 25; +int rsiLevel = 70; + +// +int maLength = 25; + +// +double stopLoss = 200; +double takeProfit = 100; + +// +bool closeSignal = false; + +// +// +// + +// +int rsiHandler; +double rsiBuffer[]; + +// +int maHandler; +double maBuffer[]; + +// +CTrade trade; + +// +MqlTick currentTick; + +// +datetime openTimeBuy = 0; +datetime openTimeSell = 0; + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + trade.SetExpertMagicNumber(magicNumber); + + // + rsiHandler = iRSI( + _Symbol, + _Period, + rsiLength, + PRICE_OPEN); + + // + maHandler = iMA( + _Symbol, + PERIOD_H1, + maLength, + 0, + MODE_SMA, + PRICE_OPEN); + + // + if (rsiHandler == INVALID_HANDLE || maHandler == INVALID_HANDLE) + { + return INIT_FAILED; + } + + // + ArraySetAsSeries(rsiBuffer, true); + ArraySetAsSeries(maBuffer, true); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +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 + + // + // De Initialize XEA Providers ... + IndicatorRelease(rsiHandler); + IndicatorRelease(maHandler); +} + +// +// On Tick Handler ... +void OnTick() +{ + // + if (!IsNewBar()) + { + return; + } + + // + // Reading Tick ... + if (!SymbolInfoTick(_Symbol, currentTick)) + { + return; + } + + // + int rsiCopied = CopyBuffer( + rsiHandler, + 0, + 0, + 2, + rsiBuffer); + if (rsiCopied < 2) + { + return; + } + + // + int maCopied = CopyBuffer( + maHandler, + 0, + 0, + 1, + maBuffer); + if (maCopied < 1) + { + return; + } + + // + Comment( + "rsi[0]: " + ToString(rsiBuffer[0]) + "\n" + + "rsi[1]: " + ToString(rsiBuffer[1]) + "\n" + + "ma[0]: " + ToString(maBuffer[0])); + + // + int buyCount; + int sellCount; + // + if (!CountOpenPositions(buyCount, sellCount)) + { + return; + } + + // + // BUY ... + if ( + buyCount == 0 && + rsiBuffer[1] >= (100 - rsiLevel) && + rsiBuffer[0] < (100 - rsiLevel) && + currentTick.ask > maBuffer[0]) + { + // + if (closeSignal) + { + // + bool isClose = ClosePositions(POSITION_TYPE_SELL); + if (!isClose) + { + return; + } + } + + // + double sl = + stopLoss <= 0 + ? 0 + : currentTick.bid - (stopLoss * _Point); + if (!NormalizePrice(sl)) + { + return; + } + + // + double tp = + takeProfit <= 0 + ? 0 + : currentTick.bid + (takeProfit * _Point); + if (!NormalizePrice(tp)) + { + return; + } + + // + trade.PositionOpen( + _Symbol, + ORDER_TYPE_BUY, + lotSize, + currentTick.ask, + sl, + tp, + ShortName); + } + + // + // SELL ... + if ( + sellCount == 0 && + rsiBuffer[1] <= rsiLevel && + rsiBuffer[0] > rsiLevel && + currentTick.bid < maBuffer[0]) + { + // + if (closeSignal) + { + // + bool isClose = ClosePositions(POSITION_TYPE_BUY); + if (!isClose) + { + return; + } + } + + // + double sl = + stopLoss <= 0 + ? 0 + : currentTick.ask - (stopLoss * _Point); + if (!NormalizePrice(sl)) + { + return; + } + + // + double tp = + takeProfit <= 0 + ? 0 + : currentTick.ask + (takeProfit * _Point); + if (!NormalizePrice(tp)) + { + return; + } + + // + trade.PositionOpen( + _Symbol, + ORDER_TYPE_SELL, + lotSize, + currentTick.bid, + sl, + tp, + ShortName); + } +} + +// +// TOOLS ... +bool IsNewBar() +{ + // + static datetime prevTime = 0; + datetime currentTime = iTime(_Symbol, _Period, 0); + + // + if (prevTime != currentTime) + { + // + prevTime = currentTime; + return true; + } + + // + return false; +} + +// +bool ValidateInputs() +{ + // + bool result = true; + + // + return result; +} + +// +bool NormalizePrice( + double &price // What to Normal +) +{ + // + bool result = false; + + // + double tickSize = 0; + result = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE, tickSize); + if (!result) + { + return result; + } + + // + price = NormalizeDouble(MathRound(price / tickSize) * tickSize, _Digits); + + // + return result; +} + +// +bool CountOpenPositions( + int &buyCount, // Buys + int &sellCount // Sells +) +{ + // + bool result = false; + + // + buyCount = 0; + sellCount = 0; + + // + int total = PositionsTotal(); + if (total <= 0) + { + return true; + } + + // + for (int i = total - 1; i >= 0; i--) + { + // + ulong ticket = PositionGetTicket(i); + if (ticket <= 0) + { + continue; + } + + // + bool isSelected = PositionSelectByTicket(ticket); + if (!isSelected) + { + continue; + } + + // + long magic; + bool isMagicSelected = PositionGetInteger(POSITION_MAGIC, magic); + if (!isMagicSelected || (isMagicSelected && magic != magicNumber)) + { + continue; + } + + // + long typeInt; + ENUM_POSITION_TYPE type; + bool isTypeSelected = PositionGetInteger(POSITION_TYPE, typeInt); + if (!isTypeSelected) + { + continue; + } + + // + type = (ENUM_POSITION_TYPE)typeInt; + + // + if (type == POSITION_TYPE_BUY) + { + buyCount++; + } + else if (type == POSITION_TYPE_SELL) + { + sellCount++; + } + } + + // + result = true; + + // + return result; +} + +// +bool ClosePositions(ENUM_POSITION_TYPE type) +{ + // + bool result = false; + + // + int total = PositionsTotal(); + if (total <= 0) + { + return true; + } + + // + for (int i = total - 1; i >= 0; i--) + { + // + ulong ticket = PositionGetTicket(i); + if (ticket <= 0) + { + continue; + } + + // + bool isSelected = PositionSelectByTicket(ticket); + if (!isSelected) + { + continue; + } + + // + long magic; + bool isMagicSelected = PositionGetInteger(POSITION_MAGIC, magic); + if (!isMagicSelected || (isMagicSelected && magic != magicNumber)) + { + continue; + } + + // + long typeInt; + ENUM_POSITION_TYPE pType; + bool isTypeSelected = PositionGetInteger(POSITION_TYPE, typeInt); + if (!isTypeSelected) + { + continue; + } + + // + pType = (ENUM_POSITION_TYPE)typeInt; + + // + if (type != pType) + { + continue; + } + + // + trade.PositionClose(ticket); + } + + // + result = true; + + // + return result; +} + +// +template +string ToString(const T value) +{ + // + return (string)value; +} \ No newline at end of file diff --git a/MQLTestWorkspace/XBEEA/14030224/Experts/x-saherelm.xbe.ea.ex5 b/MQLTestWorkspace/XBEEA/14030224/Experts/x-saherelm.xbe.ea.ex5 new file mode 100644 index 0000000..c4dbbfa Binary files /dev/null and b/MQLTestWorkspace/XBEEA/14030224/Experts/x-saherelm.xbe.ea.ex5 differ diff --git a/MQLTestWorkspace/XBEEA/14030224/Experts/x-saherelm.xbe.ea.mq5 b/MQLTestWorkspace/XBEEA/14030224/Experts/x-saherelm.xbe.ea.mq5 new file mode 100644 index 0000000..b6034c8 --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Experts/x-saherelm.xbe.ea.mq5 @@ -0,0 +1,3319 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center XBEEA MQL5 Expert Advisor +// ------------------------------------------------- +// Name: XBEEA +// Description: an Exper Advisor which used RSI and MA +// to Analyse Market ... +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +//////////////////////////////////////////////////////x +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XBEEA" +#property strict + +// +#define ShortName "XBEEA" + +// +enum ENUM_X_ZIGZAG_BUFFERS +{ + X_ZIGZAG_MAIN_LINE = 0, + X_ZIGZAG_PIVOTS_LINE = 1, +}; + +// +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.draw.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xtrade.class.mq5" + +// +// Inputs ... + +// +long xBEEAMagicNumber = 78692110; // Magic Number +int xBEEASlippage = 10; // Slippgae + +// +input double xBEEAVolume = 0.01; + +// +// Indicator Inputs ... + +// +// Maarket ... +input group "Cycles"; + +// +// Short ... +input group "Short"; +input ENUM_X_PERIOD_METHOD scMode = X_PERIOD_MANUALLY; // Method +input ENUM_TIMEFRAMES scPeriod = PERIOD_H4; // Period + +// +// Presentation ... +input bool xBEEADrawSCLabel = true; +input bool xBEEADrawSCCBar = true; +input bool xBEEADrawSCPBar = false; +input bool xBEEADrawSCCMid = true; +input bool xBEEADrawSCPMid = true; + +// +// Medium ... +input group "Medium"; +input ENUM_X_PERIOD_METHOD mcMode = X_PERIOD_MANUALLY; // Method +input ENUM_TIMEFRAMES mcPeriod = PERIOD_H12; // Mid Period + +// +// Presentation ... +input bool xBEEADrawMCLabel = true; +input bool xBEEADrawMCCBar = true; +input bool xBEEADrawMCPBar = false; +input bool xBEEADrawMCCMid = true; +input bool xBEEADrawMCPMid = true; + +// +// Long ... +input group "Long"; +input ENUM_X_PERIOD_METHOD lcMode = X_PERIOD_MANUALLY; // Method +input ENUM_TIMEFRAMES lcPeriod = PERIOD_D1; // Long Period + +// +// Presentation ... +input bool xBEEADrawLCLabel = true; +input bool xBEEADrawLCCBar = true; +input bool xBEEADrawLCPBar = false; +input bool xBEEADrawLCCMid = true; +input bool xBEEADrawLCPMid = true; + +// +// Hind ... +input group "Hind"; +input ENUM_X_PERIOD_METHOD hcMode = X_PERIOD_MANUALLY; // Method +input ENUM_TIMEFRAMES hcPeriod = PERIOD_W1; // Hind Period + +// +// Moving Averages ... +input group "Moving Average"; +input int xBEEAMaFastLength = 9; // Fast Length +input int xBEEAMaSlowLength = 18; // Slow Length +input int xBEEAMaShift = 0; // Shift +input ENUM_MA_METHOD xBEEAMaMethod = MODE_EMA; // Method +input ENUM_APPLIED_PRICE xBEEAMaAppliedTo = PRICE_CLOSE; // AppliedTo + +// +// Presentation ... +input bool xBEEADrawHCLabel = true; +input bool xBEEADrawHCCBar = true; +input bool xBEEADrawHCPBar = true; +input bool xBEEADrawHCCMid = true; +input bool xBEEADrawHCPMid = true; + +// +// Vars ... + +// +string xBEEASymbol; +ENUM_TIMEFRAMES xBEEAPeriod; + +// +int maxBuys = 1; +int maxSells = 1; +int buyCount = 0; +int sellCount = 0; + +// +double _tp = 0; +double _sl = 0; +double _entry = 0; +ENUM_POSITION_TYPE _type = NULL; + +// +MqlTick xBEEATick; +XSCTrade *xBEEATrader; + +// +// ZigZag ... +int zigZagHandler = INVALID_HANDLE; +double zigZagBuffer[]; +bool isZigZagInPeak; + +// +// Cycles Definitions ... + +// +XMarketCycle sc; +XDrawSpecifications scCMidSpecs; +XDrawSpecifications scPMidSpecs; +XOHCLDrawSpecification scCBSpecs; +XOHCLDrawSpecification scPBSpecs; +// +XOHCL scCBar; +double scCMidLine; +XOHCL scPBar; +double scPMidLine; +// +double scTrndBuffer[]; +double scFastBuffer[]; +double scSlowBuffer[]; +double scLongExit1[]; +double scLongExit2[]; +double scShortExit1[]; +double scShortExit2[]; +int scCheHandler = INVALID_HANDLE; +int scFastHandler = INVALID_HANDLE; +int scSlowHandler = INVALID_HANDLE; +int scTrndHandler = INVALID_HANDLE; + +// +bool isSCCBullish; +bool isSCPBullish; +bool isSCFastOverSlow; +bool isSCFastUnderSlow; + +// +XMarketCycle mc; +XDrawSpecifications mcCMidSpecs; +XDrawSpecifications mcPMidSpecs; +XOHCLDrawSpecification mcCBSpecs; +XOHCLDrawSpecification mcPBSpecs; +// +XOHCL mcCBar; +double mcCMidLine; +XOHCL mcPBar; +double mcPMidLine; +// +double mcTrndBuffer[]; +double mcFastBuffer[]; +double mcSlowBuffer[]; +double mcLongExit1[]; +double mcLongExit2[]; +double mcShortExit1[]; +double mcShortExit2[]; +int mcFastHandler = INVALID_HANDLE; +int mcSlowHandler = INVALID_HANDLE; +int mcTrndHandler = INVALID_HANDLE; +int mcCheHandler = INVALID_HANDLE; +// +bool isMCCBullish; +bool isMCPBullish; +bool isMCFastOverSlow; +bool isMCFastUnderSlow; + +// +XMarketCycle lc; +XDrawSpecifications lcCMidSpecs; +XDrawSpecifications lcPMidSpecs; +XOHCLDrawSpecification lcCBSpecs; +XOHCLDrawSpecification lcPBSpecs; +// +XOHCL lcCBar; +double lcCMidLine; +XOHCL lcPBar; +double lcPMidLine; +// +double lcTrndBuffer[]; +double lcFastBuffer[]; +double lcSlowBuffer[]; +double lcLongExit1[]; +double lcLongExit2[]; +double lcShortExit1[]; +double lcShortExit2[]; +int lcFastHandler = INVALID_HANDLE; +int lcSlowHandler = INVALID_HANDLE; +int lcTrndHandler = INVALID_HANDLE; +int lcCheHandler = INVALID_HANDLE; +// +bool isLCCBullish; +bool isLCPBullish; +bool isLCFastOverSlow; +bool isLCFastUnderSlow; + +// +XMarketCycle hc; +XDrawSpecifications hcCMidSpecs; +XDrawSpecifications hcPMidSpecs; +XOHCLDrawSpecification hcCBSpecs; +XOHCLDrawSpecification hcPBSpecs; +// +XOHCL hcCBar; +double hcCMidLine; +XOHCL hcPBar; +double hcPMidLine; +// +double hcTrndBuffer[]; +double hcFastBuffer[]; +double hcSlowBuffer[]; +double hcLongExit1[]; +double hcLongExit2[]; +double hcShortExit1[]; +double hcShortExit2[]; +int hcFastHandler = INVALID_HANDLE; +int hcSlowHandler = INVALID_HANDLE; +int hcTrndHandler = INVALID_HANDLE; +int hcCheHandler = INVALID_HANDLE; +// +bool isHCCBullish; +bool isHCPBullish; +bool isHCFastOverSlow; +bool isHCFastUnderSlow; + +// +int mBullishScore; +int mBearishScore; +bool xBEEAIsSummaryTrendBullish; +bool xBEEALastIsSummaryTrendBullish; +string mLastCommentHash; + +// +int mMaxBullishScore = 0; +int mMinBullishScore = 0; +int mMaxBearishScore = 0; +int mMinBearishScore = 0; + +// +double mPivots[]; +bool mPivotsScanStart; +int mPivotsLoopback = 52; +int mMinRequiredPivots = 400; +int mNumberPivotsSequential = 10; + +// +// Event Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + if (xBEEASymbol == NULL || StringLen(xBEEASymbol) <= 0) + { + xBEEASymbol = _Symbol; + } + + // + if (xBEEAPeriod == NULL) + { + xBEEAPeriod = _Period; + } + + // + // Validate Inputs ... + if (!XBEEAValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + drawPrefix = ShortName; + + // + // Initialize XTrader ... + xBEEATrader = new XSCTrade( + xBEEASlippage, + xBEEAMagicNumber); + + // + // Init Indicators ... + if (!InitIndicators()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Prepare Style Specs ... + PrepareStyleSpecs(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +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 + + // + // De Initialize XBEEA Providers ... + delete xBEEATrader; + + // + // Short ... + IndicatorRelease(scCheHandler); + IndicatorRelease(scTrndHandler); + IndicatorRelease(scFastHandler); + IndicatorRelease(scSlowHandler); + + // + // Medium ... + IndicatorRelease(mcCheHandler); + IndicatorRelease(mcTrndHandler); + IndicatorRelease(mcFastHandler); + IndicatorRelease(mcSlowHandler); + + // + // Long ... + IndicatorRelease(lcCheHandler); + IndicatorRelease(lcTrndHandler); + IndicatorRelease(lcFastHandler); + IndicatorRelease(lcSlowHandler); + + // + // Hind ... + IndicatorRelease(hcCheHandler); + IndicatorRelease(hcTrndHandler); + IndicatorRelease(hcFastHandler); + IndicatorRelease(hcSlowHandler); + + // + IndicatorRelease(zigZagHandler); +} + +// +// On Tick Handler ... +void OnTick() +{ + // + if (!HasEnoughPivots()) + { + // + if (!mPivotsScanStart) + { + ProcessPivots(); + } + + // + return; + } + + // + if (!IsNewCandle( + xBEEASymbol, + xBEEAPeriod)) + { + return; + } + + // + // Reading Tick ... + if (!SymbolInfoTick(xBEEASymbol, xBEEATick)) + { + return; + } + + // + // Reading Data From XDSR Indicator ... + ReadData(); + + // + // Counting Currently Open Positions ... + buyCount = xBEEATrader.CountPositions(xBEEASymbol, POSITION_TYPE_BUY); + sellCount = xBEEATrader.CountPositions(xBEEASymbol, POSITION_TYPE_SELL); + + // + if (buyCount < maxBuys) + { + // + // Check For Buy Signals ... + } + + // + if (sellCount < maxSells) + { + // + // Check for Sell Signals ... + } + + // + UpdatePivots(); + + // + string comment = XBEEAGenerateState(); + Comment(comment); +} + +// +// Custom Functions ... + +// +// Validate Variables nd Inputs ... +bool XBEEAValidateInputs() +{ + // + bool result = false; + + // + result = + // + xBEEASlippage > 0 && + xBEEAMagicNumber > 0 + // + && + // + // Short ... + IsValidCycle( + scMode, + scPeriod) + // + && + // + // Medium ... + IsValidCycle( + mcMode, + mcPeriod) + // + && + // + // Long ... + IsValidCycle( + lcMode, + lcPeriod) + // + && + // + // Hind ... + IsValidCycle( + hcMode, + hcPeriod) + // + ; + + // + return result; +} + +// +// Initial Indicators ... +bool InitIndicators() +{ + // + bool result = false; + + // + // Init XZG Indicator ... + zigZagHandler = iCustom( + xBEEASymbol, + xBEEAPeriod, + "x-saherelm.x121.xzg", + // + // Inputs ... + // TODO: + // add these inputs to TODO ... + 12, // Depth ... + 5, // Deviation ... + 3, // Back Step ... + 1 // MODE ENUM_X_ZG_PRICE_MODE (X_ZG_PRICE_HIGH_LOW_MODE) ... + // + ); + result = zigZagHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // Here we have to Init XMarketCycles also ... + result = InitMarketCycles(); + + // + return result; +} + +// +// Initial Market Cycles ... +bool InitMarketCycles() +{ + // + bool result = false; + + // + // Short ... + sc.method = scMode; + sc.period = scPeriod; + result = sc.Init( + xBEEASymbol, + xBEEAPeriod, + X_MARKET_CYCLE_SHORT // + ); + if (!result) + { + return result; + } + + // + // Trend ... + ArraySetAsSeries(scTrndBuffer, true); + scTrndHandler = iCustom( + xBEEASymbol, + sc.period, + "x-saherelm.x121.xstr", + // + // Inputs ... + // + // ATR ... + "", + 14, // Length + 3.5, // Multiplier + PRICE_MEDIAN, // Applied To + // + // Presentation ... + "", + true, // Show Trends + false // Fill Trends + // + ); + + // + // Che ... + ArraySetAsSeries(scLongExit1, true); + ArraySetAsSeries(scLongExit2, true); + ArraySetAsSeries(scShortExit1, true); + ArraySetAsSeries(scShortExit2, true); + scCheHandler = iCustom( + xBEEASymbol, + sc.period, + "x-saherelm.x121.xche", + // + // Inputs ... + // + // Market ... + "", + 35, + 26, + 3.0, + 3.5, + // + // Calculations ... + "", + PRICE_HIGH, + PRICE_LOW, + // + // Presentation ... + "", + true, + true, + true, + true + // + ); + + // + // MA's ... + ArraySetAsSeries(scFastBuffer, true); + scFastHandler = iMA( + xBEEASymbol, + sc.period, + xBEEAMaFastLength, + xBEEAMaShift, + xBEEAMaMethod, + xBEEAMaAppliedTo // + ); + ArraySetAsSeries(scSlowBuffer, true); + scSlowHandler = iMA( + xBEEASymbol, + sc.period, + xBEEAMaSlowLength, + xBEEAMaShift, + xBEEAMaMethod, + xBEEAMaAppliedTo // + ); + + // + result = + // + scCheHandler != INVALID_HANDLE && + scTrndHandler != INVALID_HANDLE && + scFastHandler != INVALID_HANDLE && + scSlowHandler != INVALID_HANDLE + // + ; + if (!result) + { + return result; + } + + // + // Medium ... + mc.method = mcMode; + mc.period = mcPeriod; + result = mc.Init( + xBEEASymbol, + xBEEAPeriod, + X_MARKET_CYCLE_MEDIUM // + ); + if (!result) + { + return result; + } + + // + // Trend ... + ArraySetAsSeries(mcTrndBuffer, true); + mcTrndHandler = iCustom( + xBEEASymbol, + mc.period, + "x-saherelm.x121.xstr", + // + // Inputs ... + // + // ATR ... + "", + 14, // Length + 3.5, // Multiplier + PRICE_MEDIAN, // Applied To + // + // Presentation ... + "", + true, // Show Trends + false // Fill Trends + // + ); + + // + // Che ... + ArraySetAsSeries(mcLongExit1, true); + ArraySetAsSeries(mcLongExit2, true); + ArraySetAsSeries(mcShortExit1, true); + ArraySetAsSeries(mcShortExit2, true); + mcCheHandler = iCustom( + xBEEASymbol, + mc.period, + "x-saherelm.x121.xche", + // + // Inputs ... + // + // Market ... + "", + 35, + 26, + 3.0, + 3.5, + // + // Calculations ... + "", + PRICE_HIGH, + PRICE_LOW, + // + // Presentation ... + "", + true, + true, + true, + true + // + ); + + // + // MA's ... + ArraySetAsSeries(mcFastBuffer, true); + mcFastHandler = iMA( + xBEEASymbol, + mc.period, + xBEEAMaFastLength, + xBEEAMaShift, + xBEEAMaMethod, + xBEEAMaAppliedTo // + ); + ArraySetAsSeries(mcSlowBuffer, true); + mcSlowHandler = iMA( + xBEEASymbol, + mc.period, + xBEEAMaSlowLength, + xBEEAMaShift, + xBEEAMaMethod, + xBEEAMaAppliedTo // + ); + + // + result = + // + mcTrndHandler != INVALID_HANDLE && + mcFastHandler != INVALID_HANDLE && + mcSlowHandler != INVALID_HANDLE + // + ; + if (!result) + { + return result; + } + + // + // Long ... + lc.method = lcMode; + lc.period = lcPeriod; + result = lc.Init( + xBEEASymbol, + xBEEAPeriod, + X_MARKET_CYCLE_LONG // + ); + if (!result) + { + return result; + } + + // + // Trend ... + ArraySetAsSeries(lcTrndBuffer, true); + lcTrndHandler = iCustom( + xBEEASymbol, + lc.period, + "x-saherelm.x121.xstr", + // + // Inputs ... + // + // ATR ... + "", + 14, // Length + 3.5, // Multiplier + PRICE_MEDIAN, // Applied To + // + // Presentation ... + "", + true, // Show Trends + false // Fill Trends + // + ); + + // + // Che ... + ArraySetAsSeries(lcLongExit1, true); + ArraySetAsSeries(lcLongExit2, true); + ArraySetAsSeries(lcShortExit1, true); + ArraySetAsSeries(lcShortExit2, true); + lcCheHandler = iCustom( + xBEEASymbol, + lc.period, + "x-saherelm.x121.xche", + // + // Inputs ... + // + // Market ... + "", + 35, + 26, + 3.0, + 3.5, + // + // Calculations ... + "", + PRICE_HIGH, + PRICE_LOW, + // + // Presentation ... + "", + true, + true, + true, + true + // + ); + + // + // MA's ... + ArraySetAsSeries(lcFastBuffer, true); + lcFastHandler = iMA( + xBEEASymbol, + lc.period, + xBEEAMaFastLength, + xBEEAMaShift, + xBEEAMaMethod, + xBEEAMaAppliedTo // + ); + ArraySetAsSeries(lcSlowBuffer, true); + lcSlowHandler = iMA( + xBEEASymbol, + lc.period, + xBEEAMaSlowLength, + xBEEAMaShift, + xBEEAMaMethod, + xBEEAMaAppliedTo // + ); + + // + result = + // + lcTrndHandler != INVALID_HANDLE && + lcFastHandler != INVALID_HANDLE && + lcSlowHandler != INVALID_HANDLE + // + ; + if (!result) + { + return result; + } + + // + // Hind ... + hc.method = hcMode; + hc.period = hcPeriod; + result = hc.Init( + xBEEASymbol, + xBEEAPeriod, + X_MARKET_CYCLE_HIND // + ); + if (!result) + { + return result; + } + + // + // Trend ... + ArraySetAsSeries(hcTrndBuffer, true); + hcTrndHandler = iCustom( + xBEEASymbol, + hc.period, + "x-saherelm.x121.xstr", + // + // Inputs ... + // + // ATR ... + "", + 14, // Length + 3.5, // Multiplier + PRICE_MEDIAN, // Applied To + // + // Presentation ... + "", + true, // Show Trends + false // Fill Trends + // + ); + + // + // Che ... + ArraySetAsSeries(hcLongExit1, true); + ArraySetAsSeries(hcLongExit2, true); + ArraySetAsSeries(hcShortExit1, true); + ArraySetAsSeries(hcShortExit2, true); + hcCheHandler = iCustom( + xBEEASymbol, + hc.period, + "x-saherelm.x121.xche", + // + // Inputs ... + // + // Market ... + "", + 35, + 26, + 3.0, + 3.5, + // + // Calculations ... + "", + PRICE_HIGH, + PRICE_LOW, + // + // Presentation ... + "", + true, + true, + true, + true + // + ); + + // + // MA's ... + ArraySetAsSeries(hcFastBuffer, true); + hcFastHandler = iMA( + xBEEASymbol, + hc.period, + xBEEAMaFastLength, + xBEEAMaShift, + xBEEAMaMethod, + xBEEAMaAppliedTo // + ); + ArraySetAsSeries(hcSlowBuffer, true); + hcSlowHandler = iMA( + xBEEASymbol, + hc.period, + xBEEAMaSlowLength, + xBEEAMaShift, + xBEEAMaMethod, + xBEEAMaAppliedTo // + ); + + // + result = + // + hcTrndHandler != INVALID_HANDLE && + hcFastHandler != INVALID_HANDLE && + hcSlowHandler != INVALID_HANDLE + // + ; + if (!result) + { + return result; + } + + // + return result; +} + +// +// Prepare Style Specs for Drawings ... +void PrepareStyleSpecs() +{ + // + // Each Cycle has 2 Kind of Specs: + // 1- MidLines; + // 2- Candles; + // + // also for each Cycle we have 2 Series of Specs: + // 1- For Current Bar; + // 2- Prev Bar; + + // + // Short ... + + // + // Current ... + + // + // MidLine ... + scCMidSpecs.width = 1; + scCMidSpecs.style = STYLE_DOT; + scCMidSpecs.clr = clrSpringGreen; + scCMidSpecs.Label( + sc.prefix + "_C MID", + scCMidSpecs.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + + // + // XOHCL ... + scCBSpecs.Default(); + scCBSpecs.Width(1); + scCBSpecs.Style(STYLE_DOT); + // + // scCBSpecs.openStyle.clr = clrDarkOliveGreen; + // scCBSpecs.closeStyle.clr = clrDarkOrchid; + // scCBSpecs.highStyle.clr = clrDarkSeaGreen; + // scCBSpecs.lowStyle.clr = clrPink; + // + scCBSpecs.openStyle.Label( + sc.prefix + "_C O", + scCBSpecs.openStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + scCBSpecs.highStyle.Label( + sc.prefix + "_C H", + scCBSpecs.highStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + scCBSpecs.closeStyle.Label( + sc.prefix + "_C C", + scCBSpecs.closeStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + scCBSpecs.lowStyle.Label( + sc.prefix + "_C L", + scCBSpecs.lowStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + + // + // Prev ... + + // + // MidLine ... + scPMidSpecs.width = 2; + scPMidSpecs.style = STYLE_SOLID; + scPMidSpecs.clr = clrLimeGreen; + scPMidSpecs.Label( + sc.prefix + "_P MID", + scPMidSpecs.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + + // + // XOHCL ... + scPBSpecs.Default(); + scPBSpecs.Width(2); + // + // scPBSpecs.openStyle.clr = ; + // scPBSpecs.closeStyle.clr = ; + // scPBSpecs.highStyle.clr = ; + // scPBSpecs.lowStyle.clr = ; + // + scPBSpecs.openStyle.Label( + sc.prefix + "_P O", + scPBSpecs.openStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + scPBSpecs.highStyle.Label( + sc.prefix + "_P H", + scPBSpecs.highStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + scPBSpecs.closeStyle.Label( + sc.prefix + "_P C", + scPBSpecs.closeStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + scPBSpecs.lowStyle.Label( + sc.prefix + "_P L", + scPBSpecs.lowStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + + // + // Medium ... + + // + // Current ... + + // + // MidLine ... + mcCMidSpecs.width = 1; + mcCMidSpecs.style = STYLE_DOT; + mcCMidSpecs.clr = clrSteelBlue; + mcCMidSpecs.Label( + mc.prefix + "_C MID", + mcCMidSpecs.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + + // + // XOHCL ... + mcCBSpecs.Default(); + mcCBSpecs.Width(1); + mcCBSpecs.Style(STYLE_DOT); + // + // mcCBSpecs.openStyle.clr = clrDarkOliveGreen; + // mcCBSpecs.closeStyle.clr = clrDarkOrchid; + // mcCBSpecs.highStyle.clr = clrDarkSeaGreen; + // mcCBSpecs.lowStyle.clr = clrPink; + // + mcCBSpecs.openStyle.Label( + mc.prefix + "_C O", + mcCBSpecs.openStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + mcCBSpecs.highStyle.Label( + mc.prefix + "_C H", + mcCBSpecs.highStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + mcCBSpecs.closeStyle.Label( + mc.prefix + "_C C", + mcCBSpecs.closeStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + mcCBSpecs.lowStyle.Label( + mc.prefix + "_C L", + mcCBSpecs.lowStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + + // + // Prev ... + + // + // MidLine ... + mcPMidSpecs.width = 2; + mcPMidSpecs.style = STYLE_SOLID; + mcPMidSpecs.clr = clrRoyalBlue; + mcPMidSpecs.Label( + mc.prefix + "_P MID", + mcPMidSpecs.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + + // + // XOHCL ... + mcPBSpecs.Default(); + mcPBSpecs.Width(2); + // + // mcPBSpecs.openStyle.clr = ; + // mcPBSpecs.closeStyle.clr = ; + // mcPBSpecs.highStyle.clr = ; + // mcPBSpecs.lowStyle.clr = ; + // + mcPBSpecs.openStyle.Label( + mc.prefix + "_P O", + mcCBSpecs.openStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + mcPBSpecs.highStyle.Label( + mc.prefix + "_P H", + mcPBSpecs.highStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + mcPBSpecs.closeStyle.Label( + mc.prefix + "_P C", + mcPBSpecs.closeStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + mcPBSpecs.lowStyle.Label( + mc.prefix + "_P L", + mcPBSpecs.lowStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + + // + // Long ... + + // + // Current ... + + // + // MidLine ... + lcCMidSpecs.width = 1; + lcCMidSpecs.style = STYLE_DOT; + lcCMidSpecs.clr = clrYellow; + lcCMidSpecs.Label( + lc.prefix + "_C MID", + lcCMidSpecs.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + + // + // XOHCL ... + lcCBSpecs.Default(); + lcCBSpecs.Width(1); + lcCBSpecs.Style(STYLE_DOT); + // + // lcCBSpecs.openStyle.clr = clrDarkOliveGreen; + // lcCBSpecs.closeStyle.clr = clrDarkOrchid; + // lcCBSpecs.highStyle.clr = clrDarkSeaGreen; + // lcCBSpecs.lowStyle.clr = clrPink; + // + lcCBSpecs.openStyle.Label( + lc.prefix + "_C O", + lcCBSpecs.openStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + lcCBSpecs.highStyle.Label( + lc.prefix + "_C H", + lcCBSpecs.highStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + lcCBSpecs.closeStyle.Label( + lc.prefix + "_C C", + lcCBSpecs.closeStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + lcCBSpecs.lowStyle.Label( + lc.prefix + "_C L", + lcCBSpecs.lowStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + + // + // Prev ... + + // + // MidLine ... + lcPMidSpecs.width = 2; + lcPMidSpecs.style = STYLE_SOLID; + lcPMidSpecs.clr = clrOrange; + lcPMidSpecs.Label( + lc.prefix + "_P MID", + lcPMidSpecs.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + + // + // XOHCL ... + lcPBSpecs.Default(); + lcPBSpecs.Width(2); + // + // lcPBSpecs.openStyle.clr = ; + // lcPBSpecs.closeStyle.clr = ; + // lcPBSpecs.highStyle.clr = ; + // lcPBSpecs.lowStyle.clr = ; + // + lcPBSpecs.openStyle.Label( + lc.prefix + "_P O", + lcCBSpecs.openStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + lcPBSpecs.highStyle.Label( + lc.prefix + "_P H", + lcPBSpecs.highStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + lcPBSpecs.closeStyle.Label( + lc.prefix + "_P C", + lcPBSpecs.closeStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + lcPBSpecs.lowStyle.Label( + lc.prefix + "_P L", + lcPBSpecs.lowStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + + // + // Hind ... + + // + // Current ... + + // + // MidLine ... + hcCMidSpecs.width = 1; + hcCMidSpecs.style = STYLE_DOT; + hcCMidSpecs.clr = clrSandyBrown; + hcCMidSpecs.Label( + hc.prefix + "_C MID", + hcCMidSpecs.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + + // + // XOHCL ... + hcCBSpecs.Default(); + hcCBSpecs.Width(1); + hcCBSpecs.Style(STYLE_DOT); + // + // hcCBSpecs.openStyle.clr = clrDarkOliveGreen; + // hcCBSpecs.closeStyle.clr = clrDarkOrchid; + // hcCBSpecs.highStyle.clr = clrDarkSeaGreen; + // hcCBSpecs.lowStyle.clr = clrPink; + // + hcCBSpecs.openStyle.Label( + hc.prefix + "_C O", + hcCBSpecs.openStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + hcCBSpecs.highStyle.Label( + hc.prefix + "_C H", + hcCBSpecs.highStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + hcCBSpecs.closeStyle.Label( + hc.prefix + "_C C", + hcCBSpecs.closeStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + hcCBSpecs.lowStyle.Label( + hc.prefix + "_C L", + hcCBSpecs.lowStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + + // + // Prev ... + + // + // MidLine ... + hcPMidSpecs.width = 2; + hcPMidSpecs.style = STYLE_SOLID; + hcPMidSpecs.clr = clrSaddleBrown; + hcPMidSpecs.Label( + hc.prefix + "_P MID", + hcPMidSpecs.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + + // + // XOHCL ... + hcPBSpecs.Default(); + hcPBSpecs.Width(2); + // + // hcPBSpecs.openStyle.clr = clrDarkOliveGreen; + // hcPBSpecs.closeStyle.clr = clrDarkOrchid; + // hcPBSpecs.highStyle.clr = clrDarkSeaGreen; + // hcPBSpecs.lowStyle.clr = clrPink; + // + hcPBSpecs.openStyle.Label( + hc.prefix + "_P O", + hcPBSpecs.openStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + hcPBSpecs.highStyle.Label( + hc.prefix + "_P H", + hcPBSpecs.highStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + hcPBSpecs.closeStyle.Label( + hc.prefix + "_P C", + hcPBSpecs.closeStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); + hcPBSpecs.lowStyle.Label( + hc.prefix + "_P L", + hcPBSpecs.lowStyle.clr, + "Arial", + 8, + ANCHOR_LEFT_UPPER, + 90 + // + ); +} + +// +// Reading Data From Indicators ... +void ReadData() +{ + // + int mLoopBack = 15; + + // + // Update Market Cycles ... + UpdateMarketCycles(0); + + // + // Short ... + CopyBuffer( + scFastHandler, + 0, + 0, + mLoopBack, + scFastBuffer + // + ); + CopyBuffer( + scSlowHandler, + 0, + 0, + mLoopBack, + scSlowBuffer + // + ); + isSCFastOverSlow = scFastBuffer[1] > scSlowBuffer[1]; + isSCFastUnderSlow = scFastBuffer[1] > scSlowBuffer[1]; + + // + // Medium ... + CopyBuffer( + mcFastHandler, + 0, + 0, + mLoopBack, + mcFastBuffer + // + ); + CopyBuffer( + mcSlowHandler, + 0, + 0, + mLoopBack, + mcSlowBuffer + // + ); + isMCFastOverSlow = mcFastBuffer[1] > mcSlowBuffer[1]; + isMCFastUnderSlow = mcFastBuffer[1] > mcSlowBuffer[1]; + + // + // Long ... + CopyBuffer( + lcFastHandler, + 0, + 0, + mLoopBack, + lcFastBuffer + // + ); + CopyBuffer( + lcSlowHandler, + 0, + 0, + mLoopBack, + lcSlowBuffer + // + ); + isLCFastOverSlow = lcFastBuffer[1] > lcSlowBuffer[1]; + isLCFastUnderSlow = lcFastBuffer[1] > lcSlowBuffer[1]; + + // + // Hind ... + CopyBuffer( + hcFastHandler, + 0, + 0, + mLoopBack, + hcFastBuffer + // + ); + CopyBuffer( + hcSlowHandler, + 0, + 0, + mLoopBack, + hcSlowBuffer + // + ); + isHCFastOverSlow = hcFastBuffer[1] > hcSlowBuffer[1]; + isHCFastUnderSlow = hcFastBuffer[1] > hcSlowBuffer[1]; + + // + // XZigZag ... + CopyBuffer( + zigZagHandler, + X_ZIGZAG_PIVOTS_LINE, + 0, + mLoopBack, + zigZagBuffer + // + ); + + // + isZigZagInPeak = zigZagBuffer[0] < MathMax(xBEEATick.ask, xBEEATick.bid); + + // + // Summary ... + CalculateSummary(); + + // + // Provide all Draws ... + XBEEAHandleDraws( + // + // Short ... + xBEEADrawSCLabel, + xBEEADrawSCCBar, + xBEEADrawSCPBar, + xBEEADrawSCCMid, + xBEEADrawSCPMid, + // + // Medium ... + xBEEADrawMCLabel, + xBEEADrawMCCBar, + xBEEADrawMCPBar, + xBEEADrawMCCMid, + xBEEADrawMCPMid, + // + // Long ... + xBEEADrawLCLabel, + xBEEADrawLCCBar, + xBEEADrawLCPBar, + xBEEADrawLCCMid, + xBEEADrawLCPMid, + // + // Hind ... + xBEEADrawHCLabel, + xBEEADrawHCCBar, + xBEEADrawHCPBar, + xBEEADrawHCCMid, + xBEEADrawHCPMid + // + ); +} + +// +// Update Market Cycles ... +bool UpdateMarketCycles(int barIndex) +{ + // + bool result = false; + + // + XOHCL cBar; + XOHCL pBar; + + // + // Short ... + result = sc.Update(barIndex); + if (!result) + { + return result; + } + // + cBar = sc.GetBar(0); + pBar = sc.GetBar(1); + scCBar = cBar; + scPBar = pBar; + scCMidLine = (cBar.high - cBar.low) / 2; + scPMidLine = (pBar.high - pBar.low) / 2; + isSCCBullish = cBar.close > cBar.open; + isSCPBullish = pBar.close > pBar.open; + + // + // Medium ... + result = mc.Update(barIndex); + if (!result) + { + return result; + } + // + cBar = mc.GetBar(0); + pBar = mc.GetBar(1); + mcCBar = cBar; + mcPBar = pBar; + mcCMidLine = (cBar.high - cBar.low) / 2; + mcPMidLine = (pBar.high - pBar.low) / 2; + isMCCBullish = cBar.close > cBar.open; + isMCPBullish = pBar.close > pBar.open; + + // + // Long ... + result = lc.Update(barIndex); + if (!result) + { + return result; + } + // + cBar = lc.GetBar(0); + pBar = lc.GetBar(1); + lcCBar = cBar; + lcPBar = pBar; + lcCMidLine = (cBar.high - cBar.low) / 2; + lcPMidLine = (pBar.high - pBar.low) / 2; + isLCCBullish = cBar.close > cBar.open; + isLCPBullish = pBar.close > pBar.open; + + // + // Hind ... + result = hc.Update(barIndex); + if (!result) + { + return result; + } + // + cBar = hc.GetBar(0); + pBar = hc.GetBar(1); + hcCBar = cBar; + hcPBar = pBar; + hcCMidLine = (cBar.high - cBar.low) / 2; + hcPMidLine = (pBar.high - pBar.low) / 2; + isHCCBullish = cBar.close > cBar.open; + isHCPBullish = pBar.close > pBar.open; + + // + return result; +} + +// +// Pivots ... + +// +int CountPivots() +{ + return ArraySize(mPivots); +} + +// +bool HasEnoughPivots() +{ + return CountPivots() >= mMinRequiredPivots; +} + +// +// First time Scan for Previous Pivots ... +void ProcessPivots() +{ + // + if (mPivotsScanStart) + { + return; + } + + // + mPivotsScanStart = true; + + // + ArraySetAsSeries(mPivots, true); + + // + double tmpPivots[]; + + // + int count = iBars( + xBEEASymbol, + xBEEAPeriod) - + mPivotsLoopback * 2; + + // + // Reading Pivots based on ZigZag ... + int bIdx = 0; + while (!HasEnoughPivots() && bIdx < count) + { + // + UpdatePivots(bIdx); + + // + bIdx++; + } +} + +// +// Update Pivots on Running ... +void UpdatePivots(int barIndex = 0) +{ + // + double tmpPivots[]; + + // + CopyBuffer( + zigZagHandler, + X_ZIGZAG_PIVOTS_LINE, + barIndex, + mPivotsLoopback, + tmpPivots); + + // + int valueVerifications = 0; + double selectedValue = tmpPivots[0]; + + // + int start = 1; + int end = ArraySize(tmpPivots) - 1; + for (int i = start; i < end; i++) + { + // + double iValue = tmpPivots[i]; + + // + if (iValue == selectedValue) + { + valueVerifications++; + } + } + + // + if (valueVerifications >= mNumberPivotsSequential) + { + // + AddIfNotExists( + selectedValue, + mPivots + // + ); + } + + // + ArrayFree(tmpPivots); +} + +// +// Other ... + +// +// Calculated Suggested States ... +void CalculateSummary() +{ + // + // Summary ... + + // + int bullishSigns = 0; + int bearishSigns = 0; + + // + // Short ... + + // + if (isSCCBullish) + { + bullishSigns++; + } + else + { + bearishSigns++; + } + + // + if (isSCPBullish) + { + bullishSigns++; + } + else + { + bearishSigns++; + } + + // + if (isSCFastOverSlow) + { + bullishSigns++; + } + else if (isSCFastUnderSlow) + { + bearishSigns++; + } + + // + if (scCMidLine < MathMin(scCBar.open, scCBar.close)) + { + bearishSigns++; + } + + if (scCMidLine < scCBar.low) + { + bearishSigns++; + } + + if (scPMidLine < MathMin(scPBar.open, scPBar.close)) + { + bearishSigns++; + } + + if (scPMidLine < scPBar.low) + { + bearishSigns++; + } + + if (scCMidLine < MathMin(scPBar.open, scPBar.close)) + { + bearishSigns++; + } + + if (scCMidLine < scPBar.low) + { + bearishSigns++; + } + + // + if (scCMidLine > MathMax(scCBar.open, scCBar.close)) + { + bullishSigns++; + } + + if (scCMidLine > scCBar.high) + { + bullishSigns++; + } + + if (scPMidLine > MathMax(scPBar.open, scPBar.close)) + { + bullishSigns++; + } + + if (scPMidLine > scPBar.high) + { + bullishSigns++; + } + + if (scCMidLine > MathMax(scPBar.open, scPBar.close)) + { + bullishSigns++; + } + + if (scCMidLine > scPBar.high) + { + bullishSigns++; + } + + // + // Medium ... + + // + if (isMCCBullish) + { + bullishSigns++; + } + else + { + bearishSigns++; + } + + // + if (isMCPBullish) + { + bullishSigns++; + } + else + { + bearishSigns++; + } + + // + if (isMCFastOverSlow) + { + bullishSigns++; + } + else if (isMCFastUnderSlow) + { + bearishSigns++; + } + + // + if (mcCMidLine < MathMin(mcCBar.open, mcCBar.close)) + { + bearishSigns++; + } + + if (mcCMidLine < mcCBar.low) + { + bearishSigns++; + } + + if (mcPMidLine < MathMin(mcPBar.open, mcPBar.close)) + { + bearishSigns++; + } + + if (mcPMidLine < mcPBar.low) + { + bearishSigns++; + } + + if (mcCMidLine < MathMin(mcPBar.open, mcPBar.close)) + { + bearishSigns++; + } + + if (mcCMidLine < mcPBar.low) + { + bearishSigns++; + } + + // + if (mcCMidLine > MathMax(mcCBar.open, mcCBar.close)) + { + bullishSigns++; + } + + if (mcCMidLine > mcCBar.high) + { + bullishSigns++; + } + + if (mcPMidLine > MathMax(mcPBar.open, mcPBar.close)) + { + bullishSigns++; + } + + if (mcPMidLine > mcPBar.high) + { + bullishSigns++; + } + + if (mcCMidLine > MathMax(mcPBar.open, mcPBar.close)) + { + bullishSigns++; + } + + if (mcCMidLine > mcPBar.high) + { + bullishSigns++; + } + + // + // Long ... + + // + if (isLCCBullish) + { + bullishSigns++; + } + else + { + bearishSigns++; + } + + // + if (isLCPBullish) + { + bullishSigns++; + } + else + { + bearishSigns++; + } + + // + if (isLCFastOverSlow) + { + bullishSigns++; + } + else if (isLCFastUnderSlow) + { + bearishSigns++; + } + + // + if (lcCMidLine < MathMin(lcCBar.open, lcCBar.close)) + { + bearishSigns++; + } + + if (lcCMidLine < lcCBar.low) + { + bearishSigns++; + } + + if (lcPMidLine < MathMin(lcPBar.open, lcPBar.close)) + { + bearishSigns++; + } + + if (lcPMidLine < lcPBar.low) + { + bearishSigns++; + } + + if (lcCMidLine < MathMin(lcPBar.open, lcPBar.close)) + { + bearishSigns++; + } + + if (lcCMidLine < lcPBar.low) + { + bearishSigns++; + } + + // + if (lcCMidLine > MathMax(lcCBar.open, lcCBar.close)) + { + bullishSigns++; + } + + if (lcCMidLine > lcCBar.high) + { + bullishSigns++; + } + + if (lcPMidLine > MathMax(lcPBar.open, lcPBar.close)) + { + bullishSigns++; + } + + if (lcPMidLine > lcPBar.high) + { + bullishSigns++; + } + + if (lcCMidLine > MathMax(lcPBar.open, lcPBar.close)) + { + bullishSigns++; + } + + if (lcCMidLine > lcPBar.high) + { + bullishSigns++; + } + + // + // Hind ... + + // + if (isHCCBullish) + { + bullishSigns++; + } + else + { + bearishSigns++; + } + + // + if (isHCPBullish) + { + bullishSigns++; + } + else + { + bearishSigns++; + } + + // + if (isHCFastOverSlow) + { + bullishSigns++; + } + else if (isHCFastUnderSlow) + { + bearishSigns++; + } + + // + if (hcCMidLine < MathMin(hcCBar.open, hcCBar.close)) + { + bearishSigns++; + } + + if (hcCMidLine < hcCBar.low) + { + bearishSigns++; + } + + if (hcPMidLine < MathMin(hcPBar.open, hcPBar.close)) + { + bearishSigns++; + } + + if (hcPMidLine < hcPBar.low) + { + bearishSigns++; + } + + if (hcCMidLine < MathMin(hcPBar.open, hcPBar.close)) + { + bearishSigns++; + } + + if (hcCMidLine < hcPBar.low) + { + bearishSigns++; + } + + // + if (hcCMidLine > MathMax(hcCBar.open, hcCBar.close)) + { + bullishSigns++; + } + + if (hcCMidLine > hcCBar.high) + { + bullishSigns++; + } + + if (hcPMidLine > MathMax(hcPBar.open, hcPBar.close)) + { + bullishSigns++; + } + + if (hcPMidLine > hcPBar.high) + { + bullishSigns++; + } + + if (hcCMidLine > MathMax(hcPBar.open, hcPBar.close)) + { + bullishSigns++; + } + + if (hcCMidLine > hcPBar.high) + { + bullishSigns++; + } + + // + // ZigZag ... + if (isZigZagInPeak) + { + bearishSigns++; + } + else + { + bullishSigns++; + } + + // + mBullishScore = bullishSigns; + mBearishScore = bearishSigns; + xBEEAIsSummaryTrendBullish = bullishSigns > bearishSigns; + + // + // Calculate Max an Min Scores ... + + // + mMinBullishScore = + // + mMinBullishScore == 0 || mMinBullishScore > mBullishScore + ? mBullishScore + : mMinBullishScore + // + ; + + // + mMinBearishScore = + // + mMinBearishScore == 0 || mMinBearishScore > mBearishScore + ? mBearishScore + : mMinBearishScore + // + ; + + // + mMaxBullishScore = + // + mMaxBullishScore == 0 || mMaxBullishScore < mBullishScore + ? mBullishScore + : mMaxBullishScore + // + ; + + // + mMaxBearishScore = + // + mMaxBearishScore == 0 || mMaxBearishScore < mBearishScore + ? mBearishScore + : mMaxBearishScore + // + ; + + // + if (xBEEAIsSummaryTrendBullish != xBEEALastIsSummaryTrendBullish) + { + // + // TODO: Summary Trend Change Alert ... + LogMessage("Majour Trend Changed Happens: " + (xBEEAIsSummaryTrendBullish ? "Bullish" : "Bearish")); + } + + // + xBEEALastIsSummaryTrendBullish = xBEEAIsSummaryTrendBullish; +} + +// +// Handle All Draws of Experts ... +void XBEEAHandleDraws( + // + // Short ... + bool drawSCLabel = true, + bool drawSCCBar = true, + bool drawSCPBar = true, + bool drawSCCMid = true, + bool drawSCPMid = true, + // + // Medium ... + bool drawMCLabel = true, + bool drawMCCBar = true, + bool drawMCPBar = true, + bool drawMCCMid = true, + bool drawMCPMid = true, + // + // Long ... + bool drawLCLabel = true, + bool drawLCCBar = true, + bool drawLCPBar = true, + bool drawLCCMid = true, + bool drawLCPMid = true, + // + // Hind ... + bool drawHCLabel = true, + bool drawHCCBar = true, + bool drawHCPBar = true, + bool drawHCCMid = true, + bool drawHCPMid = true // +) +{ + // + int offset = 0; + + // + // Short ... + + // + // Cycle ... + if (drawSCCBar || drawSCPBar) + { + // + XBEEADrawCycle( + sc.cycle, + drawSCLabel, + !drawSCCBar && drawSCPBar, + !drawSCPBar && drawSCCBar, + offset + // + ); + + // + if (drawSCLabel) + { + // + if (drawSCCBar) + { + offset += 3; + } + + // + if (drawSCPBar) + { + offset += 3; + } + + // + if (drawSCCMid) + { + offset++; + } + + // + if (drawSCPMid) + { + offset++; + } + } + } + + // + // MidLine ... + if (drawSCCMid || drawSCPMid) + { + // + XBEEADrawMidLine( + sc.cycle, + drawSCLabel, + !drawSCCMid && drawSCPMid, + !drawSCPMid && drawSCCMid, + offset + // + ); + + // + if (drawSCLabel) + { + // + if (drawSCCMid) + { + offset++; + } + + // + if (drawSCPMid) + { + offset++; + } + } + } + + // + // Medium ... + + // + // Cycle ... + if (drawMCCBar || drawMCPBar) + { + // + XBEEADrawCycle( + mc.cycle, + drawMCLabel, + !drawMCCBar && drawMCPBar, + !drawMCPBar && drawMCCBar, + offset + // + ); + + // + if (drawMCLabel) + { + // + if (drawMCCBar) + { + offset += 3; + } + + // + if (drawMCPBar) + { + offset += 3; + } + + // + if (drawMCCMid) + { + offset++; + } + + // + if (drawMCPMid) + { + offset++; + } + } + } + + // + // Mid Line ... + if (drawMCCMid || drawMCPMid) + { + // + XBEEADrawMidLine( + mc.cycle, + drawMCLabel, + !drawMCCMid && drawMCPMid, + !drawMCPMid && drawMCCMid, + offset + // + ); + + // + if (drawMCLabel) + { + // + if (drawMCCMid) + { + offset++; + } + + // + if (drawMCPMid) + { + offset++; + } + } + } + + // + // Long ... + + // + // Cycle ... + if (drawLCCBar || drawLCPBar) + { + // + XBEEADrawCycle( + lc.cycle, + drawLCLabel, + !drawLCCBar && drawLCPBar, + !drawLCPBar && drawLCCBar, + offset + // + ); + + // + if (drawLCLabel) + { + // + if (drawLCCBar) + { + offset += 3; + } + + // + if (drawLCPBar) + { + offset += 3; + } + + // + if (drawLCCMid) + { + offset++; + } + + // + if (drawLCPMid) + { + offset++; + } + } + } + + // + // MidLine ... + if (drawLCCMid || drawLCPMid) + { + // + XBEEADrawMidLine( + lc.cycle, + drawLCLabel, + !drawLCCMid && drawLCPMid, + !drawLCPMid && drawLCCMid, + offset + // + ); + + // + if (drawLCLabel) + { + // + if (drawLCCMid) + { + offset++; + } + + // + if (drawLCPMid) + { + offset++; + } + } + } + + // + // Hind ... + + // + // Cycle ... + if (drawHCCBar || drawHCPBar) + { + // + XBEEADrawCycle( + hc.cycle, + drawHCLabel, + !drawHCCBar && drawHCPBar, + !drawHCPBar && drawHCCBar, + offset + // + ); + + // + if (drawHCLabel) + { + // + if (drawHCCBar) + { + offset += 3; + } + + // + if (drawHCPBar) + { + offset += 3; + } + + // + if (drawHCCMid) + { + offset++; + } + + // + if (drawHCPMid) + { + offset++; + } + } + } + + // + // MidLine ... + if (drawHCCMid || drawHCPMid) + { + // + XBEEADrawMidLine( + hc.cycle, + drawHCLabel, + !drawHCCMid && drawHCPMid, + !drawHCPMid && drawHCCMid, + offset + // + ); + } +} + +// +// Draw Middle Line of Cycle ... +void XBEEADrawCycle( + ENUM_X_MARKET_CYCLES cycle, // Specify Which Cycle to Draw ... + bool drawLabel = false, // Specify Draw Label of Mid Line or not ... + bool drawOnlyPrev = false, // Specify Draw Only Prev Bar of Cycle ... + bool drawOnlyCurrent = false, // Specify Draw Only Current Bar of Cycle ... + int offset = 0 // Distance used for Labels ... +) +{ + // + if (offset < 0) + { + offset = 0; + } + + // + XMarketCycle cycleModel; + XOHCLDrawSpecification cycleCBarSpecs; + XOHCLDrawSpecification cyclePBarSpecs; + + // + switch (cycle) + { + // + case X_MARKET_CYCLE_SHORT: + // + cycleModel = sc; + cycleCBarSpecs = scCBSpecs; + cyclePBarSpecs = scPBSpecs; + break; + + // + case X_MARKET_CYCLE_MEDIUM: + // + cycleModel = mc; + cycleCBarSpecs = mcCBSpecs; + cyclePBarSpecs = mcPBSpecs; + break; + + // + case X_MARKET_CYCLE_LONG: + // + cycleModel = lc; + cycleCBarSpecs = lcCBSpecs; + cyclePBarSpecs = lcPBSpecs; + break; + + // + case X_MARKET_CYCLE_HIND: + // + cycleModel = hc; + cycleCBarSpecs = hcCBSpecs; + cyclePBarSpecs = hcPBSpecs; + break; + } + + // + string baseTag = ToString(cycle); + + // + XOHCL cBar = cycleModel.GetBar(0); + XOHCL pBar = cycleModel.GetBar(1); + + // + datetime fromCDate = cycleModel.GetBarTime(0); + datetime fromPDate = cycleModel.GetBarTime(1); + + // + datetime cTime = TimeCurrent(); + + // + // Try to Draw ... + + // + bool canDrawPrev = !drawOnlyCurrent; + bool canDrawCurrent = !drawOnlyPrev; + + // + // Set Cycles Color based on Current Candle ... + + // + bool isCBarBullish = + cBar.open < cBar.close; + + // + bool isPBarBullish = + pBar.open < pBar.close; + + // + color clrTemoBullishColor = cycleCBarSpecs.openStyle.clr; + color clrTemoBearishColor = cycleCBarSpecs.closeStyle.clr; + + // + color cBarSelectedColor = isCBarBullish ? clrTemoBullishColor : clrTemoBearishColor; + color pBarSelectedColor = isPBarBullish ? clrTemoBullishColor : clrTemoBearishColor; + + // + cycleCBarSpecs.openStyle.clr = cBarSelectedColor; + cycleCBarSpecs.openStyle.labelColor = cBarSelectedColor; + + // + cycleCBarSpecs.closeStyle.clr = cBarSelectedColor; + cycleCBarSpecs.closeStyle.labelColor = cBarSelectedColor; + + // + cyclePBarSpecs.openStyle.clr = pBarSelectedColor; + cyclePBarSpecs.openStyle.labelColor = pBarSelectedColor; + + // + cyclePBarSpecs.closeStyle.clr = pBarSelectedColor; + cyclePBarSpecs.closeStyle.labelColor = pBarSelectedColor; + + // + if (canDrawPrev) + { + offset++; + } + + // + // Label ... + if (drawLabel) + { + // + if (canDrawPrev) + { + // + // Draw Prev Bar Lables ... + + // + XBEEADrawCycleXOHCLLabel( + cycleModel, + pBar, + cyclePBarSpecs, + "P", + cTime, + offset - 1 + // + ); + + // + offset += 3; + } + + // + if (canDrawCurrent) + { + // + // Draw Current Bar Lables ... + + // + XBEEADrawCycleXOHCLLabel( + cycleModel, + cBar, + cycleCBarSpecs, + "C", + cTime, + offset + // + ); + } + } + + // + // Line ... + + // + if (canDrawPrev) + { + // + // Draw Cycle Prev Bar ... + XBEEADrawCycleXOHCLContent( + cycleModel, + pBar, + cyclePBarSpecs, + "P", + fromPDate + // + ); + } + + // + if (canDrawCurrent) + { + // + // Draw Cycle Current Bar ... + XBEEADrawCycleXOHCLContent( + cycleModel, + cBar, + cycleCBarSpecs, + "C", + fromCDate + // + ); + } +} + +// +// Draw Middle Line of Cycle ... +void XBEEADrawMidLine( + ENUM_X_MARKET_CYCLES cycle, // Specify Which Cycle to Draw ... + bool drawLabel = false, // Specify Draw Label of Mid Line or not ... + bool drawOnlyPrev = false, // Specify Draw Only Prev Bar of Cycle ... + bool drawOnlyCurrent = false, // Specify Draw Only Current Bar of Cycle ... + int offset = 0 // Distance used for Labels ... +) +{ + // + if (offset < 0) + { + offset = 0; + } + + // + XMarketCycle cycleModel; + XDrawSpecifications cycleCMidSpecs; + XDrawSpecifications cyclePMidSpecs; + + // + switch (cycle) + { + // + case X_MARKET_CYCLE_SHORT: + // + cycleModel = sc; + cycleCMidSpecs = scCMidSpecs; + cyclePMidSpecs = scPMidSpecs; + break; + + // + case X_MARKET_CYCLE_MEDIUM: + // + cycleModel = mc; + cycleCMidSpecs = mcCMidSpecs; + cyclePMidSpecs = mcPMidSpecs; + break; + + // + case X_MARKET_CYCLE_LONG: + // + cycleModel = lc; + cycleCMidSpecs = lcCMidSpecs; + cyclePMidSpecs = lcPMidSpecs; + break; + + // + case X_MARKET_CYCLE_HIND: + // + cycleModel = hc; + cycleCMidSpecs = hcCMidSpecs; + cyclePMidSpecs = hcPMidSpecs; + break; + } + + // + // Calculate Mid Line ... + double midLine = (cycleModel.bar.high + cycleModel.bar.low) / 2; + + // + XOHCL cyclePrevBar = cycleModel.GetBar(1); + double midLinePrev = (cyclePrevBar.high + cyclePrevBar.low) / 2; + + // + string baseTag = ToString(cycle); + + // + string midCTag = baseTag + "|MID|C|"; + string midPTag = baseTag + "|MID|P|"; + + // + string midCLblTag = midCTag + "lbl"; + string midPLblTag = midPTag + "lbl"; + + // + datetime fromCDate = cycleModel.GetBarTime(0); + datetime fromPDate = cycleModel.GetBarTime(1); + + // + datetime cTime = TimeCurrent(); + + // + // Try to Draw ... + + // + bool canDrawPrev = !drawOnlyCurrent; + bool canDrawCurrent = !drawOnlyPrev; + + // + if (canDrawPrev) + { + offset++; + } + + // + // Label ... + if (drawLabel) + { + // + if (canDrawPrev) + { + // + // Draw Prev Candle MidLine Lable ... + XBEEADrawLabel( + cyclePMidSpecs, + midPLblTag, + cTime, + midLinePrev, + offset // + ); + } + + // + if (canDrawCurrent) + { + // + // Draw Current Candle MidLine Label ... + XBEEADrawLabel( + cycleCMidSpecs, + midCLblTag, + cTime, + midLine, + offset - 1 // + ); + } + } + + // + // Line ... + + // + if (canDrawPrev) + { + // + // Draw Prev Candle MidLine ... + XBEEADrawTrendLine( + cyclePMidSpecs, + midPTag, + fromPDate, + midLinePrev // + ); + } + + // + if (canDrawCurrent) + { + // + // Draw Current Candle MidLine ... + XBEEADrawTrendLine( + cycleCMidSpecs, + midCTag, + fromCDate, + midLine // + ); + } +} + +// +// Generate Expert State ... +string XBEEAGenerateState() +{ + // + string result = ""; + + // + // Summary ... + result += + // + "Summary: \n" + + "------------------\n" + + "Pivots: " + ToString(CountPivots()) + "\n" + + "BullishScore: " + ToString(mBullishScore) + ", min: " + ToString(mMinBullishScore) + ", max: " + ToString(mMaxBullishScore) + "\n" + + "BearishScore: " + ToString(mBearishScore) + ", min: " + ToString(mMinBearishScore) + ", max: " + ToString(mMaxBearishScore) + "\n" + + "isSUmmaryBullish: " + ToString(xBEEAIsSummaryTrendBullish) + "\n" + + "\n" + // + ; + + // + // ZigZag ... + result += + // + "Peaks and Vales: \n" + + "------------------\n" + + "Looking for New: " + (isZigZagInPeak ? "Vale" : "Peak") + "\n" + + "\n" + // + ; + + // + // Short ... + result += + // + "Short: \n" + + "------------------\n" + + "Period: " + ToString(sc.period) + "\n" + + "Bar 0: " + (isSCCBullish ? "Bullish" : "Bearish") + "\n" + + "Bar 1: " + (isSCPBullish ? "Bullish" : "Bearish") + "\n" + + "Trend MA: " + (isSCFastOverSlow ? "Bullish" : "Bearish") + "\n" + + "\n" + // + ; + + // + // Long ... + result += + // + "Medium: \n" + + "------------------\n" + + "Period: " + ToString(mc.period) + "\n" + + "Bar 0: " + (isMCCBullish ? "Bullish" : "Bearish") + "\n" + + "Bar 1: " + (isMCPBullish ? "Bullish" : "Bearish") + "\n" + + "Trend MA: " + (isMCFastOverSlow ? "Bullish" : "Bearish") + "\n" + + "\n" + // + ; + + // + // Medium ... + result += + // + "Long: \n" + + "------------------\n" + + "Period: " + ToString(lc.period) + "\n" + + "Bar 0: " + (isLCCBullish ? "Bullish" : "Bearish") + "\n" + + "Bar 1: " + (isLCPBullish ? "Bullish" : "Bearish") + "\n" + + "Trend MA: " + (isLCFastOverSlow ? "Bullish" : "Bearish") + "\n" + + "\n" + // + ; + + // + // Hind ... + result += + // + "Hind: \n" + + "------------------\n" + + "Period: " + ToString(hc.period) + "\n" + + "Bar 0: " + (isHCCBullish ? "Bullish" : "Bearish") + "\n" + + "Bar 1: " + (isHCPBullish ? "Bullish" : "Bearish") + "\n" + + "Trend MA: " + (isHCFastOverSlow ? "Bullish" : "Bearish") + "\n" + + "\n" + // + ; + + // + string hash = ToMD5(result); + if (hash != mLastCommentHash) + { + // + LogMessage(result); + + // + LogMessage(hash); + + // + mLastCommentHash = hash; + } + + // + return result; +} + +// +// Custom DRAW(s) ... + +// +// Draw OHCL Labels ... +void XBEEADrawCycleXOHCLLabel( + XMarketCycle &cycleModel, // Specify Which Cycle to Draw ... + XOHCL &bar, // Specify Cycle XOHCL Model to Draw ... + XOHCLDrawSpecification &specs, // Specify Cycle XOHCL Draw Specifications ... + string baseTag, // Specify a Unique Tag ... + datetime time, // Draw Time ... + int offset = 0 // +) +{ + // + // Open ... + string openTag = cycleModel.prefix + "_" + baseTag + "_O_lbl"; + XBEEADrawLabel( + specs.openStyle, + openTag, + time, + bar.open, + offset + // + ); + + // + // High ... + string highTag = cycleModel.prefix + "_" + baseTag + "_H_lbl"; + XBEEADrawLabel( + specs.highStyle, + highTag, + time, + bar.high, + offset + 1 + // + ); + + // + // Close ... + string closeTag = cycleModel.prefix + "_" + baseTag + "_C_lbl"; + XBEEADrawLabel( + specs.closeStyle, + closeTag, + time, + bar.close, + offset + 2 + // + ); + + // + // Low ... + string lowTag = cycleModel.prefix + "_" + baseTag + "_L_lbl"; + XBEEADrawLabel( + specs.lowStyle, + lowTag, + time, + bar.low, + offset + 3 + // + ); +} + +// +// Draw OHCL Content ... +void XBEEADrawCycleXOHCLContent( + XMarketCycle &cycleModel, // Specify Which Cycle to Draw ... + XOHCL &bar, // Specify Cycle XOHCL Model to Draw ... + XOHCLDrawSpecification &specs, // Specify Cycle XOHCL Draw Specifications ... + string baseTag, // Specify a Unique Tag ... + datetime time // Draw Time ... +) +{ + // + // Open ... + string openTag = cycleModel.prefix + "_" + baseTag + "_O"; + XBEEADrawTrendLine( + specs.openStyle, + openTag, + time, + bar.open + // + ); + + // + // High ... + string highTag = cycleModel.prefix + "_" + baseTag + "_H"; + XBEEADrawTrendLine( + specs.highStyle, + highTag, + time, + bar.high + // + ); + + // + // Close ... + string closeTag = cycleModel.prefix + "_" + baseTag + "_C"; + XBEEADrawTrendLine( + specs.closeStyle, + closeTag, + time, + bar.close + // + ); + + // + // Low ... + string lowTag = cycleModel.prefix + "_" + baseTag + "_L"; + XBEEADrawTrendLine( + specs.lowStyle, + lowTag, + time, + bar.low + // + ); +} + +// +// Draw Label Using Specifications ... +void XBEEADrawLabel( + XDrawSpecifications &specs, + string tag, + datetime time, + double price, + int offset = 0 // +) +{ + // + long chartId = ChartID(); + int subWindow = 0; + + // + if (offset < 0) + { + offset = 0; + } + + // + int offsetSeconds = PeriodSeconds(xBEEAPeriod) * offset; + + // + string value = specs.label; + + // + DrawText( + chartId, + tag, + subWindow, + time - offsetSeconds, + price, + specs.label, + specs.labelFont, + specs.labelFontSize, + specs.labelColor, + specs.labelAngel, + specs.labelAnchor, + specs.back, + specs.selection, + specs.hidden, + specs.zOrder // + ); +} + +// +// Draw TrendLine Using Specifications ... +void XBEEADrawTrendLine( + XDrawSpecifications &specs, + string tag, + datetime fromDate, + double fromPrice, + datetime toDate = NULL, + double toPrice = 0 // +) +{ + // + long chartId = ChartID(); + int subWindow = 0; + + // + if (toPrice <= 0) + { + toPrice = fromPrice; + } + + // + if (toDate == 0 || toDate == NULL) + { + toDate = TimeCurrent(); + } + + // + DrawTrendLine( + chartId, + tag, + subWindow, + fromDate, + fromPrice, + toDate, + toPrice, + specs.clr, + specs.style, + specs.width, + specs.back, + specs.selection, + specs.rayRight, + specs.hidden, + specs.zOrder // + ); +} diff --git a/MQLTestWorkspace/XBEEA/14030224/Experts/x-saherelm.xea.ex5 b/MQLTestWorkspace/XBEEA/14030224/Experts/x-saherelm.xea.ex5 new file mode 100644 index 0000000..eb80b89 Binary files /dev/null and b/MQLTestWorkspace/XBEEA/14030224/Experts/x-saherelm.xea.ex5 differ diff --git a/MQLTestWorkspace/XBEEA/14030224/Experts/x-saherelm.xea.mq5 b/MQLTestWorkspace/XBEEA/14030224/Experts/x-saherelm.xea.mq5 new file mode 100644 index 0000000..52210bb --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Experts/x-saherelm.xea.mq5 @@ -0,0 +1,377 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Expert Advisor +// ---------------------------------------- +// Name: X121EA +// Description: this is an expert controller +// advisors which provides a mechanism for use them ... +// +// NOTE: about provider instancing in multi asset state: +// you can provide configurations using this: +// +// EURUSDb,USDCHFb|M5|0.01|X786,X92|true +// EURUSDb,GBPUSDb,USDJPYb,USDCHFb,XAUUSDb|M5,M15|0.01|X786|true +// EURUSDb,GBPUSDb,USDJPYb,USDCHFb,XAUUSDb|M5,M15|0.01|X786|true +// +// or make the instance use this: +// +// XPV(EURUSDb|M15|0.01|X92|true)XPV(GBPUSDb|M5|0.02|X786|false) +// +// if leave Configuration string blank this will used default config +// and One asset mode enabled ... +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +//////////////////////////////////////////////////////x +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121EA" +#property strict + +// +// START Definitions ... +// + +// +#define ShortName "X121EA" + +// +// END Definitions ... +// + +// +// START Inputs ... +// + +// +// EA ... +input group "Common"; +input bool xEAEnable = true; // Enable EA +input int xEASlippage = 10; // Slippgae +input ulong xEAMagicNumber = 1604056; // Magic Number + +// +// Providers ... +input group "Providers"; +input string xEAProvidersConfiguration = "EURUSDb,GBPUSDb,USDJPYb,USDCHFb,XAUUSDb|M5,M15|0.01|X786|true"; // Providers Configuration +input string xEADefaultSignalProviders = "XTEST"; // Default Allowed Signal Providers + +// +// Signals ... +input group "Signals"; +input bool xEAEnableLongs = true; // Enable Long Trades +input bool xEAEnableShorts = true; // Enable Short Trades + +// +// Risk Management ... +input group "Risk Management"; +input double xEAMaxAllowedSpread = 10; // Max Allowed Spread to Execute Signal +input int xEAMaxOpenPositions = 15; // Max Allowed Open Trades +input double xEAMinRiskAmountPerTrade = 0.001; // Min Risk Amount Per Trade +input double xEAMaxAllowedDrawDownFactor = 0.01; // Max Allowed Drawdown Factor +input double xEAMinProfitPerTrade = 0.5; // Min Acceptable Profit Per Trade +input double xEAMinProfitPerVolumeFactor = 0.01; // Min Acceptable Profit Volume Factor Per Trade +input bool xEAUseRiskAmountAsStaticVolume = true; // Use Provided Risk Amount as Static Volume + +// +input group "EQM"; +input int xEAMinAgeForDoSupport = 35; // Minimum Age For Supporting In Drawdown Positions when there isn't Equity +input int xEAMinAgeForUpdateSupports = 35; // Minimum Age For Update Untriggered Support Orders + +// +// Alerts ... +input group "Alerts"; +input bool xEAEnableAlerts = true; // Enable Events Alert +input bool xEAEnableHourlyAlerts = false; // Send Alert on each new Hour +input bool xEAEnableDailyAlerts = false; // Send Alert on each new Day +input bool xEAEnableWeeklyAlerts = false; // Send Alert on each new Week +input bool xEAEnableMonthlyAlerts = false; // Send Alert on each new Month + +// +// END Inputs ... +// + +// +// START Including Providers ... +// + +// +// Logger Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Classes/x-saherelm.x121.xea.class.mq5" +#include "../Libraries/x-saherelm.seriallizer.lib.mq5" + +// +// END Including Providers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +XSCX121EA *mX121EA; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + logTag = ShortName; + drawPrefix = logTag; + alertPrefix = logTag; + + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + bool isInit = InitEAInstance(); + if (!isInit) + { + return INIT_FAILED; + } + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +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 + + // + // De Initialize XEA Providers ... + delete mX121EA; +} + +// +// On Tick Handler ... +void OnTick() +{ + // + // Prevent Going Forward if user Disable it ... + if (xEAEnable) + { + mX121EA.OnTick(); + } +} + +// +// Handle Trade Events ... +void OnTrade() +{ + mX121EA.OnTrade(); +} + +// +// Handle Signal Event ... +void OnSignalConditionsRecieved(X121MarketConditions &info) +{ +} + +// +// Handle StopLoss Event ... +void OnStopLossTriggered(const XDeal &deal) +{ +} + +// +// Handle TakeProfit Event ... +void OnTakeProfitTriggered(const XDeal &deal) +{ +} + +// +// Handle Deals Changed Event ... +void OnDealsChangedHandler(int count) +{ +} + +// +// Handle Order Changed Event ... +void OnOrdersChangedHandler(int count) +{ +} + +// +// Handle Position Changed Event ... +void OnPositionsChangedHandler(int count) +{ +} + +// +// Handle Trade State Changed ... +void OnTradeStateChangedHandler(const XOnTradeHandlerState &state) +{ +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + // Validate Args ... + result = + // + xEASlippage > 0 && + xEAMagicNumber > 0 && + xEAMinRiskAmountPerTrade > 0 && + StringLen(xEADefaultSignalProviders) > 0 + // + // TODO: add new validations here ... + // + ; + + // + // Validate Providers ... + if (result) + { + // + string providers[]; + SplitContent( + providers, + xEADefaultSignalProviders); + + // + int providersCount = ArraySize(providers); + if (providersCount <= 0) + { + // + result = false; + return result; + } + + // + string allProviders[]; + GetAllProviders(allProviders); + + // + bool hasError = false; + for (int i = 0; i < providersCount; i++) + { + // + string iProvider = providers[i]; + if (!Contains(iProvider, allProviders)) + { + // + hasError = true; + break; + } + } + + // + if (hasError) + { + // + result = false; + return result; + } + } + + // + // Logging State ... + string message = "Validation of (" + logTag + ") Inputs " + (result ? "Succeeded" : "Failed") + " ..."; + LogMessage(message); + + // + return result; +} + +// +// Initialize X121EA Class Instances ... +bool InitEAInstance() +{ + // + bool result = false; + + // + X121SignalProvider providers[]; + + // + // Try to Extract Configs ... + int configsCount = ExtractProviderConfigurations( + providers, + xEAProvidersConfiguration, + xEADefaultSignalProviders, + xEAMinRiskAmountPerTrade, + xEAUseRiskAmountAsStaticVolume); + + // + mX121EA = new XSCX121EA( + _Symbol, + _Period, + xEAMagicNumber, + xEASlippage, + xEAMaxAllowedSpread, + xEAMaxOpenPositions, + xEAMinProfitPerTrade, + xEAMinProfitPerVolumeFactor, + xEAMaxAllowedDrawDownFactor, + OnStopLossTriggered, + OnTakeProfitTriggered, + OnDealsChangedHandler, + OnOrdersChangedHandler, + OnPositionsChangedHandler, + OnTradeStateChangedHandler, + // + xEAMinAgeForDoSupport, + xEAMinAgeForUpdateSupports, + OnSignalConditionsRecieved); + + // + mX121EA.EnableLongs(xEAEnableLongs); + mX121EA.EnableShorts(xEAEnableShorts); + + // + // Attach Providers to EA Instance ... + int providersCount = ArraySize(providers); + int addedProviders = mX121EA.AddProviders(providers); + result = addedProviders == providersCount; + + // + return result; +} +// +// END Functions ... +// diff --git a/MQLTestWorkspace/XBEEA/14030224/Helpers/x-saherelm.x121.xman.helper.class.ex5 b/MQLTestWorkspace/XBEEA/14030224/Helpers/x-saherelm.x121.xman.helper.class.ex5 new file mode 100644 index 0000000..c92beba Binary files /dev/null and b/MQLTestWorkspace/XBEEA/14030224/Helpers/x-saherelm.x121.xman.helper.class.ex5 differ diff --git a/MQLTestWorkspace/XBEEA/14030224/Helpers/x-saherelm.x121.xman.helper.class.mq5 b/MQLTestWorkspace/XBEEA/14030224/Helpers/x-saherelm.x121.xman.helper.class.mq5 new file mode 100644 index 0000000..dc0d890 --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Helpers/x-saherelm.x121.xman.helper.class.mq5 @@ -0,0 +1,1927 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXMANHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +#include "../Libraries/x-saherelm.xman.parser.lib.mq5" + +// +// All Extractable Buffers ... +enum ENUM_XMAN_BUFFERS +{ + // + // Peaks and Vales ... + XMAN_PEAKS_LINE = 0, // Peaks + XMAN_VALES_LINE = 1, // Vales + XMAN_PEAKS_STATE_LINE = 74, // New Peak + XMAN_VALES_STATE_LINE = 75, // New Vales + // + // Fibonacci Retracement ... + XMAN_FIB_L1_LINE = 6, // Fibo Level 1 + XMAN_FIB_L2_LINE = 8, // Fibo Level 2 + XMAN_FIB_L3_LINE = 10, // Fibo Level 3 + XMAN_FIB_L4_LINE = 12, // Fibo Level 3 + XMAN_FIB_L5_LINE = 14, // Fibo Level 3 + // + // Period Cycles ... + // + // Short Cycle ... + XMAN_SC_HH_LINE = 16, // High + XMAN_SC_LL_LINE = 18, // Low + XMAN_SC_HH_STATE_LINE = 76, // High State + XMAN_SC_LL_STATE_LINE = 77, // Low State + // + // Medium ... + XMAN_MC_HH_LINE = 20, // High + XMAN_MC_LL_LINE = 22, // Low + XMAN_MC_HH_STATE_LINE = 78, // High State + XMAN_MC_LL_STATE_LINE = 79, // Low State + // + // Long ... + XMAN_LC_HH_LINE = 24, // High + XMAN_LC_LL_LINE = 26, // Low + XMAN_LC_HH_STATE_LINE = 80, // High State + XMAN_LC_LL_STATE_LINE = 81, // Low State + // + // Hind ... + XMAN_HC_HH_LINE = 28, // High + XMAN_HC_LL_LINE = 30, // Low + XMAN_HC_HH_STATE_LINE = 82, // High State + XMAN_HC_LL_STATE_LINE = 83, // Low State + // + // XSTR ... + XMAN_TREND_LINE = 34, // Trend Value + XMAN_TREND_STATE_LINE = 84, // Trend Direction + // + // XMRB ... + // + // RIBBON 1 _ HIGH ... + XMAN_RB1_LINE = 36, // Value + XMAN_RB1_STATE_LINE = 85, // State + // + // RIBBON 2 _ OPEN ... + XMAN_RB2_LINE = 38, // Value + XMAN_RB2_STATE_LINE = 86, // State + // + // RIBBON 3 _ CLOSE ... + XMAN_RB3_LINE = 40, // Value + XMAN_RB3_STATE_LINE = 87, // State + // + // RIBBON 4 _ MEDIAN ... + XMAN_RB4_LINE = 42, // Value + XMAN_RB4_STATE_LINE = 88, // State + // + // RIBBON 5 _ TYPICAL ... + XMAN_RB5_LINE = 44, // Value + XMAN_RB5_STATE_LINE = 89, // State + // + // RIBBON 6 _ LOW ... + XMAN_RB6_LINE = 46, // Value + XMAN_RB6_STATE_LINE = 90, // State + // + // XSSLC ... + XMAN_SSLC_UP_LINE = 48, // Up + XMAN_SSLC_DOWN_LINE = 50, // Down + // + // XHULL ... + XMAN_HULL_UP_LINE = 52, // Up + XMAN_HULL_DOWN_LINE = 54, // Down + XMAN_HULL_UP_STATE_LINE = 91, // Up State + XMAN_HULL_DOWN_STATE_LINE = 92, // Down State + // + // XHK ... + XMAN_HK_OPEN_LINE = 56, // Open + XMAN_HK_HIGH_LINE = 57, // High + XMAN_HK_LOW_LINE = 58, // Low + XMAN_HK_CLOSE_LINE = 59, // Close + XMAN_HK_STATE_LINE = 93, // State + // + // XSMHK ... + XMAN_SMHK_OPEN_LINE = 61, // Open + XMAN_SMHK_HIGH_LINE = 62, // High + XMAN_SMHK_LOW_LINE = 63, // Low + XMAN_SMHK_CLOSE_LINE = 64, // Close +}; + +// +// Define States On XMAN ... +enum ENUM_XMAN_STATES +{ + XMAN_STATE_BULLISH = 2, + XMAN_STATE_STRONG_BULLISH = 8, + XMAN_STATE_BEARISH = 3, + XMAN_STATE_STRONG_BEARISH = 9, + XMAN_STATE_NEUTURAL = 1, + XMAN_STATE_STRONG_NEUTURAL = 7, +}; + +// +// Model all required info as a Model for Instancing Helper Class ... +struct XMANInputs +{ + // + // Candle Timer ... + color candleTimerColor; // Text Color + ENUM_BASE_CORNER candleTimerCorner; // Text Position + + // + // Chart Style ... + color upColor; // Up Color + color downColor; // Down Color + color lineColor; // Line mode and Doji candlestick Color + color bearishColor; // Bullish Color + color bullishColor; // Bearish Color + color volumesColor; // Volumes Color + ENUM_CHART_MODE chartMode; // Chart Mode + + // + // Market Cycles ... + + // + // Level 1 ... + ENUM_X_PERIOD_METHOD l1Method; // How to Find Period + ENUM_TIMEFRAMES l1Period; // Time Period + + // + // Level 2 ... + ENUM_X_PERIOD_METHOD l2Method; // How to Find Period + ENUM_TIMEFRAMES l2Period; // Time Period + + // + // Level 3 ... + ENUM_X_PERIOD_METHOD l3Method; // How to Find Period + ENUM_TIMEFRAMES l3Period; // Time Period + + // + // Level 4 ... + ENUM_X_PERIOD_METHOD l4Method; // How to Find Period + ENUM_TIMEFRAMES l4Period; // Time Period + + // + // Fibonacci ... + double fiboLevel1; // Fibio 1st Level + double fiboLevel2; // Fibio 2st Level + double fiboLevel3; // Fibio 3rd Level + double fiboLevel4; // Fibio 4th Level + double fiboLevel5; // Fibio 5th Level + + // + // Boundary Detection Modes ... + ENUM_SERIESMODE hhMode; // Highest High Calculation Method + ENUM_SERIESMODE llMode; // Lowest Low Calculation Method + + // + // Trend Detection + double trendMultiplier; // Multiplier + ENUM_APPLIED_PRICE trendPriceAppliedTo; // Applied To + + // + // Ribbon Detection ... + ENUM_X_MA_METHOD ribbonMode; // How to Calculate + + // + // Hull Trend Detection ... + double hullDivisor; // Divisor (Speed) + ENUM_APPLIED_PRICE hullUpAppliedTo; // Up Zone Applied to + ENUM_APPLIED_PRICE hullDownAppliedTo; // Down Zone Applied to + + // + // SSL Channel Detection ... + ENUM_X_MA_METHOD sslcMode; // How to Calculate + ENUM_APPLIED_PRICE sslcUpAppliedTo; // Up Applied To + ENUM_APPLIED_PRICE sslcDownAppliedTo; // Down Applied To + + // + // Presentation ... + bool showCandleTimer; // Show Candle Time + bool showCandles; // Show Candles + bool showHKCandles; // Draw Hiken Ashi Candle + bool showSMHKCandles; // Draw Smoothed Hiken Ashi Candle + bool showPeaksAndVales; // Show Peaks and Vales + bool showTrends; // Show Trends + bool fillTrends; // Fill Trends + bool showLevels; // Show Levels + bool showConsolidations; // Show Consolidations + bool showRibbons; // Show Ribbons + bool showHull; // Show Hull + bool showSSLChannel; // Show SSL Channel + bool showFibo1Levels; // Show Fibo 1st Level + bool showFibo2Levels; // Show Fibo 2nd Level + bool showFibo3Levels; // Show Fibo 3rd Level + bool showFibo4Levels; // Show Fibo 4th Level + bool showFibo5Levels; // Show Fibo 5th Level +}; + +// +// Model all Extractable Info as a Model for Market Analyzing ... +struct XMANInfo +{ + // + // COMMONS ... + + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // SPECIALS ... + + // + // Buffers ... + + // + // Chanes ... + XValueChanged trendChanges[]; + XValueChanged peakChanges[]; + XValueChanged valeChanges[]; + + // + // Peaks and Vales ... + double peaks[]; + double peaksStates[]; + double vales[]; + double valesStates[]; + + // + // Fibonacci ... + double fibLevel1s[]; + double fibLevel2s[]; + double fibLevel3s[]; + double fibLevel4s[]; + double fibLevel5s[]; + + // + // Cycles ... + + // + // Short ... + double sHHs[]; + double sHHStates[]; + double sLLs[]; + double sLLStates[]; + + // + // Medium ... + double mHHs[]; + double mHHStates[]; + double mLLs[]; + double mLLStates[]; + + // + // Long ... + double lHHs[]; + double lHHStates[]; + double lLLs[]; + double lLLStates[]; + + // + // Hind ... + double hHHs[]; + double hHHStates[]; + double hLLs[]; + double hLLStates[]; + + // + // Trends ... + double trends[]; + double trendStates[]; + + // + // Ribbons ... + + // + // 1 _ High ... + double ribbon1s[]; + double ribbon1States[]; + + // + // 2 _ Open ... + double ribbon2s[]; + double ribbon2States[]; + + // + // 3 _ Close ... + double ribbon3s[]; + double ribbon3States[]; + + // + // 4 _ Median ... + double ribbon4s[]; + double ribbon4States[]; + + // + // 5 _ Typical ... + double ribbon5s[]; + double ribbon5States[]; + + // + // 6 _ Low ... + double ribbon6s[]; + double ribbon6States[]; + + // + // SSL Channel ... + double sslcUps[]; + double sslcDowns[]; + + // + // Hull Trend ... + double hullUps[]; + double hullUpStates[]; + double hullDowns[]; + double hullDownStates[]; + + // + // Hiken Ashi ... + double hkOpens[]; + double hkHighs[]; + double hkLows[]; + double hkCloses[]; + double hkStates[]; + + // + // Smoothed Hiken Ashi ... + double smhkOpens[]; + double smhkHighs[]; + double smhkLows[]; + double smhkCloses[]; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +class XSCXMANHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + XValueChanged trendChanges[]; + XValueChanged peakChanges[]; + XValueChanged valeChanges[]; + + // + // Peaks and Vales ... + double peaksBuffer[]; + double peaksStateBuffer[]; + double valesBuffer[]; + double valesStateBuffer[]; + + // + // Fibonacci ... + double fibLevel1Buffer[]; + double fibLevel2Buffer[]; + double fibLevel3Buffer[]; + double fibLevel4Buffer[]; + double fibLevel5Buffer[]; + + // + // Cycles ... + + // + // Short ... + double sHHBuffer[]; + double sHHStateBuffer[]; + double sLLBuffer[]; + double sLLStateBuffer[]; + + // + // Medium ... + double mHHBuffer[]; + double mHHStateBuffer[]; + double mLLBuffer[]; + double mLLStateBuffer[]; + + // + // Long ... + double lHHBuffer[]; + double lHHStateBuffer[]; + double lLLBuffer[]; + double lLLStateBuffer[]; + + // + // Hind ... + double hHHBuffer[]; + double hHHStateBuffer[]; + double hLLBuffer[]; + double hLLStateBuffer[]; + + // + // Trends ... + double trendBuffer[]; + double trendStateBuffer[]; + + // + // Ribbons ... + + // + // 1 _ High ... + double ribbon1Buffer[]; + double ribbon1StateBuffer[]; + + // + // 2 _ Open ... + double ribbon2Buffer[]; + double ribbon2StateBuffer[]; + + // + // 3 _ Close ... + double ribbon3Buffer[]; + double ribbon3StateBuffer[]; + + // + // 4 _ Median ... + double ribbon4Buffer[]; + double ribbon4StateBuffer[]; + + // + // 5 _ Typical ... + double ribbon5Buffer[]; + double ribbon5StateBuffer[]; + + // + // 6 _ Low ... + double ribbon6Buffer[]; + double ribbon6StateBuffer[]; + + // + // SSL Channel ... + double sslUpBuffer[]; + double sslDownBuffer[]; + + // + // Hull Trend ... + double hullUpBuffer[]; + double hullUpStateBuffer[]; + double hullDownBuffer[]; + double hullDownStateBuffer[]; + + // + // Hiken Ashi ... + double hkOpenBuffer[]; + double hkHighBuffer[]; + double hkLowBuffer[]; + double hkCloseBuffer[]; + double hkStateBuffer[]; + + // + // Smoothed Hiken Ashi ... + double smhkOpenBuffer[]; + double smhkHighBuffer[]; + double smhkLowBuffer[]; + double smhkCloseBuffer[]; + + // + // Constructor ... + void XSCXMANHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXMANHelper() + { + } + + // + // START Properties ... + // + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XMAN" + GetTagPrefix(); + } + + // + virtual int GetMaxLength() + { + // + int result = 1; + + // + result = 1; + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Args ... + result = + // + // L1 ... + // Short Cycle ... + ( + // + mL1Method == X_PERIOD_AUTO + ? mL1Period == NULL + : mL1Period != NULL && mL1Method != X_PERIOD_NOTHING + // + ) + // + && + // + // L2 ... + // Medium Cycle ... + ( + // + mL2Method == X_PERIOD_AUTO + ? mL2Period == NULL + : mL2Period != NULL && mL2Method != X_PERIOD_NOTHING + // + ) + // + && + // + // L3 ... + // Long Cycle ... + ( + // + mL3Method == X_PERIOD_AUTO + ? mL3Period == NULL + : mL3Period != NULL && mL3Method != X_PERIOD_NOTHING + // + ) + // + && + // + // L4 ... + // Hind Cycle ... + ( + // + mL4Method == X_PERIOD_AUTO + ? mL4Period == NULL + : mL4Period != NULL && mL4Method != X_PERIOD_NOTHING + // + ) + // + && + // + // Validate Ribbon ... + ( + // + mRibbonMode != X_MA_NOTHING + // + ) + // + ; + if (!result) + { + return false; + } + + // + // Now we Have to Generate Proper Configs of Inputs ... + // to bypass into iCustom ... + + // + // Candle Timer ... + string ctConfig = GenerateCTimerConfig( + mCandleTimerColor, + mCandleTimerCorner); + + // + // Chart Style ... + string chStyleConfig = GenerateChartStyleConfig( + mUpColor, + mDownColor, + mLineColor, + mBearishColor, + mBullishColor, + mVolumesColor, + mChartMode); + + // + // Market Cycles ... + + // + // SHORT ... + string scConfig = GenerateSCConfig( + mL1Method, + mL1Period); + + // + // MEDIUM ... + string mcConfig = GenerateMCConfig( + mL2Method, + mL2Period); + + // + // LONG ... + string lcConfig = GenerateLCConfig( + mL3Method, + mL3Period); + + // + // HIND ... + string hcConfig = GenerateHCConfig( + mL4Method, + mL4Period); + + // + // Fibonacci ... + string fiboConfig = GenerateFibonacciConfig( + mFiboLevel1, + mFiboLevel2, + mFiboLevel3, + mFiboLevel4, + mFiboLevel5); + + // + // Boundary Detection ... + string bdConfig = GenerateBDConfig( + mHHMode, + mLLMode); + + // + // Trend Detection ... + string tdConfig = GenerateTDConfig( + mTrendMultiplier, + mTrendPriceAppliedTo); + + // + // Ribbon ... + string rbConfig = GenerateRBConfig( + mRibbonMode); + + // + // Hull Trend ... + string hullConfig = GenerateHullConfig( + mHullDivisor, + mHullUpAppliedTo, + mHullDownAppliedTo); + + // + // SSL Channel ... + string sslcConfig = GenerateSSLCConfig( + mSslcMode, + mSslcUpAppliedTo, + mSslcDownAppliedTo); + + // + // Presentations ... + + // + // STYLES ... + string stylesPRSConfig = GenerateStylePresentationConfig( + mShowCandleTimer, + mShowCandles, + mShowHKCandles, + mShowSMHKCandles); + + // + // PEAKSANDVALES ... + string pvPRSConfig = GeneratePVPresentationConfig( + mShowPeaksAndVales, + mShowLevels, + mShowConsolidations); + + // + // TREND ... + string trendPRSConfig = GenerateTrendPresentationConfig( + mShowTrends, + mFillTrends, + mShowRibbons, + mShowHull, + mShowSSLChannel); + + // + // FIBO ... + string fiboPRSConfig = GenerateFiboPresentationConfig( + mShowFibo1Levels, + mShowFibo2Levels, + mShowFibo3Levels, + mShowFibo4Levels, + mShowFibo5Levels); + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xman", + // + // Inputs ... + // + // Candle Timer + "", + ctConfig, + // + // Chart Style + "", + chStyleConfig, + // + // Makret Cycles + "", + // + // Short + "", + scConfig, + // + // Medium + "", + mcConfig, + // + // Long + "", + lcConfig, + // + // Hind + "", + hcConfig, + // + // Fibonacci + "", + fiboConfig, + // + // Boundary Detection Modes + "", + bdConfig, + // + // Trend Detection + "", + tdConfig, + // + // Ribbon Detection + "", + rbConfig, + // + // Hull Trend Detection + "", + hullConfig, + // + // SSL Channel + "", + sslcConfig, + // + // Presentations + "", + // + // STYLES + stylesPRSConfig, + // + // PEAKSANDVALES + pvPRSConfig, + // + // TREND + trendPRSConfig, + // + // FIBO + fiboPRSConfig + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XMANInputs GetConfig() + { + // + XMANInputs result; + + // + result.candleTimerColor = mCandleTimerColor; + result.candleTimerCorner = mCandleTimerCorner; + result.upColor = mUpColor; + result.downColor = mDownColor; + result.lineColor = mLineColor; + result.bearishColor = mBearishColor; + result.bullishColor = mBullishColor; + result.volumesColor = mVolumesColor; + result.chartMode = mChartMode; + result.l1Method = mL1Method; + result.l1Period = mL1Period; + result.l2Method = mL2Method; + result.l2Period = mL2Period; + result.l3Method = mL3Method; + result.l3Period = mL3Period; + result.l4Method = mL4Method; + result.l4Period = mL4Period; + result.fiboLevel1 = mFiboLevel1; + result.fiboLevel2 = mFiboLevel2; + result.fiboLevel3 = mFiboLevel3; + result.fiboLevel4 = mFiboLevel4; + result.fiboLevel5 = mFiboLevel5; + result.hhMode = mHHMode; + result.llMode = mLLMode; + result.trendMultiplier = mTrendMultiplier; + result.trendPriceAppliedTo = mTrendPriceAppliedTo; + result.ribbonMode = mRibbonMode; + result.hullDivisor = mHullDivisor; + result.hullUpAppliedTo = mHullUpAppliedTo; + result.hullDownAppliedTo = mHullDownAppliedTo; + result.sslcMode = mSslcMode; + result.sslcUpAppliedTo = mSslcUpAppliedTo; + result.sslcDownAppliedTo = mSslcDownAppliedTo; + result.showCandleTimer = mShowCandleTimer; + result.showCandles = mShowCandles; + result.showHKCandles = mShowHKCandles; + result.showSMHKCandles = mShowSMHKCandles; + result.showPeaksAndVales = mShowPeaksAndVales; + result.showTrends = mShowTrends; + result.fillTrends = mFillTrends; + result.showLevels = mShowLevels; + result.showConsolidations = mShowConsolidations; + result.showRibbons = mShowRibbons; + result.showHull = mShowHull; + result.showSSLChannel = mShowSSLChannel; + result.showFibo1Levels = mShowFibo1Levels; + result.showFibo2Levels = mShowFibo2Levels; + result.showFibo3Levels = mShowFibo3Levels; + result.showFibo4Levels = mShowFibo4Levels; + result.showFibo5Levels = mShowFibo5Levels; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XMANInputs &config) + { + // + bool result = false; + + // + mCandleTimerColor = config.candleTimerColor; + mCandleTimerCorner = config.candleTimerCorner; + mUpColor = config.upColor; + mDownColor = config.downColor; + mLineColor = config.lineColor; + mBearishColor = config.bearishColor; + mBullishColor = config.bullishColor; + mVolumesColor = config.volumesColor; + mChartMode = config.chartMode; + mL1Method = config.l1Method; + mL1Period = config.l1Period; + mL2Method = config.l2Method; + mL2Period = config.l2Period; + mL3Method = config.l3Method; + mL3Period = config.l3Period; + mL4Method = config.l4Method; + mL4Period = config.l4Period; + mFiboLevel1 = config.fiboLevel1; + mFiboLevel2 = config.fiboLevel2; + mFiboLevel3 = config.fiboLevel3; + mFiboLevel4 = config.fiboLevel4; + mFiboLevel5 = config.fiboLevel5; + mHHMode = config.hhMode; + mLLMode = config.llMode; + mTrendMultiplier = config.trendMultiplier; + mTrendPriceAppliedTo = config.trendPriceAppliedTo; + mRibbonMode = config.ribbonMode; + mHullDivisor = config.hullDivisor; + mHullUpAppliedTo = config.hullUpAppliedTo; + mHullDownAppliedTo = config.hullDownAppliedTo; + mSslcMode = config.sslcMode; + mSslcUpAppliedTo = config.sslcUpAppliedTo; + mSslcDownAppliedTo = config.sslcDownAppliedTo; + mShowCandleTimer = config.showCandleTimer; + mShowCandles = config.showCandles; + mShowHKCandles = config.showHKCandles; + mShowSMHKCandles = config.showSMHKCandles; + mShowPeaksAndVales = config.showPeaksAndVales; + mShowTrends = config.showTrends; + mFillTrends = config.fillTrends; + mShowLevels = config.showLevels; + mShowConsolidations = config.showConsolidations; + mShowRibbons = config.showRibbons; + mShowHull = config.showHull; + mShowSSLChannel = config.showSSLChannel; + mShowFibo1Levels = config.showFibo1Levels; + mShowFibo2Levels = config.showFibo2Levels; + mShowFibo3Levels = config.showFibo3Levels; + mShowFibo4Levels = config.showFibo4Levels; + mShowFibo5Levels = config.showFibo5Levels; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + // + // Peaks ... + ArraySetAsSeries(peaksBuffer, true); + CopyBuffer( + mHandler, + XMAN_PEAKS_LINE, + barIndex, + mLoopbackBars, + peaksBuffer); + + // + // Peaks State ... + ArraySetAsSeries(peaksStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_PEAKS_STATE_LINE, + barIndex, + mLoopbackBars, + peaksStateBuffer); + + // + // Vales ... + ArraySetAsSeries(valesBuffer, true); + CopyBuffer( + mHandler, + XMAN_VALES_LINE, + barIndex, + mLoopbackBars, + valesBuffer); + + // + // Vales State ... + ArraySetAsSeries(valesStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_VALES_STATE_LINE, + barIndex, + mLoopbackBars, + valesStateBuffer); + + // + // Fibo 1 ... + ArraySetAsSeries(fibLevel1Buffer, true); + CopyBuffer( + mHandler, + XMAN_FIB_L1_LINE, + barIndex, + mLoopbackBars, + fibLevel1Buffer); + + // + // Fibo 2 ... + ArraySetAsSeries(fibLevel2Buffer, true); + CopyBuffer( + mHandler, + XMAN_FIB_L2_LINE, + barIndex, + mLoopbackBars, + fibLevel2Buffer); + + // + // Fibo 3 ... + ArraySetAsSeries(fibLevel3Buffer, true); + CopyBuffer( + mHandler, + XMAN_FIB_L3_LINE, + barIndex, + mLoopbackBars, + fibLevel3Buffer); + + // + // Fibo 4 ... + ArraySetAsSeries(fibLevel4Buffer, true); + CopyBuffer( + mHandler, + XMAN_FIB_L4_LINE, + barIndex, + mLoopbackBars, + fibLevel4Buffer); + + // + // Fibo 5 ... + ArraySetAsSeries(fibLevel5Buffer, true); + CopyBuffer( + mHandler, + XMAN_FIB_L5_LINE, + barIndex, + mLoopbackBars, + fibLevel5Buffer); + + // + // Cycles ... + + // + // Short ... + + // + // High ... + ArraySetAsSeries(sHHBuffer, true); + CopyBuffer( + mHandler, + XMAN_SC_HH_LINE, + barIndex, + mLoopbackBars, + sHHBuffer); + + // + // High State ... + ArraySetAsSeries(sHHStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_SC_HH_STATE_LINE, + barIndex, + mLoopbackBars, + sHHStateBuffer); + + // + // High ... + ArraySetAsSeries(sLLBuffer, true); + CopyBuffer( + mHandler, + XMAN_SC_LL_LINE, + barIndex, + mLoopbackBars, + sLLBuffer); + + // + // High State ... + ArraySetAsSeries(sLLStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_SC_LL_STATE_LINE, + barIndex, + mLoopbackBars, + sLLStateBuffer); + + // + // Medium ... + + // + // High ... + ArraySetAsSeries(mHHBuffer, true); + CopyBuffer( + mHandler, + XMAN_MC_HH_LINE, + barIndex, + mLoopbackBars, + mHHBuffer); + + // + // High State ... + ArraySetAsSeries(mHHStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_MC_HH_STATE_LINE, + barIndex, + mLoopbackBars, + mHHStateBuffer); + + // + // High ... + ArraySetAsSeries(mLLBuffer, true); + CopyBuffer( + mHandler, + XMAN_MC_LL_LINE, + barIndex, + mLoopbackBars, + mLLBuffer); + + // + // High State ... + ArraySetAsSeries(mLLStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_MC_LL_STATE_LINE, + barIndex, + mLoopbackBars, + mLLStateBuffer); + + // + // Long ... + + // + // High ... + ArraySetAsSeries(lHHBuffer, true); + CopyBuffer( + mHandler, + XMAN_LC_HH_LINE, + barIndex, + mLoopbackBars, + lHHBuffer); + + // + // High State ... + ArraySetAsSeries(lHHStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_LC_HH_STATE_LINE, + barIndex, + mLoopbackBars, + lHHStateBuffer); + + // + // High ... + ArraySetAsSeries(lLLBuffer, true); + CopyBuffer( + mHandler, + XMAN_LC_LL_LINE, + barIndex, + mLoopbackBars, + lLLBuffer); + + // + // High State ... + ArraySetAsSeries(lLLStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_LC_LL_STATE_LINE, + barIndex, + mLoopbackBars, + lLLStateBuffer); + + // + // Hind ... + + // + // High ... + ArraySetAsSeries(hHHBuffer, true); + CopyBuffer( + mHandler, + XMAN_HC_HH_LINE, + barIndex, + mLoopbackBars, + hHHBuffer); + + // + // High State ... + ArraySetAsSeries(hHHStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_HC_HH_STATE_LINE, + barIndex, + mLoopbackBars, + hHHStateBuffer); + + // + // High ... + ArraySetAsSeries(hLLBuffer, true); + CopyBuffer( + mHandler, + XMAN_HC_LL_LINE, + barIndex, + mLoopbackBars, + hLLBuffer); + + // + // High State ... + ArraySetAsSeries(hLLStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_HC_LL_STATE_LINE, + barIndex, + mLoopbackBars, + hLLStateBuffer); + + // + // Trend ... + + // + // Trend ... + ArraySetAsSeries(trendBuffer, true); + CopyBuffer( + mHandler, + XMAN_TREND_LINE, + barIndex, + mLoopbackBars, + trendBuffer); + + // + // Trend State ... + ArraySetAsSeries(trendStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_TREND_STATE_LINE, + barIndex, + mLoopbackBars, + trendStateBuffer); + + // + // Ribbons ... + + // + // 1 ... + + // + // R1 ... + ArraySetAsSeries(ribbon1Buffer, true); + CopyBuffer( + mHandler, + XMAN_RB1_LINE, + barIndex, + mLoopbackBars, + ribbon1Buffer); + + // + // R1 State ... + ArraySetAsSeries(ribbon1StateBuffer, true); + CopyBuffer( + mHandler, + XMAN_RB1_STATE_LINE, + barIndex, + mLoopbackBars, + ribbon1StateBuffer); + + // + // 2 ... + + // + // R2 ... + ArraySetAsSeries(ribbon2Buffer, true); + CopyBuffer( + mHandler, + XMAN_RB2_LINE, + barIndex, + mLoopbackBars, + ribbon2Buffer); + + // + // R2 State ... + ArraySetAsSeries(ribbon2StateBuffer, true); + CopyBuffer( + mHandler, + XMAN_RB2_STATE_LINE, + barIndex, + mLoopbackBars, + ribbon2StateBuffer); + + // + // 3 ... + + // + // R3 ... + ArraySetAsSeries(ribbon3Buffer, true); + CopyBuffer( + mHandler, + XMAN_RB3_LINE, + barIndex, + mLoopbackBars, + ribbon3Buffer); + + // + // R3 State ... + ArraySetAsSeries(ribbon3StateBuffer, true); + CopyBuffer( + mHandler, + XMAN_RB3_STATE_LINE, + barIndex, + mLoopbackBars, + ribbon3StateBuffer); + + // + // 4 ... + + // + // R4 ... + ArraySetAsSeries(ribbon4Buffer, true); + CopyBuffer( + mHandler, + XMAN_RB4_LINE, + barIndex, + mLoopbackBars, + ribbon4Buffer); + + // + // R4 State ... + ArraySetAsSeries(ribbon4StateBuffer, true); + CopyBuffer( + mHandler, + XMAN_RB4_STATE_LINE, + barIndex, + mLoopbackBars, + ribbon4StateBuffer); + + // + // 5 ... + + // + // R5 ... + ArraySetAsSeries(ribbon5Buffer, true); + CopyBuffer( + mHandler, + XMAN_RB5_LINE, + barIndex, + mLoopbackBars, + ribbon5Buffer); + + // + // R5 State ... + ArraySetAsSeries(ribbon5StateBuffer, true); + CopyBuffer( + mHandler, + XMAN_RB5_STATE_LINE, + barIndex, + mLoopbackBars, + ribbon5StateBuffer); + + // + // 6 ... + + // + // R6 ... + ArraySetAsSeries(ribbon6Buffer, true); + CopyBuffer( + mHandler, + XMAN_RB6_LINE, + barIndex, + mLoopbackBars, + ribbon6Buffer); + + // + // R6 State ... + ArraySetAsSeries(ribbon6StateBuffer, true); + CopyBuffer( + mHandler, + XMAN_RB6_STATE_LINE, + barIndex, + mLoopbackBars, + ribbon6StateBuffer); + + // + // SSL Channel ... + + // + // UP ... + ArraySetAsSeries(sslUpBuffer, true); + CopyBuffer( + mHandler, + XMAN_SSLC_UP_LINE, + barIndex, + mLoopbackBars, + sslUpBuffer); + + // + // DOWN ... + ArraySetAsSeries(sslDownBuffer, true); + CopyBuffer( + mHandler, + XMAN_SSLC_DOWN_LINE, + barIndex, + mLoopbackBars, + sslDownBuffer); + + // + // HULL Trend ... + + // + // UP ... + ArraySetAsSeries(hullUpBuffer, true); + CopyBuffer( + mHandler, + XMAN_HULL_UP_LINE, + barIndex, + mLoopbackBars, + hullUpBuffer); + + // + // UP State ... + ArraySetAsSeries(hullUpStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_HULL_UP_STATE_LINE, + barIndex, + mLoopbackBars, + hullUpStateBuffer); + + // + // DOWN ... + ArraySetAsSeries(hullDownBuffer, true); + CopyBuffer( + mHandler, + XMAN_HULL_DOWN_LINE, + barIndex, + mLoopbackBars, + hullDownBuffer); + + // + // DOWN State ... + ArraySetAsSeries(hullDownStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_HULL_DOWN_STATE_LINE, + barIndex, + mLoopbackBars, + hullDownStateBuffer); + + // + // Hiken Ashi ... + + // + // Open ... + ArraySetAsSeries(hkOpenBuffer, true); + CopyBuffer( + mHandler, + XMAN_HK_OPEN_LINE, + barIndex, + mLoopbackBars, + hkOpenBuffer); + + // + // High ... + ArraySetAsSeries(hkHighBuffer, true); + CopyBuffer( + mHandler, + XMAN_HK_HIGH_LINE, + barIndex, + mLoopbackBars, + hkHighBuffer); + + // + // Low ... + ArraySetAsSeries(hkLowBuffer, true); + CopyBuffer( + mHandler, + XMAN_HK_LOW_LINE, + barIndex, + mLoopbackBars, + hkLowBuffer); + + // + // Close ... + ArraySetAsSeries(hkCloseBuffer, true); + CopyBuffer( + mHandler, + XMAN_HK_CLOSE_LINE, + barIndex, + mLoopbackBars, + hkCloseBuffer); + + // + // Close ... + ArraySetAsSeries(hkStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_HK_STATE_LINE, + barIndex, + mLoopbackBars, + hkStateBuffer); + + // + // XSMHK ... + + // + // Open ... + ArraySetAsSeries(smhkOpenBuffer, true); + CopyBuffer( + mHandler, + XMAN_SMHK_OPEN_LINE, + barIndex, + mLoopbackBars, + smhkOpenBuffer); + + // + // High ... + ArraySetAsSeries(smhkHighBuffer, true); + CopyBuffer( + mHandler, + XMAN_SMHK_HIGH_LINE, + barIndex, + mLoopbackBars, + smhkHighBuffer); + + // + // Low ... + ArraySetAsSeries(smhkLowBuffer, true); + CopyBuffer( + mHandler, + XMAN_SMHK_LOW_LINE, + barIndex, + mLoopbackBars, + smhkLowBuffer); + + // + // Close ... + ArraySetAsSeries(smhkCloseBuffer, true); + CopyBuffer( + mHandler, + XMAN_SMHK_CLOSE_LINE, + barIndex, + mLoopbackBars, + smhkCloseBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XMANInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XMANInfo result; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + // Buffers ... + + // + Copy(peaksBuffer, + result.peaks); + Copy(peaksStateBuffer, + result.peaksStates); + Copy(valesBuffer, + result.vales); + Copy(valesStateBuffer, + result.valesStates); + + // + Copy(fibLevel1Buffer, + result.fibLevel1s); + Copy(fibLevel2Buffer, + result.fibLevel2s); + Copy(fibLevel3Buffer, + result.fibLevel3s); + Copy(fibLevel4Buffer, + result.fibLevel4s); + Copy(fibLevel5Buffer, + result.fibLevel5s); + + // + Copy(sHHBuffer, + result.sHHs); + Copy(sHHStateBuffer, + result.sHHStates); + Copy(sLLBuffer, + result.sLLs); + Copy(sLLStateBuffer, + result.sLLStates); + + // + Copy(mHHBuffer, + result.mHHs); + Copy(mHHStateBuffer, + result.mHHStates); + Copy(mLLBuffer, + result.mLLs); + Copy(mLLStateBuffer, + result.mLLStates); + + // + Copy(lHHBuffer, + result.lHHs); + Copy(lHHStateBuffer, + result.lHHStates); + Copy(lLLBuffer, + result.lLLs); + Copy(lLLStateBuffer, + result.lLLStates); + + // + Copy(hHHBuffer, + result.hHHs); + Copy(hHHStateBuffer, + result.hHHStates); + Copy(hLLBuffer, + result.hLLs); + Copy(hLLStateBuffer, + result.hLLStates); + + // + Copy(trendBuffer, + result.trends); + Copy(trendStateBuffer, + result.trendStates); + + // + Copy(ribbon1Buffer, + result.ribbon1s); + Copy(ribbon1StateBuffer, + result.ribbon1States); + + // + Copy(ribbon2Buffer, + result.ribbon2s); + Copy(ribbon2StateBuffer, + result.ribbon2States); + + // + Copy(ribbon3Buffer, + result.ribbon3s); + Copy(ribbon3StateBuffer, + result.ribbon3States); + + // + Copy(ribbon4Buffer, + result.ribbon4s); + Copy(ribbon4StateBuffer, + result.ribbon4States); + + // + Copy(ribbon5Buffer, + result.ribbon5s); + Copy(ribbon5StateBuffer, + result.ribbon5States); + + // + Copy(ribbon6Buffer, + result.ribbon6s); + Copy(ribbon6StateBuffer, + result.ribbon6States); + + // + Copy(sslUpBuffer, + result.sslcUps); + Copy(sslDownBuffer, + result.sslcDowns); + + // + Copy(hullUpBuffer, + result.hullUps); + Copy(hullUpStateBuffer, + result.hullUpStates); + Copy(hullDownBuffer, + result.hullDowns); + Copy(hullDownStateBuffer, + result.hullDownStates); + + // + Copy(hkOpenBuffer, + result.hkOpens); + Copy(hkHighBuffer, + result.hkHighs); + Copy(hkLowBuffer, + result.hkLows); + Copy(hkCloseBuffer, + result.hkCloses); + Copy(hkStateBuffer, + result.hkStates); + + // + Copy(smhkOpenBuffer, + result.smhkOpens); + Copy(smhkHighBuffer, + result.smhkHighs); + Copy(smhkLowBuffer, + result.smhkLows); + Copy(smhkCloseBuffer, + result.smhkCloses); + + // + // Prepare Change Handlers ... + barTime = GetCandleTime( + mSymbol, + mPeriod, + 0); + + // + // Trend Change ... + bool isTrendChangedHandled = + HandleValueChanged( + trendChanges, + trendStateBuffer, + trendBuffer, + barTime); + + // + Copy( + trendChanges, + result.trendChanges); + + // + // Peak Change ... + bool isPeaksChangedHandled = + HandleValueChanged( + peakChanges, + peaksBuffer, + peaksBuffer, + barTime); + + // + Copy( + peakChanges, + result.peakChanges); + + // + // Vale Change ... + bool isValesChangedHandled = + HandleValueChanged( + valeChanges, + valesBuffer, + valesBuffer, + barTime); + + // + Copy( + valeChanges, + result.valeChanges); + + // + return result; + } + + // + // Protcted ... +protected: + // + // Private ... +private: + // + // Inputs ... + + // + // Candle Timer ... + color mCandleTimerColor; // Text Color + ENUM_BASE_CORNER mCandleTimerCorner; // Text Position + + // + // Chart Style ... + color mUpColor; // Up Color + color mDownColor; // Down Color + color mLineColor; // Line mode and Doji candlestick Color + color mBearishColor; // Bullish Color + color mBullishColor; // Bearish Color + color mVolumesColor; // Volumes Color + ENUM_CHART_MODE mChartMode; // Chart Mode + + // + // Market Cycles ... + + // + // Level 1 ... + ENUM_X_PERIOD_METHOD mL1Method; // How to Find Period + ENUM_TIMEFRAMES mL1Period; // Time Period + + // + // Level 2 ... + ENUM_X_PERIOD_METHOD mL2Method; // How to Find Period + ENUM_TIMEFRAMES mL2Period; // Time Period + + // + // Level 3 ... + ENUM_X_PERIOD_METHOD mL3Method; // How to Find Period + ENUM_TIMEFRAMES mL3Period; // Time Period + + // + // Level 4 ... + ENUM_X_PERIOD_METHOD mL4Method; // How to Find Period + ENUM_TIMEFRAMES mL4Period; // Time Period + + // + // Fibonacci ... + double mFiboLevel1; // Fibio 1st Level + double mFiboLevel2; // Fibio 2st Level + double mFiboLevel3; // Fibio 3rd Level + double mFiboLevel4; // Fibio 4th Level + double mFiboLevel5; // Fibio 5th Level + + // + // Boundary Detection Modes ... + ENUM_SERIESMODE mHHMode; // Highest High Calculation Method + ENUM_SERIESMODE mLLMode; // Lowest Low Calculation Method + + // + // Trend Detection + double mTrendMultiplier; // Multiplier + ENUM_APPLIED_PRICE mTrendPriceAppliedTo; // Applied To + + // + // Ribbon Detection ... + ENUM_X_MA_METHOD mRibbonMode; // How to Calculate + + // + // Hull Trend Detection ... + double mHullDivisor; // Divisor (Speed) + ENUM_APPLIED_PRICE mHullUpAppliedTo; // Up Zone Applied to + ENUM_APPLIED_PRICE mHullDownAppliedTo; // Down Zone Applied to + + // + // SSL Channel Detection ... + ENUM_X_MA_METHOD mSslcMode; // How to Calculate + ENUM_APPLIED_PRICE mSslcUpAppliedTo; // Up Applied To + ENUM_APPLIED_PRICE mSslcDownAppliedTo; // Down Applied To + + // + // Presentation ... + bool mShowCandleTimer; // Show Candle Time + bool mShowCandles; // Show Candles + bool mShowHKCandles; // Draw Hiken Ashi Candle + bool mShowSMHKCandles; // Draw Smoothed Hiken Ashi Candle + bool mShowPeaksAndVales; // Show Peaks and Vales + bool mShowTrends; // Show Trends + bool mFillTrends; // Fill Trends + bool mShowLevels; // Show Levels + bool mShowConsolidations; // Show Consolidations + bool mShowRibbons; // Show Ribbons + bool mShowHull; // Show Hull + bool mShowSSLChannel; // Show SSL Channel + bool mShowFibo1Levels; // Show Fibo 1st Level + bool mShowFibo2Levels; // Show Fibo 2nd Level + bool mShowFibo3Levels; // Show Fibo 3rd Level + bool mShowFibo4Levels; // Show Fibo 4th Level + bool mShowFibo5Levels; // Show Fibo 5th Level +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xche.ex5 b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xche.ex5 new file mode 100644 index 0000000..09919a2 Binary files /dev/null and b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xche.ex5 differ diff --git a/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xche.mq5 b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xche.mq5 new file mode 100644 index 0000000..59e850f --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xche.mq5 @@ -0,0 +1,631 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: X121_XCHE +// Description: Chandelier Exit Indicator ... +// +// +// 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_XCHE Indicator" +#property strict + +// +// START Constants ... +// + +// +#define ShortName "X121_XCHE" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Market"; +input int length = 35; // Length +input int loopback = 26; // Loopback +input double multiplier1 = 3.0; // 1st Multiplier +input double multiplier2 = 3.5; // 2nd Multiplier + +// +input group "Calculation"; +input ENUM_APPLIED_PRICE upAppliedTo = PRICE_HIGH; // Up Zone Applied to +input ENUM_APPLIED_PRICE downAppliedTo = PRICE_LOW; // Down Zone Applied to + +// +input group "Presentation"; +input bool showLongExit1Line = true; // Show 1st Long Exit +input bool showShortExit1Line = true; // Show 1st Short Exit +input bool showLongExit2Line = true; // Show 2st Long Exit +input bool showShortExit2Line = true; // Show 2st Short Exit + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 8 +#property indicator_plots 8 + +// +// Long Exit 1 ... +#define longExit1BufferIndex 0 +double longExit1Buffer[]; + +// +#property indicator_label1 "X121_XCHE LE 1" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrLime +#property indicator_style1 STYLE_DOT + +// +// Short Exit 1 ... +#define shortExit1BufferIndex 1 +double shortExit1Buffer[]; + +// +#property indicator_label2 "X121_XCHE SE 1" +#property indicator_type2 DRAW_LINE +#property indicator_style2 STYLE_DOT +#property indicator_color2 clrRed + +// +// Long Exit 2 ... +#define longExit2BufferIndex 2 +double longExit2Buffer[]; + +// +#property indicator_label3 "X121_XCHE LE 2" +#property indicator_type3 DRAW_LINE +#property indicator_style2 STYLE_DOT +#property indicator_color3 clrAqua + +// +// Short Exit 2 ... +#define shortExit2BufferIndex 3 +double shortExit2Buffer[]; + +// +#property indicator_label4 "X121_XCHE SE 2" +#property indicator_type4 DRAW_LINE +#property indicator_style2 STYLE_DOT +#property indicator_color4 clrMagenta + +// +// START Arrows ... + +// +// Long Exit 1 Start ... +#define longExit1StartBufferIndex 4 +double longExit1StartBuffer[]; + +// +#property indicator_label5 "X121_XCHE LES 1" +#property indicator_type5 DRAW_ARROW +#property indicator_color5 clrLime + +// +// Short Exit 1 Start ... +#define shortExit1StartBufferIndex 5 +double shortExit1StartBuffer[]; + +// +#property indicator_label6 "X121_XCHE SES 1" +#property indicator_type6 DRAW_ARROW +#property indicator_color6 clrRed + +// +// Long Exit 2 Start ... +#define longExit2StartBufferIndex 6 +double longExit2StartBuffer[]; + +// +#property indicator_label7 "X121_XCHE LES 2" +#property indicator_type7 DRAW_ARROW +#property indicator_color7 clrAqua + +// +// Short Exit 2 Start ... +#define shortExit2StartBufferIndex 7 +double shortExit2StartBuffer[]; + +// +#property indicator_label8 "X121_XCHE SES 2" +#property indicator_type8 DRAW_ARROW +#property indicator_color8 clrMagenta + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +// Working Array ... +double work[][6]; +#define hi1Idx 0 +#define lo1Idx 1 +#define hi2Idx 2 +#define lo2Idx 3 +#define trend1Idx 4 +#define trend2Idx 5 + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // 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(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +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 mPeriod 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 +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + if (Bars(_Symbol, _Period) < rates_total) + { + return (prev_calculated); + } + + // + if (ArrayRange(work, 0) != rates_total) + { + ArrayResize(work, rates_total); + } + + // + // this counts Available Bars ... + int limit; + + // + limit = prev_calculated - 1; + if (limit < 0) + { + limit = 0; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + CalculateBuffers( + i, + prev_calculated, + rates_total, + // + open, + high, + low, + close); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + result = + length >= 9 && + loopback >= 0; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(length, loopback); + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + uint arrowCode = 159; + + // + // LEVEL 1 ... + + // + // Long Exit 1 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE longExit1DrawType = showLongExit1Line ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE longExit1StartDrawType = showLongExit1Line ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(longExit1BufferIndex, longExit1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(longExit1BufferIndex, PLOT_SHOW_DATA, showLongExit1Line); + PlotIndexSetInteger(longExit1BufferIndex, PLOT_DRAW_TYPE, longExit1DrawType); + + // + // Start Buffer ... + SetIndexBuffer(longExit1StartBufferIndex, longExit1StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(longExit1StartBufferIndex, PLOT_ARROW, arrowCode); + PlotIndexSetInteger(longExit1StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(longExit1StartBufferIndex, PLOT_DRAW_TYPE, longExit1StartDrawType); + + // + // Short Exit 1 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE shortExit1DrawType = showShortExit1Line ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE shortExit1StartDrawType = showShortExit1Line ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(shortExit1BufferIndex, shortExit1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(shortExit1BufferIndex, PLOT_SHOW_DATA, showShortExit1Line); + PlotIndexSetInteger(shortExit1BufferIndex, PLOT_DRAW_TYPE, shortExit1DrawType); + + // + // Start Buffer ... + SetIndexBuffer(shortExit1StartBufferIndex, shortExit1StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(shortExit1StartBufferIndex, PLOT_ARROW, arrowCode); + PlotIndexSetInteger(shortExit1StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(shortExit1StartBufferIndex, PLOT_DRAW_TYPE, shortExit1StartDrawType); + + // + // LEVEL 2 ... + + // + // Long Exit 2 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE longExit2DrawType = showLongExit2Line ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE longExit2StartDrawType = showLongExit2Line ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(longExit2BufferIndex, longExit2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(longExit2BufferIndex, PLOT_SHOW_DATA, showLongExit2Line); + PlotIndexSetInteger(longExit2BufferIndex, PLOT_DRAW_TYPE, longExit2DrawType); + + // + // Start Buffer ... + SetIndexBuffer(longExit2StartBufferIndex, longExit2StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(longExit2StartBufferIndex, PLOT_ARROW, arrowCode); + PlotIndexSetInteger(longExit2StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(longExit2StartBufferIndex, PLOT_DRAW_TYPE, longExit2StartDrawType); + + // + // Short Exit 2 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE shortExit2DrawType = showShortExit2Line ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE shortExit2StartDrawType = showShortExit2Line ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(shortExit2BufferIndex, shortExit2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(shortExit2BufferIndex, PLOT_SHOW_DATA, showShortExit2Line); + PlotIndexSetInteger(shortExit2BufferIndex, PLOT_DRAW_TYPE, shortExit2DrawType); + + // + // Start Buffer ... + SetIndexBuffer(shortExit2StartBufferIndex, shortExit2StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(shortExit2StartBufferIndex, PLOT_ARROW, arrowCode); + PlotIndexSetInteger(shortExit2StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(shortExit2StartBufferIndex, PLOT_DRAW_TYPE, shortExit2StartDrawType); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, // Selected Bar Index + int prevCalculated, // Previous Calculated + int ratesTotal, // Total Rates + const double &open[], // Rates Open ... + const double &high[], // Rates High ... + const double &low[], // Rates Low ... + const double &close[] // Rates Close ... +) +{ + // + // Cleanup Buffers ... + longExit1Buffer[bar_index] = longExit1StartBuffer[bar_index] = shortExit1Buffer[bar_index] = shortExit1StartBuffer[bar_index] = EMPTY_VALUE; + longExit2Buffer[bar_index] = longExit2StartBuffer[bar_index] = shortExit2Buffer[bar_index] = shortExit2StartBuffer[bar_index] = EMPTY_VALUE; + + // + int start = MathMax(bar_index - loopback, 0); + + // + // Calculate ATR Value ... + double atrValue = 0; + for (int k = 1; k <= length && (bar_index - k - 1) >= 0; k++) + { + // + atrValue += MathMax(high[bar_index - k], close[MathMax(bar_index - k - 1, 0)]) - + MathMin(low[bar_index - k], close[MathMax(bar_index - k - 1, 0)]); + } + atrValue /= (double)length; + + // + // Retrieve Highest High and Lowest Lows ... + double loopbackMax = high[ArrayMaximum(high, start, loopback)]; + double loopbackMin = low[ArrayMinimum(low, start, loopback)]; + + // + // Fill Multi Dimesional Working Array ... + work[bar_index][hi1Idx] = loopbackMax - multiplier1 * atrValue; + work[bar_index][lo1Idx] = loopbackMin + multiplier1 * atrValue; + work[bar_index][hi2Idx] = loopbackMax - multiplier2 * atrValue; + work[bar_index][lo2Idx] = loopbackMin + multiplier2 * atrValue; + work[bar_index][trend1Idx] = (bar_index > 0) ? work[bar_index - 1][trend1Idx] : 0; + work[bar_index][trend2Idx] = (bar_index > 0) ? work[bar_index - 1][trend2Idx] : 0; + + // + if (bar_index > 0) + { + // + // Calculate Trends ... + if (close[bar_index] > work[bar_index - 1][lo1Idx]) + { + work[bar_index][trend1Idx] = 1; + } + + // + if (close[bar_index] < work[bar_index - 1][hi1Idx]) + { + work[bar_index][trend1Idx] = -1; + } + + // + if (close[bar_index] > work[bar_index - 1][lo2Idx]) + { + work[bar_index][trend2Idx] = 1; + } + + // + if (close[bar_index] < work[bar_index - 1][hi2Idx]) + { + work[bar_index][trend2Idx] = -1; + } + + // + // Calculate Exit Values ... + + // + // Exit 1 ... + + // + // Long ... + if (multiplier1 > 0 && work[bar_index][trend1Idx] == 1) + { + // + if (work[bar_index][hi1Idx] < work[bar_index - 1][hi1Idx]) + { + work[bar_index][hi1Idx] = work[bar_index - 1][hi1Idx]; + } + + // + longExit1Buffer[bar_index] = work[bar_index][hi1Idx]; + + // + if (longExit1Buffer[bar_index - 1] == EMPTY_VALUE) + { + longExit1StartBuffer[bar_index] = longExit1Buffer[bar_index]; + } + } + + // + // Short ... + if (multiplier1 > 0 && work[bar_index][trend1Idx] == -1) + { + // + if (work[bar_index][lo1Idx] > work[bar_index - 1][lo1Idx]) + { + work[bar_index][lo1Idx] = work[bar_index - 1][lo1Idx]; + } + + // + shortExit1Buffer[bar_index] = work[bar_index][lo1Idx]; + + // + if (shortExit1Buffer[bar_index - 1] == EMPTY_VALUE) + { + shortExit1StartBuffer[bar_index] = shortExit1Buffer[bar_index]; + } + } + + // + // Exit 2 ... + + // + // Long ... + if (multiplier2 > 0 && work[bar_index][trend2Idx] == 1) + { + if (work[bar_index][hi2Idx] < work[bar_index - 1][hi2Idx]) + { + work[bar_index][hi2Idx] = work[bar_index - 1][hi2Idx]; + } + + // + longExit2Buffer[bar_index] = work[bar_index][hi2Idx]; + + // + if (longExit2Buffer[bar_index - 1] == EMPTY_VALUE) + { + longExit2StartBuffer[bar_index] = longExit2Buffer[bar_index]; + } + } + + // + // Short ... + if (multiplier2 > 0 && work[bar_index][trend2Idx] == -1) + { + // + if (work[bar_index][lo2Idx] > work[bar_index - 1][lo2Idx]) + { + work[bar_index][lo2Idx] = work[bar_index - 1][lo2Idx]; + } + + // + shortExit2Buffer[bar_index] = work[bar_index][lo2Idx]; + + // + if (shortExit2Buffer[bar_index - 1] == EMPTY_VALUE) + { + shortExit2StartBuffer[bar_index] = shortExit2Buffer[bar_index]; + } + } + } +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xdema.ex5 b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xdema.ex5 new file mode 100644 index 0000000..5c339b0 Binary files /dev/null and b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xdema.ex5 differ diff --git a/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xdema.mq5 b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xdema.mq5 new file mode 100644 index 0000000..186778e --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xdema.mq5 @@ -0,0 +1,348 @@ +////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: X121_XDEMA +// Description: Super Trend Indicator ... +// +// +// 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_XAMA Indicator" +#property strict + +// +// START Constants ... +// + +#define ShortName "X121_XDEMA" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +// Market ... +input group "Market"; +input int length = 200; // Length +input int shift = 0; // Shift + +// +// Presentation ... +input group "Presentation"; +input bool showDema = true; // Show Dema +input bool showEMA = false; // Show EMA +input bool showEMAOfEMA = false; // Show EMA of EMA + +// +// END Inputs ... +// + +// +// Includes Common Library ... +#include +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 6 +#property indicator_plots 6 + +// +#define demaBufferIndex 0 +double demaBuffer[]; + +// +#define demaColorBufferIndex 1 +double demaColorBuffer[]; + +// +#property indicator_label1 "X121_XDEMA DEMA" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrDodgerBlue, CLR_NONE +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +#define emaBufferIndex 2 +double emaBuffer[]; + +// +#define emaColorBufferIndex 3 +double emaColorBuffer[]; + +// +#property indicator_label2 "X121_XDEMA EMA" +#property indicator_type2 DRAW_COLOR_LINE +#property indicator_color2 clrBlue, CLR_NONE +#property indicator_style2 STYLE_DOT +#property indicator_width2 1 + +// +#define emaOfEMABufferIndex 4 +double emaOfEMABuffer[]; + +// +#define emaOfEMAColorBufferIndex 5 +double emaOfEMAColorBuffer[]; + +// +#property indicator_label3 "X121_XDEMA EMA of EMA" +#property indicator_type3 DRAW_COLOR_LINE +#property indicator_color3 clrOrange, CLR_NONE +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // 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(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +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 +} + +// +// Do Calculations ... +int OnCalculate(const int rates_total, + const int prev_calculated, + const int begin, + const double &price[]) +{ + // + ArraySetAsSeries(price, true); + + // + // check for data ... + if (rates_total < 2 * length - 2) + { + return 0; + } + + // + int limit; + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // calculate EMA ... + ExponentialMAOnBuffer(rates_total, prev_calculated, 0, length, price, emaBuffer); + + // + // calculate EMA on EMA array ... + ExponentialMAOnBuffer(rates_total, prev_calculated, length - 1, length, emaBuffer, emaOfEMABuffer); + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + // calculate DEMA ... + demaBuffer[i] = 2 * emaBuffer[i] - emaOfEMABuffer[i]; + + // + double showColorIDX = 0; + double hideColorIDX = 1; + + // + demaColorBuffer[i] = hideColorIDX; + emaColorBuffer[i] = hideColorIDX; + emaOfEMAColorBuffer[i] = hideColorIDX; + + // + if (showDema) + { + demaColorBuffer[i] = showColorIDX; + } + + // + if (showEMA) + { + emaColorBuffer[i] = showColorIDX; + } + + // + if (showEMAOfEMA) + { + emaOfEMAColorBuffer[i] = showColorIDX; + } + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + (length > 2 && + shift >= 0) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Peaks and Vales ... + result = length; + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // DEMA ... + + // + // Buffer ... + ArraySetAsSeries(demaBuffer, true); + SetIndexBuffer(demaBufferIndex, demaBuffer, INDICATOR_DATA); + PlotIndexSetInteger(demaBufferIndex, PLOT_SHOW_DATA, showDema); + + // + // Color Buffer ... + ArraySetAsSeries(demaColorBuffer, true); + SetIndexBuffer(demaColorBufferIndex, demaColorBuffer, INDICATOR_COLOR_INDEX); + + // + // EMA ... + + // + // Buffer ... + ArraySetAsSeries(emaBuffer, true); + SetIndexBuffer(emaBufferIndex, emaBuffer, INDICATOR_DATA); + PlotIndexSetInteger(emaBufferIndex, PLOT_SHOW_DATA, showEMA); + + // + // Color Buffer ... + ArraySetAsSeries(emaColorBuffer, true); + SetIndexBuffer(emaColorBufferIndex, emaColorBuffer, INDICATOR_COLOR_INDEX); + + // + // EMA of EMA ... + + // + // Buffer ... + ArraySetAsSeries(emaOfEMABuffer, true); + SetIndexBuffer(emaOfEMABufferIndex, emaOfEMABuffer, INDICATOR_DATA); + PlotIndexSetInteger(emaOfEMABufferIndex, PLOT_SHOW_DATA, showEMAOfEMA); + + // + // Color Buffer ... + ArraySetAsSeries(emaOfEMAColorBuffer, true); + SetIndexBuffer(emaOfEMAColorBufferIndex, emaOfEMAColorBuffer, INDICATOR_COLOR_INDEX); +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xdsr.ex5 b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xdsr.ex5 new file mode 100644 index 0000000..6267385 Binary files /dev/null and b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xdsr.ex5 differ diff --git a/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xdsr.mq5 b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xdsr.mq5 new file mode 100644 index 0000000..dbae73a --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xdsr.mq5 @@ -0,0 +1,964 @@ +/////////////////////////////////////////////////////// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------- +// Name: XDSR +// Description: Dynamic Support and Resistances ... +// +// 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 XDSR Indicator" +#property strict + +// +#define ShortName "XDSR" + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// INPUT ... + +// +// Maarket ... +input group "Cycles"; + +// +// Short ... +input group "Short"; +input ENUM_X_PERIOD_METHOD scMode = X_PERIOD_MANUALLY; // Method +input ENUM_TIMEFRAMES scPeriod = PERIOD_H4; // Period + +// +// Medium ... +input group "Medium"; +input ENUM_X_PERIOD_METHOD mcMode = X_PERIOD_MANUALLY; // Method +input ENUM_TIMEFRAMES mcPeriod = PERIOD_H12; // Mid Period + +// +// Long ... +input group "Long"; +input ENUM_X_PERIOD_METHOD lcMode = X_PERIOD_MANUALLY; // Method +input ENUM_TIMEFRAMES lcPeriod = PERIOD_D1; // Long Period + +// +// Hind ... +input group "Hind"; +input ENUM_X_PERIOD_METHOD hcMode = X_PERIOD_MANUALLY; // Method +input ENUM_TIMEFRAMES hcPeriod = PERIOD_W1; // Hind Period + +// +// BUFFERS ... + +// +#property indicator_chart_window + +// +#property indicator_buffers 24 +#property indicator_plots 24 + +// +// Short ... + +// +// Open ... + +// +#define scOpenBufferIndex 0 +#define scOpenBufferPlotIndex 0 +double scOpenBuffer[]; + +// +#define scOpenColorBufferIndex 1 +double scOpenColorBuffer[]; + +// +#property indicator_label1 "X121_XDSR SC O" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrGreen, clrRed +#property indicator_width1 1 + +// +// High ... +#define scHighBufferIndex 2 +#define scHighBufferPlotIndex 1 +double scHighBuffer[]; + +// +#property indicator_label2 "X121_XDSR SC H" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrAqua +#property indicator_width2 1 + +// +// Close ... + +// +#define scCloseBufferIndex 3 +#define scCloseBufferPlotIndex 2 +double scCloseBuffer[]; + +// +#define scCloseColorBufferIndex 4 +double scCloseColorBuffer[]; + +// +#property indicator_label3 "X121_XDSR SC C" +#property indicator_type3 DRAW_COLOR_LINE +#property indicator_color3 clrGreen, clrRed +#property indicator_width3 1 + +// +// Low ... +#define scLowBufferIndex 5 +#define scLowBufferPlotIndex 3 +double scLowBuffer[]; + +// +#property indicator_label4 "X121_XDSR SC L" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrMagenta +#property indicator_width4 1 + +// +// Medium ... + +// +// Open ... + +// +#define mcOpenBufferIndex 6 +#define mcOpenBufferPlotIndex 4 +double mcOpenBuffer[]; + +// +#define mcOpenColorBufferIndex 7 +double mcOpenColorBuffer[]; + +// +#property indicator_label5 "X121_XDSR MC O" +#property indicator_type5 DRAW_COLOR_LINE +#property indicator_color5 clrGreen, clrRed +#property indicator_width5 1 + +// +// High ... +#define mcHighBufferIndex 8 +#define mcHighBufferPlotIndex 5 +double mcHighBuffer[]; + +// +#property indicator_label6 "X121_XDSR MC H" +#property indicator_type6 DRAW_LINE +#property indicator_color6 clrAqua +#property indicator_width6 1 + +// +// Close ... + +// +#define mcCloseBufferIndex 9 +#define mcCloseBufferPlotIndex 6 +double mcCloseBuffer[]; + +// +#define mcCloseColorBufferIndex 10 +double mcCloseColorBuffer[]; + +// +#property indicator_label7 "X121_XDSR MC C" +#property indicator_type7 DRAW_COLOR_LINE +#property indicator_color7 clrGreen, clrRed +#property indicator_width7 1 + +// +// Low ... +#define mcLowBufferIndex 11 +#define mcLowBufferPlotIndex 7 +double mcLowBuffer[]; + +// +#property indicator_label8 "X121_XDSR MC L" +#property indicator_type8 DRAW_LINE +#property indicator_color8 clrMagenta +#property indicator_width8 1 + +// +// Long ... + +// +// Open ... + +// +#define lcOpenBufferIndex 12 +#define lcOpenBufferPlotIndex 8 +double lcOpenBuffer[]; + +// +#define lcOpenColorBufferIndex 13 +double lcOpenColorBuffer[]; + +// +#property indicator_label9 "X121_XDSR LC O" +#property indicator_type9 DRAW_COLOR_LINE +#property indicator_color9 clrGreen, clrRed +#property indicator_width9 1 + +// +// High ... +#define lcHighBufferIndex 14 +#define lcHighBufferPlotIndex 9 +double lcHighBuffer[]; + +// +#property indicator_label10 "X121_XDSR LC H" +#property indicator_type10 DRAW_LINE +#property indicator_color10 clrAqua +#property indicator_width10 1 + +// +// Close ... + +// +#define lcCloseBufferIndex 15 +#define lcCloseBufferPlotIndex 10 +double lcCloseBuffer[]; + +// +#define lcCloseColorBufferIndex 16 +double lcCloseColorBuffer[]; + +// +#property indicator_label11 "X121_XDSR LC C" +#property indicator_type11 DRAW_COLOR_LINE +#property indicator_color11 clrGreen, clrRed +#property indicator_width11 1 + +// +// Low ... +#define lcLowBufferIndex 17 +#define lcLowBufferPlotIndex 11 +double lcLowBuffer[]; + +// +#property indicator_label12 "X121_XDSR LC L" +#property indicator_type12 DRAW_LINE +#property indicator_color12 clrMagenta +#property indicator_width12 1 + +// +// Hind ... + +// +// Open ... + +// +#define hcOpenBufferIndex 18 +#define hcOpenBufferPlotIndex 12 +double hcOpenBuffer[]; + +// +#define hcOpenColorBufferIndex 19 +double hcOpenColorBuffer[]; + +// +#property indicator_label13 "X121_XDSR HC O" +#property indicator_type13 DRAW_COLOR_LINE +#property indicator_color13 clrGreen, clrRed +#property indicator_width13 1 + +// +// High ... +#define hcHighBufferIndex 20 +#define hcHighBufferPlotIndex 13 +double hcHighBuffer[]; + +// +#property indicator_label14 "X121_XDSR HC H" +#property indicator_type14 DRAW_LINE +#property indicator_color14 clrAqua +#property indicator_width14 1 + +// +// Close ... + +// +#define hcCloseBufferIndex 21 +#define hcCloseBufferPlotIndex 14 +double hcCloseBuffer[]; + +// +#define hcCloseColorBufferIndex 22 +double hcCloseColorBuffer[]; + +// +#property indicator_label15 "X121_XDSR HC C" +#property indicator_type15 DRAW_COLOR_LINE +#property indicator_color15 clrGreen, clrRed +#property indicator_width15 1 + +// +// Low ... +#define hcLowBufferIndex 23 +#define hcLowBufferPlotIndex 15 +double hcLowBuffer[]; + +// +#property indicator_label16 "X121_XDSR HC L" +#property indicator_type16 DRAW_LINE +#property indicator_color16 clrMagenta +#property indicator_width16 1 + +// +// VARIABLES ... + +// +// Cycles Definitions ... +XMarketCycle sc; +XMarketCycle mc; +XMarketCycle lc; +XMarketCycle hc; + +// +// EVENT Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Initial Market Cycles ... + if (!InitMarketCycles()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +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 +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + 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); + + // + // this counts Available Bars ... + int limit; + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) + ? rates_total - 1 + : (rates_total - prev_calculated); + + // + // Main Loop ... + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + // Calculate Buffers ... + CalculateBuffer(i); + } + + // + return rates_total; +} + +// +// CUSTOM Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + result = + // + // Short ... + IsValidCycle( + scMode, + scPeriod) + // + && + // + // Medium ... + IsValidCycle( + mcMode, + mcPeriod) + // + && + // + // Long ... + IsValidCycle( + lcMode, + lcPeriod) + // + && + // + // Hind ... + IsValidCycle( + hcMode, + hcPeriod) + // + ; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Short ... + + // + // High ... + + // + ArraySetAsSeries(scHighBuffer, true); + SetIndexBuffer(scHighBufferIndex, scHighBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(scHighBufferPlotIndex, PLOT_SHOW_DATA, true); + PlotIndexSetInteger(scHighBufferPlotIndex, PLOT_DRAW_BEGIN, 0); + PlotIndexSetDouble(scHighBufferPlotIndex, PLOT_EMPTY_VALUE, 0); + + // + // Low ... + + // + ArraySetAsSeries(scLowBuffer, true); + SetIndexBuffer(scLowBufferIndex, scLowBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(scLowBufferPlotIndex, PLOT_SHOW_DATA, true); + PlotIndexSetInteger(scLowBufferPlotIndex, PLOT_DRAW_BEGIN, 0); + PlotIndexSetDouble(scLowBufferPlotIndex, PLOT_EMPTY_VALUE, 0); + + // + // Open ... + + // + ArraySetAsSeries(scOpenBuffer, true); + SetIndexBuffer(scOpenBufferIndex, scOpenBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(scOpenBufferPlotIndex, PLOT_SHOW_DATA, true); + PlotIndexSetInteger(scOpenBufferPlotIndex, PLOT_DRAW_BEGIN, 0); + PlotIndexSetDouble(scOpenBufferPlotIndex, PLOT_EMPTY_VALUE, 0); + + // + ArraySetAsSeries(scOpenColorBuffer, true); + SetIndexBuffer(scOpenColorBufferIndex, scOpenColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Close ... + + ArraySetAsSeries(scCloseBuffer, true); + SetIndexBuffer(scCloseBufferIndex, scCloseBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(scCloseBufferPlotIndex, PLOT_SHOW_DATA, true); + PlotIndexSetInteger(scCloseBufferPlotIndex, PLOT_DRAW_BEGIN, 0); + PlotIndexSetDouble(scCloseBufferPlotIndex, PLOT_EMPTY_VALUE, 0); + + // + ArraySetAsSeries(scCloseColorBuffer, true); + SetIndexBuffer(scCloseColorBufferIndex, scCloseColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Medium ... + + // + // High ... + + // + ArraySetAsSeries(mcHighBuffer, true); + SetIndexBuffer(mcHighBufferIndex, mcHighBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mcHighBufferPlotIndex, PLOT_SHOW_DATA, true); + PlotIndexSetInteger(mcHighBufferPlotIndex, PLOT_DRAW_BEGIN, 0); + PlotIndexSetDouble(mcHighBufferPlotIndex, PLOT_EMPTY_VALUE, 0); + + // + // Low ... + + // + ArraySetAsSeries(mcLowBuffer, true); + SetIndexBuffer(mcLowBufferIndex, mcLowBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mcLowBufferPlotIndex, PLOT_SHOW_DATA, true); + PlotIndexSetInteger(mcLowBufferPlotIndex, PLOT_DRAW_BEGIN, 0); + PlotIndexSetDouble(mcLowBufferPlotIndex, PLOT_EMPTY_VALUE, 0); + + // + // Open ... + + // + ArraySetAsSeries(mcOpenBuffer, true); + SetIndexBuffer(mcOpenBufferIndex, mcOpenBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mcOpenBufferPlotIndex, PLOT_SHOW_DATA, true); + PlotIndexSetInteger(mcOpenBufferPlotIndex, PLOT_DRAW_BEGIN, 0); + PlotIndexSetDouble(mcOpenBufferPlotIndex, PLOT_EMPTY_VALUE, 0); + + // + ArraySetAsSeries(mcOpenColorBuffer, true); + SetIndexBuffer(mcOpenColorBufferIndex, mcOpenColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Close ... + + ArraySetAsSeries(mcCloseBuffer, true); + SetIndexBuffer(mcCloseBufferIndex, mcCloseBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mcCloseBufferPlotIndex, PLOT_SHOW_DATA, true); + PlotIndexSetInteger(mcCloseBufferPlotIndex, PLOT_DRAW_BEGIN, 0); + PlotIndexSetDouble(mcCloseBufferPlotIndex, PLOT_EMPTY_VALUE, 0); + + // + ArraySetAsSeries(mcCloseColorBuffer, true); + SetIndexBuffer(mcCloseColorBufferIndex, mcCloseColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Long ... + + // + // High ... + + // + ArraySetAsSeries(lcHighBuffer, true); + SetIndexBuffer(lcHighBufferIndex, lcHighBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(lcHighBufferPlotIndex, PLOT_SHOW_DATA, true); + PlotIndexSetInteger(lcHighBufferPlotIndex, PLOT_DRAW_BEGIN, 0); + PlotIndexSetDouble(lcHighBufferPlotIndex, PLOT_EMPTY_VALUE, 0); + + // + // Low ... + + // + ArraySetAsSeries(lcLowBuffer, true); + SetIndexBuffer(lcLowBufferIndex, lcLowBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(lcLowBufferPlotIndex, PLOT_SHOW_DATA, true); + PlotIndexSetInteger(lcLowBufferPlotIndex, PLOT_DRAW_BEGIN, 0); + PlotIndexSetDouble(lcLowBufferPlotIndex, PLOT_EMPTY_VALUE, 0); + + // + // Open ... + + // + ArraySetAsSeries(lcOpenBuffer, true); + SetIndexBuffer(lcOpenBufferIndex, lcOpenBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(lcOpenBufferPlotIndex, PLOT_SHOW_DATA, true); + PlotIndexSetInteger(lcOpenBufferPlotIndex, PLOT_DRAW_BEGIN, 0); + PlotIndexSetDouble(lcOpenBufferPlotIndex, PLOT_EMPTY_VALUE, 0); + + // + ArraySetAsSeries(lcOpenColorBuffer, true); + SetIndexBuffer(lcOpenColorBufferIndex, lcOpenColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Close ... + + ArraySetAsSeries(lcCloseBuffer, true); + SetIndexBuffer(lcCloseBufferIndex, lcCloseBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(lcCloseBufferPlotIndex, PLOT_SHOW_DATA, true); + PlotIndexSetInteger(lcCloseBufferPlotIndex, PLOT_DRAW_BEGIN, 0); + PlotIndexSetDouble(lcCloseBufferPlotIndex, PLOT_EMPTY_VALUE, 0); + + // + ArraySetAsSeries(lcCloseColorBuffer, true); + SetIndexBuffer(lcCloseColorBufferIndex, lcCloseColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Hind ... + + // + // High ... + + // + ArraySetAsSeries(hcHighBuffer, true); + SetIndexBuffer(hcHighBufferIndex, hcHighBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hcHighBufferPlotIndex, PLOT_SHOW_DATA, true); + PlotIndexSetInteger(hcHighBufferPlotIndex, PLOT_DRAW_BEGIN, 0); + PlotIndexSetDouble(hcHighBufferPlotIndex, PLOT_EMPTY_VALUE, 0); + + // + // Low ... + + // + ArraySetAsSeries(hcLowBuffer, true); + SetIndexBuffer(hcLowBufferIndex, hcLowBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hcLowBufferPlotIndex, PLOT_SHOW_DATA, true); + PlotIndexSetInteger(hcLowBufferPlotIndex, PLOT_DRAW_BEGIN, 0); + PlotIndexSetDouble(hcLowBufferPlotIndex, PLOT_EMPTY_VALUE, 0); + + // + // Open ... + + // + ArraySetAsSeries(hcOpenBuffer, true); + SetIndexBuffer(hcOpenBufferIndex, hcOpenBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hcOpenBufferPlotIndex, PLOT_SHOW_DATA, true); + PlotIndexSetInteger(hcOpenBufferPlotIndex, PLOT_DRAW_BEGIN, 0); + PlotIndexSetDouble(hcOpenBufferPlotIndex, PLOT_EMPTY_VALUE, 0); + + // + ArraySetAsSeries(hcOpenColorBuffer, true); + SetIndexBuffer(hcOpenColorBufferIndex, hcOpenColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Close ... + + ArraySetAsSeries(hcCloseBuffer, true); + SetIndexBuffer(hcCloseBufferIndex, hcCloseBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hcCloseBufferPlotIndex, PLOT_SHOW_DATA, true); + PlotIndexSetInteger(hcCloseBufferPlotIndex, PLOT_DRAW_BEGIN, 0); + PlotIndexSetDouble(hcCloseBufferPlotIndex, PLOT_EMPTY_VALUE, 0); + + // + ArraySetAsSeries(hcCloseColorBuffer, true); + SetIndexBuffer(hcCloseColorBufferIndex, hcCloseColorBuffer, INDICATOR_COLOR_INDEX); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +void CalculateBuffer(const int barIndex) +{ + // + // First Update Market Cycles ... + UpdateMarketCycles(barIndex); + + // + double bullishColorIDX = 0; + double bearishColorIDX = 1; + + // + // Short ... + int scBarIndex = sc.GetBarIndex(barIndex); + XOHCL scBar1 = sc.GetBar(scBarIndex + 1); + + // + bool isSCBar1Bullish = scBar1.open < scBar1.close; + + // + scOpenBuffer[barIndex] = scBar1.open; + scHighBuffer[barIndex] = scBar1.high; + scCloseBuffer[barIndex] = scBar1.close; + scLowBuffer[barIndex] = scBar1.low; + + // + scOpenColorBuffer[barIndex] = + isSCBar1Bullish + ? bullishColorIDX + : bearishColorIDX; + + // + scCloseColorBuffer[barIndex] = + isSCBar1Bullish + ? bullishColorIDX + : bearishColorIDX; + + // + // Medium ... + int mcBarIndex = mc.GetBarIndex(barIndex); + XOHCL mcBar1 = mc.GetBar(mcBarIndex + 1); + + // + bool isMCBar1Bullish = mcBar1.open < mcBar1.close; + + // + mcOpenBuffer[barIndex] = mcBar1.open; + mcHighBuffer[barIndex] = mcBar1.high; + mcCloseBuffer[barIndex] = mcBar1.close; + mcLowBuffer[barIndex] = mcBar1.low; + + // + mcOpenColorBuffer[barIndex] = + isMCBar1Bullish + ? bullishColorIDX + : bearishColorIDX; + + // + mcCloseColorBuffer[barIndex] = + isMCBar1Bullish + ? bullishColorIDX + : bearishColorIDX; + + // + // Long ... + int lcBarIndex = lc.GetBarIndex(barIndex); + XOHCL lcBar1 = lc.GetBar(lcBarIndex + 1); + + // + bool isLCBar1Bullish = lcBar1.open < lcBar1.close; + + // + lcOpenBuffer[barIndex] = lcBar1.open; + lcHighBuffer[barIndex] = lcBar1.high; + lcCloseBuffer[barIndex] = lcBar1.close; + lcLowBuffer[barIndex] = lcBar1.low; + + // + lcOpenColorBuffer[barIndex] = + isLCBar1Bullish + ? bullishColorIDX + : bearishColorIDX; + + // + lcCloseColorBuffer[barIndex] = + isLCBar1Bullish + ? bullishColorIDX + : bearishColorIDX; + + // + // Hind ... + int hcBarIndex = hc.GetBarIndex(barIndex); + XOHCL hcBar1 = hc.GetBar(hcBarIndex + 1); + + // + bool isHCBar1Bullish = hcBar1.open < hcBar1.close; + + // + hcOpenBuffer[barIndex] = hcBar1.open; + hcHighBuffer[barIndex] = hcBar1.high; + hcCloseBuffer[barIndex] = hcBar1.close; + hcLowBuffer[barIndex] = hcBar1.low; + + // + hcOpenColorBuffer[barIndex] = + isHCBar1Bullish + ? bullishColorIDX + : bearishColorIDX; + + // + hcCloseColorBuffer[barIndex] = + isHCBar1Bullish + ? bullishColorIDX + : bearishColorIDX; +} + +// +// TOOLS ... + +// +// Initial Market Cycles ... +bool InitMarketCycles() +{ + // + bool result = false; + + // + // Short ... + sc.method = scMode; + sc.period = scPeriod; + result = sc.Init( + _Symbol, + _Period, + X_MARKET_CYCLE_SHORT); + if (!result) + { + return result; + } + + // + // Medium ... + mc.method = mcMode; + mc.period = mcPeriod; + result = mc.Init( + _Symbol, + _Period, + X_MARKET_CYCLE_MEDIUM); + if (!result) + { + return result; + } + + // + // Long ... + lc.method = lcMode; + lc.period = lcPeriod; + result = lc.Init( + _Symbol, + _Period, + X_MARKET_CYCLE_LONG); + if (!result) + { + return result; + } + + // + // Hind ... + hc.method = hcMode; + hc.period = hcPeriod; + result = hc.Init( + _Symbol, + _Period, + X_MARKET_CYCLE_HIND); + if (!result) + { + return result; + } + + // + return result; +} + +// +// Update Market Cycles ... +bool UpdateMarketCycles(int barIndex) +{ + // + bool result = false; + + // + // Short ... + result = sc.Update(barIndex); + if (!result) + { + return result; + } + + // + // Medium ... + result = mc.Update(barIndex); + if (!result) + { + return result; + } + + // + // Long ... + result = lc.Update(barIndex); + if (!result) + { + return result; + } + + // + // Hind ... + result = hc.Update(barIndex); + if (!result) + { + return result; + } + + // + return result; +} diff --git a/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xich.ex5 b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xich.ex5 new file mode 100644 index 0000000..2c0d33a Binary files /dev/null and b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xich.ex5 differ diff --git a/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xich.mq5 b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xich.mq5 new file mode 100644 index 0000000..724aff6 --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xich.mq5 @@ -0,0 +1,836 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------------- +// Name: X121_XICH +// Description: Ichimoku Kinko Hyo ... +// +// +// 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_XICH Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_XICH" + +// +// Ichimoku Golden Numbers ... +enum ENUM_X_ICHIMOKU_GOLDEN_NUMBERS +{ + X_ICH_BASE = 9, + X_ICH_GOLDEN = 17, + X_ICH_CYCLE = 26, + X_ICH_PERIOD = 35, + X_ICH_STAR = 45, + X_ICH_MED = 52, + X_ICH_LONG = 63, + X_ICH_FULL = 72 +}; + +// +// Ichimoku Lines Calculator Mode ... +enum ENUM_X_ICHIMOKU_CALCULATION_MODE +{ + // + X_XICH_HH_LL_MODE = 1, // Highest High and Lowest Low + X_XICH_HO_LC_MODE = 2, // Highest Open and Lowest Close +}; + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +// ICHIMOKU Kinko Hyo ... + +// +// TENKANSEN ... +input group "Tenkan Sen"; +input int tenkanSenLength = 9; // Length +input ENUM_X_ICHIMOKU_CALCULATION_MODE tenkanSenMode = X_XICH_HH_LL_MODE; // Calculation Mode + +// +// KIJUNSEN ... +input group "Kijun Sen"; +input int kijunSenLength = 26; // Length +input ENUM_X_ICHIMOKU_CALCULATION_MODE kijunSenMode = X_XICH_HH_LL_MODE; // Calculation Mode + +// +// SENKOUSPANB ... +input group "Senkou Span B"; +input int senkouSpanBLength = 52; // Length +input ENUM_X_ICHIMOKU_CALCULATION_MODE senkouSpanBMode = X_XICH_HH_LL_MODE; // Calculation Mode + +// +// CHIKOUSPAN ... +input group "Chikou Span"; +input ENUM_APPLIED_PRICE chikuoSpanAppliedTo = PRICE_CLOSE; // Price Type + +// +input group "Presentation"; +input bool showTenkanSen = true; // Show Tenkan Sen +input bool showKijunSen = true; // Show Kijun Sen +input bool showKijunSenPlus = false; // Show Kijun Sen + +input bool showKijunSenNegative = false; // Show Kijun Sen - +input bool showChikouSpan = true; // Show Chikou Span +input bool showSenkouSpanA = true; // Show Senkou Span A +input bool showSenkouSpanB = true; // Show Senkou Span B +input bool showKumo = true; // Show Kumo +input bool shiftKumo = true; // Shift Kumo to Future + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 15 +#property indicator_plots 8 + +// +// PLOTTED Buffers ... + +// +// ICHIMOKU ... + +// +// TENKANSEN ... + +// +#define tenkanSenBufferIndex 0 +double tenkanSenBuffer[]; + +// +#property indicator_label1 "X121_XICH TK" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrBrown +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +// KIJUNSEN ... + +// +#define kijunSenBufferIndex 1 +double kijunSenBuffer[]; + +// +#property indicator_label2 "X121_XICH KJ" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrDodgerBlue +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +#define kijunSenPlusBufferIndex 2 +double kijunSenPlusBuffer[]; + +// +#property indicator_label3 "X121_XICH KJ+" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrMediumTurquoise +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +#define kijunSenNegativeBufferIndex 3 +double kijunSenNegativeBuffer[]; + +// +#property indicator_label4 "X121_XICH KJ-" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrDarkSeaGreen +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +// CHIKOUSPAN ... + +// +#define chikouSpanBufferIndex 4 +double chikouSpanBuffer[]; + +// +#property indicator_label5 "X121_XICH CS" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrDarkGreen +#property indicator_style5 STYLE_SOLID +#property indicator_width5 1 + +// +#define senkouABufferIndex 5 +double senkouABuffer[]; + +// +#property indicator_label6 "X121_XICH SSA" +#property indicator_type6 DRAW_LINE +#property indicator_color6 clrLightGray +#property indicator_style6 STYLE_DASHDOTDOT +#property indicator_width6 1 + +// +#define senkouBBufferIndex 6 +double senkouBBuffer[]; + +// +#property indicator_label7 "X121_XICH SSB" +#property indicator_type7 DRAW_LINE +#property indicator_color7 clrLightGray +#property indicator_style7 STYLE_DASHDOTDOT +#property indicator_width7 1 + +// +// KUMO ... + +// +// SENKOUSPANA ... + +// +#define senkouSpanABufferIndex 7 +double senkouSpanABuffer[]; + +// +// SENKOUSPANB ... + +// +#define senkouSpanBBufferIndex 8 +double senkouSpanBBuffer[]; + +// +// KUMOCLOUD ... + +// +#define kumoBufferIndex 7 + +// +#property indicator_label8 "X121_XICH Kumo" +#property indicator_type8 DRAW_FILLING +#property indicator_color8 clrAqua, clrMagenta +#property indicator_style8 STYLE_SOLID +#property indicator_width8 1 + +// +// DATA Buffers ... + +// +#define dTenkanBufferIndex 9 +double dTenkanBuffer[]; + +// +#define dKijunBufferIndex 10 +double dKijunBuffer[]; + +// +#define dChikouBufferIndex 11 +double dChikouBuffer[]; + +// +#define dSSABufferIndex 12 +double dSSABuffer[]; + +// +#define dSSBBufferIndex 13 +double dSSBBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; +int mHandler; + +// +ENUM_SERIESMODE mTenkanSenTopMode = NULL; +ENUM_SERIESMODE mTenkanSenBottomMode = NULL; + +// +ENUM_SERIESMODE mKijunSenTopMode = NULL; +ENUM_SERIESMODE mKijunSenBottomMode = NULL; + +// +ENUM_SERIESMODE mSenkouSpanBTopMode = NULL; +ENUM_SERIESMODE mSenkouSpanBBottomMode = NULL; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // 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(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Init Handler ... + mHandler = iIchimoku( + _Symbol, + _Period, + tenkanSenLength, + kijunSenLength, + senkouSpanBLength); + if (mHandler == INVALID_HANDLE) + { + return INIT_FAILED; + } + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +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 + + // + IndicatorRelease(mHandler); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + 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); + + // + // this counts Available Bars ... + int limit; + + // + // Check Calculated Bars ... + int ichCalculatedBars = BarsCalculated(mHandler); + if (ichCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedTenkans = CopyBuffer(mHandler, TENKANSEN_LINE, 0, limit, dTenkanBuffer); + int copiedKijuns = CopyBuffer(mHandler, KIJUNSEN_LINE, 0, limit, dKijunBuffer); + int copiedChikous = CopyBuffer(mHandler, CHIKOUSPAN_LINE, 0, limit, dChikouBuffer); + int copiedSSAs = CopyBuffer(mHandler, SENKOUSPANA_LINE, 0, limit, dSSABuffer); + int copiedSSBs = CopyBuffer(mHandler, SENKOUSPANB_LINE, 0, limit, dSSBBuffer); + if ( + copiedSSAs < 0 || + copiedSSBs < 0 || + copiedKijuns < 0 || + copiedTenkans < 0 || + copiedChikous < 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateBuffers(i); + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + (tenkanSenLength > 2 && + kijunSenLength > tenkanSenLength && + senkouSpanBLength > kijunSenLength) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Ichimoku ... + result = MathMax(result, tenkanSenLength); + result = MathMax(result, kijunSenLength); + result = MathMax(result, senkouSpanBLength); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // ICHIMOKU ... + + // + // TENKANSEN ... + + // + ENUM_DRAW_TYPE tenkanSenDrawType = showTenkanSen ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(tenkanSenBuffer, true); + SetIndexBuffer(tenkanSenBufferIndex, tenkanSenBuffer, INDICATOR_DATA); + PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_SHOW_DATA, showTenkanSen); + PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_DRAW_TYPE, tenkanSenDrawType); + + // + // KIJUNSEN ... + + // + ENUM_DRAW_TYPE kijunSenDrawType = showKijunSen ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(kijunSenBuffer, true); + SetIndexBuffer(kijunSenBufferIndex, kijunSenBuffer, INDICATOR_DATA); + PlotIndexSetInteger(kijunSenBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(kijunSenBufferIndex, PLOT_SHOW_DATA, showKijunSen); + PlotIndexSetInteger(kijunSenBufferIndex, PLOT_DRAW_TYPE, kijunSenDrawType); + + // + // KIJUNSEN Plus ... + + // + ENUM_DRAW_TYPE kijunSenPlusDrawType = showKijunSenPlus ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(kijunSenPlusBuffer, true); + SetIndexBuffer(kijunSenPlusBufferIndex, kijunSenPlusBuffer, INDICATOR_DATA); + PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_SHIFT, kijunSenLength); + PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_DRAW_TYPE, kijunSenPlusDrawType); + + // + // KIJUNSEN Negative ... + + // + ENUM_DRAW_TYPE kijunSenNegativeDrawType = showKijunSenNegative ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(kijunSenNegativeBuffer, true); + SetIndexBuffer(kijunSenNegativeBufferIndex, kijunSenNegativeBuffer, INDICATOR_DATA); + PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_SHIFT, -kijunSenLength); + PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_DRAW_TYPE, kijunSenNegativeDrawType); + + // + // CHIKOUSPAN ... + + // + ENUM_DRAW_TYPE chikouSpanDrawType = showChikouSpan ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(chikouSpanBuffer, true); + SetIndexBuffer(chikouSpanBufferIndex, chikouSpanBuffer, INDICATOR_DATA); + PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_SHIFT, -kijunSenLength); + PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_SHOW_DATA, showChikouSpan); + PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_DRAW_TYPE, chikouSpanDrawType); + + // + // SENKOUSPAN A and B ... + int shiftSize = shiftKumo ? kijunSenLength : 0; + + // + // SENKOUSPANA ... + ENUM_DRAW_TYPE senkouSpanADrawType = showSenkouSpanA ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(senkouABuffer, true); + SetIndexBuffer(senkouABufferIndex, senkouABuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouABufferIndex, PLOT_SHIFT, shiftSize); + PlotIndexSetInteger(senkouABufferIndex, PLOT_SHOW_DATA, showSenkouSpanA); + PlotIndexSetInteger(senkouABufferIndex, PLOT_DRAW_TYPE, senkouSpanADrawType); + + // + // SENKOUSPANB ... + ENUM_DRAW_TYPE senkouSpanBDrawType = showSenkouSpanB ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(senkouBBuffer, true); + SetIndexBuffer(senkouBBufferIndex, senkouBBuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouBBufferIndex, PLOT_SHIFT, shiftSize); + PlotIndexSetInteger(senkouBBufferIndex, PLOT_SHOW_DATA, showSenkouSpanB); + PlotIndexSetInteger(senkouBBufferIndex, PLOT_DRAW_TYPE, senkouSpanBDrawType); + + // + // KUMO ... + + // + // SENKOUSPANA ... + ArraySetAsSeries(senkouSpanABuffer, true); + SetIndexBuffer(senkouSpanABufferIndex, senkouSpanABuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouSpanABufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // SENKOUSPANB ... + ArraySetAsSeries(senkouSpanBBuffer, true); + SetIndexBuffer(senkouSpanBBufferIndex, senkouSpanBBuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouSpanBBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // KUMO ... + + // + ENUM_DRAW_TYPE kumoDrawType = showKumo ? DRAW_FILLING : DRAW_NONE; + + // + PlotIndexSetInteger(kumoBufferIndex, PLOT_SHIFT, shiftSize); + PlotIndexSetInteger(kumoBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(kumoBufferIndex, PLOT_DRAW_TYPE, kumoDrawType); + + // + // DATA Buffers ... + + // + // D Tenkan ... + ArraySetAsSeries(dTenkanBuffer, true); + SetIndexBuffer(dTenkanBufferIndex, dTenkanBuffer, INDICATOR_CALCULATIONS); + + // + // D Kijun ... + ArraySetAsSeries(dKijunBuffer, true); + SetIndexBuffer(dKijunBufferIndex, dKijunBuffer, INDICATOR_CALCULATIONS); + + // + // D Chikou ... + ArraySetAsSeries(dChikouBuffer, true); + SetIndexBuffer(dChikouBufferIndex, dChikouBuffer, INDICATOR_CALCULATIONS); + + // + // D SSA ... + ArraySetAsSeries(dSSABuffer, true); + SetIndexBuffer(dSSABufferIndex, dSSABuffer, INDICATOR_CALCULATIONS); + + // + // D SSB ... + ArraySetAsSeries(dSSBBuffer, true); + SetIndexBuffer(dSSBBufferIndex, dSSBBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // ICHIMOKU ... + + // + double topValue; + double bottomValue; + + // + // TENKANSEN ... + + // + // Extract Tenkan Sen Top/Bottom Calculation Mode based on User Input ... + if (mTenkanSenTopMode == NULL || mTenkanSenBottomMode == NULL) + { + // + switch (tenkanSenMode) + { + // + case X_XICH_HH_LL_MODE: + // + mTenkanSenTopMode = MODE_HIGH; + mTenkanSenBottomMode = MODE_LOW; + break; + + // + case X_XICH_HO_LC_MODE: + // + mTenkanSenTopMode = MODE_OPEN; + mTenkanSenBottomMode = MODE_CLOSE; + break; + } + } + + // + // Calculate Top ... + topValue = GetHighestHigh( + _Symbol, + _Period, + mTenkanSenTopMode, + tenkanSenLength, + bar_index); + + // + // Calculate Bottom ... + bottomValue = GetLowestLow( + _Symbol, + _Period, + mTenkanSenBottomMode, + tenkanSenLength, + bar_index); + + // + double tenkanSenValue = (topValue + bottomValue) / 2; + tenkanSenBuffer[bar_index] = tenkanSenValue; + + // + // KIJUNSEN ... + + // + // Extract Kijun Sen Top/Bottom Calculation Mode based on User Input ... + if (mKijunSenTopMode == NULL || mKijunSenBottomMode == NULL) + { + // + switch (kijunSenMode) + { + // + case X_XICH_HH_LL_MODE: + // + mKijunSenTopMode = MODE_HIGH; + mKijunSenBottomMode = MODE_LOW; + break; + + // + case X_XICH_HO_LC_MODE: + // + mKijunSenTopMode = MODE_OPEN; + mKijunSenBottomMode = MODE_CLOSE; + break; + } + } + + // + // Calculate Top ... + topValue = GetHighestHigh( + _Symbol, + _Period, + mKijunSenTopMode, + kijunSenLength, + bar_index); + + // + // Calculate Bottom ... + bottomValue = GetLowestLow( + _Symbol, + _Period, + mKijunSenBottomMode, + kijunSenLength, + bar_index); + + // + double kijunSenValue = (topValue + bottomValue) / 2; + kijunSenBuffer[bar_index] = kijunSenValue; + + // + kijunSenPlusBuffer[bar_index] = kijunSenValue; + kijunSenNegativeBuffer[bar_index] = kijunSenValue; + + // + // CHIKOUSPAN ... + double chikouSpanValue = GetAppliedPrice( + bar_index, + chikuoSpanAppliedTo); + chikouSpanBuffer[bar_index] = chikouSpanValue; + + // + // KUMO ... + + // + // SENKOUSPANA ... + double senkouSpanAValue = (tenkanSenValue + kijunSenValue) / 2; + senkouABuffer[bar_index] = senkouSpanAValue; + senkouSpanABuffer[bar_index] = senkouSpanAValue; + + // + // SENKOUSPANB ... + + // + // Extract Senkou Span B Top/Bottom Calculation Mode based on User Input ... + if (mSenkouSpanBTopMode == NULL || mSenkouSpanBBottomMode == NULL) + { + // + switch (senkouSpanBMode) + { + // + case X_XICH_HH_LL_MODE: + // + mSenkouSpanBTopMode = MODE_HIGH; + mSenkouSpanBBottomMode = MODE_LOW; + break; + + // + case X_XICH_HO_LC_MODE: + // + mSenkouSpanBTopMode = MODE_OPEN; + mSenkouSpanBBottomMode = MODE_CLOSE; + break; + } + } + + // + // Calculate Top ... + topValue = GetHighestHigh( + _Symbol, + _Period, + mSenkouSpanBTopMode, + senkouSpanBLength, + bar_index); + + // + // Calculate Bottom ... + bottomValue = GetLowestLow( + _Symbol, + _Period, + mSenkouSpanBBottomMode, + senkouSpanBLength, + bar_index); + + // + double senkouSpanBValue = (topValue + bottomValue) / 2; + senkouBBuffer[bar_index] = senkouSpanBValue; + senkouSpanBBuffer[bar_index] = senkouSpanBValue; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xman.ex5 b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xman.ex5 new file mode 100644 index 0000000..6072b99 Binary files /dev/null and b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xman.ex5 differ diff --git a/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xman.mq5 b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xman.mq5 new file mode 100644 index 0000000..67a2484 --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xman.mq5 @@ -0,0 +1,4631 @@ +/////////////////////////////////////////////////////// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------- +// Name: X121_XMAN +// Description: Market Analyzer +// - Find Peaks and Vales +// - Find Trend +// - Find Market Direction +// - Detect Pivot Points and Swings +// +// Contains: +// ----------- +// - 4 Cycle of TimeFrames +// - Fibonacci Golden Zone +// - Trend Detection using True Range Averaging +// - Trend Detecting using Moving Averages Ribbon +// - Trend Detecting using SSL Channel +// - Trend Detecting using Hull Implementation +// +// 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_XMAN Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_XMAN" + +// +struct XHullData +{ + // + double value; + double value3; + + // + double wsum1; + double wsum2; + double wsum3; + + // + double lsum1; + double lsum2; + double lsum3; +}; + +// +// Holds an SnapShot of Charts Configuration ... +struct XChartStyle +{ + // + // chart's ID ... + long chartId; + // + // chart's mode ... + ENUM_CHART_MODE mode; + // + // show bid line ... + bool showBidLine; + // + // show ask line ... + bool showAskLine; + // + // show grids on chart ... + bool showGrid; + // + // show volumes ... + bool showVolumes; + // + // Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders) ... + bool showTradeLevels; + // + // chart autoscroll ... + bool autoScroll; + // + // chart quick navigation state ... + bool quickNavigation; + // + // chart's foreground color ... + color foreGroundColor; + // + // chart's background color ... + color backGroundColor; + // + // Up Color ... + color upColor; + // + // Down Color ... + color downColor; + // + // Bullish color ... + color bullishColor; + // + // Bearish color ... + color bearishColor; + // + // grid color ... + color gridColor; + // + // bid line color ... + color bidLineColor; + // + // ask line color ... + color askLineColor; + // + // line mode and doji candlestick color ... + color lineColor; + // + // Color of stop order levels (Stop Loss and Take Profit) ... + color stopColor; + // + // volumes color ... + color volumesColor; +}; + +// +struct XMRBColorInfo +{ + double clr; + double state; +}; + +// +// a Class For Hull Calculations ... +class XSCHull +{ + // +public: + // + // Constructor ... + XSCHull() : mFullPeriod(1), mHalfPeriod(1), mSqrtPeriod(1), mArraySize(-1) + { + // + // These are a way above to assign Private variables at Construct time ... + } + + // + // Deconstructor ... + ~XSCHull() + { + ArrayFree(mData); + } + + // + // Initial Hull ... + bool Init( + int mPeriod, + double mDivisor) + { + // + bool result = false; + + // + mFullPeriod = (int)(mPeriod > 1 ? mPeriod : 1); + mHalfPeriod = (int)(mFullPeriod > 1 ? mFullPeriod / (mDivisor > 1 ? mDivisor : 1) : 1); + mSqrtPeriod = (int)MathSqrt(mFullPeriod); + + // + mArraySize = -1; + mWeight1 = mWeight2 = mWeight3 = 1; + + // + result = true; + + // + return result; + } + + // + // CalCulate Specific Value ... + double Calculate( + double value, + int i, + int bars) + { + // + double result = 0; + + // + if (mArraySize < bars) + { + // + mArraySize = ArrayResize(mData, bars + 500); + if (mArraySize < bars) + return result; + } + + // + mData[i].value = value; + if (i > mFullPeriod) + { + // + mData[i].wsum1 = mData[i - 1].wsum1 + value * mHalfPeriod - mData[i - 1].lsum1; + mData[i].lsum1 = mData[i - 1].lsum1 + value - mData[i - mHalfPeriod].value; + mData[i].wsum2 = mData[i - 1].wsum2 + value * mFullPeriod - mData[i - 1].lsum2; + mData[i].lsum2 = mData[i - 1].lsum2 + value - mData[i - mFullPeriod].value; + } + else + { + // + mData[i].wsum1 = mData[i].wsum2 = + mData[i].lsum1 = mData[i].lsum2 = mWeight1 = mWeight2 = 0; + for (int k = 0, w1 = mHalfPeriod, w2 = mFullPeriod; w2 > 0 && i >= k; k++, w1--, w2--) + { + // + if (w1 > 0) + { + // + mData[i].wsum1 += mData[i - k].value * w1; + mData[i].lsum1 += mData[i - k].value; + mWeight1 += w1; + } + + // + mData[i].wsum2 += mData[i - k].value * w2; + mData[i].lsum2 += mData[i - k].value; + mWeight2 += w2; + } + } + + // + mData[i].value3 = 2.0 * mData[i].wsum1 / mWeight1 - mData[i].wsum2 / mWeight2; + + // + if (i > mSqrtPeriod) + { + // + mData[i].wsum3 = mData[i - 1].wsum3 + mData[i].value3 * mSqrtPeriod - mData[i - 1].lsum3; + mData[i].lsum3 = mData[i - 1].lsum3 + mData[i].value3 - mData[i - mSqrtPeriod].value3; + } + else + { + // + mData[i].wsum3 = + mData[i].lsum3 = mWeight3 = 0; + + // + for (int k = 0, w3 = mSqrtPeriod; w3 > 0 && i >= k; k++, w3--) + { + // + mData[i].wsum3 += mData[i - k].value3 * w3; + mData[i].lsum3 += mData[i - k].value3; + mWeight3 += w3; + } + } + + // + result = mData[i].wsum3 / mWeight3; + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + int mFullPeriod; + int mHalfPeriod; + int mSqrtPeriod; + int mArraySize; + double mWeight1; + double mWeight2; + double mWeight3; + + // + XHullData mData[]; +}; + +// +#include +#include "../Libraries/x-saherelm.xman.parser.lib.mq5" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Candle Timer"; +input string cTimerConfig = "candleTimerColor(clrGold)candleTimerCorner(2)"; // Config + +// +input group "Chart Style"; +input string cStyleConfig = "upColor(clrLime) downColor(clrRed) lineColor(clrLime) bearishColor(clrRed) bullishColor(clrLime) volumesColor(clrGreen) chartMode(1)"; // Config + +// +input group "Makret Cycles"; +input group "Short"; +input string scConfig = "l1Method(1)l1Period(NULL)"; // Config +input group "Medium"; +input string mcConfig = "l2Method(1)l2Period(NULL)"; // Config +input group "Long"; +input string lcConfig = "l3Method(1)l3Period(NULL)"; // Config +input group "Hind"; +input string hcConfig = "l4Method(1)l4Period(NULL)"; // Config + +// +input group "Fibonacci"; +input string fibConfig = "fiboLevel1(0.236)fiboLevel2(0.382)fiboLevel3(0.5)fiboLevel4(0.618)fiboLevel5(0.764)"; // Config + +// +input group "Boundary Detection Modes"; +input string bdConfig = "hhMode(2)llMode(1)"; // Config + +// +input group "Trend Detection"; +input string tdConfig = "trendMultiplier(3)trendPriceAppliedTo(4)"; // Config + +// +input group "Ribbon Detection"; +input string rbConfig = "ribbonMode(5)"; // Config + +// +input group "Hull Trend Detection"; +input string hullConfig = "hullDivisor(2.0)hullUpAppliedTo(3)hullDownAppliedTo(4)"; // Config + +// +input group "SSL Channel"; +input string sslcConfig = "sslcMode(1)sslcUpAppliedTo(3)sslcDownAppliedTo(4)"; // Config + +// +input group "Presentation"; +input string stylePRSConfig = "showCandleTimer(true)showCandles(true)showHKCandles(false)showSMHKCandles(false)"; // Styles +input string pvPRSConfig = "showPeaksAndVales(true)showLevels(false)showConsolidations(false)"; // Peaks and Vales +input string trendPRSConfig = "showHull(false)showTrends(false)fillTrends(false)showRibbons(false)showSSLChannel(false)"; // Trend +input string fiboPRSConfig = "showFibo1Levels(false)showFibo2Levels(false)showFibo3Levels(false)showFibo4Levels(false)showFibo5Levels(false)"; // Fibonacci + +// +// END Inputs ... +// + +// +// START Configs ... +// + +// +// Candles Timer ... +color candleTimerColor = clrGold; // Text Color +ENUM_BASE_CORNER candleTimerCorner = CORNER_RIGHT_UPPER; // Text Position + +// +// Chart Style +color upColor = clrLime; // Up Color +color downColor = clrRed; // Down Color +color lineColor = clrLime; // Line mode and Doji candlestick Color +color bearishColor = clrRed; // Bullish Color +color bullishColor = clrLime; // Bearish Color +color volumesColor = clrGreen; // Volumes Color +ENUM_CHART_MODE chartMode = CHART_CANDLES; // Chart Mode + +// +// Makret Cycles + +// +// Level 1 ... +ENUM_X_PERIOD_METHOD l1Method = X_PERIOD_AUTO; // How to Find Period +ENUM_TIMEFRAMES l1Period = NULL; // Time Period + +// +// Level 2 ... +ENUM_X_PERIOD_METHOD l2Method = X_PERIOD_AUTO; // How to Find Period +ENUM_TIMEFRAMES l2Period = NULL; // Time Period + +// +// Level 3 ... +ENUM_X_PERIOD_METHOD l3Method = X_PERIOD_AUTO; // How to Find Period +ENUM_TIMEFRAMES l3Period = NULL; // Time Period + +// +// Level 4 ... +ENUM_X_PERIOD_METHOD l4Method = X_PERIOD_AUTO; // How to Find Period +ENUM_TIMEFRAMES l4Period = NULL; // Time Period + +// +// Fibonacci ... +double fiboLevel1 = 0.236; // Fibio 1st Level +double fiboLevel2 = 0.382; // Fibio 2st Level +double fiboLevel3 = 0.5; // Fibio 3rd Level +double fiboLevel4 = 0.618; // Fibio 4th Level +double fiboLevel5 = 0.764; // Fibio 5th Level + +// +// Boundary Detection Modes ... +ENUM_SERIESMODE hhMode = MODE_HIGH; // Highest High Calculation Method +ENUM_SERIESMODE llMode = MODE_LOW; // Lowest Low Calculation Method + +// +// Trend Detection ... +double trendMultiplier = 3.5; // Multiplier +ENUM_APPLIED_PRICE trendPriceAppliedTo = PRICE_MEDIAN; // Applied To + +// +// Ribbon Detection ... +ENUM_X_MA_METHOD ribbonMode = X_MA_AMA; // How to Calculate + +// +// Hull Trend Detection ... +double hullDivisor = 2.0; // Divisor (Speed) +ENUM_APPLIED_PRICE hullUpAppliedTo = PRICE_HIGH; // Up Zone Applied to +ENUM_APPLIED_PRICE hullDownAppliedTo = PRICE_LOW; // Down Zone Applied to + +// +// SSL Channel Detection ... +ENUM_X_MA_METHOD sslcMode = X_MA_SMA; // How to Calculate +ENUM_APPLIED_PRICE sslcUpAppliedTo = PRICE_HIGH; // Up Applied To +ENUM_APPLIED_PRICE sslcDownAppliedTo = PRICE_LOW; // Down Applied To + +// +// Presentation ... +bool showCandleTimer = true; // Show Candle Time +bool showCandles = true; // Show Candles +bool showHKCandles = false; // Draw Hiken Ashi Candle +bool showSMHKCandles = false; // Draw Smoothed Hiken Ashi Candle +bool showPeaksAndVales = true; // Show Peaks and Vales +bool showTrends = true; // Show Trends +bool fillTrends = false; // Fill Trends +bool showLevels = false; // Show Levels +bool showConsolidations = false; // Show Consolidations +bool showRibbons = false; // Show Ribbons +bool showHull = false; // Show Hull +bool showSSLChannel = false; // Show SSL Channel +bool showFibo1Levels = false; // Show Fibo 1st Level +bool showFibo2Levels = false; // Show Fibo 2nd Level +bool showFibo3Levels = false; // Show Fibo 3rd Level +bool showFibo4Levels = false; // Show Fibo 4th Level +bool showFibo5Levels = false; // Show Fibo 5th Level + +// +// END Configs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 94 +#property indicator_plots 50 + +// +// PEKSANDVALES ... + +// +// PEAKS ... + +// +#define peaksBufferIndex 0 +double peaksBuffer[]; + +// +#property indicator_label1 "X121_XMAN PEAKS" +#property indicator_type1 DRAW_ARROW +#property indicator_color1 clrAqua +#property indicator_width1 1 + +// +// VALES ... + +// +#define valesBufferIndex 1 +double valesBuffer[]; + +// +#property indicator_label2 "X121_XMAN VALES" +#property indicator_type2 DRAW_ARROW +#property indicator_color2 clrMagenta +#property indicator_width2 1 + +// +#define rBufferIndex 2 +double rBuffer[]; + +// +#define rColorBufferIndex 3 +double rColorBuffer[]; + +// +#property indicator_label3 "X121_XMAN R" +#property indicator_type3 DRAW_COLOR_LINE +#property indicator_color3 CLR_NONE, clrAqua +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +#define sBufferIndex 4 +#define sBufferPlotIndex 3 +double sBuffer[]; + +// +#define sColorBufferIndex 5 +double sColorBuffer[]; + +// +#property indicator_label4 "X121_XMAN S" +#property indicator_type4 DRAW_COLOR_LINE +#property indicator_color4 CLR_NONE, clrMagenta +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +// FIBBO Level 1 ... + +// +#define fl1BufferIndex 6 +#define fl1BufferPlotIndex 4 +double fl1Buffer[]; + +// +#define fl1ColorBufferIndex 7 +double fl1ColorBuffer[]; + +// +#property indicator_label5 "X121_XMAN FL1" +#property indicator_type5 DRAW_COLOR_LINE +#property indicator_color5 CLR_NONE, clrGold +#property indicator_style5 STYLE_DASHDOTDOT +#property indicator_width5 1 + +// +// FIBBO Level 2 ... + +// +#define fl2BufferIndex 8 +#define fl2BufferPlotIndex 5 +double fl2Buffer[]; + +// +#define fl2ColorBufferIndex 9 +double fl2ColorBuffer[]; + +// +#property indicator_label6 "X121_XMAN FL2" +#property indicator_type6 DRAW_COLOR_LINE +#property indicator_color6 CLR_NONE, clrGold +#property indicator_style6 STYLE_DASHDOTDOT +#property indicator_width6 1 + +// +// FIBBO Level 3 ... + +// +#define fl3BufferIndex 10 +#define fl3BufferPlotIndex 6 +double fl3Buffer[]; + +// +#define fl3ColorBufferIndex 11 +double fl3ColorBuffer[]; + +// +#property indicator_label7 "X121_XMAN FL3" +#property indicator_type7 DRAW_COLOR_LINE +#property indicator_color7 CLR_NONE, clrGold +#property indicator_style7 STYLE_DASHDOTDOT +#property indicator_width7 1 + +// +// FIBBO Level 4 ... + +// +#define fl4BufferIndex 12 +#define fl4BufferPlotIndex 7 +double fl4Buffer[]; + +// +#define fl4ColorBufferIndex 13 +double fl4ColorBuffer[]; + +// +#property indicator_label8 "X121_XMAN FL4" +#property indicator_type8 DRAW_COLOR_LINE +#property indicator_color8 CLR_NONE, clrGold +#property indicator_style8 STYLE_DASHDOTDOT +#property indicator_width8 1 + +// +// FIBBO Level 5 ... + +// +#define fl5BufferIndex 14 +#define fl5BufferPlotIndex 8 +double fl5Buffer[]; + +// +#define fl5ColorBufferIndex 15 +double fl5ColorBuffer[]; + +// +#property indicator_label9 "X121_XMAN FL5" +#property indicator_type9 DRAW_COLOR_LINE +#property indicator_color9 CLR_NONE, clrGold +#property indicator_style9 STYLE_DASHDOTDOT +#property indicator_width9 1 + +// +// LEVELS ... + +// +#define sHHBufferIndex 16 +#define sHHBufferPlotIndex 9 +double sHHBuffer[]; + +// +#define sHHColorBufferIndex 17 +double sHHColorBuffer[]; + +// +#property indicator_label10 "X121_XMAN SHH" +#property indicator_type10 DRAW_COLOR_LINE +#property indicator_color10 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style10 STYLE_DOT +#property indicator_width10 1 + +#define sLLBufferIndex 18 +#define sLLBufferPlotIndex 10 +double sLLBuffer[]; + +// +#define sLLColorBufferIndex 19 +double sLLColorBuffer[]; + +// +#property indicator_label11 "X121_XMAN SLL" +#property indicator_type11 DRAW_COLOR_LINE +#property indicator_color11 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style11 STYLE_DOT +#property indicator_width11 1 + +// +#define mHHBufferIndex 20 +#define mHHBufferPlotIndex 11 +double mHHBuffer[]; + +// +#define mHHColorBufferIndex 21 +double mHHColorBuffer[]; + +// +#property indicator_label12 "X121_XMAN MHH" +#property indicator_type12 DRAW_COLOR_LINE +#property indicator_color12 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style12 STYLE_DOT +#property indicator_width12 1 + +// +#define mLLBufferIndex 22 +#define mLLBufferPlotIndex 12 +double mLLBuffer[]; + +// +#define mLLColorBufferIndex 23 +double mLLColorBuffer[]; + +// +#property indicator_label13 "X121_XMAN MLL" +#property indicator_type13 DRAW_COLOR_LINE +#property indicator_color13 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style13 STYLE_DOT +#property indicator_width13 1 + +// +#define lHHBufferIndex 24 +#define lHHBufferPlotIndex 13 +double lHHBuffer[]; + +// +#define lHHColorBufferIndex 25 +double lHHColorBuffer[]; + +// +#property indicator_label14 "X121_XMAN LHH" +#property indicator_type14 DRAW_COLOR_LINE +#property indicator_color14 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style14 STYLE_DOT +#property indicator_width14 1 + +// +#define lLLBufferIndex 26 +#define lLLBufferPlotIndex 14 +double lLLBuffer[]; + +// +#define lLLColorBufferIndex 27 +double lLLColorBuffer[]; + +// +#property indicator_label15 "X121_XMAN LLL" +#property indicator_type15 DRAW_COLOR_LINE +#property indicator_color15 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style15 STYLE_DOT +#property indicator_width15 1 + +// +#define hHHBufferIndex 28 +#define hHHBufferPlotIndex 15 +double hHHBuffer[]; + +// +#define hHHColorBufferIndex 29 +double hHHColorBuffer[]; + +// +#property indicator_label16 "X121_XMAN HHH" +#property indicator_type16 DRAW_COLOR_LINE +#property indicator_color16 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style16 STYLE_DOT +#property indicator_width16 1 + +// +#define hLLBufferIndex 30 +#define hLLBufferPlotIndex 16 +double hLLBuffer[]; + +// +#define hLLColorBufferIndex 31 +double hLLColorBuffer[]; + +// +#property indicator_label17 "X121_XMAN HLL" +#property indicator_type17 DRAW_COLOR_LINE +#property indicator_color17 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style17 STYLE_DOT +#property indicator_width17 1 + +// +// XSTR Buffers ... + +// +#define fillUpBufferIndex 32 +double fillUpBuffer[]; + +#define fillDownBufferIndex 33 +double fillDownBuffer[]; + +// +#define fillingBufferPlotIndex 17 + +// +#property indicator_label18 "X121_XMAN TRND Filling" +#property indicator_type18 DRAW_FILLING +#property indicator_color18 clrBisque, clrPaleGreen + +// +#define trendBufferIndex 34 +#define trendBufferPlotIndex 18 +double trendBuffer[]; + +// +#define trendColorBufferIndex 35 +double trendColorBuffer[]; + +// +#property indicator_label19 "X121_XMAN TRND" +#property indicator_type19 DRAW_COLOR_LINE +#property indicator_color19 CLR_NONE, clrGreen, clrDarkRed +#property indicator_style19 STYLE_DOT +#property indicator_width19 1 + +// +// XMRB ... + +// +// RIBBON 1 ... +// High ... + +// +#define ribbon1BufferIndex 36 +#define ribbon1BufferPlotIndex 19 +double ribbon1Buffer[]; + +// +#define ribbon1ColorBufferIndex 37 +double ribbon1ColorBuffer[]; + +// +#property indicator_label20 "X121_XMAN RB 1" +#property indicator_type20 DRAW_COLOR_LINE +#property indicator_color20 CLR_NONE, clrGray, clrGreen, clrDarkRed +#property indicator_style20 STYLE_DASH +#property indicator_width20 1 + +// +// RIBBON 2 ... +// Open ... + +// +#define ribbon2BufferIndex 38 +#define ribbon2BufferPlotIndex 20 +double ribbon2Buffer[]; + +// +#define ribbon2ColorBufferIndex 39 +double ribbon2ColorBuffer[]; + +// +#property indicator_label21 "X121_XMAN RB 2" +#property indicator_type21 DRAW_COLOR_LINE +#property indicator_color21 CLR_NONE, clrGray, clrGreen, clrDarkRed +#property indicator_style21 STYLE_DASH +#property indicator_width21 1 + +// +// RIBBON 3 ... +// Close ... + +// +#define ribbon3BufferIndex 40 +#define ribbon3BufferPlotIndex 21 +double ribbon3Buffer[]; + +// +#define ribbon3ColorBufferIndex 41 +double ribbon3ColorBuffer[]; + +// +#property indicator_label22 "X121_XMAN RB 3" +#property indicator_type22 DRAW_COLOR_LINE +#property indicator_color22 CLR_NONE, clrGray, clrGreen, clrDarkRed +#property indicator_style22 STYLE_DASH +#property indicator_width22 1 + +// +// RIBBON 4 ... +// Median ... + +// +#define ribbon4BufferIndex 42 +#define ribbon4BufferPlotIndex 22 +double ribbon4Buffer[]; + +// +#define ribbon4ColorBufferIndex 43 +double ribbon4ColorBuffer[]; + +// +#property indicator_label23 "X121_XMAN RB 4" +#property indicator_type23 DRAW_COLOR_LINE +#property indicator_color23 CLR_NONE, clrGray, clrGreen, clrDarkRed +#property indicator_style23 STYLE_DASH +#property indicator_width23 1 + +// +// RIBBON 5 ... +// Typical ... + +// +#define ribbon5BufferIndex 44 +#define ribbon5BufferPlotIndex 23 +double ribbon5Buffer[]; + +// +#define ribbon5ColorBufferIndex 45 +double ribbon5ColorBuffer[]; + +// +#property indicator_label24 "X121_XMAN RB 5" +#property indicator_type24 DRAW_COLOR_LINE +#property indicator_color24 CLR_NONE, clrGray, clrGreen, clrDarkRed +#property indicator_style24 STYLE_DASH +#property indicator_width24 1 + +// +// RIBBON 6 ... +// Low ... + +// +#define ribbon6BufferIndex 46 +#define ribbon6BufferPlotIndex 24 +double ribbon6Buffer[]; + +// +#define ribbon6ColorBufferIndex 47 +double ribbon6ColorBuffer[]; + +// +#property indicator_label25 "X121_XMAN RB 6" +#property indicator_type25 DRAW_COLOR_LINE +#property indicator_color25 CLR_NONE, clrGray, clrGreen, clrDarkRed +#property indicator_style25 STYLE_DASH +#property indicator_width25 1 + +// +// XSSLC ... + +// +#define sslcUpBufferIndex 48 +#define sslcUpBufferPlotIndex 25 +double sslcUpBuffer[]; + +// +#define sslcUpColorBufferIndex 49 +double sslcUpColorBuffer[]; + +// +#property indicator_label26 "X121_XMAN SSLC Up" +#property indicator_type26 DRAW_COLOR_LINE +#property indicator_color26 CLR_NONE, clrLime +#property indicator_style26 STYLE_SOLID +#property indicator_width26 1 + +// +#define sslcDownBufferIndex 50 +#define sslcDownBufferPlotIndex 26 +double sslcDownBuffer[]; + +// +#define sslcDownColorBufferIndex 51 +double sslcDownColorBuffer[]; + +// +#property indicator_label27 "X121_XMAN SSLC Down" +#property indicator_type27 DRAW_COLOR_LINE +#property indicator_color27 CLR_NONE, clrRed +#property indicator_style27 STYLE_SOLID +#property indicator_width27 1 + +// +// XHULL ... + +// +// UP Zone ... + +// +#define hullUpZoneBufferIndex 52 +#define hullUpZoneBufferPlotIndex 27 +#define hullUpZoneColorBufferIndex 53 + +// +double hullUpZoneBuffer[]; +double hullUpZoneColorBuffer[]; + +// +#property indicator_label28 "X121_XMAN HULL Up" +#property indicator_type28 DRAW_COLOR_LINE +#property indicator_color28 CLR_NONE, clrGray, clrAqua, clrMagenta +#property indicator_width28 1 + +// +// DOWN Zone ... + +// +#define hullDownZoneBufferIndex 54 +#define hullDownZoneBufferPlotIndex 28 +#define hullDownZoneColorBufferIndex 55 + +// +double hullDownZoneBuffer[]; +double hullDownZoneColorBuffer[]; + +// +#property indicator_label29 "X121_XMAN HULL Down" +#property indicator_type29 DRAW_COLOR_LINE +#property indicator_color29 CLR_NONE, clrGray, clrAqua, clrMagenta +#property indicator_width29 1 + +// +// Open ... +#define hkOpenBufferIndex 56 +double hkOpenBuffer[]; + +// +// High ... +#define hkHighBufferIndex 57 +double hkHighBuffer[]; + +// +// Low ... +#define hkLowBufferIndex 58 +double hkLowBuffer[]; + +// +// Close ... +#define hkCloseBufferIndex 59 +double hkCloseBuffer[]; + +// +// Candle Color ... +#define hkCandleColorBufferIndex 60 +double hkCandleColorBuffer[]; + +// +#define hkCandlesBufferIndex 29 + +// +#property indicator_label30 "X121_XMAN HK Open;X121_XMAN HK High;X121_XMAN HK Low;X121_XMAN HK Close" +#property indicator_type30 DRAW_COLOR_CANDLES +#property indicator_color30 CLR_NONE, clrAqua, clrMagenta + +// +// Open ... +#define smhkOpenBufferIndex 61 +double smhkOpenBuffer[]; + +// +// High ... +#define smhkHighBufferIndex 62 +double smhkHighBuffer[]; + +// +// Low ... +#define smhkLowBufferIndex 63 +double smhkLowBuffer[]; + +// +// Close ... +#define smhkCloseBufferIndex 64 +double smhkCloseBuffer[]; + +// +// Candle Color ... +#define smhkCandleColorBufferIndex 65 +double smhkCandleColorBuffer[]; + +// +#define smhkCandlesBufferIndex 30 + +// +#property indicator_label31 "X121_XMAN SMHK Open;X121_XMAN SMHK High;X121_XMAN SMHK Low;X121_XMAN SMHK Close" +#property indicator_type31 DRAW_COLOR_CANDLES +#property indicator_color31 CLR_NONE, clrOliveDrab, clrSaddleBrown + +// +// DATA Buffers ... + +#define lastBufferIndex 65 + +// +// 66 +#define atrBufferIndex lastBufferIndex + 1 +double atrBuffer[]; + +// +// 67 +#define trendStateBufferIndex lastBufferIndex + 2 +double trendStateBuffer[]; + +// +// 68 +#define upBufferIndex lastBufferIndex + 3 +double upBuffer[]; + +// +// 69 +#define downBufferIndex lastBufferIndex + 4 +double downBuffer[]; + +// +// 70 +#define priceBufferIndex lastBufferIndex + 5 +double priceBuffer[]; + +// +// 71 +#define sslcUpMaBufferIndex lastBufferIndex + 6 +double sslcUpMaBuffer[]; + +// +// 72 +#define sslcDownMaBufferIndex lastBufferIndex + 7 +double sslcDownMaBuffer[]; + +// +// 73 +#define sslcKpiBufferIndex lastBufferIndex + 8 +double sslcKpiBuffer[]; + +// +// STATE Buffers ... + +// +// 74 +// When new Peaks Happens it's Valued otherwise EMPTY_VALUE ... +#define peaksStateBufferIndex lastBufferIndex + 9 +double peaksStateBuffer[]; + +// +// 75 +// When new Vales Happens it's Valued otherwise EMPTY_VALUE ... +#define valesStateBufferIndex lastBufferIndex + 10 +double valesStateBuffer[]; + +// +// SHORT Cycle ... + +// +// 76 +#define sHHStateBufferIndex lastBufferIndex + 11 +double sHHStateBuffer[]; + +// +// 77 +#define sLLStateBufferIndex lastBufferIndex + 12 +double sLLStateBuffer[]; + +// +// MEDIUM Cycle ... + +// +// 78 +#define mHHStateBufferIndex lastBufferIndex + 13 +double mHHStateBuffer[]; + +// +// 79 +#define mLLStateBufferIndex lastBufferIndex + 14 +double mLLStateBuffer[]; + +// +// LONG Cycle ... + +// +// 80 +#define lHHStateBufferIndex lastBufferIndex + 15 +double lHHStateBuffer[]; + +// +// 81 +#define lLLStateBufferIndex lastBufferIndex + 16 +double lLLStateBuffer[]; + +// +// HIND Cycle ... + +// +// 82 +#define hHHStateBufferIndex lastBufferIndex + 17 +double hHHStateBuffer[]; + +// +// 83 +#define hLLStateBufferIndex lastBufferIndex + 18 +double hLLStateBuffer[]; + +// +// XSTR ... +// 84 +#define strTrendStateBufferIndex lastBufferIndex + 19 +double strTrendStateBuffer[]; + +// +// XMRB ... + +// +// RIBBON 1 (High) ... +// 85 +#define rb1StateBufferIndex lastBufferIndex + 20 +double rb1StateBuffer[]; + +// +// RIBBON 2 (Open) ... +// 86 +#define rb2StateBufferIndex lastBufferIndex + 21 +double rb2StateBuffer[]; + +// +// RIBBON 3 (Close) ... +// 87 +#define rb3StateBufferIndex lastBufferIndex + 22 +double rb3StateBuffer[]; + +// +// RIBBON 4 (Median) ... +// 88 +#define rb4StateBufferIndex lastBufferIndex + 23 +double rb4StateBuffer[]; + +// +// RIBBON 5 (Typical) ... +// 89 +#define rb5StateBufferIndex lastBufferIndex + 24 +double rb5StateBuffer[]; + +// +// RIBBON 6 (Low) ... +// 90 +#define rb6StateBufferIndex lastBufferIndex + 25 +double rb6StateBuffer[]; + +// +// XHULL ... + +// +// 91 +#define hullUpStateBufferIndex lastBufferIndex + 26 +double hullUpStateBuffer[]; + +// +// 92 +#define hullDownStateBufferIndex lastBufferIndex + 27 +double hullDownStateBuffer[]; + +// +// XHK ... +// 93 +#define hkStateBufferIndex lastBufferIndex + 28 +double hkStateBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +double lastPeak; +double lastVale; + +// +double mLastSHH = 0; +double mLastSLL = 0; + +// +double mLastMHH = 0; +double mLastMLL = 0; + +// +double mLastLHH = 0; +double mLastLLL = 0; + +// +double mLastHHH = 0; +double mLastHLL = 0; + +// +double mHideColorIDX = 0; + +// +int currentPeriodSecconds = 0; + +// +// CYCLE 1 ... +int mL1Candles; +int mL1PeriodSecconds = 0; +int mLastL1StartBarIndex = 0; +datetime mLastL1StartTime = NULL; +ENUM_TIMEFRAMES mL1Period = NULL; + +// +// CYCLE 2 ... +int mL2Candles; +int mL2PeriodSecconds = 0; +int mLastL2StartBarIndex = 0; +datetime mLastL2StartTime = NULL; +ENUM_TIMEFRAMES mL2Period = NULL; + +// +// CYCLE 3 ... +int mL3Candles; +int mL3PeriodSecconds = 0; +int mLastL3StartBarIndex = 0; +datetime mLastL3StartTime = NULL; +ENUM_TIMEFRAMES mL3Period = NULL; + +// +// CYCLE 4 ... +int mL4Candles; +int mL4PeriodSecconds = 0; +int mLastL4StartBarIndex = 0; +datetime mLastL4StartTime = NULL; +ENUM_TIMEFRAMES mL4Period = NULL; + +// +// XSTR ... + +// +int atrHandler = INVALID_HANDLE; + +// +int changeOfTrend; +int startBearishTrend; +int startBullishTrend; + +// +int mStrLength; + +// +// XMRB ... + +int mMRBLength; +int mMRBAMAFast = 2; +int mMRBAMASlow = 30; + +// +int rb1Handler = INVALID_HANDLE; +int rb2Handler = INVALID_HANDLE; +int rb3Handler = INVALID_HANDLE; +int rb4Handler = INVALID_HANDLE; +int rb5Handler = INVALID_HANDLE; +int rb6Handler = INVALID_HANDLE; + +// +// XSSLC ... + +// +int mSSLCLength; + +// +int sslcUpHandler = INVALID_HANDLE; +int sslcDownHandler = INVALID_HANDLE; + +// +// XHULL ... + +// +int mHULLLength; + +// +XSCHull *mUpZHull; +XSCHull *mDownZHull; + +// +double mLastHullUpValue; +double mLastHullUpColorValue = 1; +double mLastHullDownValue; +double mLastHullDownColorValue = 1; + +// +// XCC ... + +// +XChartStyle chartStyle; +XChartStyle clearStyle; + +// +int mHKSmoothingLength; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Parse Configs ... + if (!ParseConfigs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + InitCandleTimer(); + + // + // Initial Periods ... + InitialCycles(); + + // + drawPrefix = ShortName; + + // + // 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(); + + // + // We Can Choose ATR Length based on Other Cycles ... + mStrLength = mL4Candles * 3; + atrHandler = iATR( + _Symbol, + _Period, + mStrLength); + if (atrHandler == INVALID_HANDLE) + { + return INIT_FAILED; + } + + // + mMRBLength = mL4Candles; + if (!InitRibbons()) + { + return INIT_FAILED; + } + + // + mSSLCLength = mL4Candles; + if (!InitSSLChannel()) + { + return INIT_FAILED; + } + + // + mHULLLength = mL4Candles; + if (!InitHullTrend()) + { + return INIT_FAILED; + } + + // + mHKSmoothingLength = mL4Candles * 3; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Apply Chart Style ... + ApplyCustomChartStyle(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +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 + + // + // Here we can handle De Initialization Reasons ... + IndicatorRelease(atrHandler); + + // + // XMRB ... + IndicatorRelease(rb1Handler); + IndicatorRelease(rb2Handler); + IndicatorRelease(rb3Handler); + IndicatorRelease(rb4Handler); + IndicatorRelease(rb5Handler); + IndicatorRelease(rb6Handler); + + // + // XSSLC ... + IndicatorRelease(sslcUpHandler); + IndicatorRelease(sslcDownHandler); + + // + // XHULL ... + delete mUpZHull; + delete mDownZHull; + + // + ObjectDelete(0, ShortName); + + // + Comment(""); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Calculate Candle Remain Time ... + CalculateCandleTimer(); + + // + // this counts Available Bars ... + int limit; + + // + limit = prev_calculated - 1; + if (limit < 0) + { + limit = 0; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + // + double upPrice = GetAppliedPrice( + hullUpAppliedTo, + open, high, low, close, i); + + // + double downPrice = GetAppliedPrice( + hullDownAppliedTo, + open, high, low, close, i); + + // + CalculateHull(i, rates_total, upPrice, downPrice); + } + + // + bool isXSTRCalculated = CalculateXSTR( + rates_total, + prev_calculated, + open, + high, + low, + close); + if (!isXSTRCalculated) + { + return prev_calculated; + } + + // + // 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); + + // + + // + // Checking Handlers Calculated Bars ... + + // + // XMRB ... + int rb1CalculatedBars = BarsCalculated(rb1Handler); + int rb2CalculatedBars = BarsCalculated(rb2Handler); + int rb3CalculatedBars = BarsCalculated(rb3Handler); + int rb4CalculatedBars = BarsCalculated(rb4Handler); + int rb5CalculatedBars = BarsCalculated(rb5Handler); + int rb6CalculatedBars = BarsCalculated(rb6Handler); + + // + // XSSLC ... + int sslcUpCalculatedBars = BarsCalculated(sslcUpHandler); + int sslcDownCalculatedBars = BarsCalculated(sslcDownHandler); + + // + bool isCalculatedBarsNotPassed = + // + // XMRB ... + rb1CalculatedBars < maxLength || + rb2CalculatedBars < maxLength || + rb3CalculatedBars < maxLength || + rb4CalculatedBars < maxLength || + rb5CalculatedBars < maxLength || + rb6CalculatedBars < maxLength || + // + // XSSLC ... + sslcUpCalculatedBars < maxLength || + sslcDownCalculatedBars < maxLength + // + ; + + // + if (isCalculatedBarsNotPassed) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Check Handlers Copied Bars ... + + // + // XMRB ... + int rb1CopiedBars = CopyBuffer(rb1Handler, 0, 0, limit, ribbon1Buffer); + int rb2CopiedBars = CopyBuffer(rb2Handler, 0, 0, limit, ribbon2Buffer); + int rb3CopiedBars = CopyBuffer(rb3Handler, 0, 0, limit, ribbon3Buffer); + int rb4CopiedBars = CopyBuffer(rb4Handler, 0, 0, limit, ribbon4Buffer); + int rb5CopiedBars = CopyBuffer(rb5Handler, 0, 0, limit, ribbon5Buffer); + int rb6CopiedBars = CopyBuffer(rb6Handler, 0, 0, limit, ribbon6Buffer); + + // + // XSSLC ... + int sslcUpCopiedBars = CopyBuffer(sslcUpHandler, 0, 0, limit, sslcUpMaBuffer); + int sslcDownCopiedBars = CopyBuffer(sslcDownHandler, 0, 0, limit, sslcDownMaBuffer); + + // + bool isCopiedBarsNotPassed = + // + // XMRB ... + rb1CopiedBars < 0 || + rb2CopiedBars < 0 || + rb3CopiedBars < 0 || + rb4CopiedBars < 0 || + rb5CopiedBars < 0 || + rb6CopiedBars < 0 || + // + // XSSLC ... + sslcUpCopiedBars < 0 || + sslcDownCopiedBars < 0 + // + ; + + // + if (isCopiedBarsNotPassed) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i); + + // + CalculateRibbonsColors(i, low, high); + + // + CalculateHikenAshi(i, prev_calculated, rates_total, open, high, close, low); + + // + CalculateSSLC(i, limit, rates_total, prev_calculated, close); + } + + // + CalculateSMHK(rates_total, prev_calculated); + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Parse Configs ... +bool ParseConfigs() +{ + // + bool result = false; + + // + // Since we Use Default Values ... + // Apply Changes Only When it's Provided ... + + // + bool hasCTConfig = StringLen(cTimerConfig) > 0; + if (hasCTConfig) + { + // + XCTimerConfig cfg = ParseCTimerConfig(cTimerConfig); + + // + candleTimerColor = cfg.candleTimerColor; + candleTimerCorner = cfg.candleTimerCorner; + } + + // + bool hasChartConfig = StringLen(cStyleConfig) > 0; + if (hasChartConfig) + { + // + XChartStyleConfig cfg = ParseChartStyleConfig(cStyleConfig); + + // + upColor = cfg.upColor; + downColor = cfg.downColor; + lineColor = cfg.lineColor; + bearishColor = cfg.bearishColor; + bullishColor = cfg.bullishColor; + volumesColor = cfg.volumesColor; + chartMode = cfg.chartMode; + } + + // + bool hasSCConfig = StringLen(scConfig) > 0; + if (hasSCConfig) + { + // + XSCConfig cfg = PrseSCConfig(scConfig); + + // + l1Method = cfg.l1Method; + l1Period = cfg.l1Period; + } + + // + bool hasMCConfig = StringLen(mcConfig) > 0; + if (hasMCConfig) + { + // + XMCConfig cfg = PrseMCConfig(mcConfig); + + // + l2Method = cfg.l2Method; + l2Period = cfg.l2Period; + } + + // + bool hasLCConfig = StringLen(lcConfig) > 0; + if (hasLCConfig) + { + // + XLCConfig cfg = PrseLCConfig(lcConfig); + + // + l3Method = cfg.l3Method; + l3Period = cfg.l3Period; + } + + // + bool hasHCConfig = StringLen(hcConfig) > 0; + if (hasHCConfig) + { + // + XHCConfig cfg = PrseHCConfig(hcConfig); + + // + l4Method = cfg.l4Method; + l4Period = cfg.l4Period; + } + + // + bool hasFibConfig = StringLen(fibConfig) > 0; + if (hasFibConfig) + { + // + XFiboConfig cfg = PrseFiboConfig(fibConfig); + + // + fiboLevel1 = cfg.fiboLevel1; + fiboLevel2 = cfg.fiboLevel2; + fiboLevel3 = cfg.fiboLevel3; + fiboLevel4 = cfg.fiboLevel4; + fiboLevel5 = cfg.fiboLevel5; + } + + // + bool hasBDConfig = StringLen(bdConfig) > 0; + if (hasBDConfig) + { + // + XBDConfig cfg = ParseBDConfig(bdConfig); + + // + hhMode = cfg.hhMode; + llMode = cfg.llMode; + } + + // + bool hasTDConfig = StringLen(tdConfig) > 0; + if (hasTDConfig) + { + // + XTDConfig cfg = ParseTDConfig(tdConfig); + + // + trendMultiplier = cfg.trendMultiplier; + trendPriceAppliedTo = cfg.trendPriceAppliedTo; + } + + // + bool hasRBConfig = StringLen(rbConfig) > 0; + if (hasRBConfig) + { + // + XRBConfig cfg = ParseRBConfig(rbConfig); + + // + ribbonMode = cfg.ribbonMode; + } + + // + bool hasHullConfig = StringLen(hullConfig) > 0; + if (hasHullConfig) + { + // + XHullConfig cfg = ParseHullConfig(hullConfig); + + // + hullDivisor = cfg.hullDivisor; + hullUpAppliedTo = cfg.hullUpAppliedTo; + hullDownAppliedTo = cfg.hullDownAppliedTo; + } + + // + bool hasSSLCConfig = StringLen(sslcConfig) > 0; + if (hasSSLCConfig) + { + // + XSSLCConfig cfg = ParseSSLCConfig(sslcConfig); + + // + sslcMode = cfg.sslcMode; + sslcUpAppliedTo = cfg.sslcUpAppliedTo; + sslcDownAppliedTo = cfg.sslcDownAppliedTo; + } + + // + bool hasStylePresentationConfig = StringLen(stylePRSConfig) > 0; + if (hasStylePresentationConfig) + { + // + XStylePresentationConfig cfg = ParseStylePresentationConfig(stylePRSConfig); + + // + showCandleTimer = cfg.showCandleTimer; + showCandles = cfg.showCandles; + showHKCandles = cfg.showHKCandles; + showSMHKCandles = cfg.showSMHKCandles; + } + + // + bool hasPVPresentationConfig = StringLen(pvPRSConfig) > 0; + if (hasPVPresentationConfig) + { + // + XPVPresentationConfig cfg = ParsePVPresentationConfig(pvPRSConfig); + + // + showPeaksAndVales = cfg.showPeaksAndVales; + showLevels = cfg.showLevels; + showConsolidations = cfg.showConsolidations; + } + + // + bool hasSTrendPresentationConfig = StringLen(trendPRSConfig) > 0; + if (hasSTrendPresentationConfig) + { + // + XTrendPresentationConfig cfg = ParseTrendPresentationConfig(trendPRSConfig); + + // + showHull = cfg.showHull; + showTrends = cfg.showTrends; + fillTrends = cfg.fillTrends; + showRibbons = cfg.showRibbons; + showSSLChannel = cfg.showSSLChannel; + } + + // + bool hasFiboPresentationConfig = StringLen(fiboPRSConfig) > 0; + if (hasFiboPresentationConfig) + { + // + XFiboPresentationConfig cfg = ParePresentationConfig(fiboPRSConfig); + + // + showFibo1Levels = cfg.showFibo1Levels; + showFibo2Levels = cfg.showFibo2Levels; + showFibo3Levels = cfg.showFibo3Levels; + showFibo4Levels = cfg.showFibo4Levels; + showFibo5Levels = cfg.showFibo5Levels; + } + + // + result = true; + + // + return result; +} + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + // Validate User Inputs ... + result = + // + // L1 ... + // Short Cycle ... + ( + // + l1Method == X_PERIOD_AUTO + ? l1Period == NULL + : l1Period != NULL && l1Method != X_PERIOD_NOTHING + // + ) + // + && + // + // L2 ... + // Medium Cycle ... + ( + // + l2Method == X_PERIOD_AUTO + ? l2Period == NULL + : l2Period != NULL && l2Method != X_PERIOD_NOTHING + // + ) + // + && + // + // L3 ... + // Long Cycle ... + ( + // + l3Method == X_PERIOD_AUTO + ? l3Period == NULL + : l3Period != NULL && l3Method != X_PERIOD_NOTHING + // + ) + // + && + // + // L4 ... + // Hind Cycle ... + ( + // + l4Method == X_PERIOD_AUTO + ? l4Period == NULL + : l4Period != NULL && l4Method != X_PERIOD_NOTHING + // + ) + // + && + // + // Validate Ribbon ... + ( + // + ribbonMode != X_MA_NOTHING + // + ) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 1; + + // + result = MathMax(result, mL1Candles); + result = MathMax(result, mL2Candles); + result = MathMax(result, mL3Candles); + result = MathMax(result, mL4Candles); + + // + return result; +} + +// +// Init Candle Timer ... +void InitCandleTimer() +{ + // + // Validate Inputs ... + if (showCandleTimer) + { + CreateIndicatorObject(); + } + else + { + ObjectDelete(0, ShortName); + } +} + +// +// Initial Multi Time Frame Cycles Periods ... +void InitialCycles() +{ + // + // Calculate Current Period Secconds ... + currentPeriodSecconds = PeriodSeconds(_Period); + + // + // Nearest ... + // Calculate Cycle 1 Requirements ... + if (mL1Period == NULL) + { + // + if (l1Method == X_PERIOD_AUTO) + { + mL1Period = GetNearestTimeFrame(_Period); + } + else + { + mL1Period = l1Period; + } + + // + mL1PeriodSecconds = PeriodSeconds(mL1Period); + + // + mL1Candles = mL1PeriodSecconds / currentPeriodSecconds; + } + + // + // Mediest ... + // Calculate Cycle 2 Requirements ... + if (mL2Period == NULL) + { + // + if (l2Method == X_PERIOD_AUTO) + { + mL2Period = GetMediestTimeFrame(_Period); + } + else + { + mL2Period = l2Period; + } + + // + mL2PeriodSecconds = PeriodSeconds(mL2Period); + + // + mL2Candles = mL2PeriodSecconds / currentPeriodSecconds; + } + + // + // Farest ... + // Calculate Cycle 3 Requirements ... + if (mL3Period == NULL) + { + // + if (l3Method == X_PERIOD_AUTO) + { + mL3Period = GetFarestTimeFrame(_Period); + } + else + { + mL3Period = l3Period; + } + + // + mL3PeriodSecconds = PeriodSeconds(mL3Period); + + // + mL3Candles = mL3PeriodSecconds / currentPeriodSecconds; + } + + // + // HindMost ... + // Calculate Cycle 4 Requirements ... + if (mL4Period == NULL) + { + // + if (l4Method == X_PERIOD_AUTO) + { + mL4Period = GetHindmostTimeFrame(_Period); + } + else + { + mL4Period = l4Period; + } + + // + mL4PeriodSecconds = PeriodSeconds(mL4Period); + + // + mL4Candles = mL4PeriodSecconds / currentPeriodSecconds; + } + + // + string comment = GenerateCyclesRepresentation(); + Comment(comment); +} + +// +bool InitRibbons() +{ + // + bool result = false; + + // + if (mMRBLength <= 0) + { + return result; + } + + // + // RIBBON 1 ... + // High ... + result = InitMaHandler( + rb1Handler, + mMRBLength, + ribbonMode, + PRICE_HIGH); + if (!result) + { + return result; + } + + // + // RIBBON 2 ... + // Open ... + result = InitMaHandler( + rb2Handler, + mMRBLength, + ribbonMode, + PRICE_OPEN); + if (!result) + { + return result; + } + + // + // RIBBON 3 ... + // Close ... + result = InitMaHandler( + rb3Handler, + mMRBLength, + ribbonMode, + PRICE_CLOSE); + if (!result) + { + return result; + } + + // + // RIBBON 4 ... + // Median ... + result = InitMaHandler( + rb4Handler, + mMRBLength, + ribbonMode, + PRICE_MEDIAN); + if (!result) + { + return result; + } + + // + // RIBBON 5 ... + // Typical ... + result = InitMaHandler( + rb5Handler, + mMRBLength, + ribbonMode, + PRICE_TYPICAL); + if (!result) + { + return result; + } + + // + // RIBBON 6 ... + // Low ... + result = InitMaHandler( + rb6Handler, + mMRBLength, + ribbonMode, + PRICE_LOW); + + // + return result; +} + +// +bool InitSSLChannel() +{ + // + bool result = false; + + // + if (mSSLCLength <= 0) + { + return result; + } + + // + // SSLUP ... + result = InitMaHandler( + sslcUpHandler, + mSSLCLength, + sslcMode, + sslcUpAppliedTo); + if (!result) + { + return result; + } + + // + // SSLDOWN ... + result = InitMaHandler( + sslcDownHandler, + mSSLCLength, + sslcMode, + sslcDownAppliedTo); + + // + return result; +} + +// +bool InitHullTrend() +{ + // + bool result = false; + + // + if (mHULLLength <= 0) + { + return result; + } + + // + mUpZHull = new XSCHull(); + mUpZHull.Init( + mHULLLength, + hullDivisor); + + // + mDownZHull = new XSCHull(); + mDownZHull.Init( + mHULLLength, + hullDivisor); + + // + result = true; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // RANGE ... + + // + // PEAKS and VALES ... + ENUM_DRAW_TYPE pvDrawType = showPeaksAndVales ? DRAW_ARROW : DRAW_NONE; + + // + // PEAKS ... + ArraySetAsSeries(peaksBuffer, true); + SetIndexBuffer(peaksBufferIndex, peaksBuffer, INDICATOR_DATA); + PlotIndexSetInteger(peaksBufferIndex, PLOT_ARROW, 225); + PlotIndexSetDouble(peaksBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + PlotIndexSetInteger(peaksBufferIndex, PLOT_SHOW_DATA, showPeaksAndVales); + PlotIndexSetInteger(peaksBufferIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + // VALES ... + ArraySetAsSeries(valesBuffer, true); + SetIndexBuffer(valesBufferIndex, valesBuffer, INDICATOR_DATA); + PlotIndexSetInteger(valesBufferIndex, PLOT_ARROW, 225); + PlotIndexSetDouble(valesBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + PlotIndexSetInteger(valesBufferIndex, PLOT_SHOW_DATA, showPeaksAndVales); + PlotIndexSetInteger(valesBufferIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + // SUPPORT and RESISTANCE ... + // + + // + // RESISTANCE ... + ArraySetAsSeries(rBuffer, true); + SetIndexBuffer(rBufferIndex, rBuffer, INDICATOR_DATA); + PlotIndexSetInteger(rBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(rBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // RESISTANCE Color ... + ArraySetAsSeries(rColorBuffer, true); + SetIndexBuffer(rColorBufferIndex, rColorBuffer, INDICATOR_COLOR_INDEX); + + // + // SUPPORT ... + ArraySetAsSeries(sBuffer, true); + SetIndexBuffer(sBufferIndex, sBuffer, INDICATOR_DATA); + PlotIndexSetInteger(sBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(sBufferPlotIndex, PLOT_SHOW_DATA, false); + + // + // SUPPORT Color ... + ArraySetAsSeries(sColorBuffer, true); + SetIndexBuffer(sColorBufferIndex, sColorBuffer, INDICATOR_COLOR_INDEX); + + // + // FIBBO Levels ... + + // + // LEVEL 1 ... + + // + // Buffer ... + ArraySetAsSeries(fl1Buffer, true); + SetIndexBuffer(fl1BufferIndex, fl1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl1BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl1BufferPlotIndex, PLOT_SHOW_DATA, showFibo1Levels); + + // + // Color ... + ArraySetAsSeries(fl1ColorBuffer, true); + SetIndexBuffer(fl1ColorBufferIndex, fl1ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 2 ... + + // + // Buffer ... + ArraySetAsSeries(fl2Buffer, true); + SetIndexBuffer(fl2BufferIndex, fl2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl2BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl2BufferPlotIndex, PLOT_SHOW_DATA, showFibo2Levels); + + // + // Color ... + ArraySetAsSeries(fl2ColorBuffer, true); + SetIndexBuffer(fl2ColorBufferIndex, fl2ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 3 ... + + // + // Buffer ... + ArraySetAsSeries(fl3Buffer, true); + SetIndexBuffer(fl3BufferIndex, fl3Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl3BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl3BufferPlotIndex, PLOT_SHOW_DATA, showFibo3Levels); + + // + // Color ... + ArraySetAsSeries(fl3ColorBuffer, true); + SetIndexBuffer(fl3ColorBufferIndex, fl3ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 4 ... + + // + // Buffer ... + ArraySetAsSeries(fl4Buffer, true); + SetIndexBuffer(fl4BufferIndex, fl4Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl4BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl4BufferPlotIndex, PLOT_SHOW_DATA, showFibo4Levels); + + // + // Color ... + ArraySetAsSeries(fl4ColorBuffer, true); + SetIndexBuffer(fl4ColorBufferIndex, fl4ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 5 ... + + // + // Buffer ... + ArraySetAsSeries(fl5Buffer, true); + SetIndexBuffer(fl5BufferIndex, fl5Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl5BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl5BufferPlotIndex, PLOT_SHOW_DATA, showFibo5Levels); + + // + // Color ... + ArraySetAsSeries(fl5ColorBuffer, true); + SetIndexBuffer(fl5ColorBufferIndex, fl5ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // SHORT Buffers ... + + // + // HIGH ... + ArraySetAsSeries(sHHBuffer, true); + SetIndexBuffer(sHHBufferIndex, sHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(sHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(sHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(sHHColorBuffer, true); + SetIndexBuffer(sHHColorBufferIndex, sHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(sLLBuffer, true); + SetIndexBuffer(sLLBufferIndex, sLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(sLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(sLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(sLLColorBuffer, true); + SetIndexBuffer(sLLColorBufferIndex, sLLColorBuffer, INDICATOR_COLOR_INDEX); + + // + // MEDIUM Buffer ... + + // + // HIGH ... + ArraySetAsSeries(mHHBuffer, true); + SetIndexBuffer(mHHBufferIndex, mHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(mHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(mHHColorBuffer, true); + SetIndexBuffer(mHHColorBufferIndex, mHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(mLLBuffer, true); + SetIndexBuffer(mLLBufferIndex, mLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(mLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(mLLColorBuffer, true); + SetIndexBuffer(mLLColorBufferIndex, mLLColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LONG Buffer ... + + // + // HIGH ... + ArraySetAsSeries(lHHBuffer, true); + SetIndexBuffer(lHHBufferIndex, lHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(lHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(lHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(lHHColorBuffer, true); + SetIndexBuffer(lHHColorBufferIndex, lHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(lLLBuffer, true); + SetIndexBuffer(lLLBufferIndex, lLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(lLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(lLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(lLLColorBuffer, true); + SetIndexBuffer(lLLColorBufferIndex, lLLColorBuffer, INDICATOR_COLOR_INDEX); + + // + // HIND Buffer ... + + // + // HIGH ... + ArraySetAsSeries(hHHBuffer, true); + SetIndexBuffer(hHHBufferIndex, hHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(hHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(hHHColorBuffer, true); + SetIndexBuffer(hHHColorBufferIndex, hHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(hLLBuffer, true); + SetIndexBuffer(hLLBufferIndex, hLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(hLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(hLLColorBuffer, true); + SetIndexBuffer(hLLColorBufferIndex, hLLColorBuffer, INDICATOR_COLOR_INDEX); + + // + // XSTR ... + + // + // FILLINGS ... + SetIndexBuffer(fillUpBufferIndex, fillUpBuffer, INDICATOR_DATA); + SetIndexBuffer(fillDownBufferIndex, fillDownBuffer, INDICATOR_DATA); + PlotIndexSetInteger(fillingBufferPlotIndex, PLOT_SHOW_DATA, false); + + // + // MAIN ... + SetIndexBuffer(trendBufferIndex, trendBuffer, INDICATOR_DATA); + PlotIndexSetInteger(trendBufferPlotIndex, PLOT_SHOW_DATA, showTrends); + SetIndexBuffer(trendColorBufferIndex, trendColorBuffer, INDICATOR_COLOR_INDEX); + + // + // RIBBON 1 ... + + // + ArraySetAsSeries(ribbon1Buffer, true); + SetIndexBuffer(ribbon1BufferIndex, ribbon1Buffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(ribbon1BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(ribbon1BufferPlotIndex, PLOT_SHOW_DATA, showRibbons); + + // + ArraySetAsSeries(ribbon1ColorBuffer, true); + SetIndexBuffer(ribbon1ColorBufferIndex, ribbon1ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // RIBBON 2 ... + + // + ArraySetAsSeries(ribbon2Buffer, true); + SetIndexBuffer(ribbon2BufferIndex, ribbon2Buffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(ribbon2BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(ribbon2BufferPlotIndex, PLOT_SHOW_DATA, showRibbons); + + // + ArraySetAsSeries(ribbon2ColorBuffer, true); + SetIndexBuffer(ribbon2ColorBufferIndex, ribbon2ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // RIBBON 3 ... + + // + ArraySetAsSeries(ribbon3Buffer, true); + SetIndexBuffer(ribbon3BufferIndex, ribbon3Buffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(ribbon3BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(ribbon3BufferPlotIndex, PLOT_SHOW_DATA, showRibbons); + + // + ArraySetAsSeries(ribbon3ColorBuffer, true); + SetIndexBuffer(ribbon3ColorBufferIndex, ribbon3ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // RIBBON 4 ... + + // + ArraySetAsSeries(ribbon4Buffer, true); + SetIndexBuffer(ribbon4BufferIndex, ribbon4Buffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(ribbon4BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(ribbon4BufferPlotIndex, PLOT_SHOW_DATA, showRibbons); + + // + ArraySetAsSeries(ribbon4ColorBuffer, true); + SetIndexBuffer(ribbon4ColorBufferIndex, ribbon4ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // RIBBON 5 ... + + // + ArraySetAsSeries(ribbon5Buffer, true); + SetIndexBuffer(ribbon5BufferIndex, ribbon5Buffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(ribbon5BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(ribbon5BufferPlotIndex, PLOT_SHOW_DATA, showRibbons); + + // + ArraySetAsSeries(ribbon5ColorBuffer, true); + SetIndexBuffer(ribbon5ColorBufferIndex, ribbon5ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // RIBBON 6 ... + + // + ArraySetAsSeries(ribbon6Buffer, true); + SetIndexBuffer(ribbon6BufferIndex, ribbon6Buffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(ribbon6BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(ribbon6BufferPlotIndex, PLOT_SHOW_DATA, showRibbons); + + // + ArraySetAsSeries(ribbon6ColorBuffer, true); + SetIndexBuffer(ribbon6ColorBufferIndex, ribbon6ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // XSSLC ... + + // + // UP ... + + // + ArraySetAsSeries(sslcUpBuffer, true); + SetIndexBuffer(sslcUpBufferIndex, sslcUpBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(sslcUpBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(sslcUpBufferPlotIndex, PLOT_SHOW_DATA, showSSLChannel); + + // + ArraySetAsSeries(sslcUpColorBuffer, true); + SetIndexBuffer(sslcUpColorBufferIndex, sslcUpColorBuffer, INDICATOR_COLOR_INDEX); + + // + // DOWN ... + + // + ArraySetAsSeries(sslcDownBuffer, true); + SetIndexBuffer(sslcDownBufferIndex, sslcDownBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(sslcDownBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(sslcDownBufferPlotIndex, PLOT_SHOW_DATA, showSSLChannel); + + // + ArraySetAsSeries(sslcDownColorBuffer, true); + SetIndexBuffer(sslcDownColorBufferIndex, sslcDownColorBuffer, INDICATOR_COLOR_INDEX); + + // + // XHULL ... + + // + // UP ... + + // + SetIndexBuffer(hullUpZoneBufferIndex, hullUpZoneBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hullUpZoneBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(hullUpZoneBufferPlotIndex, PLOT_SHOW_DATA, showHull); + + // + SetIndexBuffer(hullUpZoneColorBufferIndex, hullUpZoneColorBuffer, INDICATOR_COLOR_INDEX); + + // + // DOWN ... + + // + SetIndexBuffer(hullDownZoneBufferIndex, hullDownZoneBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hullDownZoneBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(hullDownZoneBufferPlotIndex, PLOT_SHOW_DATA, showHull); + + // + SetIndexBuffer(hullDownZoneColorBufferIndex, hullDownZoneColorBuffer, INDICATOR_COLOR_INDEX); + + // + // XHK ... + + // + // Candles Color ... + ArraySetAsSeries(hkCandleColorBuffer, true); + SetIndexBuffer(hkCandleColorBufferIndex, hkCandleColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on Candles Buffer ... + PlotIndexSetDouble(hkCandlesBufferIndex, PLOT_EMPTY_VALUE, 0.0); + + // + PlotIndexSetInteger(hkCandlesBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(hkCandleColorBufferIndex, PLOT_SHOW_DATA, false); + + // + // Open ... + ArraySetAsSeries(hkOpenBuffer, true); + PlotIndexSetInteger(hkOpenBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(hkOpenBufferIndex, hkOpenBuffer, INDICATOR_DATA); + + // + // High ... + ArraySetAsSeries(hkHighBuffer, true); + SetIndexBuffer(hkHighBufferIndex, hkHighBuffer, INDICATOR_DATA); + PlotIndexSetInteger(hkHighBufferIndex, PLOT_SHOW_DATA, false); + + // + // Close ... + ArraySetAsSeries(hkCloseBuffer, true); + SetIndexBuffer(hkCloseBufferIndex, hkCloseBuffer, INDICATOR_DATA); + PlotIndexSetInteger(hkCloseBufferIndex, PLOT_SHOW_DATA, false); + + // + // Low ... + ArraySetAsSeries(hkLowBuffer, true); + SetIndexBuffer(hkLowBufferIndex, hkLowBuffer, INDICATOR_DATA); + PlotIndexSetInteger(hkLowBufferIndex, PLOT_SHOW_DATA, false); + + // + // XSMHK ... + + // + // Candles Color ... + ArraySetAsSeries(smhkCandleColorBuffer, true); + SetIndexBuffer(smhkCandleColorBufferIndex, smhkCandleColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on Candles Buffer ... + PlotIndexSetDouble(smhkCandlesBufferIndex, PLOT_EMPTY_VALUE, 0.0); + + // + PlotIndexSetInteger(smhkCandlesBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(smhkCandleColorBufferIndex, PLOT_SHOW_DATA, false); + + // + // Open ... + ArraySetAsSeries(smhkOpenBuffer, true); + PlotIndexSetInteger(smhkOpenBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(smhkOpenBufferIndex, smhkOpenBuffer, INDICATOR_DATA); + + // + // High ... + ArraySetAsSeries(smhkHighBuffer, true); + SetIndexBuffer(smhkHighBufferIndex, smhkHighBuffer, INDICATOR_DATA); + PlotIndexSetInteger(smhkHighBufferIndex, PLOT_SHOW_DATA, false); + + // + // Close ... + ArraySetAsSeries(smhkCloseBuffer, true); + SetIndexBuffer(smhkCloseBufferIndex, smhkCloseBuffer, INDICATOR_DATA); + PlotIndexSetInteger(smhkCloseBufferIndex, PLOT_SHOW_DATA, false); + + // + // Low ... + ArraySetAsSeries(smhkLowBuffer, true); + SetIndexBuffer(smhkLowBufferIndex, smhkLowBuffer, INDICATOR_DATA); + PlotIndexSetInteger(smhkLowBufferIndex, PLOT_SHOW_DATA, false); + + // + // DATA Buffers ... + + // + // ATR ... + SetIndexBuffer(atrBufferIndex, atrBuffer, INDICATOR_CALCULATIONS); + + // + // TREND ... + SetIndexBuffer(trendStateBufferIndex, trendStateBuffer, INDICATOR_CALCULATIONS); + + // + // UP ... + SetIndexBuffer(upBufferIndex, upBuffer, INDICATOR_CALCULATIONS); + + // + // DOWN ... + SetIndexBuffer(downBufferIndex, downBuffer, INDICATOR_CALCULATIONS); + + // + // PRICE ... + SetIndexBuffer(priceBufferIndex, priceBuffer, INDICATOR_CALCULATIONS); + + // + // SSLCDOWNMA ... + ArraySetAsSeries(sslcUpMaBuffer, true); + SetIndexBuffer(sslcUpMaBufferIndex, sslcUpMaBuffer, INDICATOR_CALCULATIONS); + + // + // SSLCUPMA ... + ArraySetAsSeries(sslcDownMaBuffer, true); + SetIndexBuffer(sslcDownMaBufferIndex, sslcDownMaBuffer, INDICATOR_CALCULATIONS); + + // + // SSLCKPI ... + ArraySetAsSeries(sslcKpiBuffer, true); + SetIndexBuffer(sslcKpiBufferIndex, sslcKpiBuffer, INDICATOR_CALCULATIONS); + + // + // STATE Buffers ... + + // + // PEAKS ... + ArraySetAsSeries(peaksStateBuffer, true); + SetIndexBuffer(peaksStateBufferIndex, peaksStateBuffer, INDICATOR_CALCULATIONS); + + // + // VALES ... + ArraySetAsSeries(valesStateBuffer, true); + SetIndexBuffer(valesStateBufferIndex, valesStateBuffer, INDICATOR_CALCULATIONS); + + // + // CYCLES ... + + // + // SHORT ... + + // + ArraySetAsSeries(sHHStateBuffer, true); + SetIndexBuffer(sHHStateBufferIndex, sHHStateBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(sLLStateBuffer, true); + SetIndexBuffer(sLLStateBufferIndex, sLLStateBuffer, INDICATOR_CALCULATIONS); + + // + // MEDIUM ... + + // + ArraySetAsSeries(mHHStateBuffer, true); + SetIndexBuffer(mHHStateBufferIndex, mHHStateBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(mLLStateBuffer, true); + SetIndexBuffer(mLLStateBufferIndex, mLLStateBuffer, INDICATOR_CALCULATIONS); + + // + // LONG ... + + // + ArraySetAsSeries(lHHStateBuffer, true); + SetIndexBuffer(lHHStateBufferIndex, lHHStateBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(lLLStateBuffer, true); + SetIndexBuffer(lLLStateBufferIndex, lLLStateBuffer, INDICATOR_CALCULATIONS); + + // + // HIND ... + + // + ArraySetAsSeries(hHHStateBuffer, true); + SetIndexBuffer(hHHStateBufferIndex, hHHStateBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(hLLStateBuffer, true); + SetIndexBuffer(hLLStateBufferIndex, hLLStateBuffer, INDICATOR_CALCULATIONS); + + // + // XSTR ... + SetIndexBuffer(strTrendStateBufferIndex, strTrendStateBuffer, INDICATOR_CALCULATIONS); + + // + // XMBR ... + + // + // RIBBON 1 _ (High) ... + ArraySetAsSeries(rb1StateBuffer, true); + SetIndexBuffer(rb1StateBufferIndex, rb1StateBuffer, INDICATOR_CALCULATIONS); + + // + // RIBBON 2 _ (Open) ... + ArraySetAsSeries(rb2StateBuffer, true); + SetIndexBuffer(rb2StateBufferIndex, rb2StateBuffer, INDICATOR_CALCULATIONS); + + // + // RIBBON 3 _ (Close) ... + ArraySetAsSeries(rb3StateBuffer, true); + SetIndexBuffer(rb3StateBufferIndex, rb3StateBuffer, INDICATOR_CALCULATIONS); + + // + // RIBBON 4 _ (Median) ... + ArraySetAsSeries(rb4StateBuffer, true); + SetIndexBuffer(rb4StateBufferIndex, rb4StateBuffer, INDICATOR_CALCULATIONS); + + // + // RIBBON 5 _ (Typical) ... + ArraySetAsSeries(rb5StateBuffer, true); + SetIndexBuffer(rb5StateBufferIndex, rb5StateBuffer, INDICATOR_CALCULATIONS); + + // + // RIBBON 6 _ (Low) ... + ArraySetAsSeries(rb6StateBuffer, true); + SetIndexBuffer(rb6StateBufferIndex, rb6StateBuffer, INDICATOR_CALCULATIONS); + + // + // XHULL ... + + // + // UP Zone ... + SetIndexBuffer(hullUpStateBufferIndex, hullUpStateBuffer, INDICATOR_CALCULATIONS); + + // + // DOWN Zone ... + SetIndexBuffer(hullDownStateBufferIndex, hullDownStateBuffer, INDICATOR_CALCULATIONS); + + // + // XHK ... + + // + ArraySetAsSeries(hkStateBuffer, true); + SetIndexBuffer(hkStateBufferIndex, hkStateBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // Calculate ... + + // + // Calculate Short Cycle ... + CalculateShortCycle(bar_index); + + // + // Calculate Medium Cycle ... + CalculateMediumCycle(bar_index); + + // + // Calculate Long Cycle ... + CalculateLongCycle(bar_index); + + // + // Calculate Hind Cycle ... + CalculateHindCycle(bar_index); + + // + // Calculate Peaks and Vales ... + CalculatePeaksAndVales(bar_index); + + // + // Calculate Fibonnaci ... + CalculateFibonacci(bar_index); +} + +// +// START Calculation Parts ... +// + +// +// SHORT Cycle ... +void CalculateShortCycle( + int bar_index // Selected Bar Index +) +{ + // + ENUM_TIMEFRAMES mPeriod = mL1Period; + + // + double hhValue = GetCycleHHC( + bar_index, + mPeriod); + + // + double llValue = GetCycleLLC( + bar_index, + mPeriod); + + // + double lastHH = mLastSHH; + double lastLL = mLastSLL; + + // + double mHHState = EMPTY_VALUE; + double mhhColorIDX = mHideColorIDX; + if (showLevels) + { + // + if (hhValue == lastHH) + { + mhhColorIDX = showConsolidations ? 1 : mHideColorIDX; + } + else if (hhValue > lastHH) + { + mhhColorIDX = 2; + } + else if (hhValue < lastHH) + { + mhhColorIDX = 3; + } + + // + mHHState = mhhColorIDX; + } + else + { + mhhColorIDX = mHideColorIDX; + } + + // + double mLLState = EMPTY_VALUE; + double mllColorIDX = mHideColorIDX; + if (showLevels) + { + // + if (llValue == lastLL) + { + mllColorIDX = showConsolidations ? 1 : mHideColorIDX; + } + else if (llValue > lastLL) + { + mllColorIDX = 2; + } + else if (llValue < lastLL) + { + mllColorIDX = 3; + } + + // + mLLState = mllColorIDX; + } + else + { + mllColorIDX = mHideColorIDX; + } + + // + mLastSHH = hhValue; + mLastSLL = llValue; + + // + sHHBuffer[bar_index] = hhValue; + sLLBuffer[bar_index] = llValue; + sHHStateBuffer[bar_index] = mHHState; + sLLStateBuffer[bar_index] = mLLState; + sHHColorBuffer[bar_index] = mhhColorIDX; + sLLColorBuffer[bar_index] = mllColorIDX; +} + +// +// MEDIUM Cycle ... +void CalculateMediumCycle( + int bar_index // Selected Bar Index +) +{ + // + ENUM_TIMEFRAMES mPeriod = mL2Period; + + // + double hhValue = GetCycleHHC( + bar_index, + mPeriod); + + // + double llValue = GetCycleLLC( + bar_index, + mPeriod); + + // + double lastHH = mLastMHH; + double lastLL = mLastMLL; + + // + double mHHState = EMPTY_VALUE; + double mhhColorIDX = mHideColorIDX; + if (showLevels) + { + // + if (hhValue == lastHH) + { + mhhColorIDX = showConsolidations ? 1 : mHideColorIDX; + } + else if (hhValue > lastHH) + { + mhhColorIDX = 2; + } + else if (hhValue < lastHH) + { + mhhColorIDX = 3; + } + + // + mHHState = mhhColorIDX; + } + else + { + mhhColorIDX = mHideColorIDX; + } + + // + double mLLState = EMPTY_VALUE; + double mllColorIDX = mHideColorIDX; + if (showLevels) + { + // + if (llValue == lastLL) + { + mllColorIDX = showConsolidations ? 1 : mHideColorIDX; + } + else if (llValue > lastLL) + { + mllColorIDX = 2; + } + else if (llValue < lastLL) + { + mllColorIDX = 3; + } + + // + mLLState = mllColorIDX; + } + else + { + mllColorIDX = mHideColorIDX; + } + + // + mLastMHH = hhValue; + mLastMLL = llValue; + + // + mHHBuffer[bar_index] = hhValue; + mLLBuffer[bar_index] = llValue; + mHHStateBuffer[bar_index] = mHHState; + mLLStateBuffer[bar_index] = mLLState; + mHHColorBuffer[bar_index] = mhhColorIDX; + mLLColorBuffer[bar_index] = mllColorIDX; +} + +// +// LONG Cycle ... +void CalculateLongCycle( + int bar_index // Selected Bar Index +) +{ + // + ENUM_TIMEFRAMES mPeriod = mL3Period; + + // + double hhValue = GetCycleHHC( + bar_index, + mPeriod); + + // + double llValue = GetCycleLLC( + bar_index, + mPeriod); + + // + double lastHH = mLastLHH; + double lastLL = mLastLLL; + + // + double mHHState = EMPTY_VALUE; + double mhhColorIDX = mHideColorIDX; + if (showLevels) + { + // + if (hhValue == lastHH) + { + mhhColorIDX = showConsolidations ? 1 : mHideColorIDX; + } + else if (hhValue > lastHH) + { + mhhColorIDX = 2; + } + else if (hhValue < lastHH) + { + mhhColorIDX = 3; + } + + // + mHHState = mhhColorIDX; + } + else + { + mhhColorIDX = mHideColorIDX; + } + + // + double mLLState = EMPTY_VALUE; + double mllColorIDX = mHideColorIDX; + if (showLevels) + { + // + if (llValue == lastLL) + { + mllColorIDX = showConsolidations ? 1 : mHideColorIDX; + } + else if (llValue > lastLL) + { + mllColorIDX = 2; + } + else if (llValue < lastLL) + { + mllColorIDX = 3; + } + + // + mLLState = mllColorIDX; + } + else + { + mllColorIDX = mHideColorIDX; + } + + // + mLastLHH = hhValue; + mLastLLL = llValue; + + // + lHHBuffer[bar_index] = hhValue; + lLLBuffer[bar_index] = llValue; + lHHStateBuffer[bar_index] = mHHState; + lLLStateBuffer[bar_index] = mLLState; + lHHColorBuffer[bar_index] = mhhColorIDX; + lLLColorBuffer[bar_index] = mllColorIDX; +} + +// +// HIND Cycle ... +void CalculateHindCycle( + int bar_index // Selected Bar Index +) +{ + // + ENUM_TIMEFRAMES mPeriod = mL4Period; + + // + double hhValue = GetCycleHHC( + bar_index, + mPeriod); + + // + double llValue = GetCycleLLC( + bar_index, + mPeriod); + + // + double lastHH = mLastHHH; + double lastLL = mLastHLL; + + // + double mHHState = EMPTY_VALUE; + double mhhColorIDX = mHideColorIDX; + if (showLevels) + { + // + if (hhValue == lastHH) + { + mhhColorIDX = showConsolidations ? 1 : mHideColorIDX; + } + else if (hhValue > lastHH) + { + mhhColorIDX = 2; + } + else if (hhValue < lastHH) + { + mhhColorIDX = 3; + } + + // + mHHState = mhhColorIDX; + } + else + { + mhhColorIDX = mHideColorIDX; + } + + // + double mLLState = EMPTY_VALUE; + double mllColorIDX = mHideColorIDX; + if (showLevels) + { + // + if (llValue == lastLL) + { + mllColorIDX = showConsolidations ? 1 : mHideColorIDX; + } + else if (llValue > lastLL) + { + mllColorIDX = 2; + } + else if (llValue < lastLL) + { + mllColorIDX = 3; + } + + // + mLLState = mllColorIDX; + } + else + { + mllColorIDX = mHideColorIDX; + } + + // + mLastHHH = hhValue; + mLastHLL = llValue; + + // + hHHBuffer[bar_index] = hhValue; + hLLBuffer[bar_index] = llValue; + hHHStateBuffer[bar_index] = mHHState; + hLLStateBuffer[bar_index] = mLLState; + hHHColorBuffer[bar_index] = mhhColorIDX; + hLLColorBuffer[bar_index] = mllColorIDX; +} + +// +// Calculate Peaks and Values ... +void CalculatePeaksAndVales( + int bar_index // Bar Index +) +{ + // + // Retrieve Requirements ... + + // + // Short ... + double sHHValue = sHHBuffer[bar_index]; + double sLLValue = sLLBuffer[bar_index]; + + // + // Medium ... + double mHHValue = mHHBuffer[bar_index]; + double mLLValue = mLLBuffer[bar_index]; + + // + // Long ... + double lHHValue = lHHBuffer[bar_index]; + double lLLValue = lLLBuffer[bar_index]; + + // + // Hind ... + double hHHValue = hHHBuffer[bar_index]; + double hLLValue = hLLBuffer[bar_index]; + + // + double rColorIDX = mHideColorIDX; + double sColorIDX = mHideColorIDX; + + // + // RESISTANCE ... + double rValue = (sHHValue + mHHValue + lHHValue + hHHValue) / 4; + + // + // PEAKS ... + bool isPeak = rValue == hHHValue && + hHHValue == lHHValue && + lHHValue == mHHValue && + mHHValue == sHHValue; + + // + if (isPeak && lastPeak != rValue) + { + // + rColorIDX = 1; + lastPeak = rValue; + peaksStateBuffer[bar_index] = rColorIDX; + } + else + { + peaksStateBuffer[bar_index] = EMPTY_VALUE; + } + + // + // SUPPORT ... + double sValue = (sLLValue + mLLValue + lLLValue + hLLValue) / 4; + + // + // VALES ... + bool isVale = sValue == hLLValue && + hLLValue == lLLValue && + lLLValue == mLLValue && + mLLValue == sLLValue; + + // + if (isVale && lastVale != sValue) + { + // + sColorIDX = 1; + lastVale = sValue; + valesStateBuffer[bar_index] = sColorIDX; + } + else + { + valesStateBuffer[bar_index] = EMPTY_VALUE; + } + + // + rBuffer[bar_index] = rValue; + sBuffer[bar_index] = sValue; + peaksBuffer[bar_index] = lastPeak; + valesBuffer[bar_index] = lastVale; + + // + if (showPeaksAndVales) + { + // + rColorBuffer[bar_index] = rColorIDX; + sColorBuffer[bar_index] = sColorIDX; + } + else + { + // + rColorBuffer[bar_index] = mHideColorIDX; + sColorBuffer[bar_index] = mHideColorIDX; + } +} + +// +// Calculate Fibonacci Level 1 ... +void CalculateFibonacci( + int bar_index // Bar Index +) +{ + // + // Select Requirements ... + double upPrice = peaksBuffer[bar_index]; + double downPrice = valesBuffer[bar_index]; + + // + // Level 1 ... + double fibLevel1Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel1, + 1); + // + // Level 2 ... + double fibLevel2Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel2, + 1); + + // + // Level 3 ... + double fibLevel3Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel3, + 1); + + // + // Level 4 ... + double fibLevel4Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel4, + 1); + + // + // Level 5 ... + double fibLevel5Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel5, + 1); + + // + fl1Buffer[bar_index] = fibLevel1Value; + fl2Buffer[bar_index] = fibLevel2Value; + fl3Buffer[bar_index] = fibLevel3Value; + fl4Buffer[bar_index] = fibLevel4Value; + fl5Buffer[bar_index] = fibLevel5Value; + + // + double fl1ColorIdx = showFibo1Levels ? 1 : mHideColorIDX; + double fl2ColorIdx = showFibo2Levels ? 1 : mHideColorIDX; + double fl3ColorIdx = showFibo3Levels ? 1 : mHideColorIDX; + double fl4ColorIdx = showFibo4Levels ? 1 : mHideColorIDX; + double fl5ColorIdx = showFibo5Levels ? 1 : mHideColorIDX; + + // + fl1ColorBuffer[bar_index] = fl1ColorIdx; + fl2ColorBuffer[bar_index] = fl2ColorIdx; + fl3ColorBuffer[bar_index] = fl3ColorIdx; + fl4ColorBuffer[bar_index] = fl4ColorIdx; + fl5ColorBuffer[bar_index] = fl5ColorIdx; +} + +// +// XSTR ... +bool CalculateXSTR( + const int rates_total, + const int prev_calculated, + const double &open[], + const double &high[], + const double &low[], + const double &close[] // +) +{ + // + bool result = false; + + // + int numOfRequiredAtrs; + if (prev_calculated > rates_total || prev_calculated < 0) + { + numOfRequiredAtrs = rates_total; + } + else + { + // + numOfRequiredAtrs = rates_total - prev_calculated; + if (prev_calculated > 0) + { + numOfRequiredAtrs++; + } + } + + // + // Checking for stop ... + if (IsStopped()) + { + return result; + } + + // + // Check Number of items Copy or not ... + int copiedATRs = CopyBuffer(atrHandler, 0, 0, numOfRequiredAtrs, atrBuffer); + if (copiedATRs <= 0) + { + return result; + } + + // + // + int limit; + + // + // checking for the limit start of calculation of an indicator ... + if (prev_calculated > rates_total || prev_calculated <= 0) + { + // + // starting index for calculation of all bars ... + limit = maxLength; + } + else + { + // + // starting number for calculation of new bars + limit = prev_calculated - 1; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + // + // Calculated Price ... + double price = GetAppliedPrice( + trendPriceAppliedTo, + open, + high, + low, + close, + i); + priceBuffer[i] = price; + + // + double atr = atrBuffer[i]; + + // + // Up ... + upBuffer[i] = price + (trendMultiplier * atr); + + // + // Down ... + downBuffer[i] = price - (trendMultiplier * atr); + + // + if (close[i] > upBuffer[i - 1]) + { + // + trendStateBuffer[i] = 1; + if (trendStateBuffer[i - 1] == -1) + { + changeOfTrend = 1; + } + } + else if (close[i] < downBuffer[i - 1]) + { + // + trendStateBuffer[i] = -1; + if (trendStateBuffer[i - 1] == 1) + { + changeOfTrend = 1; + } + } + else if (trendStateBuffer[i - 1] == 1) + { + // + trendStateBuffer[i] = 1; + changeOfTrend = 0; + } + else if (trendStateBuffer[i - 1] == -1) + { + // + trendStateBuffer[i] = -1; + changeOfTrend = 0; + } + + // + // Down Trend Starting ... + if (trendStateBuffer[i] < 0 && trendStateBuffer[i - 1] > 0) + { + startBearishTrend = 1; + } + else + { + startBearishTrend = 0; + } + + // + // Up Trend Starting ... + if (trendStateBuffer[i] > 0 && trendStateBuffer[i - 1] < 0) + { + startBullishTrend = 1; + } + else + { + startBullishTrend = 0; + } + + // + if (trendStateBuffer[i] > 0 && downBuffer[i] < downBuffer[i - 1]) + { + downBuffer[i] = downBuffer[i - 1]; + } + + // + if (trendStateBuffer[i] < 0 && upBuffer[i] > upBuffer[i - 1]) + { + upBuffer[i] = upBuffer[i - 1]; + } + + // + if (startBearishTrend == 1) + { + upBuffer[i] = priceBuffer[i] + (trendMultiplier * atr); + } + + // + if (startBullishTrend == 1) + { + downBuffer[i] = priceBuffer[i] - (trendMultiplier * atr); + } + + // + // Draw the indicator ... + + // + double colorIDX = 0; + double state = EMPTY_VALUE; + trendColorBuffer[i] = colorIDX; + + // + if (trendStateBuffer[i] == 1) + { + // + trendBuffer[i] = downBuffer[i]; + if (changeOfTrend == 1) + { + // + trendBuffer[i - 1] = trendBuffer[i - 2]; + changeOfTrend = 0; + + // + state = 2; + } + + // + colorIDX = 1; + } + else if (trendStateBuffer[i] == -1) + { + // + trendBuffer[i] = upBuffer[i]; + if (changeOfTrend == 1) + { + // + trendBuffer[i - 1] = trendBuffer[i - 2]; + changeOfTrend = 0; + + // + state = 3; + } + + // + colorIDX = 2; + } + + // + if (showTrends) + { + trendColorBuffer[i] = colorIDX; + } + strTrendStateBuffer[i] = state; + + // + // Filling ... + if (fillTrends) + { + // + fillUpBuffer[i] = trendBuffer[i]; + fillDownBuffer[i] = close[i]; + } + else + { + // + fillUpBuffer[i] = EMPTY_VALUE; + fillDownBuffer[i] = EMPTY_VALUE; + } + } + + // + result = true; + + // + return true; +} + +// +XMRBColorInfo GetRibbonColorIndex( + double value, + const double h, + const double l // +) +{ + // + XMRBColorInfo result; + + // + result.state = EMPTY_VALUE; + result.clr = mHideColorIDX; + + // + // Color Indexes ... + // 0 => HIDE + // 1 => NEUTURAL + // 2 => BULLISH + // 3 => BEARISH + + // + result.clr = 1; + + // + if (value < l && value < h) + { + result.clr = 2; + } + else if (value > h && value > l) + { + result.clr = 3; + } + else if (value < h && value > l) + { + result.clr = 1; + } + + // + result.state = result.clr; + + // + if (!showRibbons) + { + result.clr = mHideColorIDX; + } + + // + return result; +} + +// +// Calculate Ribbons Color ... +void CalculateRibbonsColors( + int bar_index, // Bar Index + const double &high[], + const double &low[] // +) +{ + // + double tmpVal; + XMRBColorInfo tmpColorIDX; + + // + double h = high[bar_index]; + double l = low[bar_index]; + + // + // RIBBON 1 ... + tmpVal = ribbon1Buffer[bar_index]; + tmpColorIDX = GetRibbonColorIndex( + tmpVal, + h, + l); + rb1StateBuffer[bar_index] = tmpColorIDX.state; + ribbon1ColorBuffer[bar_index] = tmpColorIDX.clr; + + // + // RIBBON 2 ... + tmpVal = ribbon2Buffer[bar_index]; + tmpColorIDX = GetRibbonColorIndex( + tmpVal, + h, + l); + rb2StateBuffer[bar_index] = tmpColorIDX.state; + ribbon2ColorBuffer[bar_index] = tmpColorIDX.clr; + + // + // RIBBON 3 ... + tmpVal = ribbon3Buffer[bar_index]; + tmpColorIDX = GetRibbonColorIndex( + tmpVal, + h, + l); + rb3StateBuffer[bar_index] = tmpColorIDX.state; + ribbon3ColorBuffer[bar_index] = tmpColorIDX.clr; + + // + // RIBBON 4 ... + tmpVal = ribbon4Buffer[bar_index]; + tmpColorIDX = GetRibbonColorIndex( + tmpVal, + h, + l); + rb4StateBuffer[bar_index] = tmpColorIDX.state; + ribbon4ColorBuffer[bar_index] = tmpColorIDX.clr; + + // + // RIBBON 5 ... + tmpVal = ribbon5Buffer[bar_index]; + tmpColorIDX = GetRibbonColorIndex( + tmpVal, + h, + l); + rb5StateBuffer[bar_index] = tmpColorIDX.state; + ribbon5ColorBuffer[bar_index] = tmpColorIDX.clr; + + // + // RIBBON 6 ... + tmpVal = ribbon6Buffer[bar_index]; + tmpColorIDX = GetRibbonColorIndex( + tmpVal, + h, + l); + rb6StateBuffer[bar_index] = tmpColorIDX.state; + ribbon6ColorBuffer[bar_index] = tmpColorIDX.clr; +} + +// +// Calculate SSL Channel ... +void CalculateSSLC( + int bar_index, // Selected Bar Index + int limit, + int ratesTotal, + int prevCalculated, + const double &close[]) +{ + // + double upMaValue = sslcUpMaBuffer[bar_index]; + double downMaValue = sslcDownMaBuffer[bar_index]; + + // + double closeValue = close[bar_index]; + + // + double kpiValue; + if (closeValue > upMaValue) + { + kpiValue = 1; + } + else if (closeValue < downMaValue) + { + kpiValue = -1; + } + else + { + kpiValue = sslcKpiBuffer[bar_index + 1]; + } + + // + sslcKpiBuffer[bar_index] = kpiValue; + + // + double upValue = kpiValue < 0 ? downMaValue : upMaValue; + sslcUpBuffer[bar_index] = upValue; + + // + double downValue = kpiValue < 0 ? upMaValue : downMaValue; + sslcDownBuffer[bar_index] = downValue; + + // + if (showSSLChannel) + { + // + sslcUpColorBuffer[bar_index] = 1; + sslcDownColorBuffer[bar_index] = 1; + } + else + { + // + sslcUpColorBuffer[bar_index] = mHideColorIDX; + sslcDownColorBuffer[bar_index] = mHideColorIDX; + } +} + +// +// Calculate XHULL ... +void CalculateHull( + int bar_index, // Selected Bar Index + int ratesTotal, // Total Rates + double upPrice, // Up Price ... + double downPrice // Down Price ... +) +{ + // + double upValue = mUpZHull.Calculate( + upPrice, + bar_index, + ratesTotal); + hullUpZoneBuffer[bar_index] = upValue; + double upColorIDX = (bar_index > 0) + ? (hullUpZoneBuffer[bar_index] > hullUpZoneBuffer[bar_index - 1]) + ? 2 + : (hullUpZoneBuffer[bar_index] < hullUpZoneBuffer[bar_index - 1]) + ? 3 + : hullUpZoneColorBuffer[bar_index - 1] + : 1; + + // + double downValue = mDownZHull.Calculate( + downPrice, + bar_index, + ratesTotal); + hullDownZoneBuffer[bar_index] = downValue; + double downColorIDX = (bar_index > 0) + ? (hullDownZoneBuffer[bar_index] > hullDownZoneBuffer[bar_index - 1]) + ? 2 + : (hullDownZoneBuffer[bar_index] < hullDownZoneBuffer[bar_index - 1]) + ? 3 + : hullDownZoneColorBuffer[bar_index - 1] + : 1; + + // + hullUpStateBuffer[bar_index] = upColorIDX == 0 ? 1 : upColorIDX; + hullDownStateBuffer[bar_index] = downColorIDX == 0 ? 1 : downColorIDX; + if (showHull) + { + // + hullUpZoneColorBuffer[bar_index] = upColorIDX; + hullDownZoneColorBuffer[bar_index] = downColorIDX; + } + else + { + // + hullUpZoneColorBuffer[bar_index] = mHideColorIDX; + hullDownZoneColorBuffer[bar_index] = mHideColorIDX; + } +} + +// +// Calculate HikenAshi Buffers ... +void CalculateHikenAshi( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[]) +{ + // + double mPrevHKOpenValue; + double mPrevHKCloseValue; + + // + if (ArraySize(open) <= bar_index + 1) + { + // + mPrevHKOpenValue = 0; + mPrevHKCloseValue = 0; + } + else + { + // + mPrevHKOpenValue = hkOpenBuffer[bar_index + 1]; + mPrevHKCloseValue = hkCloseBuffer[bar_index + 1]; + } + + // + double mHKOpenValue = (mPrevHKOpenValue + mPrevHKCloseValue) / 2; + double mHKCloseValue = (open[bar_index] + high[bar_index] + close[bar_index] + low[bar_index]) / 4; + double mHKHighValue = MathMax(high[bar_index], MathMax(mHKOpenValue, mHKCloseValue)); + double mHKLowValue = MathMin(low[bar_index], MathMin(mHKOpenValue, mHKCloseValue)); + + // + hkOpenBuffer[bar_index] = mHKOpenValue; + hkHighBuffer[bar_index] = mHKHighValue; + hkLowBuffer[bar_index] = mHKLowValue; + hkCloseBuffer[bar_index] = mHKCloseValue; + + // + double candleColorValue = + mHKOpenValue < mHKCloseValue ? 1 : 2; + + // + hkStateBuffer[bar_index] = candleColorValue + 1; + hkCandleColorBuffer[bar_index] = showHKCandles ? candleColorValue : 0; +} + +// +// Calculate Candle Timer ... +void CalculateCandleTimer() +{ + // + if (!showCandleTimer) + { + return; + } + + // + XCandleRemains remainTime; + GetCandleRemainsTime( + remainTime, + _Symbol, + _Period, + 0); + + // + string msg = ToString( + remainTime, + "", + "", + "", + "", + "", + ":", + true); + + // + long mSpread = SymbolInfoInteger(Symbol(), SYMBOL_SPREAD); + + // + string _sp = ""; + if (mSpread < 10) + _sp = ".."; + else if (mSpread < 100) + _sp = "."; + + // + string objText = "Spread: " + IntegerToString(mSpread) + _sp + " Next Bar in: " + msg; + + // + ObjectSetString(0, ShortName, OBJPROP_TEXT, objText); + ObjectSetInteger(0, ShortName, OBJPROP_FONTSIZE, 10); + ObjectSetString(0, ShortName, OBJPROP_FONT, "Courier"); + ObjectSetInteger(0, ShortName, OBJPROP_COLOR, candleTimerColor); +} + +// +// Calculate Smoothed Hiken Ashi Candles ... +void CalculateSMHK( + int ratesTotal, // Total Bars + int prevCalculated // Calculated Bars +) +{ + // + // Open ... + int calculatedSMHKOpens = ExponentialMAOnBuffer( + ratesTotal, + prevCalculated, + 0, + mHKSmoothingLength, + hkOpenBuffer, + smhkOpenBuffer); + + // + // High ... + int calculatedSMHKHighs = ExponentialMAOnBuffer( + ratesTotal, + prevCalculated, + 0, + mHKSmoothingLength, + hkHighBuffer, + smhkHighBuffer); + + // + // Low ... + int calculatedSMHKLows = ExponentialMAOnBuffer( + ratesTotal, + prevCalculated, + 0, + mHKSmoothingLength, + hkLowBuffer, + smhkLowBuffer); + + // + // Close ... + int calculatedSMHKCloses = ExponentialMAOnBuffer( + ratesTotal, + prevCalculated, + 0, + mHKSmoothingLength, + hkCloseBuffer, + smhkCloseBuffer); + + // + // Find Calculated Items for Colors ... + int mNumberOfItems = MathMin(calculatedSMHKOpens, calculatedSMHKHighs); + mNumberOfItems = MathMin(mNumberOfItems, calculatedSMHKLows); + mNumberOfItems = MathMin(mNumberOfItems, calculatedSMHKCloses); + + // + // Create a Loop for Color of Candles ... + for (int i = 0; i < mNumberOfItems; i++) + { + // + bool isBearish = + // + smhkOpenBuffer[i] > smhkCloseBuffer[i] + // + ; + + // + if (showSMHKCandles) + { + // + smhkCandleColorBuffer[i] = isBearish + ? 2 + : 1; + } + else + { + // + smhkCandleColorBuffer[i] = mHideColorIDX; + } + } +} + +// +// END Calculation Parts ... +// + +// +// START Utilities ... +// + +// +// Create Candle Timer ... +void CreateIndicatorObject() +{ + // + if (!showCandleTimer) + { + return; + } + + // + ObjectCreate(0, ShortName, OBJ_LABEL, 0, 0, 0); + ObjectSetInteger(0, ShortName, OBJPROP_CORNER, candleTimerCorner); + ObjectSetInteger(0, ShortName, OBJPROP_XDISTANCE, 10); + ObjectSetInteger(0, ShortName, OBJPROP_YDISTANCE, 2); + + // + ENUM_ANCHOR_POINT Anchor = ANCHOR_LEFT_UPPER; + switch (candleTimerCorner) + { + case CORNER_LEFT_UPPER: + Anchor = ANCHOR_LEFT_UPPER; + break; + case CORNER_RIGHT_UPPER: + Anchor = ANCHOR_RIGHT_UPPER; + break; + case CORNER_LEFT_LOWER: + Anchor = ANCHOR_LEFT_LOWER; + break; + case CORNER_RIGHT_LOWER: + Anchor = ANCHOR_RIGHT_LOWER; + break; + } + + // + ObjectSetInteger(0, ShortName, OBJPROP_ANCHOR, Anchor); +} + +// +bool InitMaHandler( + int &handler, + int length, + ENUM_X_MA_METHOD mode, + ENUM_APPLIED_PRICE appliedTo) +{ + // + bool result = false; + + // + if (length <= 0) + { + return result; + } + + // + bool genericMethod = false; + ENUM_MA_METHOD method = NULL; + if (mode == X_MA_AMA) + { + // + handler = iAMA( + _Symbol, + _Period, + length, + mMRBAMAFast, + mMRBAMASlow, + 0, + appliedTo); + } + else if (mode == X_MA_EMA) + { + // + method = MODE_EMA; + genericMethod = true; + } + else if (mode == X_MA_LWMA) + { + // + method = MODE_LWMA; + genericMethod = true; + } + else if (mode == X_MA_SMA) + { + // + method = MODE_SMA; + genericMethod = true; + } + else if (mode == X_MA_SMMA) + { + // + method = MODE_SMMA; + genericMethod = true; + } + + // + if (genericMethod && handler == INVALID_HANDLE) + { + // + handler = iMA( + _Symbol, + _Period, + length, + 0, + method, + appliedTo); + } + + // + result = handler != INVALID_HANDLE; + + // + return result; +} + +// +// Retrieve Cycles Highest High ... +double GetCycleHH( + int bar_index, // Bar Index + ENUM_TIMEFRAMES period // Period +) +{ + // + datetime mCycleStartAt = GetPeriodStartTime( + _Symbol, + period); + + // + int mStartCycleBarIndex = iBarShift( + _Symbol, + _Period, + mCycleStartAt, + false); + + // + int mCycleCount = MathAbs(mStartCycleBarIndex - bar_index); + if (mCycleCount < 1) + { + mCycleCount = 1; + } + + // + // HIGH ... + int hhIndex = iHighest( + _Symbol, + _Period, + hhMode, + mCycleCount, + bar_index); + double result = GetAppliedPrice( + hhIndex, + hhMode); + + // + return result; +} + +// +// Retrieve Cycles Lowest Low ... +double GetCycleLL( + int bar_index, // Bar Index + ENUM_TIMEFRAMES period // Period +) +{ + // + datetime mCycleStartAt = GetPeriodStartTime( + _Symbol, + period); + + // + int mStartCycleBarIndex = iBarShift( + _Symbol, + _Period, + mCycleStartAt, + false); + + // + int mCycleCount = MathAbs(mStartCycleBarIndex - bar_index); + if (mCycleCount < 1) + { + mCycleCount = 1; + } + + // + // LOW ... + int llIndex = iLowest( + _Symbol, + _Period, + llMode, + mCycleCount, + bar_index); + double result = GetAppliedPrice( + llIndex, + llMode); + + // + return result; +} + +// +// Retrieve Cycles Highest High ... +double GetCycleHHC( + int bar_index, // Bar Index + ENUM_TIMEFRAMES period // Period +) +{ + // + int mCycleCount = 0; + if (period == mL1Period) + { + mCycleCount = mL1Candles; + } + else if (period == mL2Period) + { + mCycleCount = mL2Candles; + } + else if (period == mL3Period) + { + mCycleCount = mL3Candles; + } + else if (period == mL4Period) + { + mCycleCount = mL4Candles; + } + + // + // HIGH ... + int hhIndex = iHighest( + _Symbol, + _Period, + hhMode, + mCycleCount, + bar_index); + double result = GetAppliedPrice( + hhIndex, + hhMode); + + // + return result; +} + +// +// Retrieve Cycles Lowest Low ... +double GetCycleLLC( + int bar_index, // Bar Index + ENUM_TIMEFRAMES period // Period +) +{ + // + int mCycleCount = 0; + if (period == mL1Period) + { + mCycleCount = mL1Candles; + } + else if (period == mL2Period) + { + mCycleCount = mL2Candles; + } + else if (period == mL3Period) + { + mCycleCount = mL3Candles; + } + else if (period == mL4Period) + { + mCycleCount = mL4Candles; + } + + // + // LOW ... + int llIndex = iLowest( + _Symbol, + _Period, + llMode, + mCycleCount, + bar_index); + double result = GetAppliedPrice( + llIndex, + llMode); + + // + return result; +} + +// +string GenerateCyclesRepresentation() +{ + // + string result = ""; + + // + result += "C1: " + ToString(mL1Period) + "\n"; + result += "C2: " + ToString(mL2Period) + "\n"; + result += "C3: " + ToString(mL3Period) + "\n"; + result += "C4: " + ToString(mL4Period); + + // + return result; +} + +// +// Apply Custom Chart Style ... +void ApplyCustomChartStyle() +{ + // + // Read Current Chart Config and Store it ... + ReadChartStyle(); + + // + // After Reading Current Chart Style ... + // we have to Save Configs and Change Styles ... + clearStyle = chartStyle; + + // + clearStyle.upColor = CLR_NONE; + clearStyle.downColor = CLR_NONE; + clearStyle.lineColor = CLR_NONE; + clearStyle.bullishColor = CLR_NONE; + clearStyle.bearishColor = CLR_NONE; + + // + // Decide to Show or not Candles based on User Input ... + if (showCandles) + { + SetChartStyle(chartStyle); + } + else + { + SetChartStyle(clearStyle); + } +} + +// +// Read Previous Chart Style ... +void ReadChartStyle() +{ + // + // Retrieve Current Chart ID ... + long chartId = ChartID(); + chartStyle.chartId = chartId; + + // + // Retrieve Chart Mode ... + chartStyle.mode = (ENUM_CHART_MODE)ChartGetInteger(chartId, CHART_MODE); + + // + chartStyle.showBidLine = (bool)ChartGetInteger(chartId, CHART_SHOW_BID_LINE); + chartStyle.showAskLine = (bool)ChartGetInteger(chartId, CHART_SHOW_ASK_LINE); + chartStyle.showGrid = (bool)ChartGetInteger(chartId, CHART_SHOW_GRID); + chartStyle.showVolumes = (bool)ChartGetInteger(chartId, CHART_SHOW_VOLUMES); + chartStyle.showTradeLevels = (bool)ChartGetInteger(chartId, CHART_SHOW_TRADE_LEVELS); + chartStyle.autoScroll = (bool)ChartGetInteger(chartId, CHART_AUTOSCROLL); + chartStyle.quickNavigation = (bool)ChartGetInteger(chartId, CHART_QUICK_NAVIGATION); + + // + chartStyle.foreGroundColor = (color)ChartGetInteger(chartId, CHART_COLOR_FOREGROUND); + chartStyle.backGroundColor = (color)ChartGetInteger(chartId, CHART_COLOR_BACKGROUND); + chartStyle.upColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_UP); + chartStyle.downColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_DOWN); + chartStyle.bullishColor = (color)ChartGetInteger(chartId, CHART_COLOR_CANDLE_BULL); + chartStyle.bearishColor = (color)ChartGetInteger(chartId, CHART_COLOR_CANDLE_BEAR); + chartStyle.gridColor = (color)ChartGetInteger(chartId, CHART_COLOR_GRID); + chartStyle.bidLineColor = (color)ChartGetInteger(chartId, CHART_COLOR_BID); + chartStyle.askLineColor = (color)ChartGetInteger(chartId, CHART_COLOR_ASK); + chartStyle.stopColor = (color)ChartGetInteger(chartId, CHART_COLOR_STOP_LEVEL); + chartStyle.lineColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_LINE); + chartStyle.volumesColor = (color)ChartGetInteger(chartId, CHART_COLOR_VOLUME); + + // + chartStyle.mode = chartMode; + chartStyle.upColor = upColor; + chartStyle.downColor = downColor; + chartStyle.lineColor = lineColor; + chartStyle.bearishColor = bearishColor; + chartStyle.bullishColor = bullishColor; + chartStyle.volumesColor = volumesColor; + + // + chartStyle.showGrid = false; + chartStyle.showAskLine = true; + chartStyle.showBidLine = true; +} + +// +// Set Chart Style ... +void SetChartStyle( + XChartStyle &mChartStyle // Chart Style to Apply +) +{ + // + ApplyChartStyle( + mChartStyle.chartId, + mChartStyle.mode, + mChartStyle.showBidLine, + mChartStyle.showAskLine, + mChartStyle.showGrid, + mChartStyle.showVolumes, + mChartStyle.showTradeLevels, + mChartStyle.autoScroll, + mChartStyle.quickNavigation, + mChartStyle.foreGroundColor, + mChartStyle.backGroundColor, + mChartStyle.upColor, + mChartStyle.downColor, + mChartStyle.bullishColor, + mChartStyle.bearishColor, + mChartStyle.gridColor, + mChartStyle.bidLineColor, + mChartStyle.askLineColor, + mChartStyle.lineColor, + mChartStyle.stopColor, + mChartStyle.volumesColor); +} + +// +// END Utilities ... +// + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xosc.ex5 b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xosc.ex5 new file mode 100644 index 0000000..4358f8a Binary files /dev/null and b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xosc.ex5 differ diff --git a/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xosc.mq5 b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xosc.mq5 new file mode 100644 index 0000000..0f0f9ef --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xosc.mq5 @@ -0,0 +1,721 @@ +////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: X121_XOSC +// Description: provides some oscillator values +// as empty Indicator ... +// +// +// 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_XAMA Indicator" +#property strict + +// +// START Constants ... +// + +#define ShortName "X121_XOSC" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +// ATR ... +input group "ATR"; +input int atrLength = 14; // Length + +// +// RVI ... +// The buffer numbers are the following: 0 - MAIN_LINE, 1 - SIGNAL_LINE. +input group "RVI"; +input int rviLength = 10; // Length + +// +// BULLPOWER ... +input group "Bulls Power"; +input int bullpLength = 13; // Length + +// +// BEARPOWER ... +input group "Bears Power"; +input int bearpLength = 13; // Length + +// +// VOLUME ... +input group "Volumes"; +input ENUM_APPLIED_VOLUME volumeAppliedTo = VOLUME_TICK; // Applied To + +// +// RSI ... +input group "RSI"; +input int rsiLength = 14; // Length +input ENUM_APPLIED_PRICE rsiAppliedTo = PRICE_CLOSE; // Applied To + +// +// CCI ... +input group "CCI"; +input int cciLength = 14; // Length +input ENUM_APPLIED_PRICE cciAppliedTo = PRICE_TYPICAL; // Applied To + +// +// STDDEV ... +input group "Standard Deviation"; +input int stddevLength = 20; // Length +input int stddevShift = 0; // Shift +input ENUM_MA_METHOD stddevMethod = MODE_SMA; // Mode +input ENUM_APPLIED_PRICE stddevAppliedTo = PRICE_CLOSE; // AppliedTo + +// +// MOMENTUM ... +input group "Momentum"; +input int momentumLength = 14; // Length +input ENUM_APPLIED_PRICE momentumAppliedTo = PRICE_CLOSE; // Applied To + +// +// SAR ... +input group "SAR"; +input double sarStep = 0.02; // Step +input double sarMaximum = 0.2; // Maximum + +// +// MACD ... +// The buffer numbers are the following: 0 - MAIN_LINE, 1 - SIGNAL_LINE. +input group "MACD"; +input int macdFastLength = 12; // Fast Length +input int macdSlowLength = 26; // Slow Length +input int macdSignaLength = 9; // Signal Length +input ENUM_APPLIED_PRICE macdAppliedTo = PRICE_CLOSE; // Applied To + +// +// STOCHASTIC ... +// The buffer numbers: 0 - MAIN_LINE, 1 - SIGNAL_LINE. +input group "Stochastic"; +input int stochKLength = 5; // K Length +input int stochDLength = 3; // D Length +input int stochSlowing = 3; // Slowing +input ENUM_MA_METHOD stochMaMethod = MODE_SMA; // Ma Method +input ENUM_STO_PRICE stochMode = STO_LOWHIGH; // Calculation Mode + +// +// END Inputs ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 15 +#property indicator_plots 0 + +// +// ATR ... +#define atrBufferIndex 0 +double atrBuffer[]; + +// +// RVI ... +#define rviMainBufferIndex 1 +#define rviSignalBufferIndex 2 +double rviMainBuffer[]; +double rviSignalBuffer[]; + +// +// BULLPOWER ... +#define bullPBufferIndex 3 +double bullPBuffer[]; + +// +// BEARPOWER ... +#define bearPBufferIndex 4 +double bearPBuffer[]; + +// +// VOLUME ... +#define volumeBufferIndex 5 +double volumeBuffer[]; + +// +// RSI ... +#define rsiBufferIndex 6 +double rsiBuffer[]; + +// +// CCI ... +#define cciBufferIndex 7 +double cciBuffer[]; + +// +// MOMENTUM ... +#define momentumBufferIndex 8 +double momentumBuffer[]; + +// +// SAR ... +#define sarBufferIndex 9 +double sarBuffer[]; + +// +// MACD ... +#define macdMainBufferIndex 10 +#define macdSignalBufferIndex 11 +double macdMainBuffer[]; +double macdSignalBuffer[]; + +// +// STOCHASTIC ... +#define stochMainBufferIndex 12 +#define stochSignalBufferIndex 13 +double stochMainBuffer[]; +double stochSignalBuffer[]; + +// +// STANDARDDEVIATION ... +#define stddevBufferIndex 14 +double stddevBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int atrHandler = INVALID_HANDLE; +int rviHandler = INVALID_HANDLE; +int bullPHandler = INVALID_HANDLE; +int bearPHandler = INVALID_HANDLE; +int volumeHandler = INVALID_HANDLE; +int rsiHandler = INVALID_HANDLE; +int cciHandler = INVALID_HANDLE; +int momentumHandler = INVALID_HANDLE; +int sarHandler = INVALID_HANDLE; +int macdHandler = INVALID_HANDLE; +int stochHandler = INVALID_HANDLE; +int stddevHandler = INVALID_HANDLE; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // 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(); + + // + // Initializing Handlers ... + + // + // ATR ... + atrHandler = iATR( + _Symbol, + _Period, + atrLength); + + // + // RVI ... + rviHandler = iRVI( + _Symbol, + _Period, + rviLength); + + // + // BULLSPOWER ... + bullPHandler = iBullsPower( + _Symbol, + _Period, + bullpLength); + + // + // BEARSPOWER ... + bearPHandler = iBearsPower( + _Symbol, + _Period, + bullpLength); + + // + // VOLUMES ... + volumeHandler = iVolumes( + _Symbol, + _Period, + volumeAppliedTo); + + // + // RSI ... + rsiHandler = iRSI( + _Symbol, + _Period, + rsiLength, + rsiAppliedTo); + + // + // CCI ... + cciHandler = iCCI( + _Symbol, + _Period, + cciLength, + cciAppliedTo); + + // + // MOMENTUM ... + momentumHandler = iMomentum( + _Symbol, + _Period, + momentumLength, + momentumAppliedTo); + + // + // SAR ... + sarHandler = iSAR( + _Symbol, + _Period, + sarStep, + sarMaximum); + + // + // MACD ... + macdHandler = iMACD( + _Symbol, + _Period, + macdFastLength, + macdSlowLength, + macdSignaLength, + macdAppliedTo); + + // + // STOCHASTIC ... + stochHandler = iStochastic( + _Symbol, + _Period, + stochKLength, + stochDLength, + stochSlowing, + stochMaMethod, + stochMode); + + // + // STANDARDDEVIATION ... + stddevHandler = iStdDev( + _Symbol, + _Period, + stddevLength, + stddevShift, + stddevMethod, + stddevAppliedTo); + + // + bool isAllHandlersInit = + // + atrHandler != INVALID_HANDLE && + rviHandler != INVALID_HANDLE && + bullPHandler != INVALID_HANDLE && + bearPHandler != INVALID_HANDLE && + volumeHandler != INVALID_HANDLE && + rsiHandler != INVALID_HANDLE && + cciHandler != INVALID_HANDLE && + momentumHandler != INVALID_HANDLE && + sarHandler != INVALID_HANDLE && + macdHandler != INVALID_HANDLE && + stochHandler != INVALID_HANDLE && + stddevHandler != INVALID_HANDLE + // + ; + if (!isAllHandlersInit) + { + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +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 + + // + // Here we can handle De Initialization Reasons ... + IndicatorRelease(atrHandler); + IndicatorRelease(rviHandler); + IndicatorRelease(bullPHandler); + IndicatorRelease(bearPHandler); + IndicatorRelease(volumeHandler); + IndicatorRelease(rsiHandler); + IndicatorRelease(cciHandler); + IndicatorRelease(momentumHandler); + IndicatorRelease(sarHandler); + IndicatorRelease(macdHandler); + IndicatorRelease(stochHandler); + IndicatorRelease(stddevHandler); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + 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); + + // + // this counts Available Bars ... + int limit; + + // + // Check Calculated Bars ... + int atrCalculatedBars = BarsCalculated(atrHandler); + int rviCalculatedBars = BarsCalculated(rviHandler); + int bullPCalculatedBars = BarsCalculated(bullPHandler); + int bearPCalculatedBars = BarsCalculated(bearPHandler); + int volumeCalculatedBars = BarsCalculated(volumeHandler); + int rsiCalculatedBars = BarsCalculated(rsiHandler); + int cciCalculatedBars = BarsCalculated(cciHandler); + int momentumCalculatedBars = BarsCalculated(momentumHandler); + int sarCalculatedBars = BarsCalculated(sarHandler); + int macdCalculatedBars = BarsCalculated(macdHandler); + int stochCalculatedBars = BarsCalculated(stochHandler); + int stddevCalculatedBars = BarsCalculated(stddevHandler); + + // + bool isCalculatedBarsPassed = + // + atrCalculatedBars >= maxLength && + rviCalculatedBars >= maxLength && + bullPCalculatedBars >= maxLength && + bearPCalculatedBars >= maxLength && + volumeCalculatedBars >= maxLength && + rsiCalculatedBars >= maxLength && + cciCalculatedBars >= maxLength && + momentumCalculatedBars >= maxLength && + sarCalculatedBars >= maxLength && + macdCalculatedBars >= maxLength && + stochCalculatedBars >= maxLength && + stddevCalculatedBars >= maxLength + // + ; + if (!isCalculatedBarsPassed) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int atrCopiedItems = CopyBuffer(atrHandler, 0, 0, limit, atrBuffer); + int rviMainCopiedItems = CopyBuffer(rviHandler, MAIN_LINE, 0, limit, rviMainBuffer); + int rviSignalCopiedItems = CopyBuffer(rviHandler, SIGNAL_LINE, 0, limit, rviSignalBuffer); + int bullPCopiedItems = CopyBuffer(bullPHandler, 0, 0, limit, bullPBuffer); + int bearPCopiedItems = CopyBuffer(bearPHandler, 0, 0, limit, bearPBuffer); + int volumeCopiedItems = CopyBuffer(volumeHandler, 0, 0, limit, volumeBuffer); + int rsiCopiedItems = CopyBuffer(rsiHandler, 0, 0, limit, rsiBuffer); + int cciCopiedItems = CopyBuffer(cciHandler, 0, 0, limit, cciBuffer); + int momentumCopiedItems = CopyBuffer(momentumHandler, 0, 0, limit, momentumBuffer); + int sarCopiedItems = CopyBuffer(sarHandler, 0, 0, limit, sarBuffer); + int macdMainCopiedItems = CopyBuffer(macdHandler, MAIN_LINE, 0, limit, macdMainBuffer); + int macdSignalCopiedItems = CopyBuffer(macdHandler, SIGNAL_LINE, 0, limit, macdSignalBuffer); + int stochMainCopiedItems = CopyBuffer(stochHandler, MAIN_LINE, 0, limit, stochMainBuffer); + int stocSignalhCopiedItems = CopyBuffer(stochHandler, SIGNAL_LINE, 0, limit, stochSignalBuffer); + int stddevCopiedItems = CopyBuffer(stddevHandler, 0, 0, limit, stddevBuffer); + + // + bool isCopiedBarsPassed = + // + atrCopiedItems > 0 && + rviMainCopiedItems > 0 && + rviSignalCopiedItems > 0 && + bullPCopiedItems > 0 && + bearPCopiedItems > 0 && + volumeCopiedItems > 0 && + rsiCopiedItems > 0 && + cciCopiedItems > 0 && + momentumCopiedItems > 0 && + sarCopiedItems > 0 && + macdMainCopiedItems > 0 && + macdSignalCopiedItems > 0 && + stochMainCopiedItems > 0 && + stocSignalhCopiedItems > 0 && + stddevCopiedItems > 0 + // + ; + if (!isCopiedBarsPassed) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + // Do Buffers Calculation ... + // HERE We Do Not anything ... + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + result = + // + atrLength >= 2 && + rviLength >= 2 && + bullpLength >= 2 && + bearpLength >= 2 && + rsiLength >= 2 && + cciLength >= 2 && + momentumLength >= 2 && + sarStep > 0 && + sarStep < sarMaximum && + macdFastLength >= 2 && + macdSlowLength > macdFastLength && + macdSignaLength >= 2 && + stochKLength >= 2 && + stochDLength >= 2 && + stochSlowing >= 2 && + stddevLength >= 2 && + stddevShift >= 0 + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(atrLength, rviLength); + result = MathMax(result, bullpLength); + result = MathMax(result, bearpLength); + result = MathMax(result, rsiLength); + result = MathMax(result, cciLength); + result = MathMax(result, momentumLength); + result = MathMax(result, macdFastLength); + result = MathMax(result, macdSlowLength); + result = MathMax(result, macdSignaLength); + result = MathMax(result, stochKLength); + result = MathMax(result, stochDLength); + result = MathMax(result, stochSlowing); + result = MathMax(result, stddevLength); + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // DATA Buffers ... + + // + // ATR ... + ArraySetAsSeries(atrBuffer, true); + SetIndexBuffer(atrBufferIndex, atrBuffer, INDICATOR_CALCULATIONS); + + // + // RVI ... + + // + // Main ... + ArraySetAsSeries(rviMainBuffer, true); + SetIndexBuffer(rviMainBufferIndex, rviMainBuffer, INDICATOR_CALCULATIONS); + + // + // Signal ... + ArraySetAsSeries(rviSignalBuffer, true); + SetIndexBuffer(rviSignalBufferIndex, rviSignalBuffer, INDICATOR_CALCULATIONS); + + // + // BULLPOWER ... + ArraySetAsSeries(bullPBuffer, true); + SetIndexBuffer(bullPBufferIndex, bullPBuffer, INDICATOR_CALCULATIONS); + + // + // BEARPOWER ... + ArraySetAsSeries(bearPBuffer, true); + SetIndexBuffer(bearPBufferIndex, bearPBuffer, INDICATOR_CALCULATIONS); + + // + // VOLUME ... + ArraySetAsSeries(volumeBuffer, true); + SetIndexBuffer(volumeBufferIndex, volumeBuffer, INDICATOR_CALCULATIONS); + + // + // RSI ... + ArraySetAsSeries(rsiBuffer, true); + SetIndexBuffer(rsiBufferIndex, rsiBuffer, INDICATOR_CALCULATIONS); + + // + // CCI ... + ArraySetAsSeries(cciBuffer, true); + SetIndexBuffer(cciBufferIndex, cciBuffer, INDICATOR_CALCULATIONS); + + // + // MOMENTUM ... + ArraySetAsSeries(momentumBuffer, true); + SetIndexBuffer(momentumBufferIndex, momentumBuffer, INDICATOR_CALCULATIONS); + + // + // SAR ... + ArraySetAsSeries(sarBuffer, true); + SetIndexBuffer(sarBufferIndex, sarBuffer, INDICATOR_CALCULATIONS); + + // + // STANDARDDEVIATION ... + ArraySetAsSeries(stddevBuffer, true); + SetIndexBuffer(stddevBufferIndex, stddevBuffer, INDICATOR_CALCULATIONS); + + // + // MACD ... + + // + // Main ... + ArraySetAsSeries(macdMainBuffer, true); + SetIndexBuffer(macdMainBufferIndex, macdMainBuffer, INDICATOR_CALCULATIONS); + + // + // Signal ... + ArraySetAsSeries(macdSignalBuffer, true); + SetIndexBuffer(macdSignalBufferIndex, macdSignalBuffer, INDICATOR_CALCULATIONS); +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xstr.ex5 b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xstr.ex5 new file mode 100644 index 0000000..542535d Binary files /dev/null and b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xstr.ex5 differ diff --git a/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xstr.mq5 b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xstr.mq5 new file mode 100644 index 0000000..bca9597 --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xstr.mq5 @@ -0,0 +1,580 @@ +////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: X121_XSTR +// Description: Super Trend Indicator ... +// +// +// 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_XAMA Indicator" +#property strict + +// +// START Constants ... +// + +#define ShortName "X121_XSTR" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +// Market ... +input group "ATR"; +input int atrLength = 14; // Length +input double atrMultiplier = 3.0; // Multiplier +input ENUM_APPLIED_PRICE atrAppliedTo = PRICE_MEDIAN; // Applied To + +// +// Presentation ... +input group "Presentation"; +input bool showTrends = true; // Show Trends +input bool fillTrends = true; // Fill Trends + +// +// END Inputs ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 9 +#property indicator_plots 2 + +// +#define fillUpBufferIndex 0 +double fillUpBuffer[]; + +#define fillDownBufferIndex 1 +double fillDownBuffer[]; + +// +#define fillingPlotBufferIndex 0 + +// +#property indicator_label1 "X121_XSTR Filling" +#property indicator_type1 DRAW_FILLING +#property indicator_color1 clrBisque, clrPaleGreen + +// +#define mainBufferIndex 2 +#define mainPlotBufferIndex 1 +double mainBuffer[]; + +// +#define mainColorBufferIndex 3 +double mainColorBuffer[]; + +// +#property indicator_label2 "X121_XSTR" +#property indicator_type2 DRAW_COLOR_LINE +#property indicator_color2 CLR_NONE, clrGreen, clrDarkRed +#property indicator_style2 STYLE_DOT + +// +// DATA Buffers ... + +// +#define atrBufferIndex 4 +double atrBuffer[]; + +// +#define trendBufferIndex 5 +double trendBuffer[]; + +// +#define upBufferIndex 6 +double upBuffer[]; + +// +#define downBufferIndex 7 +double downBuffer[]; + +// +#define priceBufferIndex 8 +double priceBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int atrHandler = INVALID_HANDLE; + +// +int changeOfTrend; +int startBearishTrend; +int startBullishTrend; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // 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(); + + // + atrHandler = iATR( + _Symbol, + _Period, + atrLength); + if (atrHandler == INVALID_HANDLE) + { + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +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 + + // + // Here we can handle De Initialization Reasons ... + IndicatorRelease(atrHandler); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + int numOfRequiredAtrs; + if (prev_calculated > rates_total || prev_calculated < 0) + { + numOfRequiredAtrs = rates_total; + } + else + { + // + numOfRequiredAtrs = rates_total - prev_calculated; + if (prev_calculated > 0) + { + numOfRequiredAtrs++; + } + } + + // + // Checking for stop ... + if (IsStopped()) + { + return 0; + } + + // + // Check Number of items Copy or not ... + int copiedATRs = CopyBuffer(atrHandler, 0, 0, numOfRequiredAtrs, atrBuffer); + if (copiedATRs <= 0) + { + return 0; + } + + // + int limit; + + // + // checking for the limit start of calculation of an indicator ... + if (prev_calculated > rates_total || prev_calculated <= 0) + { + // + // starting index for calculation of all bars ... + limit = maxLength; + } + else + { + // + // starting number for calculation of new bars + limit = prev_calculated - 1; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + // + // Calculated Price ... + double price = getPrice( + atrAppliedTo, + open, + high, + low, + close, + i); + // price = (high[i] + low[i]) / 2; + priceBuffer[i] = price; + + // + double atr = atrBuffer[i]; + + // + // Up ... + upBuffer[i] = price + (atrMultiplier * atr); + + // + // Down ... + downBuffer[i] = price - (atrMultiplier * atr); + + // + if (close[i] > upBuffer[i - 1]) + { + // + trendBuffer[i] = 1; + if (trendBuffer[i - 1] == -1) + { + changeOfTrend = 1; + } + } + else if (close[i] < downBuffer[i - 1]) + { + // + trendBuffer[i] = -1; + if (trendBuffer[i - 1] == 1) + { + changeOfTrend = 1; + } + } + else if (trendBuffer[i - 1] == 1) + { + // + trendBuffer[i] = 1; + changeOfTrend = 0; + } + else if (trendBuffer[i - 1] == -1) + { + // + trendBuffer[i] = -1; + changeOfTrend = 0; + } + + // + // Down Trend Starting ... + if (trendBuffer[i] < 0 && trendBuffer[i - 1] > 0) + { + startBearishTrend = 1; + } + else + { + startBearishTrend = 0; + } + + // + // Up Trend Starting ... + if (trendBuffer[i] > 0 && trendBuffer[i - 1] < 0) + { + startBullishTrend = 1; + } + else + { + startBullishTrend = 0; + } + + // + if (trendBuffer[i] > 0 && downBuffer[i] < downBuffer[i - 1]) + { + downBuffer[i] = downBuffer[i - 1]; + } + + // + if (trendBuffer[i] < 0 && upBuffer[i] > upBuffer[i - 1]) + { + upBuffer[i] = upBuffer[i - 1]; + } + + // + if (startBearishTrend == 1) + { + upBuffer[i] = priceBuffer[i] + (atrMultiplier * atr); + } + + // + if (startBullishTrend == 1) + { + downBuffer[i] = priceBuffer[i] - (atrMultiplier * atr); + } + + // + // Draw the indicator ... + + // + double colorIDX = 0; + mainColorBuffer[i] = colorIDX; + + // + if (trendBuffer[i] == 1) + { + // + mainBuffer[i] = downBuffer[i]; + if (changeOfTrend == 1) + { + mainBuffer[i - 1] = mainBuffer[i - 2]; + changeOfTrend = 0; + } + + // + colorIDX = 1; + } + else if (trendBuffer[i] == -1) + { + // + mainBuffer[i] = upBuffer[i]; + if (changeOfTrend == 1) + { + // + mainBuffer[i - 1] = mainBuffer[i - 2]; + changeOfTrend = 0; + } + + // + colorIDX = 2; + } + + // + if (showTrends) + { + mainColorBuffer[i] = colorIDX; + } + + // + // Filling ... + if (fillTrends) + { + // + fillUpBuffer[i] = mainBuffer[i]; + fillDownBuffer[i] = close[i]; + } + else + { + // + fillUpBuffer[i] = EMPTY_VALUE; + fillDownBuffer[i] = EMPTY_VALUE; + } + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + result = + // + atrLength >= 2 + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = atrLength; + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // PLOT Buffers ... + + // + // FILLINGS ... + SetIndexBuffer(fillUpBufferIndex, fillUpBuffer, INDICATOR_DATA); + SetIndexBuffer(fillDownBufferIndex, fillDownBuffer, INDICATOR_DATA); + PlotIndexSetInteger(fillingPlotBufferIndex, PLOT_SHOW_DATA, false); + + // + // MAIN ... + SetIndexBuffer(mainBufferIndex, mainBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mainPlotBufferIndex, PLOT_SHOW_DATA, showTrends); + SetIndexBuffer(mainColorBufferIndex, mainColorBuffer, INDICATOR_COLOR_INDEX); + + // + // DATA Buffers ... + + // + // ATR ... + SetIndexBuffer(atrBufferIndex, atrBuffer, INDICATOR_CALCULATIONS); + + // + // TREND ... + SetIndexBuffer(trendBufferIndex, trendBuffer, INDICATOR_CALCULATIONS); + + // + // UP ... + SetIndexBuffer(upBufferIndex, upBuffer, INDICATOR_CALCULATIONS); + + // + // DOWN ... + SetIndexBuffer(downBufferIndex, downBuffer, INDICATOR_CALCULATIONS); + + // + // PRICE ... + SetIndexBuffer(priceBufferIndex, priceBuffer, INDICATOR_CALCULATIONS); +} + +// +// END Functions ... +// + +// +// TEMPLATE Function ... + +template +double getPrice(ENUM_APPLIED_PRICE tprice, T &open[], T &high[], T &low[], T &close[], int i) +{ + switch (tprice) + { + case PRICE_CLOSE: + return (close[i]); + case PRICE_OPEN: + return (open[i]); + case PRICE_HIGH: + return (high[i]); + case PRICE_LOW: + return (low[i]); + case PRICE_MEDIAN: + return ((high[i] + low[i]) / 2.0); + case PRICE_TYPICAL: + return ((high[i] + low[i] + close[i]) / 3.0); + case PRICE_WEIGHTED: + return ((high[i] + low[i] + close[i] + close[i]) / 4.0); + } + return (0); +} diff --git a/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xzg.ex5 b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xzg.ex5 new file mode 100644 index 0000000..5d14851 Binary files /dev/null and b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xzg.ex5 differ diff --git a/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xzg.mq5 b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xzg.mq5 new file mode 100644 index 0000000..d7cde07 --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.x121.xzg.mq5 @@ -0,0 +1,757 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: X121_XZG +// Description: Zogzag Implementation ... +// +// +// 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_XZG Indicator" +#property strict + +// +#define ShortName "X121_XZG" + +// +// DEFINITIONS ... +enum ENUM_X_ZG_SEARCH_MODE +{ + X_ZG_SEARCH_EXTREMUM = 0, // searching for the first extremum + X_ZG_SEARCH_PEAK = 1, // searching for the next ZigZag peak + X_ZG_SEARCH_VALE = -1 // searching for the next ZigZag vale +}; + +// +// How to Calculate Up and Down Price ... +enum ENUM_X_ZG_PRICE_MODE +{ + // + X_ZG_PRICE_HIGH_LOW_MODE = 1, + X_ZG_PRICE_OPEN_CLOSE_MODE = 2, +}; + +// +// INPUT ... + +// +input int depth = 12; // Depth +input int deviation = 5; // Deviation +input int backStep = 3; // Back Step +input ENUM_X_ZG_PRICE_MODE mode = X_ZG_PRICE_HIGH_LOW_MODE; // Mode + +// +// BUFFERS ... + +// +#property indicator_chart_window + +// +#property indicator_buffers 5 +#property indicator_plots 3 + +// +// ZigZag ... + +// +#define mainBufferIndex 0 +#define mainBufferPlotIndex 0 +double mainBuffer[]; + +// +#property indicator_label1 "X121_XZG Main" +#property indicator_type1 DRAW_SECTION +#property indicator_color1 clrYellow +#property indicator_width1 2 + +// +// Highs ... + +// +// ZigZag Pointer or Line Indicator ... +#define arrowBufferIndex 1 +#define arrowBufferPlotIndex 1 +double arrowBuffer[]; + +// +#define arrowColorBufferIndex 2 +double arrowColorBuffer[]; + +// +#property indicator_label2 "X121_XZG PV" +#property indicator_type2 DRAW_COLOR_ARROW +#property indicator_color2 clrAqua, clrMagenta +#property indicator_width2 1 + +// +#define highsBufferIndex 3 +double highsBuffer[]; + +// +// Lows ... + +// +#define lowsBufferIndex 4 +double lowsBuffer[]; + +// +// VARIABLES ... + +// +int mRecalc = 3; // Number of last extremes for recalculation + +// +// EVENT Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // logTag = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +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 +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[] // +) +{ + // + double mZGHigh[]; + double mZGLow[]; + if (mode == X_ZG_PRICE_OPEN_CLOSE_MODE) + { + // + ArrayCopy( + mZGHigh, + open + // + ); + + // + ArrayCopy( + mZGLow, + close + // + ); + } + else + { + // + ArrayCopy( + mZGHigh, + high + // + ); + + // + ArrayCopy( + mZGLow, + low + // + ); + } + + // + int zigZagResult = CalcukateZigZag( + prev_calculated, + rates_total, + mZGHigh, + mZGLow + // + ); + + // + if (zigZagResult != rates_total) + { + return zigZagResult; + } + + // + return rates_total; +} + +// +// CUSTOM Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + result = + // + depth > 0 && + deviation > 0 && + backStep > 0 + // + ; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Main ... + + // + SetIndexBuffer(mainBufferIndex, mainBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mainBufferPlotIndex, PLOT_SHOW_DATA, true); + PlotIndexSetInteger(mainBufferPlotIndex, PLOT_DRAW_BEGIN, 0); + PlotIndexSetDouble(mainBufferPlotIndex, PLOT_EMPTY_VALUE, 0); + + // + // Arrow ... + + // + SetIndexBuffer(arrowBufferIndex, arrowBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(arrowBufferPlotIndex, PLOT_SHOW_DATA, true); + PlotIndexSetInteger(arrowBufferPlotIndex, PLOT_DRAW_BEGIN, 0); + PlotIndexSetInteger(arrowBufferPlotIndex, PLOT_ARROW, 159); + PlotIndexSetInteger(arrowBufferPlotIndex, PLOT_ARROW_SHIFT, 0); + PlotIndexSetDouble(arrowBufferPlotIndex, PLOT_EMPTY_VALUE, 0); + + // + // Arrow Color ... + SetIndexBuffer(arrowColorBufferIndex, arrowColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Highs ... + SetIndexBuffer(highsBufferIndex, highsBuffer, INDICATOR_CALCULATIONS); + + // + // Lows ... + SetIndexBuffer(lowsBufferIndex, lowsBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculating Zig Zag ... +int CalcukateZigZag( + const int prev_calculated, + const int rates_total, + double &high[], + double &low[] + // +) +{ + // + if (rates_total < 100) + { + return 0; + } + + // + // Define Variables ... + int i = 0; + + // + int start = 0; + int extreme_counter = 0; + int extreme_search = X_ZG_SEARCH_EXTREMUM; + int shift = 0; + int back = 0; + int last_high_pos = 0; + int last_low_pos = 0; + + // + double val = 0; + double res = 0; + double curlow = 0; + double curhigh = 0; + double last_high = 0; + double last_low = 0; + + // + double colorIDX = 0; + double lastZigZagValue = 0; + + // + // Initializing ... + if (prev_calculated == 0) + { + // + ArrayInitialize(mainBuffer, 0); + ArrayInitialize(highsBuffer, 0); + ArrayInitialize(lowsBuffer, 0); + + // + start = depth; + } + + // + // Already Calculated Before ... + if (prev_calculated > 0) + { + // + i = rates_total - 1; + + // + // Searching for the third X_ZG_SEARCH_EXTREMUM from the last UnComplete Bar ... + while (extreme_counter < mRecalc && i > rates_total - 100) + { + // + res = mainBuffer[i]; + if (res != 0) + { + extreme_counter++; + } + + // + i--; + } + + // + i++; + start = i; + + // + // What type of X_ZG_SEARCH_EXTREMUM we Search for ... + if (lowsBuffer[i] != 0) + { + // + curlow = lowsBuffer[i]; + extreme_search = X_ZG_SEARCH_PEAK; + } + else + { + // + curhigh = highsBuffer[i]; + extreme_search = X_ZG_SEARCH_VALE; + } + + // + // Clear Values ... + for (i = start + 1; i < rates_total && !IsStopped(); i++) + { + // + mainBuffer[i] = 0; + lowsBuffer[i] = 0; + highsBuffer[i] = 0; + } + } + + // + // Search for High and Low Extremes ... + for (shift = start; shift < rates_total && !IsStopped(); shift++) + { + // + // Low ... + val = low[Lowest(low, depth, shift)]; + if (val == last_low) + { + val = 0; + } + else + { + // + last_low = val; + + // + if ((low[shift] - val) > deviation * _Point) + { + val = 0; + } + else + { + // + for (back = 1; back <= backStep; back++) + { + // + res = lowsBuffer[shift - back]; + if ((res != 0) && (res > val)) + { + lowsBuffer[shift - back] = 0; + } + } + } + } + + // + if (low[shift] == val) + { + lowsBuffer[shift] = val; + } + else + { + lowsBuffer[shift] = 0; + } + + // + // High ... + val = high[Highest(high, depth, shift)]; + if (val == last_high) + { + val = 0; + } + else + { + // + last_high = val; + + // + if ((val - high[shift]) > deviation * _Point) + { + val = 0; + } + else + { + // + for (back = 1; back <= backStep; back++) + { + // + res = highsBuffer[shift - back]; + if ((res != 0) && (res < val)) + { + highsBuffer[shift - back] = 0; + } + } + } + } + + // + if (high[shift] == val) + { + highsBuffer[shift] = val; + } + else + { + highsBuffer[shift] = 0; + } + } + + // + // Set Last Value ... + if (extreme_search == 0) // Undefined Values ... + { + // + last_low = 0; + last_high = 0; + } + else + { + // + last_low = curlow; + last_high = curhigh; + } + + // + // Final Selection of Extreme Points for ZigZag ... + for (shift = start; shift < rates_total && !IsStopped(); shift++) + { + // + res = 0; + + // + switch (extreme_search) + { + // + case X_ZG_SEARCH_EXTREMUM: + // + if (last_low == 0 && last_high == 0) + { + // + if (highsBuffer[shift] != 0) + { + // + last_high_pos = shift; + last_high = high[shift]; + + // + extreme_search = X_ZG_SEARCH_VALE; + + // + mainBuffer[shift] = last_high; + + // + res = 1; + } + + // + if (lowsBuffer[shift] != 0) + { + // + last_low_pos = shift; + last_low = low[shift]; + + // + extreme_search = X_ZG_SEARCH_PEAK; + + // + mainBuffer[shift] = last_low; + + // + res = 1; + } + } + break; + + // + case X_ZG_SEARCH_PEAK: + // + if (lowsBuffer[shift] != 0 && lowsBuffer[shift] < last_low && highsBuffer[shift] == 0) + { + // + mainBuffer[last_low_pos] = 0; + + // + last_low_pos = shift; + last_low = lowsBuffer[shift]; + + // + mainBuffer[shift] = last_low; + + // + res = 1; + } + + // + if (highsBuffer[shift] != 0 && lowsBuffer[shift] == 0) + { + // + last_high_pos = shift; + last_high = highsBuffer[shift]; + + // + mainBuffer[shift] = last_high; + + // + extreme_search = X_ZG_SEARCH_VALE; + + // + res = 1; + } + break; + + // + case X_ZG_SEARCH_VALE: + // + if (highsBuffer[shift] != 0 && highsBuffer[shift] > last_high && lowsBuffer[shift] == 0) + { + // + mainBuffer[last_high_pos] = 0; + + // + last_high_pos = shift; + last_high = highsBuffer[shift]; + + // + mainBuffer[shift] = last_high; + } + + // + if (lowsBuffer[shift] != 0 && highsBuffer[shift] == 0) + { + // + last_low_pos = shift; + last_low = lowsBuffer[shift]; + + // + mainBuffer[shift] = last_low; + + // + extreme_search = X_ZG_SEARCH_PEAK; + } + break; + } + + // + double iZigZagForColor = lastZigZagValue; + double iZigZag = mainBuffer[shift]; + if (iZigZag == 0 && lastZigZagValue != 0) + { + arrowBuffer[shift] = lastZigZagValue; + } + else if (iZigZag != 0) + { + // + lastZigZagValue = iZigZag; + arrowBuffer[shift] = lastZigZagValue; + } + + // + colorIDX = + lastZigZagValue > iZigZagForColor + ? 0 + : lastZigZagValue < iZigZagForColor + ? 1 + : colorIDX; + arrowColorBuffer[shift] = colorIDX; + } + + // + return rates_total; +} + +// +// TOOLS ... + +// +// Search for the index of the highest bar ... +int Highest( + const double &mArray[], + const int mDepth, + const int mStart // +) +{ + // + int result = 0; + + // + if (mStart < 0) + { + return result; + } + + // + double max = mArray[mStart]; + result = mStart; + + // + // Start searching ... + for (int i = mStart - 1; i > mStart - mDepth && i >= 0; i--) + { + // + if (mArray[i] > max) + { + // + result = i; + max = mArray[i]; + } + } + + // + // Return index of the highest bar + return result; +} + +// +// Search for the index of the lowest bar ... +int Lowest( + const double &mArray[], + const int mDepth, + const int mStart // +) +{ + // + int result = 0; + + // + if (mStart < 0) + { + return result; + } + + // + double min = mArray[mStart]; + result = mStart; + + // + // Start searching ... + for (int i = mStart - 1; i > mStart - mDepth && i >= 0; i--) + { + // + if (mArray[i] < min) + { + // + result = i; + min = mArray[i]; + } + } + + // + // Return index of the lowest bar + return result; +} diff --git a/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.xchnl.ex5 b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.xchnl.ex5 new file mode 100644 index 0000000..55aff36 Binary files /dev/null and b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.xchnl.ex5 differ diff --git a/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.xchnl.mq5 b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.xchnl.mq5 new file mode 100644 index 0000000..c850540 --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.xchnl.mq5 @@ -0,0 +1,775 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: X121_XCHNL +// Description: XCHL Channel Indicator ... +// +// +// 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_XCHNL Indicator" +#property strict + +// +// START Constants ... +// + +// +#define ShortName "X121_XCHNL" + +// +// END Constants ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Includes Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START XSCHULL Class Definition ... +// + +// +// END XSCHULL Class Definition ... +// + +// +// START Inputs ... +// + +// +input group "Makret Cycles"; +input int shortLength = 9; // Short Length +input int mediumLength = 17; // Medium Length +input int longLength = 26; // Long Length +input int hindLength = 35; // Hind Length + +// +input group "Trend"; +input int numOfShoulder = 10; // Number of Shoulders for Swings + +// +input group "Detection Modes"; +input ENUM_SERIESMODE hhMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE llMode = MODE_LOW; // Lowest Low Calculation Method + +// +input group "Presentation"; +input bool showTrend = false; // Show Trend +input bool showSRs = false; // Show Support and Resistance + +// +// END Inputs ... +// + +// +// START Buffers ... +// + +// +// PEKSANDVALES ... + +#property indicator_chart_window + +// +#property indicator_buffers 8 +#property indicator_plots 0 + +#define sHHBufferIndex 0 +#define sLLBufferIndex 1 +#define mHHBufferIndex 2 +#define mLLBufferIndex 3 +#define lHHBufferIndex 4 +#define lLLBufferIndex 5 +#define hHHBufferIndex 6 +#define hLLBufferIndex 7 + +double sHHBuffer[]; +double sLLBuffer[]; +double mHHBuffer[]; +double mLLBuffer[]; +double lHHBuffer[]; +double lLLBuffer[]; +double hHHBuffer[]; +double hLLBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + drawPrefix = ShortName; + + // + // 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(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Make an Instance of Hull Class ... + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +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 mPeriod 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 + + // + RemoveDraws(drawPrefix); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // this counts Available Bars ... + int limit; + + // + limit = prev_calculated - 1; + if (limit < 0) + { + limit = 0; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + result = + // + // Validate Peaks and Vales ... + (shortLength > 2 && + mediumLength > shortLength && + longLength > mediumLength && + hindLength > longLength) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Peaks and Vales ... + result = MathMax(shortLength, mediumLength); + result = MathMax(result, longLength); + result = MathMax(result, hindLength); + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + ArraySetAsSeries(sHHBuffer, true); + SetIndexBuffer(sHHBufferIndex, sHHBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(sLLBuffer, true); + SetIndexBuffer(sLLBufferIndex, sLLBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(mHHBuffer, true); + SetIndexBuffer(mHHBufferIndex, mHHBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(mLLBuffer, true); + SetIndexBuffer(mLLBufferIndex, mLLBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(lHHBuffer, true); + SetIndexBuffer(lHHBufferIndex, lHHBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(lLLBuffer, true); + SetIndexBuffer(lLLBufferIndex, lLLBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(hHHBuffer, true); + SetIndexBuffer(hHHBufferIndex, hHHBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(hLLBuffer, true); + SetIndexBuffer(hLLBufferIndex, hLLBuffer, INDICATOR_CALCULATIONS); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // Calculate ... + + // + // SHORT ... + + // + // HIGH ... + int sHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + shortLength, + bar_index); + double sHHValue = GetAppliedPrice( + sHHIndex, + hhMode); + + // + sHHBuffer[bar_index] = sHHValue; + + // + // LOW ... + int sLLIndex = iLowest( + _Symbol, + _Period, + llMode, + shortLength, + bar_index); + double sLLValue = GetAppliedPrice( + sLLIndex, + llMode); + + // + sLLBuffer[bar_index] = sLLValue; + + // + // MEDIUM ... + + // + // HIGH ... + int mHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + mediumLength, + bar_index); + double mHHValue = GetAppliedPrice( + mHHIndex, + hhMode); + + // + mHHBuffer[bar_index] = mHHValue; + + // + // LOW ... + int mLLIndex = iLowest( + _Symbol, + _Period, + llMode, + mediumLength, + bar_index); + double mLLValue = GetAppliedPrice( + mLLIndex, + llMode); + + // + mLLBuffer[bar_index] = mLLValue; + + // + // LONG ... + + // + // HIGH ... + int lHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + longLength, + bar_index); + double lHHValue = GetAppliedPrice( + lHHIndex, + hhMode); + + // + lHHBuffer[bar_index] = lHHValue; + + // + // LOW ... + int lLLIndex = iLowest( + _Symbol, + _Period, + llMode, + longLength, + bar_index); + double lLLValue = GetAppliedPrice( + lLLIndex, + llMode); + + // + lLLBuffer[bar_index] = lLLValue; + + // + // HIND ... + + // + // HIGH ... + int hHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + hindLength, + bar_index); + double hHHValue = GetAppliedPrice( + hHHIndex, + hhMode); + + // + hHHBuffer[bar_index] = hHHValue; + + // + // LOW ... + int hLLIndex = iLowest( + _Symbol, + _Period, + llMode, + hindLength, + bar_index); + double hLLValue = GetAppliedPrice( + hLLIndex, + llMode); + + // + hLLBuffer[bar_index] = hLLValue; + + // + // Find Swings ... + + // + // High ... + int hSwing1 = FindSwing( + _Symbol, + _Period, + MODE_HIGH, + numOfShoulder, + bar_index + 1); + + int hSwing2 = FindSwing( + _Symbol, + _Period, + MODE_HIGH, + numOfShoulder, + hSwing1 + 1); + + // + // High ... + int hSwing3 = FindSwing( + _Symbol, + _Period, + MODE_HIGH, + numOfShoulder, + hSwing2 + 1); + + // int hSwing4 = FindSwing( + // _Symbol, + // _Period, + // MODE_HIGH, + // numOfShoulder, + // hSwing3 + 1); + + // + // Low ... + int lSwing1 = FindSwing( + _Symbol, + _Period, + MODE_LOW, + numOfShoulder, + bar_index + 1); + + int lSwing2 = FindSwing( + _Symbol, + _Period, + MODE_LOW, + numOfShoulder, + lSwing1 + 1); + + int lSwing3 = FindSwing( + _Symbol, + _Period, + MODE_LOW, + numOfShoulder, + lSwing2 + 1); + + // int lSwing4 = FindSwing( + // _Symbol, + // _Period, + // MODE_LOW, + // numOfShoulder, + // lSwing3 + 1); + + // + if (bar_index < 50) + { + + // + bool isStrongResistance = + // + hHHBuffer[bar_index + 1] == hHHBuffer[bar_index + 2] && + hHHBuffer[bar_index + 2] == hHHBuffer[bar_index + 3] && + // + lHHBuffer[bar_index + 1] == lHHBuffer[bar_index + 2] && + lHHBuffer[bar_index + 2] == lHHBuffer[bar_index + 3] && + // + mHHBuffer[bar_index + 1] == mHHBuffer[bar_index + 2] && + mHHBuffer[bar_index + 2] == mHHBuffer[bar_index + 3] && + // + sHHBuffer[bar_index + 1] == sHHBuffer[bar_index + 2] && + sHHBuffer[bar_index + 2] == sHHBuffer[bar_index + 3] + // + ; + + // + bool isStrongSupport = + // + hLLBuffer[bar_index + 1] == hLLBuffer[bar_index + 2] && + hLLBuffer[bar_index + 2] == hLLBuffer[bar_index + 3] && + // + lLLBuffer[bar_index + 1] == lLLBuffer[bar_index + 2] && + lLLBuffer[bar_index + 2] == lLLBuffer[bar_index + 3] && + // + mLLBuffer[bar_index + 1] == mLLBuffer[bar_index + 2] && + mLLBuffer[bar_index + 2] == mLLBuffer[bar_index + 3] && + // + sLLBuffer[bar_index + 1] == sLLBuffer[bar_index + 2] && + sLLBuffer[bar_index + 2] == sLLBuffer[bar_index + 3] + // + ; + + // + if (isStrongResistance && showSRs) + { + // + DrawSupportResistance( + "R", + clrRed, + sHHBuffer[bar_index + 3], + bar_index + 3); + } + + // + if (isStrongSupport && showSRs) + { + // + DrawSupportResistance( + "S", + clrGreen, + sLLBuffer[bar_index + 3], + bar_index + 3); + } + } + + // + if (showTrend && bar_index < 20) + { + // + DrawSwing( + "High1", + MODE_HIGH, + clrAqua, + hSwing1, + hSwing2); + + // + DrawSwing( + "Low1", + MODE_LOW, + clrAqua, + lSwing1, + lSwing2); + + // + DrawSwing( + "High2", + MODE_HIGH, + clrMagenta, + hSwing2, + hSwing3); + + // + DrawSwing( + "Low2", + MODE_LOW, + clrMagenta, + lSwing2, + lSwing3); + } +} + +// +void DrawSwing( + string prefix, // Prefix ... + ENUM_SERIESMODE mode, // Swing Mode ... + color swingColor, // Color ... + int index1, // Index 1 ... + int index2 // Index 2 ... +) +{ + // + if (mode != MODE_HIGH && mode != MODE_LOW) + { + return; + } + + // + XOHCL c1 = GetCandle( + _Symbol, + _Period, + index1); + + // + datetime time1 = GetCandleTime( + _Symbol, + _Period, + index1); + + // + XOHCL c2 = GetCandle( + _Symbol, + _Period, + index2); + + // + datetime time2 = GetCandleTime( + _Symbol, + _Period, + index2); + + // + double value1 = -1; + double value2 = -1; + + // + switch (mode) + { + // + case MODE_HIGH: + value1 = c1.high; + value2 = c2.high; + break; + + // + case MODE_LOW: + value1 = c1.low; + value2 = c2.low; + break; + } + + // + if (value1 == -1 || value2 == -1) + { + return; + } + + // + long chartId = ChartID(); + string tlName = prefix + "_" + "TrendLine"; + + // // + // if (IsDrawExists(tlName)) { + // RemoveDraw(tlName); + // } + + // + DrawTrendLine( + chartId, + tlName, + 0, + time2, + value2, + time1, + value1, + swingColor, + STYLE_DOT, + 3, + false, + false, + true); +} + +// +// Draw Support and Resistance ... +void DrawSupportResistance( + string prefix, // Prefix ... + color lColor, // Color ... + double price, // Support or Resistance price ... + int bar_index // Start Bar Index ... +) +{ + // + datetime time1 = GetCandleTime( + _Symbol, + _Period, + bar_index); + + // + datetime time2 = GetCandleTime( + _Symbol, + _Period, + bar_index - 1); + + // + long chartId = ChartID(); + string tlName = prefix + "_" + "TL" + "_" + (string)(NormalizePrice(price, _Symbol)); + + // + DrawTrendLine( + chartId, + tlName, + 0, + time1, + price, + time2, + price, + lColor, + STYLE_DOT, + 3, + false, + false, + true); +} diff --git a/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.xdon.ex5 b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.xdon.ex5 new file mode 100644 index 0000000..e30324b Binary files /dev/null and b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.xdon.ex5 differ diff --git a/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.xdon.mq5 b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.xdon.mq5 new file mode 100644 index 0000000..e479e65 --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Indicators/x-saherelm.xdon.mq5 @@ -0,0 +1,365 @@ +/////////////////////////////////////////////////////// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------- +// Name: XDON +// Description: DONCHAIN Channel ... +// +// 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 XDON Indicator" +#property strict + +// +#define ShortName "XDON" + +// +// INPUT ... + +// +input int length = 52; // Market Length +input double offset = 0; // Offset + +// +// BUFFERS ... + +// +#property indicator_chart_window + +// +#property indicator_buffers 8 +#property indicator_plots 8 + +// +#define upperOBufferIndex 0 +double upperOBuffer[]; + +// +#property indicator_label1 "XDON OU" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrCornflowerBlue +#property indicator_width1 2 + +// +#define lowerOBufferIndex 1 +double lowerOBuffer[]; + +// +#property indicator_label2 "XDON OL" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrCornflowerBlue +#property indicator_width2 2 + +// +#define upperCBufferIndex 2 +double upperCBuffer[]; + +// +#property indicator_label3 "XDON CU" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrCoral +#property indicator_width3 2 + +// +#define lowerCBufferIndex 3 +double lowerCBuffer[]; + +// +#property indicator_label4 "XDON CL" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrCoral +#property indicator_width4 2 + +// +#define upperHBufferIndex 4 +double upperHBuffer[]; + +// +#property indicator_label5 "XDON HU" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrAquamarine +#property indicator_width5 2 + +// +#define lowerHBufferIndex 5 +double lowerHBuffer[]; + +// +#property indicator_label6 "XDON HL" +#property indicator_type6 DRAW_LINE +#property indicator_color6 clrAquamarine +#property indicator_width6 2 + +// +#define upperLBufferIndex 6 +double upperLBuffer[]; + +// +#property indicator_label7 "XDON LU" +#property indicator_type7 DRAW_LINE +#property indicator_color7 clrDarkOrchid +#property indicator_width7 2 + +// +#define lowerLBufferIndex 7 +double lowerLBuffer[]; + +// +#property indicator_label8 "XDON LL" +#property indicator_type8 DRAW_LINE +#property indicator_color8 clrDarkOrchid +#property indicator_width8 2 + +// +// EVENT Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +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 +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + if (rates_total < length - 1) + { + return prev_calculated; + } + + // + int start = prev_calculated == 0 + ? length + : prev_calculated - 1; + + // + // Main Loop ... + for (int barIndex = start; barIndex < rates_total; barIndex++) + { + // + // OPEN ... + + // + double upperOValue = open[ArrayMaximum(open, barIndex - length + 1, length)]; + double lowerOValue = open[ArrayMinimum(open, barIndex - length + 1, length)]; + + // + double oDelta = MathAbs(upperOValue - lowerOValue); + double oOffsetValue = oDelta * (offset) * 0.01; + + // + upperOBuffer[barIndex] = upperOValue - oOffsetValue; + lowerOBuffer[barIndex] = lowerOValue + oOffsetValue; + + // + // CLOSE ... + + // + double upperCValue = close[ArrayMaximum(close, barIndex - length + 1, length)]; + double lowerCValue = close[ArrayMinimum(close, barIndex - length + 1, length)]; + + // + double cDelta = MathAbs(upperCValue - lowerCValue); + double cOffsetValue = cDelta * (offset) * 0.01; + + // + upperCBuffer[barIndex] = upperCValue - cOffsetValue; + lowerCBuffer[barIndex] = lowerCValue + cOffsetValue; + + // + // HIGH ... + + // + double upperHValue = high[ArrayMaximum(high, barIndex - length + 1, length)]; + double lowerHValue = high[ArrayMinimum(high, barIndex - length + 1, length)]; + + // + double hDelta = MathAbs(upperHValue - lowerHValue); + double hOffsetValue = hDelta * (offset) * 0.01; + + // + upperHBuffer[barIndex] = upperHValue - hOffsetValue; + lowerHBuffer[barIndex] = lowerHValue + hOffsetValue; + + // + // LOW ... + + // + double upperLValue = low[ArrayMaximum(low, barIndex - length + 1, length)]; + double lowerLValue = low[ArrayMinimum(low, barIndex - length + 1, length)]; + + // + double lDelta = MathAbs(upperLValue - lowerLValue); + double lOffsetValue = lDelta * (offset) * 0.01; + + // + upperLBuffer[barIndex] = upperLValue - lOffsetValue; + lowerLBuffer[barIndex] = lowerLValue + lOffsetValue; + } + + // + return rates_total; +} + +// +// CUSTOM Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + result = length >= 7; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Open ... + + // + // UPPER ... + SetIndexBuffer(upperOBufferIndex, upperOBuffer, INDICATOR_DATA); + PlotIndexSetInteger(upperOBufferIndex, PLOT_SHOW_DATA, true); + PlotIndexSetDouble(upperOBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); + + // + // LOWER ... + SetIndexBuffer(lowerOBufferIndex, lowerOBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lowerOBufferIndex, PLOT_SHOW_DATA, true); + PlotIndexSetDouble(lowerOBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); + + // + // Close ... + + // + // UPPER ... + SetIndexBuffer(upperCBufferIndex, upperCBuffer, INDICATOR_DATA); + PlotIndexSetInteger(upperCBufferIndex, PLOT_SHOW_DATA, true); + PlotIndexSetDouble(upperCBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); + + // + // LOWER ... + SetIndexBuffer(lowerCBufferIndex, lowerCBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lowerCBufferIndex, PLOT_SHOW_DATA, true); + PlotIndexSetDouble(lowerCBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); + + // + // High ... + + // + // UPPER ... + SetIndexBuffer(upperHBufferIndex, upperHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(upperHBufferIndex, PLOT_SHOW_DATA, true); + PlotIndexSetDouble(upperHBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); + + // + // LOWER ... + SetIndexBuffer(lowerHBufferIndex, lowerHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lowerHBufferIndex, PLOT_SHOW_DATA, true); + PlotIndexSetDouble(lowerHBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); + + // + // Low ... + + // + // UPPER ... + SetIndexBuffer(upperLBufferIndex, upperLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(upperLBufferIndex, PLOT_SHOW_DATA, true); + PlotIndexSetDouble(upperLBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); + + // + // LOWER ... + SetIndexBuffer(lowerLBufferIndex, lowerLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lowerLBufferIndex, PLOT_SHOW_DATA, true); + PlotIndexSetDouble(lowerLBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} diff --git a/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.alert.lib.ex5 b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.alert.lib.ex5 new file mode 100644 index 0000000..d35859b Binary files /dev/null and b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.alert.lib.ex5 differ diff --git a/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.alert.lib.mq5 b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.alert.lib.mq5 new file mode 100644 index 0000000..429d830 --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.alert.lib.mq5 @@ -0,0 +1,187 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Alert Library +// -------------------------------------- +// Name: XAlert +// Description: provides Alerts abilities ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Inputs ... +// +input group "Alerts"; +input bool enableAlerts = true; // Enable Alerts +input bool logAlerts = true; // Log Alerts +input bool terminalAlerts = false; // Terminal Alerts +input bool mailAlerts = false; // Mail Alerts +input bool pushAlerts = false; // Push Alerts +// +// END Inputs ... +// + +// +#include "x-saherelm.log.lib.mq5" + +// +// START Global Definitions: Variables, Properties and etc ... +// +string alertPrefix = "X-Alert"; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// +// +// Initial Library if required ... +bool OnInInitAlertLibrary() +{ + return false; +} + +// +// DeInitial Library if required ... +void OnDeinitAlertLibrary() +{ +} + +// +// Attach Alert Prefix to Message ... +string PrepareAlertMessage(string message) +{ + // + StringReplace(message, "\n", " | "); + + // + StringConcatenate(message, alertPrefix, " > ", message); + + // + return message; +} + +// +// Logging an Alert ... +void LogAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts || !logAlerts) + { + return; + } + + // + LogMessage(alertPrefix, message); +} + +// +// Terminal Alert ... +void TerminalAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts || !terminalAlerts) + { + return; + } + + // + // Prepare Message ... + message = PrepareAlertMessage(message); + + // Send Terminal Alert ... + Alert(message); +} + +// +// Mail Alert ... +void MailAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts || !mailAlerts) + { + return; + } + + // + // Send Mail Alert ... + SendMail(alertPrefix, message); +} + +// +// Send Push Notification ... +void PushAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts || !pushAlerts) + { + return; + } + + // + // Prepare Message ... + message = PrepareAlertMessage(message); + + // + // Send Push Notification Alert ... + SendNotification(message); +} + +// +// Alert Sending ... +void SendAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts) + { + return; + } + + // + // Log ... + if (logAlerts) + { + LogAlert(message); + } + + // + // Terminal ... + if (terminalAlerts) + { + TerminalAlert(message); + } + + // + // Mail ... + if (mailAlerts) + { + MailAlert(message); + } + + // + // Push ... + if (pushAlerts) + { + PushAlert(message); + } +} +// +// END Provided Functions ... +// diff --git a/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.common.lib.ex5 b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.common.lib.ex5 new file mode 100644 index 0000000..5729e18 Binary files /dev/null and b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.common.lib.ex5 differ diff --git a/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.common.lib.mq5 b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.common.lib.mq5 new file mode 100644 index 0000000..b056de8 --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.common.lib.mq5 @@ -0,0 +1,5878 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Common Library +// -------------------------------------- +// Name: XCommon +// Description: provide all commonly used functions ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Inputs ... +// + +// +// END Inputs ... +// + +// +// Include Models Library ... +#include "x-saherelm.models.lib.mq5" +#include "../Classes/x-saherelm.xmd5.class.mq5" + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// + +// +// Detect is new Candle or not ... +bool IsNewCandle() +{ + // + bool result = false; + + // + static int barsOnChart = 0; + int currentBarsOnChart = Bars(_Symbol, _Period); + result = currentBarsOnChart > barsOnChart; + if (!result) + { + return result; + } + + // + barsOnChart = currentBarsOnChart; + result = true; + + // + return result; +} +bool IsNewCandle( + string mSymbol, // Trading Symbol ... + ENUM_TIMEFRAMES mPeriod // Trading Time Frame ... +) +{ + // + bool result = false; + + // + static string mChartTags[]; + static int mChartBars[]; + + // + string chTag = mSymbol + "," + ToString(mPeriod); + + // + int currChTagIdx = -1; + int chCountedBars = 0; + int currentBars = Bars(mSymbol, mPeriod); + + // + if (ArraySize(mChartTags) > 0) + { + // + for (int i = 0; i < ArraySize(mChartTags); i++) + { + // + string iTag = mChartTags[i]; + if (iTag != chTag) + { + continue; + } + + // + currChTagIdx = i; + break; + } + + // + if (currChTagIdx > -1) + { + chCountedBars = mChartBars[currChTagIdx]; + } + } + + // + result = currentBars > chCountedBars; + if (result) + { + // + if (currChTagIdx > -1) + { + // + mChartTags[currChTagIdx] = chTag; + mChartBars[currChTagIdx] = currentBars; + } + else + { + // + Add(chTag, mChartTags); + Add(currentBars, mChartBars); + } + } + + // + return result; +} + +// +double XNZ(double check, double val = 0) +{ + if (check == EMPTY_VALUE || check == 0) + { + return val; + } + else + { + return check; + } +} + +// +// Retrive Ask Price ... +double GetAsk() +{ + return SymbolInfoDouble(_Symbol, SYMBOL_ASK); +} +double GetAsk( + string symbol // selected symbol for calculations +) +{ + // + double result = SymbolInfoDouble(symbol, SYMBOL_ASK); + + // + return result; +} + +// +// Retrieve Bid Price ... +double GetBid() +{ + return SymbolInfoDouble(_Symbol, SYMBOL_BID); +} +double GetBid( + string symbol // selected symbol for calculations +) +{ + // + double result = SymbolInfoDouble(symbol, SYMBOL_BID); + + // + return result; +} + +// +// Calculate and Retrieve Spread Price ... +double GetSpread() +{ + // + double ask = GetAsk(); + double bid = GetBid(); + double result = MathAbs(ask - bid); + + // + return result; +} +double GetSpread( + string symbol // selected symbol for calculations +) +{ + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + double result = MathAbs(ask - bid); + + // + return result; +} + +// +// Get Points ... +double GetPoints() +{ + return _Point; +} +double GetPoints( + string symbol // selected symbol for calculations +) +{ + // + double result = SymbolInfoDouble(symbol, SYMBOL_POINT); + + // + return result; +} + +// +// Get Digits ... +int GetDigits() +{ + return _Digits; +} +int GetDigits( + string symbol // selected symbol for calculations +) +{ + // + int result = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS); + + // + return result; +} + +// +// Get Signal Entry ... +double GetEntry( + ENUM_POSITION_TYPE type // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + bool isLong = type == POSITION_TYPE_BUY; + result = isLong ? GetAsk() : GetBid(); + result = NormalizePrice(result); + + // + return result; +} +double GetEntry( + string symbol, // Specified Symbol + ENUM_POSITION_TYPE type // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + bool isLong = type == POSITION_TYPE_BUY; + result = isLong ? GetAsk(symbol) : GetBid(symbol); + result = NormalizePrice(result, symbol); + + // + return result; +} + +// +// Get Signal Exit ... +double GetExit( + ENUM_POSITION_TYPE type // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + bool isLong = type == POSITION_TYPE_BUY; + result = isLong ? GetBid() : GetAsk(); + result = NormalizePrice(result); + + // + return result; +} +double GetExit( + string symbol, // Specified Symbol + ENUM_POSITION_TYPE type // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + bool isLong = type == POSITION_TYPE_BUY; + result = isLong ? GetBid(symbol) : GetAsk(symbol); + result = NormalizePrice(result, symbol); + + // + return result; +} + +// +// Determine a Position type is Long or not ... +bool IsLong(ENUM_POSITION_TYPE type) +{ + // + bool result = type == POSITION_TYPE_BUY; + + // + return result; +} +bool IsLong(ENUM_ORDER_TYPE type) +{ + // + bool result = type == ORDER_TYPE_BUY; + + // + return result; +} + +// +// Determine a Position type is Short or not ... +bool IsShort(ENUM_POSITION_TYPE type) +{ + // + bool result = type == POSITION_TYPE_SELL; + + // + return result; +} +bool IsShort(ENUM_ORDER_TYPE type) +{ + // + bool result = type == ORDER_TYPE_SELL; + + // + return result; +} + +// +// Get 1 Pip in Price Value ... +double GetPipPrice() +{ + // + double result = _Point; + if (_Digits == 3 || _Digits == 5) + { + result *= 10; + } + + // + return result; +} +double GetPipPrice( + string symbol // selected symbol for calculations +) +{ + // + double symbolPoint = GetPoints(symbol); + int symbolDigits = GetDigits(symbol); + + // + double result = symbolPoint; + if (symbolDigits == 3 || symbolDigits == 5) + { + result *= 10; + } + + // + return result; +} + +// +// Converts Pips To Price ... +double PipsToPrice( + int pips // pips amount +) +{ + // + int digits = GetDigits(); + double pipValue = GetPipPrice(); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PipsToPrice( + double pips // pips amount +) +{ + // + int digits = GetDigits(); + double pipValue = GetPipPrice(); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PipsToPrice( + string symbol, // selected symbol for calculation + int pips // pips amount +) +{ + // + int digits = GetDigits(symbol); + double pipValue = GetPipPrice(symbol); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PipsToPrice( + string symbol, // selected symbol for calculation + double pips // pips amount +) +{ + // + int digits = GetDigits(symbol); + double pipValue = GetPipPrice(symbol); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} + +// +// Converts Price to Pips ... +double PriceToPips( + double price // the price amount which required to calculate +) +{ + // + int digits = GetDigits(); + double pipPrice = GetPipPrice(); + + // + double result = price / pipPrice; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PriceToPips( + string symbol, // Selected Symbol + double price // the price amount which required to calculate +) +{ + // + int digits = GetDigits(symbol); + double pipPrice = GetPipPrice(symbol); + + // + double result = price / pipPrice; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} + +// +// Convert Price to Point ... +double PriceToPoint( + double price // the price amount which required to calculate +) +{ + return PriceToPoint(_Symbol, price); +} +double PriceToPoint( + string symbol, // Selected Symbol + double price // the price amount which required to calculate +) +{ + // + double result = 0; + + // + double point = GetPoints(symbol); + result = price / point; + + // + return result; +} + +// +// Converts Point to Price ... +double PointToPrice( + double points // Points Size +) +{ + return PointToPrice(_Symbol, points); +} +double PointToPrice( + string symbol, // Selected Symbol + double points // Points Size +) +{ + // + double result = 0; + + // + double point = GetPoints(symbol); + result = points * point; + + // + return result; +} + +// +// CANDLES ... + +// +// Validate Candle ... +bool IsValid( + XOHCL &candle // specified candle +) +{ + // + bool result = false; + + // + result = + // + candle.open > 0 && + candle.close > 0 && + candle.high > 0 && + candle.low > 0 + // + ; + + // + return result; +} + +// +// Get a Candle Body ... +double GetCandleBody( + XOHCL &candle // specified candle +) +{ + // + double result = 0; + + // + bool isValid = IsValid(candle); + if (!isValid) + { + return result; + } + + // + result = MathAbs(candle.open - candle.close); + + // + return result; +} + +// +// Get a Candle Range ... +double GetCandleRange( + XOHCL &candle // specified candle +) +{ + // + double result = 0; + + // + bool isValid = IsValid(candle); + if (!isValid) + { + return result; + } + + // + result = MathAbs(candle.high - candle.low); + + // + return result; +} + +// +// Get a Candle Shadow ... +double GetCandleShadow( + XOHCL &candle // specified candle +) +{ + // + double result = 0; + + // + bool isValid = IsValid(candle); + if (!isValid) + { + return 0; + } + + // + double range = GetCandleRange(candle); + double body = GetCandleBody(candle); + + // + result = MathAbs(range - body); + + // + return result; +} + +// +// Retrieve High Shadow of Candle ... +double GetCandleHighShadow( + XOHCL &candle // specified candle +) +{ + // + double result = 0; + + // + bool isValid = IsValid(candle); + if (!isValid) + { + return result; + } + + // + double upPrice = MathMax(candle.open, candle.close); + + // + result = candle.high - upPrice; + + // + return result; +} + +// +// Retrieve Low Shadow of Candle ... +double GetCandleLowShadow( + XOHCL &candle // specified candle +) +{ + // + double result = 0; + + // + bool isValid = IsValid(candle); + if (!isValid) + { + return result; + } + + // + double downPrice = MathMin(candle.open, candle.close); + + // + result = downPrice - candle.low; + + // + return result; +} + +// +// Check a Candle is Base Candle for RTM or not ... +bool IsBaseCandle( + XOHCL &candle // specified candle +) +{ + // + double range = GetCandleRange(candle); + double body = GetCandleBody(candle); + + // + bool result = body > range; + + // + return result; +} + +// +// Check Candle Body Bigger Than it's Shadow ... +bool CandleHasStrongBody(XOHCL &candle) +{ + // + double bodySize = MathAbs(candle.open - candle.close); + double shadowSize = MathAbs(candle.high - candle.low) - bodySize; + + // + bool result = bodySize > (shadowSize * 1.5); + + // + return result; +} + +// +// Detect Doji Candle ... +bool IsDojiCandle( + XOHCL &candle, // Specified Candle + double detectFactor = 0.05 // Detect Factor +) +{ + // + bool result = false; + + // + bool isValid = IsValid(candle); + if ( + !isValid || + detectFactor <= 0 || + detectFactor > 1) + { + return result; + } + + // + // Retrieve Candle Parts ... + double body = GetCandleBody(candle); + double range = GetCandleRange(candle); + double shadows = GetCandleShadow(candle); + + // + // Calculate Candle Rate ... + double factor = range * detectFactor; + double shadowFactor = (1 - detectFactor) * range; + + // + result = + // + body > 0 && + range > 0 && + factor > 0 && + shadows > 0 && + body <= factor && + shadowFactor > 0 && + shadows >= shadowFactor + // + ; + + // + return result; +} + +// +// Detect Shadows of Specific Candles must be same .. +bool IsCrossShadowCandle( + XOHCL &candle, // Specified Candle + double smoothingFactor = 0.05 // Smoothing Factor +) +{ + // + bool result = false; + + // + bool isValid = IsValid(candle); + if (!isValid || + smoothingFactor <= 0 || + smoothingFactor >= 1) + { + return result; + } + + // + // Retrieve Candle Parts ... + double body = GetCandleBody(candle); + double range = GetCandleRange(candle); + double shadows = GetCandleShadow(candle); + + // + double upBody = MathMax(candle.open, candle.close); + double downBody = MathMin(candle.open, candle.close); + + // + double upShadow = candle.high - upBody; + double downShadow = downBody - candle.low; + + // + // Calculate Candle Rate ... + double factor = range * smoothingFactor; + + // + result = + upShadow > 0 && + downShadow > 0 && + body > 0 && + range > 0 && + shadows > 0 && + ((upShadow == downShadow) || + MathAbs(upShadow - downShadow) <= factor); + + // + return result; +} + +// +// Detect a Candle Shadow Hunt Specific price or not ... +bool IsShadowHuntCandle( + XOHCL &candle, // Specified Candle + double price // Specified Price +) +{ + // + bool result = false; + + // + // Validate Args ... + bool isValid = IsValid(candle); + if (!isValid || price <= 0) + { + return result; + } + + // + double upBody = MathMax(candle.open, candle.close); + double downBody = MathMin(candle.open, candle.close); + + // + double hShadow = GetCandleHighShadow(candle); + double lShadow = GetCandleLowShadow(candle); + + // + double range = GetCandleRange(candle); + double factor = range * 0.3; + + // + bool isStrongHShadow = hShadow >= factor; + bool isStrongLShadow = lShadow >= factor; + + // + bool isPriceUp = + price >= candle.high || + price >= upBody; + + // + result = + // + isPriceUp + // + ? + // + isStrongHShadow && + (price == candle.high || + (price > upBody && price < candle.high)) + // + : + // + isStrongLShadow && + (price == candle.low || + (price < downBody && price > candle.low)) + // + ; + + // + return result; +} + +// +// Check a Candle is Bullish or not ... +bool IsBullishCandle( + XOHCL &candle // specified candle +) +{ + // + bool result = false; + + // + bool isValid = IsValid(candle); + if (!isValid) + { + return result; + } + + // + result = candle.open < candle.close; + + // + return result; +} +bool IsBullishCandle( + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle(bar_index); + + // + result = IsBullishCandle(candle); + + // + return result; +} +bool IsBullishCandle( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle( + symbol, + mPeriod, + bar_index); + + // + result = IsBullishCandle(candle); + + // + return result; +} + +// +// Check a Candle is Bullish or not ... +bool IsBearishCandle( + XOHCL &candle // specified candle +) +{ + // + bool result = false; + + // + bool isValid = IsValid(candle); + if (!isValid) + { + return result; + } + + // + result = candle.open > candle.close; + + // + return result; +} +bool IsBearishCandle( + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle(bar_index); + + // + result = IsBearishCandle(candle); + + // + return result; +} +bool IsBearishCandle( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle( + symbol, + mPeriod, + bar_index); + + // + result = IsBearishCandle(candle); + + // + return result; +} + +// +// Retrieve Applied Price at Specific Candle ... +double GetAppliedPrice( + XOHCL &candle, // specified candle + ENUM_APPLIED_PRICE source = PRICE_CLOSE // specified Applied To +) +{ + // + double result = EMPTY_VALUE; + + // + switch (source) + { + // + // Open ... + case PRICE_OPEN: + result = candle.open; + break; + + // + // High ... + case PRICE_HIGH: + result = candle.high; + break; + + // + // Low ... + case PRICE_LOW: + result = candle.low; + break; + + // + // Median ((High + Low) / 2) ... + case PRICE_MEDIAN: + result = (candle.high + candle.low) / 2; + break; + + // + // Typical ((High + Low + Close)/3) ... + case PRICE_TYPICAL: + result = (candle.high + candle.low + candle.close) / 3; + break; + + // + // Weighted ((High + Low + Close + Close)/4) ... + case PRICE_WEIGHTED: + result = (candle.high + candle.low + (candle.close * 2)) / 4; + break; + + // + // Close ... + default: + case PRICE_CLOSE: + result = candle.close; + break; + } + + // + return result; +} +double GetAppliedPrice( + int bar_index, // specify candle index + ENUM_APPLIED_PRICE source = PRICE_CLOSE // specified Applied To +) +{ + // + double result = EMPTY_VALUE; + + // + XOHCL candle = GetCandle(bar_index); + result = GetAppliedPrice(candle, source); + + // + return result; +} +double GetAppliedPrice( + int bar_index, // specify candle index + ENUM_SERIESMODE mode // converts Series Mode to Applied Price ... +) +{ + // + double result = 0; + + // + ENUM_APPLIED_PRICE mAppliedTo = To(mode); + result = GetAppliedPrice( + bar_index, + mAppliedTo); + + // + return result; +} + +// +template +double GetAppliedPrice(ENUM_APPLIED_PRICE tprice, T &open[], T &high[], T &low[], T &close[], int i) +{ + switch (tprice) + { + case PRICE_CLOSE: + return (close[i]); + case PRICE_OPEN: + return (open[i]); + case PRICE_HIGH: + return (high[i]); + case PRICE_LOW: + return (low[i]); + case PRICE_MEDIAN: + return ((high[i] + low[i]) / 2.0); + case PRICE_TYPICAL: + return ((high[i] + low[i] + close[i]) / 3.0); + case PRICE_WEIGHTED: + return ((high[i] + low[i] + close[i] + close[i]) / 4.0); + } + return (0); +} + +// +// Converts ... +ENUM_APPLIED_PRICE To( + ENUM_SERIESMODE mode // converts Series Mode to Applied Price ... +) +{ + // + ENUM_APPLIED_PRICE result = PRICE_CLOSE; + + // + switch (mode) + { + // + // High ... + case MODE_HIGH: + result = PRICE_HIGH; + break; + + // + // Open ... + case MODE_OPEN: + result = PRICE_OPEN; + break; + + // + // Low ... + case MODE_LOW: + result = PRICE_LOW; + break; + + // + // Close ... + // Default ... + case MODE_CLOSE: + default: + result = PRICE_CLOSE; + break; + } + + // + return result; +} + +// +// Retrieve a Candel Data ... +XOHCL GetCandle(int bar_index) +{ + // + XOHCL result = {}; + + // + double open = iOpen(_Symbol, _Period, bar_index); + double high = iHigh(_Symbol, _Period, bar_index); + double close = iClose(_Symbol, _Period, bar_index); + double low = iLow(_Symbol, _Period, bar_index); + + // + result.low = low; + result.open = open; + result.high = high; + result.close = close; + + // + return result; +} +XOHCL GetCandle( + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + XOHCL result = {}; + + // + double open = iOpen(_Symbol, mPeriod, bar_index); + double high = iHigh(_Symbol, mPeriod, bar_index); + double close = iClose(_Symbol, mPeriod, bar_index); + double low = iLow(_Symbol, mPeriod, bar_index); + + // + result.low = low; + result.open = open; + result.high = high; + result.close = close; + + // + return result; +} +XOHCL GetCandle( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + XOHCL result = {}; + + // + double open = iOpen(symbol, mPeriod, bar_index); + double high = iHigh(symbol, mPeriod, bar_index); + double close = iClose(symbol, mPeriod, bar_index); + double low = iLow(symbol, mPeriod, bar_index); + + // + result.low = low; + result.open = open; + result.high = high; + result.close = close; + + // + return result; +} + +// +// Get a Series Of Candles ... +bool GetCandles( + XOHCL &result[], // Hold Result ... + string mSymbol = NULL, // Specified Symbol ... + ENUM_TIMEFRAMES mPeriod = NULL, // Specified Period ... + int mStart = 0, // Start Bar Index ... + int mCount = 1 // Specified Number of Candles ... +) +{ + // + bool mResult = false; + + // + if (mStart < 0) + { + mStart = 0; + } + + // + if (mCount <= 0) + { + mCount = 1; + } + + // + Clean(result); + + // + for (int i = mStart; i < mStart + mCount; i++) + { + // + XOHCL iC = GetCandle( + mSymbol, + mPeriod, + i); + + // + Add( + iC, + result); + } + + // + mResult = ArraySize(result) > 0; + + // + return mResult; +} + +// +// Retrieve a candle index in current timeframe inside another timeframe ... +int GetCandleBarIndex( + int bar_index, // Specify Candle index in current timeframe + ENUM_TIMEFRAMES destPeriod // Specify destination timeframe +) +{ + // + int result = -1; + + // + datetime barTime = iTime(_Symbol, _Period, bar_index); + result = iBarShift(_Symbol, destPeriod, barTime); + + // + return result; +} + +// +// Retrieve a symbol candle index in source time frame inside dest timeframe ... +int GetCandleBarIndex( + int bar_index, // Specify Candle index in current timeframe + string symbol, // Specify desired Symbol + ENUM_TIMEFRAMES sourcePeriod, // Specify bar_index timeframe + ENUM_TIMEFRAMES destPeriod // Specify destination timeframe +) +{ + // + int result = -1; + + // + datetime barTime = iTime(symbol, sourcePeriod, bar_index); + result = iBarShift(symbol, destPeriod, barTime); + + // + return result; +} + +// +// Determines a cnadle is Swing High +// or Swing Low order block ... +ENUM_X_SWING_TYPE GetCandleSwing(int bar_index) +{ + // + ENUM_X_SWING_TYPE result = X_NO_SWING; + + // + // Reading Candle Models ... + XOHCL candles[3]; + candles[0] = GetCandle(bar_index + 1); + candles[1] = GetCandle(bar_index + 2); + candles[2] = GetCandle(bar_index + 3); + + // + // Check Swing Start Candle has Strong Body ... + bool isStrongBodyCandle = CandleHasStrongBody(candles[2]); + if (!isStrongBodyCandle) + { + return result; + } + + // + // Check Swing Low Conditions ... + bool isSwingLowOrderBlock = + candles[2].low < candles[1].low && + candles[1].low < candles[0].low && + candles[2].low < candles[0].low; + if (isSwingLowOrderBlock) + { + result = X_SWING_LOW; + } + + // + // Check Swing High Conditions ... + bool isSwingHighOrderBlock = + candles[2].high > candles[1].high && + candles[1].high > candles[0].high && + candles[2].high > candles[0].high; + if (isSwingHighOrderBlock) + { + result = X_SWING_HIGH; + } + + // + return result; +} +ENUM_X_SWING_TYPE GetCandleSwing( + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + ENUM_X_SWING_TYPE result = X_NO_SWING; + + // + // Reading Candle Models ... + XOHCL candles[3]; + candles[0] = GetCandle(mPeriod, bar_index + 1); + candles[1] = GetCandle(mPeriod, bar_index + 2); + candles[2] = GetCandle(mPeriod, bar_index + 3); + + // + // Check Swing Start Candle has Strong Body ... + bool isStrongBodyCandle = CandleHasStrongBody(candles[2]); + if (!isStrongBodyCandle) + { + return result; + } + + // + // Check Swing Low Conditions ... + bool isSwingLowOrderBlock = + candles[2].low < candles[1].low && + candles[1].low < candles[0].low && + candles[2].low < candles[0].low; + if (isSwingLowOrderBlock) + { + result = X_SWING_LOW; + } + + // + // Check Swing High Conditions ... + bool isSwingHighOrderBlock = + candles[2].high > candles[1].high && + candles[1].high > candles[0].high && + candles[2].high > candles[0].high; + if (isSwingHighOrderBlock) + { + result = X_SWING_HIGH; + } + + // + return result; +} +ENUM_X_SWING_TYPE GetCandleSwing( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + ENUM_X_SWING_TYPE result = X_NO_SWING; + + // + // Reading Candle Models ... + XOHCL candles[3]; + candles[0] = GetCandle(symbol, mPeriod, bar_index + 1); + candles[1] = GetCandle(symbol, mPeriod, bar_index + 2); + candles[2] = GetCandle(symbol, mPeriod, bar_index + 3); + + // + // Check Swing Start Candle has Strong Body ... + bool isStrongBodyCandle = CandleHasStrongBody(candles[2]); + if (!isStrongBodyCandle) + { + return result; + } + + // + // Check Swing Low Conditions ... + bool isSwingLowOrderBlock = + candles[2].low < candles[1].low && + candles[1].low < candles[0].low && + candles[2].low < candles[0].low; + if (isSwingLowOrderBlock) + { + result = X_SWING_LOW; + } + + // + // Check Swing High Conditions ... + bool isSwingHighOrderBlock = + candles[2].high > candles[1].high && + candles[1].high > candles[0].high && + candles[2].high > candles[0].high; + if (isSwingHighOrderBlock) + { + result = X_SWING_HIGH; + } + + // + return result; +} + +// +// Find Swing Points ... +int FindSwing( + string mSymbol, // Trading Symbol ... + ENUM_TIMEFRAMES mPeriod, // Trading Period ... + ENUM_SERIESMODE mode, // Swing Based On Price mode ... + int mLength, // Loopback ... + int bar_index // BarIndex ... +) +{ + // + int result = -1; + + // + if (StringLen(mSymbol) == 0 || (mode != MODE_HIGH && mode != MODE_LOW)) + { + return result; + } + + // + int current = bar_index; + int founded = FindNextSwing( + mSymbol, + mPeriod, + mode, + (mLength * 2) + 1, + current - mLength); + + // + while (founded != current) + { + // + current = FindNextSwing( + mSymbol, + mPeriod, + mode, + mLength, + current + 1); + + // + founded = FindNextSwing( + mSymbol, + mPeriod, + mode, + (mLength * 2) + 1, + current - mLength); + } + + // + result = current; + + // + return result; +} + +// +// Find Next Swing ... +int FindNextSwing( + string mSymbol, // Trading Symbol ... + ENUM_TIMEFRAMES mPeriod, // Trading Period ... + ENUM_SERIESMODE mode, // Swing Based On Price mode ... + int mLength, // Loopback ... + int bar_index // BarIndex ... +) +{ + // + int result = -1; + + // + if (bar_index < 0) + { + mLength += bar_index; + bar_index = 0; + } + + // + result = mode == MODE_HIGH + ? iHighest( + mSymbol, + mPeriod, + mode, + mLength, + bar_index) + : iLowest( + mSymbol, + mPeriod, + mode, + mLength, + bar_index); + + // + return result; +} + +// +// Retrieve Market Highest High ... +double GetHighestHigh( + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + mLength, + bar_index); + + // + result = iHigh( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetHighestHigh( + int mLength, // Which market Length use + int bar_index, // bar index + ENUM_SERIESMODE mode // Calculation mode +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + _Symbol, + _Period, + mode, + mLength, + bar_index); + + // + result = iHigh( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetHighestHigh( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + symbol, + mPeriod, + MODE_HIGH, + mLength, + bar_index); + + // + result = iHigh( + symbol, + mPeriod, + rIdx); + + // + return result; +} +double GetHighestHigh( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + ENUM_SERIESMODE mode, // Calculation mode + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + symbol, + mPeriod, + mode, + mLength, + bar_index); + + // + result = iHigh( + symbol, + mPeriod, + rIdx); + + // + return result; +} + +// +// Retrieve Market Lowest Low ... +double GetLowestLow( + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + mLength, + bar_index); + + // + result = iLow( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetLowestLow( + int mLength, // Which market Length use + int bar_index, // bar index + ENUM_SERIESMODE mode // Calculation mode +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + _Symbol, + _Period, + mode, + mLength, + bar_index); + + // + result = iLow( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetLowestLow( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + symbol, + mPeriod, + MODE_LOW, + mLength, + bar_index); + + // + result = iLow( + symbol, + mPeriod, + rIdx); + + // + return result; +} +double GetLowestLow( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + ENUM_SERIESMODE mode, // Calculation mode + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + symbol, + mPeriod, + mode, + mLength, + bar_index); + + // + result = iLow( + symbol, + mPeriod, + rIdx); + + // + return result; +} + +// +// Find Support and Resistance for Specific Bar based on provided Buffer ... +XOHCLSupRes ExtractSupportAndResistance( + int barIndex, // Bar Index ... + const double &pivots[], // Provided Pivot Points ... + int count = 3, // Number of Requireds ... + double step = 0, // Distance between each item with it's Last Side ... + string mSymbol = NULL, // Trading Symbol ... + ENUM_TIMEFRAMES mPeriod = NULL // Trading Period ... +) +{ + // + if (StringLen(mSymbol) == 0 || mSymbol == NULL) + { + mSymbol = _Symbol; + } + + // + if (mPeriod == NULL) + { + mPeriod = _Period; + } + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + XOHCLSupRes result; + Clean(result.res); + Clean(result.sup); + + // + int pivotsCount = ArraySize(pivots); + if (pivotsCount <= 0) + { + return result; + } + + // + if (count <= 0 || + count > pivotsCount - 1) + { + return result; + } + + // + XOHCL cBar = GetCandle( + mSymbol, + mPeriod, + barIndex); + + // + double lastR = 0; + double tmpR[]; + + // + double lastS = 0; + double tmpS[]; + + // + // Extract Supports ... + // which prices is under low of candle ... + // + // Extract Resistance ... + // which prices is over high of candle ... + for (int i = 0; i < pivotsCount; i++) + { + // + double iFlat = pivots[i]; + + // + if (iFlat > cBar.high) + { + // + bool canAdd = + step <= 0 + ? true + : lastR == 0 || MathAbs(iFlat - lastR) >= step; + if (canAdd) + { + // + Add( + iFlat, + tmpR); + + // + lastR = iFlat; + } + } + else if (iFlat < cBar.low) + { + // + bool canAdd = + step <= 0 + ? true + : lastS == 0 || MathAbs(iFlat - lastS) >= step; + if (canAdd) + { + // + Add( + iFlat, + tmpS); + + // + lastS = iFlat; + } + } + } + + // + // Sorting Founded Resistance and Supports ... + + // + // Since Resistance Levels must be Increasing ... + ArraySort(tmpR); + + // + // Since Support Levels must be Decreasing ... + ArraySort(tmpS); + ArrayReverse(tmpS); + + // + // Fill Resistance ... + int tmpRCount = ArraySize(tmpR); + if (tmpRCount > 0) + { + // + if (tmpRCount < count) + { + // + ArrayCopy( + result.res, + tmpR); + } + else + { + // + ArrayCopy( + result.res, + tmpR, + 0, + 0, + count); + } + } + + // + // Fill Supports ... + int tmpSCount = ArraySize(tmpS); + if (tmpSCount > 0) + { + // + if (tmpSCount < count) + { + // + ArrayCopy( + result.sup, + tmpS); + } + else + { + // + ArrayCopy( + result.sup, + tmpS, + 0, + 0, + count); + } + } + + // + return result; +} + +// +// Find Support and Resistance for Specific Price based on provided Buffer ... +XOHCLSupRes ExtractSupportAndResistance( + double price, // Price ... + const double &pivots[], // Provided Pivot Points ... + int count = 3, // Number of Requireds ... + double step = 0 // Distance between each item with it's Last Side ... +) +{ + // + XOHCLSupRes result; + Clean(result.res); + Clean(result.sup); + + // + if (price <= 0) + { + return result; + } + + // + int pivotsCount = ArraySize(pivots); + if (pivotsCount <= 0) + { + return result; + } + + // + if (count <= 0 || + count > pivotsCount - 1) + { + return result; + } + + // + double lastR = 0; + double tmpR[]; + + // + double lastS = 0; + double tmpS[]; + + // + // Extract Supports ... + // which prices is under low of candle ... + // + // Extract Resistance ... + // which prices is over high of candle ... + for (int i = 0; i < pivotsCount; i++) + { + // + double iFlat = pivots[i]; + + // + if (iFlat > price) + { + // + bool canAdd = + step <= 0 + ? true + : lastR == 0 || MathAbs(iFlat - lastR) >= step; + if (canAdd) + { + // + Add( + iFlat, + tmpR); + + // + lastR = iFlat; + } + } + else if (iFlat < price) + { + // + bool canAdd = + step <= 0 + ? true + : lastS == 0 || MathAbs(iFlat - lastS) >= step; + if (canAdd) + { + // + Add( + iFlat, + tmpS); + + // + lastS = iFlat; + } + } + } + + // + // Sorting Founded Resistance and Supports ... + + // + // Since Resistance Levels must be Increasing ... + ArraySort(tmpR); + + // + // Since Support Levels must be Decreasing ... + ArraySort(tmpS); + ArrayReverse(tmpS); + + // + // Fill Resistance ... + int tmpRCount = ArraySize(tmpR); + if (tmpRCount > 0) + { + // + if (tmpRCount < count) + { + // + ArrayCopy( + result.res, + tmpR); + } + else + { + // + ArrayCopy( + result.res, + tmpR, + 0, + 0, + count); + } + } + + // + // Fill Supports ... + int tmpSCount = ArraySize(tmpS); + if (tmpSCount > 0) + { + // + if (tmpSCount < count) + { + // + ArrayCopy( + result.sup, + tmpS); + } + else + { + // + ArrayCopy( + result.sup, + tmpS, + 0, + 0, + count); + } + } + + // + return result; +} + +// +// Find a Value less than Specified ... +double FindLesserThanValue( + double value, // Specified Value ... + const double &source[], // Source ... + bool isDescend = false // Find Biggest Lesser Value ... +) +{ + // + double result = -1; + + // + int itemsCount = ArraySize(source); + if (itemsCount <= 0) + { + return result; + } + + // + // Make a Copy of source ... + double tmp[]; + + // + ArrayResize( + tmp, + ArraySize(source)); + + // + ArrayCopy( + tmp, + source); + + // + // Sort Temp Buffer ... + ArraySort(tmp); + if (isDescend) + { + ArrayReverse(tmp); + } + + // + int tmpCount = ArraySize(tmp); + for (int i = 0; i < tmpCount; i++) + { + // + double iValue = tmp[i]; + + // + if (iValue < value) + { + // + result = iValue; + break; + } + } + + // + return result; +} + +// +// Find a Value less than Specified ... +double FindBiggerThanValue( + double value, // Specified Value ... + const double &source[], // Source ... + bool isDescend = false // Find Smallest Bigger Value ... +) +{ + // + double result = -1; + + // + int itemsCount = ArraySize(source); + if (itemsCount <= 0) + { + return result; + } + + // + // Make a Copy of source ... + double tmp[]; + + // + ArrayResize( + tmp, + ArraySize(source)); + + // + ArrayCopy( + tmp, + source); + + // + // Sort Temp Buffer ... + ArraySort(tmp); + if (!isDescend) + { + ArrayReverse(tmp); + } + + // + int tmpCount = ArraySize(tmp); + for (int i = 0; i < tmpCount; i++) + { + // + double iValue = tmp[i]; + + // + if (iValue > value) + { + // + result = iValue; + break; + } + } + + // + return result; +} + +// +// Calculate Fib Level ... +double GetFibonacciLevel( + double upPrice, + double downPrice, + double level, + int direction) +{ + // + double ling = upPrice - downPrice; + double pLevel = (ling / 100) * (level * 100); + + // + double result = direction > 0 ? upPrice - pLevel : downPrice + pLevel; + result = NormalizeDouble(result, _Digits); + + // + return result; +} + +// +// Check first Cross Over second at bar_index ... +bool IsCrossOver( + const double &first[], // the buffer which check crossing over second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] > second[bar_index] && + !(first[bar_index + 1] > second[bar_index + 1]); + + // + return result; +} + +// +// Check first is Over second at bar_index ... +bool IsOver( + const double &first[], // the buffer which check over second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] > second[bar_index] && + first[bar_index + 1] > second[bar_index + 1]; + + // + return result; +} + +// +// Check first Cross Under second at bar_index ... +bool IsCrossUnder( + const double &first[], // the buffer which check crossing under second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] < second[bar_index] && + !(first[bar_index + 1] < second[bar_index + 1]); + + // + return result; +} + +// +// Check first is Under second at bar_index ... +bool IsUnder( + const double &first[], // the buffer which check under second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] < second[bar_index] && + first[bar_index + 1] < second[bar_index + 1]; + + // + return result; +} + +// +// Calculate Slope of Specified Buffer at Specified Index ... +double GetSlope( + int from, // In Past Index ... + int to, // In Past Index ... + double &buffer[]) +{ + // + double result = 0; + + // + double toValue = buffer[to]; + double fromValue = buffer[from]; + double deltaValue = toValue - fromValue; + double deltaTime = from - to; + + // + result = deltaValue / deltaTime; + + // + return result; +} + +// +// Check if a Value Increasing in Loopback ... +bool IsIncreasing( + int from, // Last Time Index + int to, // Fisr Tima Index + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + result = toValue > fromValue; + for (int i = to + 1; i <= from - 1; i++) + { + // + double iValue = buffer[i]; + bool isPassed = toValue >= iValue; + + // + bool isIIncreasing = IsIncreasing( + from, + i, + buffer); + + // + // Check Result ... + result = result && isPassed && isIIncreasing; + if (!result) + { + break; + } + } + + // + return result; +} + +// +// Check if a Value Decreasing in Loopback ... +bool IsDecreasing( + int from, // Last Time Index + int to, // Fisr Tima Index + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + result = toValue < fromValue; + for (int i = to + 1; i <= from - 1; i++) + { + // + double iValue = buffer[i]; + bool isPassed = toValue <= iValue; + + // + bool isIDecreasing = IsDecreasing( + from, + i, + buffer); + + // + // Check Result ... + result = result && isPassed && isIDecreasing; + if (!result) + { + break; + } + } + + // + return result; +} + +// +// Get Max Value of Specific Loopback of a Buffer ... +double GetMaxValue( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback) + { + return result; + } + + // + // Loop Through LoopBack ... + for (int i = 0; i < mLoopback; i++) + { + // + double iValue = buffer[i]; + + // + result = + // + result == 0 || result < iValue + // + ? iValue + // + : result + // + ; + } + + // + return result; +} + +// +// Get Min Value of Specific Loopback of a Buffer ... +double GetMinValue( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback) + { + return result; + } + + // + // Loop Through LoopBack ... + for (int i = 0; i < mLoopback; i++) + { + // + double iValue = buffer[i]; + + // + result = + // + result == 0 || result > iValue + // + ? iValue + // + : result + // + ; + } + + // + return result; +} + +// +// Find Same Values in Array ... +void FindSameValueInBuffer( + double &result[], // Holds Result ... + double &source[], // Source ... + int verifications = 3 // Number of Consequence Repeat ... +) +{ + // + Clean(result); + + // + // TenkanSen Flats ... + int sourceCount = ArraySize(source); + if (sourceCount > verifications) + { + // + double mLast = 0; + int mVerified = 0; + for (int i = 0; i < sourceCount; i++) + { + // + double iVal = source[i]; + if (mLast == 0) + { + mLast = iVal; + } + else if (mLast == iVal) + { + mVerified++; + } + else + { + mLast = iVal; + mVerified = 0; + } + + // + if (iVal == mLast && mVerified >= verifications) + { + // + Add( + iVal, + result); + + // + mLast = 0; + mVerified = 0; + } + } + } +} + +// +bool IsInPeak( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback + 1) + { + return result; + } + + // + int q1Length = mLoopback / 4; + int halfLength = mLoopback / 2; + int q2Length = halfLength + q1Length; + + // + double firstValue = buffer[1]; + double q1Value = buffer[q1Length]; + double q2Value = buffer[q2Length]; + double halfValue = buffer[halfLength]; + double lastValue = buffer[ArraySize(buffer) - 1]; + + // + // Peak ... + result = + // + firstValue > lastValue + // + && + // + ( + firstValue > q1Value && + firstValue > halfValue) + // + ; + + // + return result; +} + +// +bool IsInVale( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback + 1) + { + return result; + } + + // + int q1Length = mLoopback / 4; + int halfLength = mLoopback / 2; + int q2Length = halfLength + q1Length; + + // + double firstValue = buffer[1]; + double q1Value = buffer[q1Length]; + double q2Value = buffer[q2Length]; + double halfValue = buffer[halfLength]; + double lastValue = buffer[ArraySize(buffer) - 1]; + + // + // Peak ... + result = + // + firstValue < lastValue + // + && + // + ( + firstValue < q1Value && + firstValue < halfValue) + // + ; + + // + return result; +} + +// +// Check Sharp Happens or not ... +bool IsSharpChanged( + double fromValue, // Past Value + double toValue, // Present Value + double maxValue, // Max in Range Value + double minValue // Min in Range Value +) +{ + // + bool result = false; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double toFromDelta = MathAbs(toValue - fromValue); + double minMaxDelta = maxValue - minValue; + + // + result = toFromDelta >= (minMaxDelta / 3); + + // + return result; +} +bool IsSharpChanged( + int from, // Past Index in Series + int to, // Present Index in Series + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double minValue = GetMinValue( + ArraySize(buffer) - 1, + buffer); + double maxValue = GetMaxValue( + ArraySize(buffer) - 1, + buffer); + double minMaxDelta = maxValue - minValue; + + // + // Sharp Detection ... + result = IsSharpChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} +bool IsSharpChanged( + int from, // Past Bar Index + int to, // Present Bar Index + ENUM_APPLIED_PRICE appliedPrice // Which Price Choose in From or To +) +{ + // + bool result = false; + + // + double toValue = GetAppliedPrice( + to, + appliedPrice); + double fromValue = GetAppliedPrice( + from, + appliedPrice); + + // + int hIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + from, + to); + double maxValue = iHigh( + _Symbol, + _Period, + hIdx); + + // + int lIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + from, + to); + double minValue = iLow( + _Symbol, + _Period, + lIdx); + + // + result = IsSharpChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} + +// +// Check InCreased Sharp Happens or not ... +bool IsSharpIncreasedChanged( + double fromValue, // Past Value + double toValue, // Present Value + double maxValue, // Max in Range Value + double minValue // Min in Range Value +) +{ + // + bool result = false; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double toFromDelta = MathAbs(toValue - fromValue); + double minMaxDelta = maxValue - minValue; + + // + result = + isIncreased && + toFromDelta >= (minMaxDelta / 3); + + // + return result; +} +bool IsSharpIncreasedChanged( + int from, // Past Index in Series + int to, // Present Index in Series + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + + // + double minValue = GetMinValue( + ArraySize(buffer) - 1, + buffer); + double maxValue = GetMaxValue( + ArraySize(buffer) - 1, + buffer); + double minMaxDelta = maxValue - minValue; + + // + // Sharp Detection ... + result = IsSharpIncreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} +bool IsSharpIncreasedChanged( + int from, // Past Bar Index + int to, // Present Bar Index + ENUM_APPLIED_PRICE appliedPrice // Which Price Choose in From or To +) +{ + // + bool result = false; + + // + double toValue = GetAppliedPrice( + to, + appliedPrice); + double fromValue = GetAppliedPrice( + from, + appliedPrice); + + // + int hIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + from, + to); + double maxValue = iHigh( + _Symbol, + _Period, + hIdx); + + // + int lIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + from, + to); + double minValue = iLow( + _Symbol, + _Period, + lIdx); + + // + result = IsSharpIncreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} + +// +// Check Decreased Sharp Happens or not ... +bool IsSharpDecreasedChanged( + double fromValue, // Past Value + double toValue, // Present Value + double maxValue, // Max in Range Value + double minValue // Min in Range Value +) +{ + // + bool result = false; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double toFromDelta = MathAbs(toValue - fromValue); + double minMaxDelta = maxValue - minValue; + + // + result = + !isIncreased && + toFromDelta >= (minMaxDelta / 3); + + // + return result; +} +bool IsSharpDecreasedChanged( + int from, // Past Index in Series + int to, // Present Index in Series + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + + // + double minValue = GetMinValue( + ArraySize(buffer) - 1, + buffer); + double maxValue = GetMaxValue( + ArraySize(buffer) - 1, + buffer); + double minMaxDelta = maxValue - minValue; + + // + // Sharp Detection ... + result = IsSharpDecreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} +bool IsSharpDecreasedChanged( + int from, // Past Bar Index + int to, // Present Bar Index + ENUM_APPLIED_PRICE appliedPrice // Which Price Choose in From or To +) +{ + // + bool result = false; + + // + double toValue = GetAppliedPrice( + to, + appliedPrice); + double fromValue = GetAppliedPrice( + from, + appliedPrice); + + // + int hIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + from, + to); + double maxValue = iHigh( + _Symbol, + _Period, + hIdx); + + // + int lIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + from, + to); + double minValue = iLow( + _Symbol, + _Period, + lIdx); + + // + result = IsSharpDecreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} + +// +void Clean(int &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void Clean(ulong &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void Clean(string &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void Clean(double &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} + +// +template +bool GetLastItem( + T &item, // Holds Result + T &buffer[] // Specified Buffer +) +{ + // + bool result = false; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + item = buffer[bufferSize - 1]; + + // + result = true; + return result; +} + +// +void Add( + int item, // item want to add + int &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + ulong item, // item want to add + ulong &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + string item, // item want to add + string &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + double item, // item want to add + double &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + XOHCL &item, // item want to add + XOHCL &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + datetime &item, // item want to add + datetime &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} + +// +// Add an Item to a Buffer if not Exists ... +void AddIfNotExists( + double value, + double &values[], + double smoothingPoint = 3) +{ + // + double smoothingValue = smoothingPoint * GetPoints(_Symbol); + + // + int valuesCount = ArraySize(values); + if (valuesCount <= 0) + { + // + Add(value, + values); + } + else + { + // + bool isExists = false; + for (int i = 0; i < valuesCount; i++) + { + // + double iVal = values[i]; + + // + double diff = MathAbs(iVal - value); + + // + if (iVal == value || diff < smoothingValue) + { + // + isExists = true; + break; + } + } + + // + if (!isExists) + { + // + Add(value, + values); + } + } +} + +// +// Add a Buffers Child to another Buffer +// if it's not Contains them ... +void AddsIfNotExists( + double &source[], + double &dest[], + double smoothingPoint = 3) +{ + // + double smoothingValue = smoothingPoint * GetPoints(_Symbol); + + // + int sourceCount = ArraySize(source); + if (sourceCount <= 0) + { + return; + } + + // + for (int i = 0; i < sourceCount; i++) + { + // + double iSource = source[i]; + + // + AddIfNotExists( + iSource, + dest, + smoothingPoint); + } +} + +// +// Converts a Buffer to String Representation ... +string ToString( + const int &buffer[], // Specified Buffer + string separator = ",", // Specified Separator + bool addIndex = false, // Specified Add Items Indexes or Not + string indexLabel = "i:", // Specified Index Label + string indexSeparator = ">" // Specified Index Separator + +) +{ + // + string result = ""; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + for (int i = 0; i < bufferSize; i++) + { + // + if (addIndex) + { + // + if (StringLen(indexLabel) > 0) + { + result += indexLabel + " "; + } + + // + result += (string)i + " "; + + // + if (StringLen(indexSeparator) > 0) + { + result += indexSeparator + " "; + } + } + + // + string iItemString = (string)buffer[i]; + + // + result += iItemString; + + // + if (i < bufferSize - 1) + { + result += separator; + } + } + + // + return result; +} +string ToString( + const double &buffer[], // Specified Buffer + string separator = ",", // Specified Separator + bool addIndex = false, // Specified Add Items Indexes or Not + string indexLabel = "i:", // Specified Index Label + string indexSeparator = ">" // Specified Index Separator + +) +{ + // + string result = ""; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + for (int i = 0; i < bufferSize; i++) + { + // + if (addIndex) + { + // + if (StringLen(indexLabel) > 0) + { + result += indexLabel + " "; + } + + // + result += (string)i + " "; + + // + if (StringLen(indexSeparator) > 0) + { + result += indexSeparator + " "; + } + } + + // + string iItemString = (string)buffer[i]; + + // + result += iItemString; + + // + if (i < bufferSize - 1) + { + result += separator; + } + } + + // + return result; +} +string ToString( + const string &buffer[], // Specified Buffer + string separator = ",", // Specified Separator + bool addIndex = false, // Specified Add Items Indexes or Not + string indexLabel = "i:", // Specified Index Label + string indexSeparator = ">" // Specified Index Separator + +) +{ + // + string result = ""; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + for (int i = 0; i < bufferSize; i++) + { + // + if (addIndex) + { + // + if (StringLen(indexLabel) > 0) + { + result += indexLabel + " "; + } + + // + result += (string)i + " "; + + // + if (StringLen(indexSeparator) > 0) + { + result += indexSeparator + " "; + } + } + + // + string iItemString = (string)buffer[i]; + + // + result += iItemString; + + // + if (i < bufferSize - 1) + { + result += separator; + } + } + + // + return result; +} +string ToString( + const datetime &buffer[], // Specified Buffer + string separator = ",", // Specified Separator + bool addIndex = false, // Specified Add Items Indexes or Not + string indexLabel = "i:", // Specified Index Label + string indexSeparator = ">" // Specified Index Separator +) +{ + // + string result = ""; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + for (int i = 0; i < bufferSize; i++) + { + // + if (addIndex) + { + // + if (StringLen(indexLabel) > 0) + { + result += indexLabel + " "; + } + + // + result += (string)i + " "; + + // + if (StringLen(indexSeparator) > 0) + { + result += indexSeparator + " "; + } + } + + // + string iItemString = (string)buffer[i]; + + // + result += iItemString; + + // + if (i < bufferSize - 1) + { + result += separator; + } + } + + // + return result; +} +template +string ToString(T value) +{ + return (string)value; +} + +// +// Converts String to boolean ... +bool ToBoolean(string value) +{ + // + bool result = false; + + // + if (StringLen(value) <= 0) + { + return result; + } + + // + StringToLower(value); + result = value == "true"; + + // + return result; +} + +// +// Search Array For Specific Item ... +template +int FindIndex( + T item, // What is Search ... + T &buffer[] // Search in ... +) +{ + // + int result = -1; + + // + int count = ArraySize(buffer); + if (count <= 0) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + T iT = buffer[i]; + + // + if (iT == item) + { + // + result = i; + break; + } + } + + // + return result; +} + +// +template +bool Contains( + T item, // What is Search ... + T &buffer[] // Search in ... +) +{ + // + bool result = false; + + // + int idx = FindIndex( + item, + buffer); + result = idx > -1; + + // + return result; +} + +// +template +bool Remove( + T item, + T &buffer[]) +{ + // + bool result = false; + + // + int itemIndex = FindIndex( + item, + buffer); + if (itemIndex < 0) + { + return result; + } + + // + result = ArrayRemove( + buffer, + itemIndex, + 1); + + // + return result; +} + +// +// Split an String Representation of an Array ... +void SplitContent( + string &result[], // Hold Result ... + string content, // Source ... + string separator = ",", // Separator ... + bool forceCleanResult = true // Clean Result ... +) +{ + // + if (forceCleanResult) + { + Clean(result); + } + + // + if (separator == NULL || StringLen(separator) == 0) + { + separator = ","; + } + + // + if (StringLen(content) == 0) + { + return; + } + + // + StringSplit( + content, + StringGetCharacter( + separator, + 0), + result); +} + +// +// Extract Data from String ... +string ExtractString( + const string source, // Source String used for Extracting + const string startString, // Expression Start String must be Unique + const string endString // Where to End Extraction, usually a Sign +) +{ + // + string result = ""; + + // + // Validate String ... + if ( + StringLen(source) == 0 || + StringLen(endString) == 0 || + StringLen(startString) == 0) + { + return result; + } + + // + // Find Start String Position ... + int sPos = StringFind( + source, + startString); + if (sPos < 0) + { + return result; + } + + // + // Find End String Position after Start String ... + int searchEndFromPos = sPos + StringLen(startString); + int ePos = StringFind( + source, + endString, + searchEndFromPos); + if (ePos < 0) + { + return result; + } + + // + // Extract Data from Source ... + int dLength = ePos - searchEndFromPos; + result = StringSubstr( + source, + searchEndFromPos, + dLength); + + // + return result; +} + +// +// Extract an Array of Contents ... +int ExtractStrings( + string &result[], // Hold Result + const string source, // Source String used for Extracting + const string startString, // Expression Start String must be Unique + const string endString // Where to End Extraction, usually a Sign +) +{ + // + int mResult = 0; + + // + Clean(result); + + // + // Validate Args ... + int sourceLength = StringLen(source); + int startLength = StringLen(startString); + int endLength = StringLen(endString); + + // + int minRequiredLength = startLength + endLength; + + // + if ( + endLength <= 0 || + startLength <= 0 || + sourceLength <= 0 || + sourceLength < minRequiredLength) + { + return mResult; + } + + // + // Make a Copy of Source for Manipulating ... + string workStr = source; + + // + // Define a Loop ... + while (StringLen(workStr) > minRequiredLength) + { + // + // Find Item ... + string item = ExtractString( + workStr, + startString, + endString); + + // + // Breakout when couldn't find anymore item ... + int itemLength = StringLen(item); + if (itemLength <= 0) + { + break; + } + + // + // Prepare Item Source String for Replacing in Work String ... + string itemSource = startString + item + endString; + + // + // Add Item to Result Array ... + Add( + item, + result); + + // + // Replace Item Soure in Work String ... + StringReplace( + workStr, + itemSource, + ""); + } + + // + // Calculate Size of Array ... + mResult = ArraySize(result); + + // + return mResult; +} + +// +// Normalize a give Volume ... +double NormalizeVolume( + double volume, // desired volume to normalize + string symbol = NULL, // Specified Symbol for Normalization + int mLength = 2 // Length of Digits +) +{ + // + double result = volume; + + // + // Normalize Symbol ... + if (StringLen(symbol) == 0) + { + symbol = _Symbol; + } + + // + // Normalize Digits ... + int digits = GetDigits(symbol); + mLength = + mLength == 0 || mLength > digits + ? digits + : MathMin(mLength, digits); + + // + // Normalize Volume ... + result = NormalizeDouble(result, mLength); + + // + double maxAvailableVolume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX); + double minAvailableVolume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN); + + // + // Validate Result ... + if (result > maxAvailableVolume) + { + result = maxAvailableVolume; + } + else if (result < minAvailableVolume) + { + result = minAvailableVolume; + } + + // + return result; +} + +// +// Normallize Price ... +double NormalizePrice( + double price, // desired Price for normalization + string symbol = NULL // Specified Symbol for Normalization +) +{ + // + double result = 0; + + // + // Mormalize Symbol ... + if (StringLen(symbol) == 0) + { + symbol = _Symbol; + } + + // + double tickSize = 0; + result = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE, tickSize); + + // + int digits = GetDigits(symbol); + result = NormalizeDouble(MathRound(price / tickSize) * tickSize, digits); + + // + return result; +} + +// +// Check Expert Running in Testing Mode or not ... +bool IsRunningOnTestMode() +{ + // + bool result = false; + + // + // check programm mode ... + result = MQL5InfoInteger(MQL5_TESTING); + + // + return result; +} + +// +// Calculate Volume Weighted Moving Average ... +double iVWMA( + double price, + double volume, + int period, + int i, + int bars, + int instance = 0 // +) +{ +#define ¤ instance +#ifdef _averageInstances +#define _functionInstances _averageInstances +#else #define _functionInstances 1 +#endif + struct sVwmaArrayStruct + { + double price; + double volume; + double sump; + double sumv; + }; + static sVwmaArrayStruct m_array[][_functionInstances]; + static int m_arraySize = 0; + if (m_arraySize < bars) + { + int _res = ArrayResize(m_array, bars + 500); + if (_res <= bars) + return (0); + m_arraySize = _res; + } + + // + //--- + // + + if (volume == 0) + volume = 1; + m_array[i][¤].price = volume * price; + m_array[i][¤].volume = volume; + if (i > period) + { + m_array[i][¤].sump = m_array[i - 1][¤].sump + m_array[i][¤].price - m_array[i - period][¤].price; + m_array[i][¤].sumv = m_array[i - 1][¤].sumv + volume - m_array[i - period][¤].volume; + } + else + { + m_array[i][¤].sump = m_array[i][¤].price; + m_array[i][¤].sumv = m_array[i][¤].volume; + for (int k = 1; k < period && i >= k; k++) + { + m_array[i][¤].sump += m_array[i - k][¤].price; + m_array[i][¤].sumv += m_array[i - k][¤].volume; + } + } + return (m_array[i][¤].sump / m_array[i][¤].sumv); + + // + //--- + // + +#undef ¤ #undef _functionInstances +} + +// +// Date Time Manipulation Functions ... +// + +// +// Representation of Time Struct ... +// struct MqlDateTime +// { +// int year; // Year +// int mon; // Month +// int day; // Day +// int hour; // Hour +// int min; // Minutes +// int sec; // Seconds +// int day_of_week; // Day of week (0-Sunday, 1-Monday, ... ,6-Saturday) +// int day_of_year; // Day number of the year (January 1st is assigned the number value of zero) +// }; + +// +// Converts Time to Seconds ... +ulong TimeToSeconds( + datetime time // Specify time to Convert ... +) +{ + // + ulong result = (ulong)time; + + // + return result; +} +ulong TimeToSeconds( + MqlDateTime &time // Specify time to Convert ... +) +{ + // + datetime dTime = StructToTime(time); + + // + ulong result = TimeToSeconds(dTime); + + // + return result; +} + +// +// Converts Seconds To Time ... +datetime SecondsToTime( + ulong seconds // Specify Seconds to Convert ... +) +{ + // + datetime result = (datetime)seconds; + + // + return result; +} +MqlDateTime SecondsToStruct( + ulong seconds // Specify Seconds to Convert ... +) +{ + // + datetime dTime = SecondsToTime(seconds); + + // + MqlDateTime result = {}; + TimeToStruct( + dTime, + result); + + // + return result; +} + +// +// Converts Time to MilliSeconds ... +ulong TimeToMilliSeconds( + datetime time // Specify time to Convert ... +) +{ + // + ulong result = TimeToSeconds(time) * 1000; + + // + return result; +} +ulong TimeToMilliSeconds( + MqlDateTime &time // Specify time to Convert ... +) +{ + // + datetime dTime = StructToTime(time); + + // + ulong result = TimeToMilliSeconds(dTime); + + // + return result; +} + +// +// Converts MillisSeconds to Time ... +datetime MilliSecondsToTiem( + ulong milliSeconds // Specify MilliSeconds to Convert ... +) +{ + // + ulong seconds = milliSeconds / 1000; + + // + datetime result = SecondsToTime(seconds); + + // + return result; +} +MqlDateTime MilliSecondsToStruct( + ulong milliSeconds // Specify MilliSeconds to Convert ... +) +{ + // + datetime dTime = MilliSecondsToTiem(milliSeconds); + + // + MqlDateTime result = {}; + TimeToStruct( + dTime, + result); + + // + return result; +} + +// +// Retrieve DateTime Structure ... +MqlDateTime GetCurrentTime() +{ + // + MqlDateTime result = {}; + + // + TimeCurrent(result); + + // + return result; +} + +// +// Retrieve Current Time as Seconds ... +ulong GetCurrentTimeAsSeconds() +{ + // + datetime time = TimeCurrent(); + + // + ulong result = TimeToSeconds(time); + + // + return result; +} + +// +// Retrieve Current Time as MilliSeconds ... +ulong GetCurrentTimeAsMilliSeconds() +{ + // + datetime time = TimeCurrent(); + + // + ulong result = TimeToMilliSeconds(time); + + // + return result; +} + +// +// Retrieve Specified Candle Time ... +datetime GetCandleTime( + string symbol = "", // Specify Symbol + ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame + int bar_index = 0 // Specify Bar Index +) +{ + // + // Validate and Normalize Args ... + + // + // Normalize Symbol ... + symbol = StringLen(symbol) == 0 + ? _Symbol + : symbol; + + // + // Normalize Period ... + period = period == NULL + ? _Period + : period; + + // + // Retrieve Bar Time ... + datetime result = iTime( + symbol, + period, + bar_index); + + // + return result; +} + +// +// Retrieve Specified Candle Time ... +ulong GetCandleTimeAsSeconds( + string symbol = "", // Specify Symbol + ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame + int bar_index = 0 // Specify Bar Index +) +{ + // + // Retrieve Bar Time ... + datetime time = GetCandleTime( + symbol, + period, + bar_index); + + // + ulong result = TimeToSeconds(time); + + // + return result; +} + +// +// Retrieve Specified Candle Time ... +ulong GetCandleTimeAsMilliSeconds( + string symbol = "", // Specify Symbol + ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame + int bar_index = 0 // Specify Bar Index +) +{ + // + // Retrieve Bar Time ... + datetime time = GetCandleTime( + symbol, + period, + bar_index); + + // + ulong result = TimeToMilliSeconds(time); + + // + return result; +} + +// +// Retrieve a Candle Time Structure ... +MqlDateTime GetCandleTimeStruct( + string symbol = "", // Specify Symbol + ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame + int bar_index = 0 // Specify Bar Index +) +{ + // + MqlDateTime result = {}; + + // + // Retrieve Bar Time ... + datetime barTime = GetCandleTime( + symbol, + period, + bar_index); + + // + // Convert to Structure ... + TimeToStruct(barTime, result); + + // + return result; +} + +// +// Retrieve Number of Candles in a Day ... +int GetDailyCandleCount(ENUM_TIMEFRAMES mPeriod) +{ + // + int seconds = PeriodSeconds(mPeriod); + + // + int daySeconds = 24 * 60 * 60; + + // + int result = daySeconds / seconds; + + // + return result; +} + +int GetDailyCandleCount() +{ + // + int result = GetDailyCandleCount(_Period); + + // + return result; +} + +// +// +// + +// +// Holds Month ... +static int xMonth = -1; + +// +// Holds Day Of Week ... +static int xDayOfWeek = -1; +static int xForWeekDay = -1; + +// +// Holds Day ... +static int xDay = -1; + +// +// Holds Hour ... +static int xHour = -1; + +// +// Reset Timing Variables ... +void ResetTiming() +{ + // + xHour = -1; + xDay = -1; + xDayOfWeek = -1; + xMonth = -1; +} + +// +// Detecting New Houre ... +bool IsNewHour() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Houre ... + result = timeStruct.hour != xHour; + if (result) + { + xHour = timeStruct.hour; + } + + // + return result; +} + +// +// Detecting New Day ... +bool IsNewDay() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Houre ... + result = timeStruct.day_of_year != xDay; + if (result) + { + xDay = timeStruct.day_of_year; + } + + // + return result; +} + +// +// Detecting New Week ... +bool IsNewWeek() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Week ... + // Since Week Starts From Monday in Forex World ... + // we Calculate Start of Week by 1-Monday ... + result = + xDayOfWeek == -1 && + xForWeekDay == -1 + ? true + : timeStruct.day_of_week == 1 && + timeStruct.day_of_year > xForWeekDay; + + // + xForWeekDay = timeStruct.day_of_year; + xDayOfWeek = timeStruct.day_of_week; + + // + return result; +} + +// +// Detecting End Of Week ... +bool IsWeekEnd() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check WeekEnd ... + // Since Week Starts From Monday in Forex World ... + // we Calculate End of Week by 5-Friday ... + result = + xDayOfWeek != -1 && + timeStruct.day_of_week == 5 && + timeStruct.hour == 23 && + timeStruct.min == 59 && + timeStruct.sec == 59; + + // + return result; +} + +// +// Detecting New Month ... +bool IsNewMonth() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Houre ... + result = timeStruct.mon != xMonth; + if (result) + { + xMonth = timeStruct.mon; + } + + // + return result; +} + +// +// Find Hindmost Time Frame ... +ENUM_TIMEFRAMES GetHindmostTimeFrame( + ENUM_TIMEFRAMES mPeriod // Specified Period +) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + // Normalize Period ... + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + switch (mPeriod) + { + // + case PERIOD_M1: + case PERIOD_M2: + case PERIOD_M3: + case PERIOD_M4: + result = PERIOD_H4; + break; + + // + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + result = PERIOD_H8; + break; + + // + case PERIOD_M15: + case PERIOD_M20: + result = PERIOD_H12; + break; + + // + case PERIOD_M30: + result = PERIOD_D1; + break; + + // + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + result = PERIOD_W1; + break; + + // + case PERIOD_H4: + case PERIOD_H6: + case PERIOD_H8: + result = PERIOD_MN1; + break; + + // + case PERIOD_H12: + result = PERIOD_MN1; + break; + + // + case PERIOD_D1: + result = PERIOD_MN1; + break; + + // + case PERIOD_W1: + result = PERIOD_MN1; + break; + + // + default: + result = PERIOD_MN1; + break; + } + + // + return result; +} + +// +// Find Farest Time Frame ... +ENUM_TIMEFRAMES GetFarestTimeFrame( + ENUM_TIMEFRAMES mPeriod // Specified Period +) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + // Normalize Period ... + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + switch (mPeriod) + { + // + case PERIOD_M1: + case PERIOD_M2: + case PERIOD_M3: + case PERIOD_M4: + result = PERIOD_H1; + break; + + // + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + result = PERIOD_H2; + break; + + // + case PERIOD_M15: + case PERIOD_M20: + result = PERIOD_H3; + break; + + // + case PERIOD_M30: + result = PERIOD_H4; + break; + + // + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + result = PERIOD_H8; + break; + + // + case PERIOD_H4: + case PERIOD_H6: + case PERIOD_H8: + result = PERIOD_D1; + break; + + // + case PERIOD_H12: + result = PERIOD_MN1; + break; + + // + case PERIOD_D1: + result = PERIOD_MN1; + break; + + // + case PERIOD_W1: + result = PERIOD_MN1; + break; + + // + default: + result = PERIOD_MN1; + break; + } + + // + return result; +} + +// +// Find Medium Time Frame ... +ENUM_TIMEFRAMES GetMediestTimeFrame( + ENUM_TIMEFRAMES mPeriod // Specified Period +) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + // Normalize Period ... + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + switch (mPeriod) + { + // + case PERIOD_M1: + case PERIOD_M2: + case PERIOD_M3: + case PERIOD_M4: + result = PERIOD_M12; + break; + + // + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + result = PERIOD_M30; + break; + + // + case PERIOD_M15: + case PERIOD_M20: + result = PERIOD_H1; + break; + + // + case PERIOD_M30: + result = PERIOD_H2; + break; + + // + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + result = PERIOD_H6; + break; + + // + case PERIOD_H4: + case PERIOD_H6: + case PERIOD_H8: + result = PERIOD_H12; + break; + + // + case PERIOD_H12: + result = PERIOD_W1; + break; + + // + case PERIOD_D1: + result = PERIOD_MN1; + break; + + // + case PERIOD_W1: + result = PERIOD_MN1; + break; + + // + default: + result = PERIOD_MN1; + break; + } + + // + return result; +} + +// +// Find Nearest Time Frame ... +ENUM_TIMEFRAMES GetNearestTimeFrame( + ENUM_TIMEFRAMES mPeriod // Specified Period +) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + // Normalize Period ... + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + switch (mPeriod) + { + // + case PERIOD_M1: + case PERIOD_M2: + case PERIOD_M3: + case PERIOD_M4: + result = PERIOD_M5; + break; + + // + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + result = PERIOD_M15; + break; + + // + case PERIOD_M15: + case PERIOD_M20: + result = PERIOD_M30; + break; + + // + case PERIOD_M30: + result = PERIOD_H1; + break; + + // + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + result = PERIOD_H4; + break; + + // + case PERIOD_H4: + case PERIOD_H6: + case PERIOD_H8: + result = PERIOD_H12; + break; + + // + case PERIOD_H12: + result = PERIOD_D1; + break; + + // + case PERIOD_D1: + result = PERIOD_W1; + break; + + // + case PERIOD_W1: + result = PERIOD_MN1; + break; + + // + default: + result = PERIOD_MN1; + break; + } + + // + return result; +} + +// +// Get Specific Time Frame Start Candle Time ... +datetime GetPeriodStartTime( + string mSymbol = NULL, // Specified Symbol ... + ENUM_TIMEFRAMES mPeriod = NULL, // Specified Period ... + datetime mTime = NULL // Specified Bar Time ... +) +{ + // + // Normalize Arg ... + + // + if ( + mSymbol == NULL || + StringLen(mSymbol) == 0) + { + mSymbol = _Symbol; + } + + // + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + if ( + mTime < 0 || + mTime == NULL) + { + mTime = TimeCurrent(); + } + + // + int barIndex = iBarShift( + mSymbol, + mPeriod, + mTime, + false); + + // + datetime result = iTime( + mSymbol, + mPeriod, + barIndex); + + // + return result; +} + +// +struct XCandleRemains +{ + // + int days; + int hours; + int minutes; + int seconds; +}; + +// +string ToString( + XCandleRemains &item, + string dayId = "d", + string hourId = "h", + string minuteId = "m", + string secondId = "s", + string idSeparator = ": ", + string separator = ", ", + bool ignoreZeroValues = true) +{ + // + string result = ""; + + // + // Days ... + if (!ignoreZeroValues || item.days > 0) + { + result += dayId + idSeparator + (string)item.days + separator; + } + + // + // Hours ... + if (!ignoreZeroValues || item.hours > 0) + { + // + string strHour = ToString(item.hours); + if (StringLen(strHour) == 1) + { + strHour = "0" + strHour; + } + + // + result += hourId + idSeparator + strHour + separator; + } + + // + // Minutes ... + if (!ignoreZeroValues || item.minutes > 0) + { + // + string strMinute = ToString(item.minutes); + if (StringLen(strMinute) == 1) + { + strMinute = "0" + strMinute; + } + + // + result += minuteId + idSeparator + strMinute + separator; + } + + // + // Seconds ... + if (!ignoreZeroValues || item.seconds > 0) + { + // + string strSec = ToString(item.seconds); + if (StringLen(strSec) == 1) + { + strSec = "0" + strSec; + } + + // + result += secondId + idSeparator + strSec; + } + + // + return result; +} + +// +// Retrieve Specific Candles Ramained Time ... +void GetCandleRemainsTime( + XCandleRemains &result, // Holds Result ... + string mSymbol = NULL, // Specified Symbol ... + ENUM_TIMEFRAMES mPeriod = NULL, // Specified Period ... + int mBarIndex = 0 // Specified Bar Index ... +) +{ + // + int minuteSecoonds = 60; + int hourSeconds = minuteSecoonds * 60; + int daySeconds = 24 * hourSeconds; + + // + int periodSeconds = PeriodSeconds( + mPeriod); + datetime startTime = GetCandleTime( + mSymbol, + mPeriod, + mBarIndex); + + // + int secondsDiff = (int)startTime + periodSeconds - (int)TimeCurrent(); + + // + int days = 0; + int hours = 0; + int minutes = 0; + int seconds = 0; + + // + int mWorkingSecondsDiff = secondsDiff; + if (mWorkingSecondsDiff > daySeconds) + { + // + days = mWorkingSecondsDiff / daySeconds; + mWorkingSecondsDiff -= days * daySeconds; + } + if (mWorkingSecondsDiff > hourSeconds) + { + // + hours = mWorkingSecondsDiff / hourSeconds; + mWorkingSecondsDiff -= hours * hourSeconds; + } + if (mWorkingSecondsDiff > minuteSecoonds) + { + // + minutes = mWorkingSecondsDiff / minuteSecoonds; + mWorkingSecondsDiff -= minutes * minuteSecoonds; + } + seconds = mWorkingSecondsDiff; + + // + result.days = days; + result.hours = hours; + result.minutes = minutes; + result.seconds = seconds; +} + +// +// Converts an String to TimeFrame ... +ENUM_TIMEFRAMES ToPeriod(string value) +{ + // + if (StringLen(value) == 0) + { + return _Period; + } + + // + StringTrimLeft(value); + StringTrimRight(value); + + // + ENUM_TIMEFRAMES result = _Period; + + // + if (value == "M1") + { + result = PERIOD_M1; + } + else if (value == "M2") + { + result = PERIOD_M2; + } + else if (value == "M3") + { + result = PERIOD_M3; + } + else if (value == "M4") + { + result = PERIOD_M4; + } + else if (value == "M5") + { + result = PERIOD_M5; + } + else if (value == "M6") + { + result = PERIOD_M6; + } + else if (value == "M10") + { + result = PERIOD_M10; + } + else if (value == "M12") + { + result = PERIOD_M12; + } + else if (value == "M15") + { + result = PERIOD_M15; + } + else if (value == "M20") + { + result = PERIOD_M20; + } + else if (value == "M30") + { + result = PERIOD_M30; + } + else if (value == "H1") + { + result = PERIOD_H1; + } + else if (value == "H2") + { + result = PERIOD_H2; + } + else if (value == "H3") + { + result = PERIOD_H3; + } + else if (value == "H4") + { + result = PERIOD_H4; + } + else if (value == "H6") + { + result = PERIOD_H6; + } + else if (value == "H8") + { + result = PERIOD_H8; + } + else if (value == "H12") + { + result = PERIOD_H12; + } + else if (value == "D1") + { + result = PERIOD_D1; + } + else if (value == "W1") + { + result = PERIOD_W1; + } + else if (value == "MN1") + { + result = PERIOD_MN1; + } + + // + return result; +} + +// +// Converts Period to String ... +string ToString(ENUM_TIMEFRAMES period) +{ + // + string result = ""; + + // + string mPStr = EnumToString(period); + + string mPStrParts[]; + int partsCount = StringSplit( + mPStr, + StringGetCharacter("_", 0), + mPStrParts); + if (partsCount <= 0) + { + return result; + } + + // + result = mPStrParts[1]; + + // + return result; +} + +// +// Converts an String to it's related Market Cycle ... +ENUM_X_MARKET_CYCLES ToCycle(string value) +{ + // + ENUM_X_MARKET_CYCLES result = X_MARKET_CYCLE_UNKNOWN; + + // + ENUM_X_MARKET_CYCLES cycles[]; + int count = GetAllMarketCycles(cycles); + for (int i = 0; i < count; i++) + { + // + ENUM_X_MARKET_CYCLES iCycle = cycles[i]; + string iStr = ToString(iCycle); + + // + if (value == iStr) + { + // + result = iCycle; + break; + } + } + + // + return result; +} + +// +// Converts a Cycle to it's String Representation ... +string ToString(ENUM_X_MARKET_CYCLES cycle) +{ + // + string result = ""; + + // + string mPStr = EnumToString(cycle); + + string mPStrParts[]; + int partsCount = StringSplit( + mPStr, + StringGetCharacter("_", 0), + mPStrParts); + if (partsCount <= 0) + { + return result; + } + + // + result = mPStrParts[3]; + + // + return result; +} + +// +// Retrieve all Available Cycles ... +int GetAllMarketCycles(ENUM_X_MARKET_CYCLES &result[]) +{ + // + int mResult = 0; + + // + Clean(result); + + // + ENUM_X_MARKET_CYCLES tmp[] = { + X_MARKET_CYCLE_UNKNOWN, + X_MARKET_CYCLE_SHORT, + X_MARKET_CYCLE_MEDIUM, + X_MARKET_CYCLE_LONG, + X_MARKET_CYCLE_HIND}; + + // + Copy( + tmp, + result); + + // + Clean(tmp); + + // + mResult = ArraySize(result); + + // + return mResult; +} + +// +// CYCLES ... +struct XMarketCycle +{ + // + string prefix; // Prefix Trag ... + + // + string symbol; // Market Symbol ... + + // + ENUM_TIMEFRAMES period; // Period of Cycle ... + ENUM_X_PERIOD_METHOD method; // Period Selection Method ... + ENUM_X_MARKET_CYCLES cycle; // Cycles of MArket ... + + // + int seconds; // Number of Seconds ... + XOHCL bar; // Current Candle of Cycle ... + XCandleRemains remains; // Remains Data of current Candle ... + datetime start; // Start Date of Current Candle ... + datetime next; // Next Candle Start Date ... + + // + int length; // Number Of Candles per Current Time Frame ... + ENUM_TIMEFRAMES hostPeriod; // Current Time Frame ... + + // + datetime lastStart; // Last Candle Bar Time ... + + // + // Constructor ... + XMarketCycle() + { + // + prefix = ""; + symbol = NULL; + period = NULL; + method = NULL; + + // + seconds = 0; + start = 0; + next = 0; + + // + length = 0; + hostPeriod = NULL; + + // + lastStart = 0; + } + + // + // Check Structure Valid ... + bool IsValid() + { + // + bool result = false; + + // + result = IsValidCycle( + method, + period); + if (!result) + { + return result; + } + + // + result = + // + symbol != NULL && + period != NULL && + hostPeriod != NULL && + method != NULL && method != X_PERIOD_NOTHING && + seconds > 0 && + length > 0 + // + ; + + // + return result; + } + + // + // Init Cycle ... + bool Init( + string mSymbol, // Trading Symbol + ENUM_TIMEFRAMES mHostPeriod, // Host Period + ENUM_X_MARKET_CYCLES mCycle, // Init Cycle + int mHostBarIndex = 0, // Specified Host Period Bar Index + string mPrefix = "" // Prefix + ) + { + // + bool result = false; + + // + result = mCycle != NULL && mCycle != X_MARKET_CYCLE_UNKNOWN; + if (!result) + { + return result; + } + + // + this.cycle = mCycle; + + // + // Set Automatically Prefix ... + if (StringLen(mPrefix) == 0) + { + this.prefix = ToString(cycle); + } + + // + result = IsValidCycle( + method, + period // + ); + if (!result) + { + return result; + } + + // + this.symbol = mSymbol; + this.hostPeriod = mHostPeriod; + + // + // Find Cycle Period ... + if (method == X_PERIOD_AUTO) + { + // + // Select Period ... + switch (cycle) + { + // + case X_MARKET_CYCLE_SHORT: + // + this.period = GetNearestTimeFrame(mHostPeriod); + break; + + // + case X_MARKET_CYCLE_MEDIUM: + this.period = GetMediestTimeFrame(mHostPeriod); + break; + + // + case X_MARKET_CYCLE_LONG: + this.period = GetFarestTimeFrame(mHostPeriod); + break; + + // + case X_MARKET_CYCLE_HIND: + this.period = GetHindmostTimeFrame(mHostPeriod); + break; + } + } + + // + // Set Prefix if Provided ... + if (StringLen(mPrefix) > 0) + { + this.prefix = mPrefix; + } + + // + // Calculate Required Info ... + + // + // Seconds ... + this.seconds = PeriodSeconds(this.period); + + // + // Length ... + int hostPeriodSeconds = PeriodSeconds(this.hostPeriod); + this.length = this.seconds / hostPeriodSeconds; + + // + // Update Additional Data ... + result = this.Update(mHostBarIndex); + + // + return result; + } + + // + // Update Market Cycle Additional Info ... + bool Update(int hostBarIndex) + { + // + bool result = false; + + // + result = this.IsValid(); + if (!result) + { + return result; + } + + // + int barIndex = GetBarIndex(hostBarIndex); + + // + // Retrieve Current Candle ... + this.bar = GetCandle( + this.symbol, + this.period, + barIndex // + ); + + // + if (this.start != 0 && this.start != NULL) + { + this.lastStart = this.start; + } + + // + this.start = GetCandleTime( + this.symbol, + this.period, + barIndex // + ); + + // + if (this.lastStart == 0 || this.lastStart == NULL) + { + this.lastStart = this.start; + } + + // + this.next = this.start + this.seconds; + + // + // Retrieve Candle Remains ... + GetCandleRemainsTime( + this.remains, + this.symbol, + this.period, + barIndex // + ); + + // + return result; + } + + // + // Create and String Representation for Unique Taging ... + string ToString() + { + // + string result = ""; + + // + if (!this.IsValid()) + { + return result; + } + + // + result = + "XMarketCycle[" + + "PRFX(" + this.prefix + ")" + + "SMBL(" + this.symbol + ")" + + "CYC(" + ToString(this.cycle) + ")" + + "PRD(" + ToString(this.period) + ")" + + "PRDHST(" + ToString(this.hostPeriod) + ")" + + "MTH(" + EnumToString(this.method) + ")" + + "]"; + + // + return result; + } + + // + // Here we Produce a Summary brief of + // state of Cycle ... + string GenerateSummary() + { + // + string result = ""; + + // + bool hasPrefix = StringLen(this.prefix) > 0 && this.prefix != ToString(this.cycle); + result += (hasPrefix ? this.prefix + "[" : "") + + ToString(this.cycle) + + (hasPrefix ? "]" : "") + "\n"; + + // + result += " - PR: " + ToString(this.period) + "\n"; + + // + result += " - State: " + (this.IsBullish() ? "Bullish" : this.IsBearish() ? "Bearish" + : "Neutural"); + + // + return result; + } + + // + // TOOLS ... + + // + bool IsBullish() + { + return this.bar.open < this.bar.close; + } + + // + bool IsBearish() + { + return this.bar.open > this.bar.close; + } + + // + int Bars() + { + // + return iBars( + this.symbol, + this.period // + ); + } + + // + bool IsNewBar() + { + return this.lastStart < this.start; + } + + // + // Retrieve Current Bar Index based on Host Period bar Index ... + int GetBarIndex(int barIndex) + { + // + if (barIndex < 0) + { + return 0; + } + + // + int totalBars = this.Bars(); + if (barIndex >= totalBars) + { + return totalBars - 1; + } + + // + datetime hostBarTime = iTime( + this.symbol, + this.hostPeriod, + barIndex); + + // + int result = iBarShift( + this.symbol, + this.period, + hostBarTime); + + // + return result; + } + + // + // Retrieve Current Cycles Specific Bar ... + XOHCL GetBar(int barIndex) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + int totalBars = Bars(); + if (barIndex >= totalBars) + { + barIndex = totalBars - 1; + } + + // + XOHCL result = GetCandle( + this.symbol, + this.period, + barIndex + // + ); + + // + return result; + } + + // + // Retrieve Bar Time ... + datetime GetBarTime(int barIndex) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + int totalBars = Bars(); + if (barIndex >= totalBars) + { + barIndex = totalBars - 1; + } + + // + datetime result = GetCandleTime( + this.symbol, + this.period, + barIndex // + ); + + // + return result; + } + + // + // TODO: Add Shadow related and other tools here ... +}; + +// +// Validate Specific Period Mode ... +bool IsValidCycle( + ENUM_X_PERIOD_METHOD mMethod, // Period Select MEthod + ENUM_TIMEFRAMES mPeriod // Period +) +{ + // + bool result = false; + + // + result = + // + mMethod == X_PERIOD_NOTHING + ? false + : mMethod == X_PERIOD_MANUALLY + ? mPeriod != NULL + : mMethod == X_PERIOD_AUTO + ? true + : false + // + ; + + // + return result; +} + +// +// TYPES ... +// + +// +// Retrieve Specific Object Types Name ... +template +string GetTypeName(const T &t) +{ + return typename(T); +} + +// +// TAGGING ... +template +string GenerateTag( + T &model) +{ + // + string result = ""; + + // + string tag = model.ToString(); + if (StringLen(tag) == 0) + { + return result; + } + + // + static XSCMD5 md5; + + // + result = md5.Hash(tag); + + // + return result; +} + +// +// Hash Specified Content ... +template +string ToMD5(T content) +{ + // + string result = ""; + + // + string strContent = ToString(content); + if (StringLen(strContent) == 0) + { + return result; + } + + // + static XSCMD5 md5; + + // + result = md5.Hash(strContent); + + // + return result; +} + +// +// SIGNAL ... + +// +// Do All Normalization on Specific Signal ... +void NormalizeSignal(XSignal &signal) +{ + // + // ENTRY ... + if (signal.entry > 0) + { + signal.entry = NormalizePrice(signal.entry, signal.symbol); + } + + // + // TP ... + if (signal.tp > 0) + { + signal.tp = NormalizePrice(signal.tp, signal.symbol); + } + + // + // SL ... + if (signal.sl > 0) + { + signal.sl = NormalizePrice(signal.sl, signal.symbol); + } + + // + // VOLUME ... + if (signal.volume > 0) + { + signal.volume = NormalizeVolume(signal.volume, signal.symbol); + } +} + +// +// Prepare Base Signal ... +XSignal CreateSignal( + string symbol, // Trading Symbol ... + ENUM_TIMEFRAMES period, // Trading Time Frame ... + ENUM_POSITION_TYPE type, // Position Type ... + ENUM_X_ORDER_MODES mode, // Order Execution Mode ...Ù‘ + double entry, // Signal Entry Execution ... + double volume, // Volume ... + double tp = 0, // TP ... + double sl = 0 // SL ... +) +{ + // + XSignal result; + Clean(result); + + // + result.tp = tp; + result.sl = sl; + result.type = type; + result.mode = mode; + result.entry = entry; + result.period = period; + result.symbol = symbol; + result.volume = volume; + + // + NormalizeSignal(result); + + // + return result; +} + +// +// Find Changes ... +bool HandleValueChanged( + XValueChanged &holder[], // Change Holder Buffer ... + const double &state[], // Data State Buffer ... + const double &source[], // Data Source Buffer ... + datetime time = 0, // Checking Time ... + int resizeHolder = 100 // Resize Holder if had More than it ... +) +{ + // + bool result = false; + + // + if (time <= 0) + { + time = TimeCurrent(); + } + + // + if (ArraySize(source) <= 1) + { + return result; + } + + // + double from = source[1]; + double to = source[0]; + + // + result = + to != from && to != EMPTY_VALUE && + state[0] != state[1] && state[0] != EMPTY_VALUE; + if (result) + { + return result; + } + + // + XValueChanged lastChange; + bool hasLastChange = + GetLastItem( + lastChange, + holder); + result = + !hasLastChange + ? true + : lastChange.at < time && + lastChange.to != to && + lastChange.from != from; + if (!result) + { + return result; + } + + // + // Handle Resizing ... + if (resizeHolder > 0) + { + // + int holderCount = ArraySize(holder); + if (holderCount >= resizeHolder) + { + // + Clean(holder); + + // + Add( + lastChange, + holder); + } + } + + // + // Create a Model for add ... + lastChange.to = to; + lastChange.at = time; + lastChange.from = from; + + // + Add( + lastChange, + holder); + + // + return result; +} + +// +// END Provided Functions ... +// diff --git a/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.draw.lib.ex5 b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.draw.lib.ex5 new file mode 100644 index 0000000..98df0ed Binary files /dev/null and b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.draw.lib.ex5 differ diff --git a/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.draw.lib.mq5 b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.draw.lib.mq5 new file mode 100644 index 0000000..b714aba --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.draw.lib.mq5 @@ -0,0 +1,3608 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Draw Library +// -------------------------------------- +// Name: XDraw +// Description: provides Draw abilities ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Inputs ... +// +// +// END Inputs ... +// + +// +// Include Logger Library ... +#include "x-saherelm.log.lib.mq5" +#include "x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xmd5.class.mq5" + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +string drawPrefix = "X-OBJ"; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// + +// +// DeInitial Library if required ... +void OnDeinitDrawLibrary() +{ + RemoveDraws(); +} + +// +// remove drawn objects ... +void RemoveDraws( + string tag = NULL, + long chartId = -1, + int subWindow = -1) +{ + // + // Normalize Args ... + // + if (tag == NULL) + { + tag = drawPrefix; + } + + // + if (chartId == -1) + { + chartId = 0; + } + + // + if (subWindow == -1) + { + subWindow = 0; + } + + // + for (int iObj = ObjectsTotal(chartId, subWindow) - 1; iObj >= 0; iObj--) + { + // + string on = ObjectName(chartId, iObj, subWindow); + if (StringFind(on, tag) >= 0) + { + ObjectDelete(chartId, on); + } + } + + // + // Redraw Chart ... + ChartRedraw(); +} + +// +bool RemoveDraw( + string name, + long chartId = -1, + int subWindow = -1) +{ + // + bool result = false; + + // + if (chartId == -1) + { + chartId = 0; + } + + // + if (subWindow == -1) + { + subWindow = 0; + } + + // + string objName = ""; + for (int iObj = ObjectsTotal(chartId, subWindow) - 1; iObj >= 0; iObj--) + { + // + string on = ObjectName(chartId, iObj, subWindow); + if (StringFind(on, name) >= 0) + { + // + objName = on; + break; + } + } + + // + if (StringLen(objName) > 0) + { + result = ObjectDelete(chartId, objName); + } + + // + return result; +} + +// +// Deselect All Draws ... +void DeselectAllDraws() +{ + // + int objs = ObjectsTotal(ChartID(), 0); + for (int o = 0; o < objs; o++) + { + ObjectSetInteger(ChartID(), ObjectName(ChartID(), o, 0), OBJPROP_SELECTED, false); + } + + // + ChartRedraw(); +} + +// +// Check Object Exists ... +bool IsDrawExists( + string name, + long chartId = -1, + int subWindow = -1) +{ + // + bool result = false; + + // + if (chartId == -1) + { + chartId = 0; + } + + // + if (subWindow == -1) + { + subWindow = 0; + } + + // + for (int iObj = ObjectsTotal(chartId, subWindow) - 1; iObj >= 0; iObj--) + { + // + string on = ObjectName(chartId, iObj, subWindow); + result = StringFind(on, name) >= 0; + if (result) + { + break; + } + } + + // + return result; +} + +// +// END Provided Functions ... +// + +// +// START Regular Draws ... +// + +// +// START Arrow Functions ... +// + +// +// Draw an Arrow Object on Chart ... +bool DrawArrow( + const long chartID = 0, // chart's ID + const string name = "Arrow", // arrow name + const int subWindow = 0, // subwindow index + datetime time = 0, // anchor point time + double price = 0, // anchor point price + const uchar arrowCode = 252, // arrow code + const ENUM_ARROW_ANCHOR anchor = ANCHOR_BOTTOM, // anchor point position + const color clr = clrAqua, // arrow color + const ENUM_LINE_STYLE style = STYLE_SOLID, // border line style + const int width = 3, // arrow size + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // Order Object ... +) +{ + // + // set anchor point coordinates if they are not set ... + ChangeArrowEmptyPoint(time, price); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create an arrow ... + if (!ObjectCreate(chartID, objName, OBJ_ARROW, subWindow, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to create an arrow! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set the arrow code ... + ObjectSetInteger(chartID, objName, OBJPROP_ARROWCODE, arrowCode); + + // + // set anchor type ... + ObjectSetInteger(chartID, objName, OBJPROP_ANCHOR, anchor); + + // + // set the arrow color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set the border line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set the arrow's size ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving the arrow by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is false by default, if you want making it possible to highlight and move the object + // change it to true ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return true; +} + +// +// Move the anchor point of Arrow ... +bool MoveArrow( + const long chartID = 0, // chart's ID + const string name = "Arrow", // object name + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + // if point position is not set, move it to the current bar having Bid price ... + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // reset the error value + ResetLastError(); + + // + // move the anchor point ... + if (!ObjectMove(chartID, name, 0, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the anchor point! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Delete an arrow ... +bool DeleteArrow( + const long chartID = 0, // chart's ID + const string name = "Arrow" // arrow name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete an arrow ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete an arrow! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Change the arrow code ... +bool ArrowCodeChange( + const long chartID = 0, // chart's ID + const string name = "Arrow", // object name + const uchar code = 252 // arrow code +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change the arrow code ... + if (!ObjectSetInteger(chartID, name, OBJPROP_ARROWCODE, code)) + { + // + string message = + __FUNCTION__ + + ": failed to change the arrow code! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Change anchor type ... +bool ArrowAnchorChange( + const long chartID = 0, // chart's ID + const string name = "Arrow", // object name + const ENUM_ARROW_ANCHOR anchor = ANCHOR_TOP // anchor type +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change anchor type ... + if (!ObjectSetInteger(chartID, name, OBJPROP_ANCHOR, anchor)) + { + // + string message = + __FUNCTION__ + + ": failed to change anchor type! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Check anchor point values and set default values +// for empty ones ... +void ChangeArrowEmptyPoint( + datetime &time, + double &price) +{ + // + // if the point's time is not set, it will be on the current bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // if the point's price is not set, it will have Bid value ... + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } +} + +// +// END Arrow Functions ... +// + +// +// START Horizontal Line Functions ... +// + +// +// Create, Draw the horizontal line ... +bool DrawHorizontalLine( + const long chartID = 0, // chart's ID + const string name = "HLine", // line name + const int subWindow = 0, // subwindow index + double price = 0, // line price + const color clr = clrRed, // line color + const ENUM_LINE_STYLE style = STYLE_SOLID, // line style + const int width = 1, // line width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // if the price is not set, set it at the current Bid price level ... + if (!price) + { + price = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create a horizontal line ... + if (!ObjectCreate(chartID, objName, OBJ_HLINE, subWindow, 0, price)) + { + // + string message = + __FUNCTION__ + + ": failed to create a horizontal line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set line color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line display style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving the line by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, selection); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return true; +} + +// +// Move horizontal line ... +bool MoveHorizontalLine( + const long chartID = 0, // chart's ID + const string name = "HLine", // line name + double price = 0 // line price +) +{ + // + // if the line price is not set, move it to the current Bid price level ... + if (!price) + { + price = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move a horizontal line ... + if (!ObjectMove(chartID, name, 0, 0, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the horizontal line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Delete a horizontal line ... +bool DeleteHorizontalLine( + const long chartID = 0, // chart's ID + const string name = "HLine" // line name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete a horizontal line ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete a horizontal line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// END Horizontal Line Functions ... +// + +// +// START Vertical Line Functions ... +// + +// +// Create the vertical line ... +bool DrawVerticalLine( + const long chartID = 0, // chart's ID + const string name = "VLine", // line name + const int subWindow = 0, // subwindow index + datetime time = 0, // line time + const color clr = clrRed, // line color + const ENUM_LINE_STYLE style = STYLE_SOLID, // line style + const int width = 1, // line width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // if the line time is not set, draw it via the last bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // reset the error value + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create a vertical line ... + if (!ObjectCreate(chartID, objName, OBJ_VLINE, subWindow, time, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to create a vertical line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set line color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line display style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving the line by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return true; +} + +// +// Move the vertical line ... +bool MoveVerticalLine( + const long chartID = 0, // chart's ID + const string name = "VLine", // line name + datetime time = 0 // line time +) +{ + // + // if line time is not set, move the line to the last bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move the vertical line ... + if (!ObjectMove(chartID, name, 0, time, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to move the vertical line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Delete the vertical line ... +bool DeleteVerticalLine( + const long chartID = 0, // chart's ID + const string name = "VLine" // line name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete the vertical line ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete the vertical line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// END Vertical Line Functions ... +// + +// +// START Rectangle Functions ... +// + +// +// Create rectangle by the given coordinates ... +bool DrawRectangle( + const long chartID = 0, // chart's ID + const string name = "Rectangle", // rectangle name + const int subWindow = 0, // subwindow index + datetime time1 = 0, // first point time + double price1 = 0, // first point price + datetime time2 = 0, // second point time + double price2 = 0, // second point price + const color clr = clrRed, // rectangle color + const ENUM_LINE_STYLE style = STYLE_SOLID, // style of rectangle lines + const int width = 1, // width of rectangle lines + const bool fill = false, // filling rectangle with color + const bool back = false, // in the background + const bool selection = true, // highlight to move + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + bool result = false; + + // + // Set anchor points' coordinates if they are not set ... + ChangeRectangleEmptyPoints(time1, price1, time2, price2); + + // + // Create a rectangle by the given coordinates ... + result = ObjectCreate(chartID, name, OBJ_RECTANGLE, subWindow, time1, price1, time2, price2); + if (!result) + { + return result; + } + + // + // Set rectangle color ... + ObjectSetInteger(chartID, name, OBJPROP_COLOR, clr); + + // + // Set the style of rectangle lines + ObjectSetInteger(chartID, name, OBJPROP_STYLE, style); + + // + // Set width of the rectangle lines ... + ObjectSetInteger(chartID, name, OBJPROP_WIDTH, width); + + // + // Enable (true) or disable (false) the mode of filling the rectangle ... + ObjectSetInteger(chartID, name, OBJPROP_FILL, fill); + + // + // Display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, name, OBJPROP_BACK, back); + + // + // Enable (true) or disable (false) the mode of highlighting the rectangle for moving + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object + ObjectSetInteger(chartID, name, OBJPROP_SELECTABLE, selection); + + // + ObjectSetInteger(chartID, name, OBJPROP_SELECTED, selection); + + // + // Hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, name, OBJPROP_HIDDEN, hidden); + + // + // Set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, name, OBJPROP_ZORDER, zOrder); + + // + // Successful execution + return result; +} + +// +// Move the rectangle anchor point ...s +bool RectanglePointChange( + const long chartID = 0, // chart's ID + const string name = "Rectangle", // rectangle name + const int pointIndex = 0, // anchor point index + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + bool result = false; + + // + // if point position is not set, move it to the current bar having Bid price ... + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // Move the anchor point ... + result = ObjectMove(chartID, name, pointIndex, time, price); + if (!result) + { + return result; + } + + // + // Successful execution + return result; +} + +// +// Delete the rectangle ... +bool DeleteRectangle( + const long chartID = 0, // chart's ID + const string name = "Rectangle" // rectangle name +) +{ + // + bool result = false; + + // + result = ObjectDelete(chartID, name); + + // + return result; +} + +// +// Check the values of rectangle's anchor points and set default +// values for empty ones +void ChangeRectangleEmptyPoints( + datetime &time1, double &price1, + datetime &time2, double &price2) +{ + // + // if the first point's time is not set, it will be on the current bar ... + if (!time1) + { + time1 = TimeCurrent(); + } + + // + // if the first point's price is not set, it will have Bid value ... + if (!price1) + { + price1 = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // if the second point's time is not set, it is located 9 bars left from the second one ... + if (!time2) + { + // + // array for receiving the open time of the last 10 bars ... + datetime temp[10]; + CopyTime(Symbol(), Period(), time1, 10, temp); + + // + // set the second point 9 bars left from the first one ... + time2 = temp[0]; + } + + // + // if the second point's price is not set, move it 300 points lower than the first one ... + if (!price2) + { + price2 = price1 - 300 * SymbolInfoDouble(Symbol(), SYMBOL_POINT); + } +} + +// +// END Rectangle Functions ... +// + +// +// START RectangleLabel Functions ... +// + +// +// Create Rectangle Label Object ... +bool DrawRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const int subWindow = 0, // subwindow index + const int x = 0, // X coordinate + const int y = 0, // Y coordinate + const int width = 50, // width + const int height = 18, // height + const color bgColor = clrWhiteSmoke, // background color + const ENUM_BORDER_TYPE border = BORDER_SUNKEN, // border type + const ENUM_BASE_CORNER corner = CORNER_LEFT_UPPER, // chart corner for anchoring + const color clr = clrRed, // flat border color (Flat) + const ENUM_LINE_STYLE style = STYLE_SOLID, // flat border style + const int lineWidth = 1, // flat border width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // + // create a rectangle label + if (!ObjectCreate(chartID, objName, OBJ_RECTANGLE_LABEL, subWindow, 0, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to create a rectangle label! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set label coordinates ... + ObjectSetInteger(chartID, objName, OBJPROP_XDISTANCE, x); + ObjectSetInteger(chartID, objName, OBJPROP_YDISTANCE, y); + + // + // set label size ... + ObjectSetInteger(chartID, objName, OBJPROP_XSIZE, width); + ObjectSetInteger(chartID, objName, OBJPROP_YSIZE, height); + + // + // set background color ... + ObjectSetInteger(chartID, objName, OBJPROP_BGCOLOR, bgColor); + + // + // set border type ... + ObjectSetInteger(chartID, objName, OBJPROP_BORDER_TYPE, border); + + // + // set the chart's corner, relative to which point coordinates are defined ... + ObjectSetInteger(chartID, objName, OBJPROP_CORNER, corner); + + // + // set flat border color (in Flat mode) ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set flat border line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set flat border width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, lineWidth); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving the label by mouse ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, selection); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return true; +} + +// +// Move Rectangle Label .. +bool MoveRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const int x = 0, // X coordinate + const int y = 0 // Y coordinate +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // move the rectangle label ... + if (!ObjectSetInteger(chartID, name, OBJPROP_XDISTANCE, x)) + { + // + string message = + __FUNCTION__ + + ": failed to move X coordinate of the label! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + if (!ObjectSetInteger(chartID, name, OBJPROP_YDISTANCE, y)) + { + // + string message = + __FUNCTION__ + + ": failed to move Y coordinate of the label! Error code = " + + (string)GetLastError(); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Delete the rectangle label ... +bool DeleteRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel" // label name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete the label ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete a rectangle label! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Change Rectangle Label Size ... +bool ChangeSizeRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const int width = 50, // label width + const int height = 18 // label height +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change label size ... + if (!ObjectSetInteger(chartID, name, OBJPROP_XSIZE, width)) + { + // + string message = + __FUNCTION__ + + ": failed to change the label's width! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + if (!ObjectSetInteger(chartID, name, OBJPROP_YSIZE, height)) + { + // + string message = + __FUNCTION__ + + ": failed to change the label's height! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Change rectangle label border type ... +bool RectLabelChangeBorderType( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const ENUM_BORDER_TYPE border = BORDER_SUNKEN // border type +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change border type ... + if (!ObjectSetInteger(chartID, name, OBJPROP_BORDER_TYPE, border)) + { + // + string message = + __FUNCTION__ + + ": failed to change the border type! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// END RectangleLabel Functions ... +// + +// +// START TrendLine Funcions ... +// + +// +// Create a trend line by the given coordinates ... +bool DrawTrendLine( + const long chartID = 0, // chart's ID + const string name = "TrendLine", // line name + const int subWindow = 0, // subwindow index + datetime time1 = 0, // first point time + double price1 = 0, // first point price + datetime time2 = 0, // second point time + double price2 = 0, // second point price + const color clr = clrYellow, // line color + const ENUM_LINE_STYLE style = STYLE_SOLID, // line style + const int width = 1, // line width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool rayRight = false, // line's continuation to the right + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // set anchor points' coordinates if they are not set ... + ChangeTrendLineEmptyPoints( + time1, + price1, + time2, + price2); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create a trend line by the given coordinates ... + if (!ObjectCreate(chartID, objName, OBJ_TREND, subWindow, time1, price1, time2, price2)) + { + // + string message = + __FUNCTION__ + + ": failed to create a trend line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set line color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line display style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving the line by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // enable true or disable false the mode of continuation of the line's display to the right ... + ObjectSetInteger(chartID, objName, OBJPROP_RAY_RIGHT, rayRight); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return true; +} + +// +// Move trend line anchor point ... | +bool ChangeTrendLinePoint( + const long chartID = 0, // chart's ID + const string name = "TrendLine", // line name + const int pointindex = 0, // anchor point index + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + // if point position is not set, move it to the current bar having Bid price ... + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move trend line's anchor point ... + if (!ObjectMove(chartID, name, pointindex, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the anchor point! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// The function deletes the trend line from the chart ... +bool DeleteTrendLine( + const long chartID = 0, // chart's ID + const string name = "TrendLine" // line name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete a trend line ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete a trend line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Check the values of trend line's anchor points and set default ... +// values for empty ones ... +void ChangeTrendLineEmptyPoints( + datetime &time1, + double &price1, + datetime &time2, + double &price2) +{ + // + // if the first point's time is not set, it will be on the current bar ... + if (!time1) + { + time1 = TimeCurrent(); + } + + // + // if the first point's price is not set, it will have Bid value ... + if (!price1) + { + price1 = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // if the second point's time is not set, it is located 9 bars left from the second one ... + if (!time2) + { + // + // array for receiving the open time of the last 10 bars ... + datetime temp[10]; + CopyTime(Symbol(), Period(), time1, 10, temp); + + // + // set the second point 9 bars left from the first one ... + time2 = temp[0]; + } + + // + // if the second point's price is not set, it is equal to the first point's one ... + if (!price2) + { + price2 = price1; + } +} + +// +// END TrendLine Functions ... +// + +// +// START Text Functions ... +// + +// +// Create and Draw a Text Object ... +bool DrawText( + const long chartID = 0, // chart's ID + const string name = "Text", // object name + const int subWindow = 0, // subwindow index + datetime time = 0, // anchor point time + double price = 0, // anchor point price + const string text = "Text", // the text itself + const string font = "Arial", // font + const int fontSize = 10, // font size + const color clr = clrRed, // color + const double angle = 0.0, // text slope + const ENUM_ANCHOR_POINT anchor = ANCHOR_CENTER, // anchor type + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // set anchor point coordinates if they are not set ... + ChangeTextEmptyPoint(time, price); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // + // create Text object + if (!ObjectCreate(chartID, objName, OBJ_TEXT, subWindow, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to create \"Text\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set the text ... + ObjectSetString(chartID, objName, OBJPROP_TEXT, text); + + // + // set text font ... + ObjectSetString(chartID, objName, OBJPROP_FONT, font); + + // + // set font size ... + ObjectSetInteger(chartID, objName, OBJPROP_FONTSIZE, fontSize); + + // + // set the slope angle of the text ... + ObjectSetDouble(chartID, objName, OBJPROP_ANGLE, angle); + + // + // set anchor type ... + ObjectSetInteger(chartID, objName, OBJPROP_ANCHOR, anchor); + + // + // set color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving the object by mouse ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return true; +} + +// +// Move the anchor point ... +bool MoveText( + const long chartID = 0, // chart's ID + const string name = "Text", // object name + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + // + // if point position is not set, move it to the current bar having Bid price + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move the anchor point .. + if (!ObjectMove(chartID, name, 0, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the anchor point! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Change the object text ... +bool ChangeText( + const long chartID = 0, // chart's ID + const string name = "Text", // object name + const string text = "Text" // text +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change object text ... + if (!ObjectSetString(chartID, name, OBJPROP_TEXT, text)) + { + // + string message = + __FUNCTION__ + + ": failed to change the text! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Delete Text object ... +bool DeleteText( + const long chartID = 0, // chart's ID + const string name = "Text" // object name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete the object ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete \"Text\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution + return true; +} + +// +// Check anchor point values and set default values +// for empty ones ... +void ChangeTextEmptyPoint( + datetime &time, + double &price) +{ + // + // if the point's time is not set, it will be on the current bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // if the point's price is not set, it will have Bid value ... + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } +} + +// +// END Text Functions ... +// + +// +// START Fibonacchi Functions ... +// + +// +// Create Fibonacci Retracement by the given coordinates ... +bool DrawFibonacci( + const long chartID = 0, // chart's ID + const string name = "Fibonacci", // object name + const int subWindow = 0, // subwindow index + datetime time1 = 0, // first point time + double price1 = 0, // first point price + datetime time2 = 0, // second point time + double price2 = 0, // second point price + const color clr = clrRed, // object color + const ENUM_LINE_STYLE style = STYLE_SOLID, // object line style + const int width = 1, // object line width + const bool back = false, // in the background + const bool selection = true, // highlight to move + const bool rayRight = false, // object's continuation to the right + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // set anchor points' coordinates if they are not set ... + ChangeFibonacciEmptyPoints(time1, price1, time2, price2); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // Create Fibonacci Retracement by the given coordinates ... + if (!ObjectCreate(chartID, objName, OBJ_FIBO, subWindow, time1, price1, time2, price2)) + { + // + string message = + __FUNCTION__ + + ": failed to create \"Fibonacci Retracement\"! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of highlighting the channel for moving + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // enable true or disable false the mode of continuation of the object's display to the right ... + ObjectSetInteger(chartID, objName, OBJPROP_RAY_RIGHT, rayRight); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return true; +} + +// +// Create Fibonacci Retracement by the given coordinates ... +bool DrawCustomFibonacci( + // + int levels, // number of level lines + double &values[], // values of level lines + color &colors[], // color of level lines + ENUM_LINE_STYLE &styles[], // style of level lines + int &widths[], // width of level lines + string &descriptions[], // level Descriptions + // + const long chartID = 0, // chart's ID + const string name = "Fibonacci", // object name + const int subWindow = 0, // subwindow index + datetime time1 = 0, // first point time + double price1 = 0, // first point price + datetime time2 = 0, // second point time + double price2 = 0, // second point price + const color clr = clrAqua, // object color + const ENUM_LINE_STYLE style = STYLE_DOT, // object line style + const int width = 1, // object line width + const bool back = false, // in the background + const bool selection = true, // highlight to move + const bool rayRight = false, // object's continuation to the right + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // set anchor points' coordinates if they are not set ... + ChangeFibonacciEmptyPoints(time1, price1, time2, price2); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // Create Fibonacci Retracement by the given coordinates ... + if (!ObjectCreate(chartID, name, OBJ_FIBO, subWindow, time1, price1, time2, price2)) + { + // + string message = + __FUNCTION__ + + ": failed to create \"Fibonacci Retracement\"! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of highlighting the channel for moving + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // enable true or disable false the mode of continuation of the object's display to the right ... + ObjectSetInteger(chartID, objName, OBJPROP_RAY_RIGHT, rayRight); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // Change Levels Of Fibonacci ... + bool result = FibonacciLevelsSet( + levels, + values, + colors, + styles, + widths, + descriptions, + chartID, + objName); + + // + // successful execution ... + return result; +} + +// +// Set number of levels and their parameters ... +bool FibonacciLevelsSet( + int levels, // number of level lines + double &values[], // values of level lines + color &colors[], // color of level lines + ENUM_LINE_STYLE &styles[], // style of level lines + int &widths[], // width of level lines + string &descriptions[], // level Descriptions + const long chartID = 0, // chart's ID + const string name = "Fibonacci" // object name +) +{ + // + // check array sizes ... + if ( + levels != ArraySize(colors) || + levels != ArraySize(styles) || + levels != ArraySize(widths) || + levels != ArraySize(widths)) + { + // + string message = + __FUNCTION__ + + ": array length does not correspond to the number of levels, error!"; + + // + LogMessage(message); + + // + return false; + } + + // + // set the number of levels ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELS, levels); + + // + // set the properties of levels in the loop ... + for (int i = 0; i < levels; i++) + { + // + // level value ... + ObjectSetDouble(chartID, name, OBJPROP_LEVELVALUE, i, values[i]); + + // + // level color ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELCOLOR, i, colors[i]); + + // + // level style ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELSTYLE, i, styles[i]); + + // + // level width ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELWIDTH, i, widths[i]); + + // + // level description ... + // ObjectSetString(chartID, name, OBJPROP_LEVELTEXT, i, DoubleToString(100 * values[i], 1)); + ObjectSetString(chartID, name, OBJPROP_LEVELTEXT, i, descriptions[i]); + } + + // + // successful execution ... + return true; +} + +// +// Move Fibonacci Retracement anchor point ... +bool FibonacciPointChange( + const long chartID = 0, // chart's ID + const string name = "Fibonacci", // object name + const int pointIndex = 0, // anchor point index + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + // if point position is not set, move it to the current bar having Bid price ... + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move the anchor point ... + if (!ObjectMove(chartID, name, pointIndex, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the anchor point! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Delete Fibonacci Retracement ... +bool DeleteFibonachi( + const long chartID = 0, // chart's ID + const string name = "Fibonacci" // object name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete the object ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete \"Fibonacci Retracement\"! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Check the values of Fibonacci Retracement anchor points and set +// default values for empty ones ... +void ChangeFibonacciEmptyPoints( + datetime &time1, + double &price1, + datetime &time2, + double &price2) +{ + // + // if the second point's time is not set, it will be on the current bar ... + if (!time2) + { + time2 = TimeCurrent(); + } + + // + // if the second point's price is not set, it will have Bid value ... + if (!price2) + { + price2 = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // if the first point's time is not set, it is located 9 bars left from the second one ... + if (!time1) + { + // + // array for receiving the open time of the last 10 bars ... + datetime temp[10]; + CopyTime(Symbol(), Period(), time2, 10, temp); + + // + // set the first point 9 bars left from the second one ... + time1 = temp[0]; + } + + // + // if the first point's price is not set, move it 200 points below the second one ... + if (!price1) + { + price1 = price2 - 200 * SymbolInfoDouble(_Symbol, SYMBOL_POINT); + } +} + +// +// END Fibonacci Functions ... +// + +// +// START Event Functions ... +// + +// +// Create an Event ... +bool EventCreate( + const long chartID = 0, // chart's ID + const string name = "Event", // object name + const int subWindow = 0, // subwindow index + const string text = "Content", // event text + datetime time = 0, // anchor point time + const color clr = clrRed, // color + const int width = 1, // point width when highlighted + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + if (!time) + { + time = TimeCurrent(); + } + + // + ResetLastError(); + + // + if (!ObjectCreate(chartID, name, OBJ_EVENT, subWindow, time, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to create \"Event\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set event text + ObjectSetString(chartID, name, OBJPROP_TEXT, text); + + // + // set color + ObjectSetInteger(chartID, name, OBJPROP_COLOR, clr); + + // + // set anchor point width if the object is highlighted + ObjectSetInteger(chartID, name, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true + ObjectSetInteger(chartID, name, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving event by mouse + ObjectSetInteger(chartID, name, OBJPROP_SELECTABLE, selection); + ObjectSetInteger(chartID, name, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list + ObjectSetInteger(chartID, name, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart + ObjectSetInteger(chartID, name, OBJPROP_ZORDER, zOrder); + + // + // successful execution + return true; +} + +// +// Change Event object text +bool EventTextChange( + const long chartID = 0, // chart's ID + const string name = "Event", // event name + const string text = "Content" // text +) +{ + // + // reset the error value + ResetLastError(); + + // + // change object text + if (!ObjectSetString(chartID, name, OBJPROP_TEXT, text)) + { + // + string message = + __FUNCTION__ + + ": failed to change the text! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution + return true; +} + +// +// Move Event object +bool EventMove( + const long chartID = 0, // chart's ID + const string name = "Event", // event name + datetime time = 0 // time +) +{ + // + // if time is not set, move event to the last bar + if (!time) + { + time = TimeCurrent(); + } + + // + // reset the error value + ResetLastError(); + + // + // move the object + if (!ObjectMove(chartID, name, 0, time, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to move \"Event\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution + return true; +} + +// +// Delete Event object +bool EventDelete( + const long chartID = 0, // chart's ID + const string name = "Event" // event name +) +{ + // + // reset the error value + ResetLastError(); + + // + // delete the object + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete \"Event\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution + return true; +} + +// +// END Event Functions ... +// + +// +// START Button Functions ... +// + +// +// Create the button ... +bool ButtonCreate( + const long chartID = 0, // chart's ID + const string name = "Button", // button name + const int subWindow = 0, // subwindow index + const int x = 0, // X coordinate + const int y = 0, // Y coordinate + const int width = 50, // button width + const int height = 15, // button height + const ENUM_BASE_CORNER corner = CORNER_LEFT_UPPER, // chart corner for anchoring + const string text = "Button", // text + const string font = "Arial", // font + const int fontSize = 8, // font size + const color clr = clrBlack, // text color + const color bgColor = clrLightGray, // background color + const color borderColor = clrNONE, // border color + const bool state = false, // pressed/released + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + bool result = false; + + // + // create the button + result = ObjectCreate(chartID, name, OBJ_BUTTON, subWindow, 0, 0); + if (!result) + { + return result; + } + + // + // set button coordinates + ObjectSetInteger(chartID, name, OBJPROP_XDISTANCE, x); + ObjectSetInteger(chartID, name, OBJPROP_YDISTANCE, y); + + // + // set button size + ObjectSetInteger(chartID, name, OBJPROP_XSIZE, width); + ObjectSetInteger(chartID, name, OBJPROP_YSIZE, height); + + // + // set the chart's corner, relative to which point coordinates are defined + ObjectSetInteger(chartID, name, OBJPROP_CORNER, corner); + + // + // set the text + ObjectSetString(chartID, name, OBJPROP_TEXT, text); + + // + // set text font + ObjectSetString(chartID, name, OBJPROP_FONT, font); + + // + // set font size + ObjectSetInteger(chartID, name, OBJPROP_FONTSIZE, fontSize); + + // + // set text color + ObjectSetInteger(chartID, name, OBJPROP_COLOR, clr); + + // + // set background color + ObjectSetInteger(chartID, name, OBJPROP_BGCOLOR, bgColor); + + // + // set border color + ObjectSetInteger(chartID, name, OBJPROP_BORDER_COLOR, borderColor); + + // + // display in the foreground false or background true + ObjectSetInteger(chartID, name, OBJPROP_BACK, back); + + // + // set button state + ObjectSetInteger(chartID, name, OBJPROP_STATE, state); + + // + // enable true or disable false the mode of moving the button by mouse + ObjectSetInteger(chartID, name, OBJPROP_SELECTABLE, selection); + ObjectSetInteger(chartID, name, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list + ObjectSetInteger(chartID, name, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart + ObjectSetInteger(chartID, name, OBJPROP_ZORDER, zOrder); + + // + return result; +} + +// +// Move the button ... +bool ButtonMove( + const long chartID = 0, // chart's ID + const string name = "Button", // button name + const int x = 0, // X coordinate + const int y = 0 // Y coordinate +) +{ + // + bool result = false; + + // + // move the button + + // + result = ObjectSetInteger(chartID, name, OBJPROP_XDISTANCE, x); + if (!result) + { + return result; + } + + // + result = ObjectSetInteger(chartID, name, OBJPROP_YDISTANCE, y); + + // + return result; +} + +// +// Change button size ... +bool ButtonChangeSize( + const long chartID = 0, // chart's ID + const string name = "Button", // button name + const int width = 50, // button width + const int height = 18 // button height +) +{ + // + bool result = false; + + // + // change the button size + + // + result = ObjectSetInteger(chartID, name, OBJPROP_XSIZE, width); + if (!result) + { + return result; + } + + // + result = ObjectSetInteger(chartID, name, OBJPROP_YSIZE, height); + + // + return result; +} + +// +// Change corner of the chart for binding the button ... +bool ButtonChangeCorner( + const long chartID = 0, // chart's ID + const string name = "Button", // button name + const ENUM_BASE_CORNER corner = CORNER_LEFT_UPPER // chart corner for anchoring +) +{ + // + bool result = false; + + // + // change anchor corner + + // + result = ObjectSetInteger(chartID, name, OBJPROP_CORNER, corner); + + // + return result; +} + +// +// Change button text ... +bool ButtonTextChange( + const long chartID = 0, // chart's ID + const string name = "Button", // button name + const string text = "Text" // text +) +{ + // + bool result = false; + + // + // change object text + result = ObjectSetString(chartID, name, OBJPROP_TEXT, text); + + // + return result; +} + +// +// Delete the button ... +bool ButtonDelete( + const long chartID = 0, // chart's ID + const string name = "Button" // button name +) +{ + // + bool result = false; + + // + // delete the button + result = ObjectDelete(chartID, name); + + // + return result; +} + +// +// END Button Functions ... +// + +// +// END Regular Draws ... +// + +// +// START Chart Style Drawers ... +// + +// +// Apply Styles On Chart ... +void ApplyChartStyle( + long mChartId = -1, // chart's ID + ENUM_CHART_MODE mMode = CHART_CANDLES, // chart's mMode + bool mShowBidLine = true, // show bid line + bool mShowAskLine = true, // show ask line + bool mShowGrid = false, // show grids on chart + bool mShowVolumes = false, // show volumes + bool mShowTradeLevels = true, // Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders) + bool mAutoScroll = true, // chart autoscroll + bool mQuickNavigation = true, // chart quick navigation state + color mForeGroundColor = clrWhite, // chart's foreground color + color mBackGroundColor = clrBlack, // chart's background color + color mUpColor = clrGreen, // Up Color + color mDownColor = clrRed, // Down Color + color mBullishColor = clrGreen, // Bullish color + color mBearishColor = clrRed, // Bearish color + color mGridColor = clrGray, // grid color + color mBidLineColor = clrGray, // bid line color + color mAskLineColor = clrRed, // ask line color + color mLineColor = clrLime, // line mMode and doji candlestick color + color mStopColor = clrGold, // Color of stop order levels (Stop Loss and Take Profit) + color mVolumesColor = clrGreen // volumes color +) +{ + // + // Validate Args ... + if (mChartId == -1) + { + mChartId = 0; + } + + // + ChartSetInteger(mChartId, CHART_MODE, mMode); + ChartSetInteger(mChartId, CHART_SHOW_BID_LINE, mShowBidLine); + ChartSetInteger(mChartId, CHART_SHOW_ASK_LINE, mShowAskLine); + ChartSetInteger(mChartId, CHART_SHOW_GRID, mShowGrid); + ChartSetInteger(mChartId, CHART_SHOW_VOLUMES, mShowVolumes); + ChartSetInteger(mChartId, CHART_SHOW_TRADE_LEVELS, mShowTradeLevels); + ChartSetInteger(mChartId, CHART_AUTOSCROLL, mAutoScroll); + ChartSetInteger(mChartId, CHART_QUICK_NAVIGATION, mQuickNavigation); + ChartSetInteger(mChartId, CHART_COLOR_FOREGROUND, mForeGroundColor); + ChartSetInteger(mChartId, CHART_COLOR_BACKGROUND, mBackGroundColor); + ChartSetInteger(mChartId, CHART_COLOR_CHART_UP, mUpColor); + ChartSetInteger(mChartId, CHART_COLOR_CHART_DOWN, mDownColor); + ChartSetInteger(mChartId, CHART_COLOR_CANDLE_BULL, mBullishColor); + ChartSetInteger(mChartId, CHART_COLOR_CANDLE_BEAR, mBearishColor); + ChartSetInteger(mChartId, CHART_COLOR_GRID, mGridColor); + ChartSetInteger(mChartId, CHART_COLOR_BID, mBidLineColor); + ChartSetInteger(mChartId, CHART_COLOR_ASK, mAskLineColor); + ChartSetInteger(mChartId, CHART_COLOR_STOP_LEVEL, mStopColor); + ChartSetInteger(mChartId, CHART_COLOR_CHART_LINE, mLineColor); + ChartSetInteger(mChartId, CHART_COLOR_VOLUME, mVolumesColor); +} + +// +// Retrieve Chart Size in Pixel ... +struct XSize +{ + long width; + long height; + + // + int x; + int y; + int w; + int h; + + // + int wStep; + int hStep; +}; + +// +// Retrieve Chart Size ... +bool GetChartSize( + XSize &result, // Holds Result ... + long chartID = 0 // Specified Chart ID ... +) +{ + // + bool mResult = false; + + // + mResult = ChartGetInteger(0, CHART_WIDTH_IN_PIXELS, 0, result.width); + if (!mResult) + { + return mResult; + } + + // + mResult = ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS, 0, result.height); + + // + return mResult; +} + +// +// END Chart Style Drawers ... +// + +// +// START Custom Drawings ... +// + +// +// Define a Draw Specifications ... +struct XDrawSpecifications +{ + // + // Props ... + + // + bool draw; // Draw or Not ... + + // + int width; // Draw Witdth ... + color clr; // Draw Color ... + ENUM_LINE_STYLE style; // Draw Style ... + + // + bool back; // in the background + bool fill; // fill object if supported + bool selection; // highlight to move + bool rayRight; // line's continuation to the right + bool hidden; // hidden in the object list + long zOrder; // priority for mouse click + + // + string label; // Label ... + color labelColor; // Label Color ... + double labelAngel; // Label Angle ... + string labelFont; // Label Font ... + int labelFontSize; // Label Font Size ... + ENUM_ANCHOR_POINT labelAnchor; // Label Anchor Point ... + + // + // Constructor ... + XDrawSpecifications() + { + Clean(); + } + + // + // Operator ... + void operator=(const XDrawSpecifications &value) + { + // + clr = value.clr; + draw = value.draw; + width = value.width; + style = value.style; + + // + back = value.back; + hidden = value.hidden; + zOrder = value.zOrder; + rayRight = value.rayRight; + selection = value.selection; + + // + fill = value.fill; + + // + label = value.label; + labelColor = value.labelColor; + labelAngel = value.labelAngel; + labelFont = value.labelFont; + labelFontSize = value.labelFontSize; + labelAnchor = value.labelAnchor; + } + + // + // Functions ... + + // + void Clean() + { + // + draw = false; + width = 1; + clr = CLR_NONE; + style = STYLE_SOLID; + + // + back = false; + hidden = false; + rayRight = false; + selection = false; + fill = false; + + // + zOrder = 0; + + // + label = ""; + labelColor = CLR_NONE; + labelAngel = 0; + labelFont = "Arial"; + labelFontSize = 20; + labelAnchor = ANCHOR_LEFT_UPPER; + } + + // + void Label( + string mLabel = "", // Label ... + color mLabelColor = CLR_NONE, // Label Color ... + string mLabelFont = "Arial", // Label Font ... + int mLabelFontSize = 20, // Label Font Size ... + ENUM_ANCHOR_POINT mLabelAnchor = ANCHOR_LEFT_UPPER, // Label Anchor Point ... + double mLabelAngel = 0 // Label Angle ... + ) + { + // + label = mLabel; + labelFont = mLabelFont; + labelColor = mLabelColor; + labelAngel = mLabelAngel; + labelAnchor = mLabelAnchor; + labelFontSize = mLabelFontSize; + } +}; + +// +// Candle Draw Specifications ... +struct XOHCLDrawSpecification +{ + // + // Props ... + XDrawSpecifications openStyle; + XDrawSpecifications highStyle; + XDrawSpecifications closeStyle; + XDrawSpecifications lowStyle; + + // + // Constructors ... + XOHCLDrawSpecification() + { + Clean(); + } + + // + // Operators ... + void operator=(const XOHCLDrawSpecification &value) + { + // + lowStyle = value.lowStyle; + openStyle = value.openStyle; + highStyle = value.highStyle; + closeStyle = value.closeStyle; + } + + // + // Functions ... + + // + void Clean() + { + // + lowStyle.Clean(); + openStyle.Clean(); + highStyle.Clean(); + closeStyle.Clean(); + } + + // + void Default() + { + // + // Open ... + openStyle.width = 1; + openStyle.draw = true; + openStyle.clr = clrLime; + openStyle.style = STYLE_SOLID; + openStyle.Label( + "O", + openStyle.clr); + + // + // High ... + highStyle.width = 1; + highStyle.draw = true; + highStyle.clr = clrAqua; + highStyle.style = STYLE_SOLID; + highStyle.Label( + "H", + highStyle.clr); + + // + // Close ... + closeStyle.width = 1; + closeStyle.draw = true; + closeStyle.clr = clrRed; + closeStyle.style = STYLE_SOLID; + closeStyle.Label( + "C", + closeStyle.clr); + + // + // Low ... + lowStyle.width = 1; + lowStyle.draw = true; + lowStyle.clr = clrMagenta; + lowStyle.style = STYLE_SOLID; + lowStyle.Label( + "L", + lowStyle.clr); + } + + // + void Width(int value) + { + // + lowStyle.width = value; + openStyle.width = value; + highStyle.width = value; + closeStyle.width = value; + } + + // + void Style(ENUM_LINE_STYLE value) + { + // + lowStyle.style = value; + openStyle.style = value; + highStyle.style = value; + closeStyle.style = value; + } + + // + void Color(color value) + { + // + lowStyle.clr = value; + openStyle.clr = value; + highStyle.clr = value; + closeStyle.clr = value; + } + + // + void RayRight(bool value) + { + // + lowStyle.rayRight = value; + openStyle.rayRight = value; + highStyle.rayRight = value; + closeStyle.rayRight = value; + } + + // + void Draw(bool value) + { + // + lowStyle.draw = value; + openStyle.draw = value; + highStyle.draw = value; + closeStyle.draw = value; + } + + // + void Back(bool value) + { + // + lowStyle.back = value; + openStyle.back = value; + highStyle.back = value; + closeStyle.back = value; + } + + // + void Fill(bool value) + { + // + lowStyle.fill = value; + openStyle.fill = value; + highStyle.fill = value; + closeStyle.fill = value; + } + + // + void Label(string value) + { + // + lowStyle.Label(value); + openStyle.Label(value); + highStyle.Label(value); + closeStyle.Label(value); + } + + // + void SetLabelPrefix(string value) + { + // + lowStyle.label = value + " " + lowStyle.label; + openStyle.label = value + " " + openStyle.label; + highStyle.label = value + " " + highStyle.label; + closeStyle.label = value + " " + closeStyle.label; + } +}; + +// +bool RemoveCandle( + XOHCL &c, + long chartId = 0, + int subWindow = 0 // +) +{ + // + bool result = false; + + // + string cTag = GenerateTag(c); + + // + result = IsDrawExists( + cTag, + chartId, + subWindow); + if (!result) + { + return result; + } + + // + RemoveDraws( + cTag, + chartId, + subWindow); + + // + return result; +} + +// +// XOHCL ... +void DrawCandleAsLine( + long chartId, // Chart ID ... + int subWindow, // SubWindow ... + XOHCL &c, // the Candle Which required to Draw ... + const datetime time, // Candle Time ... + XOHCLDrawSpecification &config, // Draw Specifications ... + string tag = "", // Draw Tag ... + bool update = true, // Update Draw if Exists ... + bool drawMidLine = true // Draw Open Close Middle Line ... +) +{ + // + datetime cTime = TimeCurrent(); + XDrawSpecifications specs; + + // + string baseTag = tag + GenerateTag(c); + + // + // Open ... + specs = config.openStyle; + if (specs.draw) + { + // + double value = c.open; + string valueTag = "|O|"; + + // + string mTag = baseTag + valueTag + ToString(value); + string mLblTag = baseTag + valueTag + "_lbl"; + + // + // Check if Object Exists Delete it ... + bool isExists = IsDrawExists( + mTag, + chartId, + subWindow // + ); + bool canDraw = !isExists || (isExists && update); + + // + if (isExists && canDraw) + { + // + DeleteText( + chartId, + mLblTag // + ); + + // + DeleteTrendLine( + chartId, + mTag // + ); + } + + // + if (canDraw) + { + // + // Draw Label ... + if (StringLen(specs.label) > 0) + { + DrawText( + chartId, + mLblTag, + subWindow, + cTime, + value, + specs.label, + specs.labelFont, + specs.labelFontSize, + specs.labelColor, + specs.labelAngel, + specs.labelAnchor, + specs.back, + specs.selection, + specs.hidden, + specs.zOrder // + ); + } + + // + // Draw ... + DrawTrendLine( + chartId, + mTag, + subWindow, + time, + value, + cTime, + value, + specs.clr, + specs.style, + specs.width, + specs.back, + specs.selection, + specs.rayRight, + specs.hidden, + specs.zOrder // + ); + } + } + + // + // High ... + specs = config.highStyle; + if (specs.draw) + { + // + double value = c.high; + string valueTag = "|H|"; + + // + string mTag = baseTag + valueTag + ToString(value); + string mLblTag = baseTag + valueTag + "_lbl"; + + // + // Check if Object Exists Delete it ... + bool isExists = IsDrawExists( + mTag, + chartId, + subWindow // + ); + bool canDraw = !isExists || (isExists && update); + + // + if (isExists && canDraw) + { + // + DeleteText( + chartId, + mLblTag // + ); + + // + DeleteTrendLine( + chartId, + mTag // + ); + } + + // + if (canDraw) + { + // + // Draw Label ... + if (StringLen(specs.label) > 0) + { + DrawText( + chartId, + mLblTag, + subWindow, + cTime, + value, + specs.label, + specs.labelFont, + specs.labelFontSize, + specs.labelColor, + specs.labelAngel, + specs.labelAnchor, + specs.back, + specs.selection, + specs.hidden, + specs.zOrder // + ); + } + + // + // Draw ... + DrawTrendLine( + chartId, + mTag, + subWindow, + time, + value, + cTime, + value, + specs.clr, + specs.style, + specs.width, + specs.back, + specs.selection, + specs.rayRight, + specs.hidden, + specs.zOrder // + ); + } + } + + // + // Close ... + specs = config.closeStyle; + if (specs.draw) + { + // + double value = c.close; + string valueTag = "|C|"; + + // + string mTag = baseTag + valueTag + ToString(value); + string mLblTag = baseTag + valueTag + "_lbl"; + + // + // Check if Object Exists Delete it ... + bool isExists = IsDrawExists( + mTag, + chartId, + subWindow // + ); + bool canDraw = !isExists || (isExists && update); + + // + if (isExists && canDraw) + { + // + DeleteText( + chartId, + mLblTag // + ); + + // + DeleteTrendLine( + chartId, + mTag); + } + + // + if (canDraw) + { + // + // Draw Label ... + if (StringLen(specs.label) > 0) + { + DrawText( + chartId, + mLblTag, + subWindow, + cTime, + value, + specs.label, + specs.labelFont, + specs.labelFontSize, + specs.labelColor, + specs.labelAngel, + specs.labelAnchor, + specs.back, + specs.selection, + specs.hidden, + specs.zOrder // + ); + } + + // + // Draw ... + DrawTrendLine( + chartId, + mTag, + subWindow, + time, + value, + cTime, + value, + specs.clr, + specs.style, + specs.width, + specs.back, + specs.selection, + specs.rayRight, + specs.hidden, + specs.zOrder // + ); + } + } + + // + // Low ... + specs = config.lowStyle; + if (specs.draw) + { + // + double value = c.low; + string valueTag = "|L|"; + + // + string mTag = baseTag + valueTag + ToString(value); + string mLblTag = baseTag + valueTag + "_lbl"; + + // + // Check if Object Exists Delete it ... + bool isExists = IsDrawExists( + mTag, + chartId, + subWindow // + ); + bool canDraw = !isExists || (isExists && update); + + // + if (isExists && canDraw) + { + // + DeleteText( + chartId, + mLblTag // + ); + + // + DeleteTrendLine( + chartId, + mTag); + } + + // + if (canDraw) + { + // + // Draw Label ... + if (StringLen(specs.label) > 0) + { + DrawText( + chartId, + mLblTag, + subWindow, + cTime, + value, + specs.label, + specs.labelFont, + specs.labelFontSize, + specs.labelColor, + specs.labelAngel, + specs.labelAnchor, + specs.back, + specs.selection, + specs.hidden, + specs.zOrder // + ); + } + + // + // Draw ... + DrawTrendLine( + chartId, + mTag, + subWindow, + time, + value, + cTime, + value, + specs.clr, + specs.style, + specs.width, + specs.back, + specs.selection, + specs.rayRight, + specs.hidden, + specs.zOrder // + ); + } + } +} + +// +void DrawCandleAsBox( + long chartId, // Chart ID ... + int subWindow, // SubWindow ... + XOHCL &c, // the Candle Which required to Draw ... + const datetime time, // Candle Time ... + XOHCLDrawSpecification &config, // Draw Specifications ... + string tag = "", // Draw Tag ... + bool drawBody = true, // Draw Body ... + bool drawShadows = true, // Draw Shadows ... + bool update = true // Update Draw if Exists ... +) +{ + // + datetime cTime = TimeCurrent(); + + // + // First Check all Styles Must Be Draw true ... + bool canDraw = + // + config.openStyle.draw && + config.highStyle.draw && + config.closeStyle.draw && + config.lowStyle.draw + // + ; + + // + if (!canDraw) + { + return; + } + + // + // Next we have to determine Candle is Bullish or Bearish ... + // + bool isBullish = + c.open < c.close; + + // + bool isBearish = + c.open > c.close; + + // + XDrawSpecifications bodySpec; + if (isBullish) + { + bodySpec = config.openStyle; + } + else if (isBearish) + { + bodySpec = config.closeStyle; + } + else + { + // + bodySpec.clr = clrGray; + } + + // + // Now We have to Draw 3 Rectangle ... + // 1- Up Shadow + // 2- Candle Body + // 3- Down Shadow + + // + double upPrice = MathMax(c.open, c.close); + double downPrice = MathMin(c.open, c.close); + double upShadowSize = c.high - upPrice; + double downShadowSize = downPrice - c.low; + + // + string mTag = GenerateTag(c); + + // + // Draw Up Shadow ... + if (drawShadows) + { + // + string upShadowTag = mTag + "|US|"; + + XDrawSpecifications spec = config.highStyle; + + // + // Check if Object Exists Delete it ... + bool isExists = IsDrawExists( + upShadowTag, + chartId, + subWindow // + ); + + // + bool canDraw = !isExists || (isExists && update); + + // + if (isExists && canDraw) + { + // + DeleteRectangle( + chartId, + upShadowTag // + ); + } + + // + if (canDraw) + { + // + // New ... + DrawRectangle( + chartId, + upShadowTag, + subWindow, + time, + c.high, + cTime, + upPrice, + spec.clr, + spec.style, + spec.width, + spec.fill, + spec.back, + spec.selection, + spec.hidden, + spec.zOrder // + ); + } + } + + // + // Draw Body ... + if (drawBody) + { + // + string bodyTag = mTag + "|BDY|"; + + // + // Check if Object Exists Delete it ... + bool isExists = IsDrawExists( + bodyTag, + chartId, + subWindow // + ); + + // + bool canDraw = !isExists || (isExists && update); + + // + if (isExists && canDraw) + { + // + DeleteRectangle( + chartId, + bodyTag // + ); + } + + // + if (canDraw) + { + // + // New ... + DrawRectangle( + chartId, + bodyTag, + subWindow, + time, + upPrice, + cTime, + downPrice, + bodySpec.clr, + bodySpec.style, + bodySpec.width, + bodySpec.fill, + bodySpec.back, + bodySpec.selection, + bodySpec.hidden, + bodySpec.zOrder // + ); + } + } + + // + // Draw Down Shadow ... + if (drawShadows) + { + // + string downShadowTag = mTag + "|DS|"; + + XDrawSpecifications spec = config.lowStyle; + + // + // Check if Object Exists Delete it ... + bool isExists = IsDrawExists( + downShadowTag, + chartId, + subWindow // + ); + + // + bool canDraw = !isExists || (isExists && update); + + // + if (isExists && canDraw) + { + // + DeleteRectangle( + chartId, + downShadowTag // + ); + } + + // + if (canDraw) + { + // + // New ... + DrawRectangle( + chartId, + downShadowTag, + subWindow, + time, + downPrice, + cTime, + downPrice + downShadowSize, + spec.clr, + spec.style, + spec.width, + spec.fill, + spec.back, + spec.selection, + spec.hidden, + spec.zOrder // + ); + } + } +} + +// +// END Custom Drawings ... +// diff --git a/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.http.lib.ex5 b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.http.lib.ex5 new file mode 100644 index 0000000..2398a0f Binary files /dev/null and b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.http.lib.ex5 differ diff --git a/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.http.lib.mq5 b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.http.lib.mq5 new file mode 100644 index 0000000..97f7ac0 --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.http.lib.mq5 @@ -0,0 +1,177 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Http Library +// ------------------------------------------ +// Name: XHttp +// Description: provide http communication +// abilities ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Model Definition ... +// +enum X_HTTP_METHOD +{ + X_HTTP_GET, + X_HTTP_POST +}; +// +// END Model Definition ... +// + +// +// START Inputs ... +// +// +// END Inputs ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// +// +// Initial Library if required ... +bool OnInInitHttpLibrary() +{ + return false; +} + +// +// DeInitial Library if required ... +void OnDeinitHttpLibrary() +{ +} + +// +// Convert enum to String ... +string ToString(X_HTTP_METHOD method) +{ + // + string result = ""; + + // + switch (method) + { + // + case X_HTTP_GET: + result = "GET"; + break; + + // + case X_HTTP_POST: + result = "POST"; + break; + } + + // + return result; +} + +// +// Send Global Request ... +int SendRequest( + X_HTTP_METHOD method, // Httm Request Method + const string url, // Server Address + const string headers, // Headers providing + const char &payload[], // the Data which needs to Send + char &response[], // Response of request + string responseHeaders, // Response Headers + int timeout = 500 // Timeout for response default is 500 +) +{ + // + int result = -1; + + // + string strMethod = ToString(method); + if (StringLen(strMethod) == 0) { + return result; + } + + // + result = WebRequest( + strMethod, + url, + headers, + timeout, + payload, + response, + responseHeaders + ); + + // + return result; +} + +// +// Get Request ... +int GetRequest( + const string url, // Server Address + const string headers, // Headers providing + const char &payload[], // the Data which needs to Send + char &response[], // Response of request + string responseHeaders, // Response Headers + int timeout = 500 // Timeout for response default is 500 +) { + // + int result = SendRequest( + X_HTTP_GET, + url, + headers, + payload, + response, + responseHeaders, + timeout + ); + + // + return result; +} + +// +// Post Request ... +int PostRequest( + const string url, // Server Address + const string headers, // Headers providing + const char &payload[], // the Data which needs to Send + char &response[], // Response of request + string responseHeaders, // Response Headers + int timeout = 500 // Timeout for response default is 500 +) { + // + int result = SendRequest( + X_HTTP_POST, + url, + headers, + payload, + response, + responseHeaders, + timeout + ); + + // + return result; +} +// +// END Provided Functions ... +// diff --git a/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.log.lib.ex5 b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.log.lib.ex5 new file mode 100644 index 0000000..ca4e3bb Binary files /dev/null and b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.log.lib.ex5 differ diff --git a/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.log.lib.mq5 b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.log.lib.mq5 new file mode 100644 index 0000000..3e30eb9 --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.log.lib.mq5 @@ -0,0 +1,1088 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Logger Library +// --------------------------------------- +// Name: XLogger +// Description: provides Logging abilities ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Inputs ... +// +// input group "Logging"; +// input bool enableLogging = true; // Enable Logging +bool enableLogging = true; // Enable Logging +// +// END Inputs ... +// + +// +// Including Models ... +#include "x-saherelm.models.lib.mq5" + +// +// START Global Definitions: Variables, Properties and etc ... +// +string logTag = "X-Logger"; // LogTag +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// +// +// Logging a Message ... +void LogMessage(string message) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(logTag, " > ", message); +} +void LogMessage(string tag, string message) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(tag, " > ", message); +} + +// +void LogEmptyLine() +{ + LogMessage(" "); +} + +// +void LogError( + int error = -1 // Specific Error +) { + // + if (error <= -1) { + error = GetLastError(); + } + + // + string errorMsg = GetErrorDescription(error); + + // + LogMessage("Error: " + errorMsg); +} + +// +// Logging an Array ... +void LogArray(int &array[]) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(logTag, ">"); + ArrayPrint(array); +} +void LogArray(double &array[]) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(logTag, ">"); + ArrayPrint(array); +} +void LogArray(string &array[]) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(logTag, ">"); + ArrayPrint(array); +} +// +// END Provided Functions ... +// + + +// +// Error Descriptions Functions ... +// + +// +// Retrieve Specified Error Code Description ... +string GetErrorDescription(int err_code) +{ + // + string result = ""; + + // + switch (err_code) + { + // + //--- Constant Description + + // + case ERR_SUCCESS: + result = "The operation completed successfully"; + break; + + // + case ERR_INTERNAL_ERROR: + result = "Unexpected internal error"; + break; + + // + case ERR_WRONG_INTERNAL_PARAMETER: + result = "Wrong parameter in the inner call of the client terminal function"; + break; + + // + case ERR_INVALID_PARAMETER: + result = "Wrong parameter when calling the system function"; + break; + + // + case ERR_NOT_ENOUGH_MEMORY: + result = "Not enough memory to perform the system function"; + break; + + // + case ERR_STRUCT_WITHOBJECTS_ORCLASS: + result = "The structure contains objects of strings and/or dynamic arrays and/or structure of such objects and/or classes"; + break; + + // + case ERR_INVALID_ARRAY: + result = "Array of a wrong type, wrong size, or a damaged object of a dynamic array"; + break; + + // + case ERR_ARRAY_RESIZE_ERROR: + result = "Not enough memory for the relocation of an array, or an attempt to change the size of a static array"; + break; + + // + case ERR_STRING_RESIZE_ERROR: + result = "Not enough memory for the relocation of string"; + break; + + // + case ERR_NOTINITIALIZED_STRING: + result = "Not initialized string"; + break; + + // + case ERR_INVALID_DATETIME: + result = "Invalid date and/or time"; + break; + + // + case ERR_ARRAY_BAD_SIZE: + result = "Requested array size exceeds 2 GB"; + break; + + // + case ERR_INVALID_POINTER: + result = "Wrong pointer"; + break; + + // + case ERR_INVALID_POINTER_TYPE: + result = "Wrong type of pointer"; + break; + + // + case ERR_FUNCTION_NOT_ALLOWED: + result = "System function is not allowed to call"; + break; + + // + //--- Charts + + // + case ERR_CHART_WRONG_ID: + result = "Wrong chart ID"; + break; + + // + case ERR_CHART_NO_REPLY: + result = "Chart does not respond"; + break; + + // + case ERR_CHART_NOT_FOUND: + result = "Chart not found"; + break; + + // + case ERR_CHART_NO_EXPERT: + result = "No Expert Advisor in the chart that could handle the event"; + break; + + // + case ERR_CHART_CANNOT_OPEN: + result = "Chart opening error"; + break; + + // + case ERR_CHART_CANNOT_CHANGE: + result = "Failed to change chart symbol and period"; + break; + + // + case ERR_CHART_CANNOT_CREATE_TIMER: + result = "Failed to create timer"; + break; + + // + case ERR_CHART_WRONG_PROPERTY: + result = "Wrong chart property ID"; + break; + + // + case ERR_CHART_SCREENSHOT_FAILED: + result = "Error creating screenshots"; + break; + + // + case ERR_CHART_NAVIGATE_FAILED: + result = "Error navigating through chart"; + break; + + // + case ERR_CHART_TEMPLATE_FAILED: + result = "Error applying template"; + break; + + // + case ERR_CHART_WINDOW_NOT_FOUND: + result = "Subwindow containing the indicator was not found"; + break; + + // + case ERR_CHART_INDICATOR_CANNOT_ADD: + result = "Error adding an indicator to chart"; + break; + + // + case ERR_CHART_INDICATOR_CANNOT_DEL: + result = "Error deleting an indicator from the chart"; + break; + + // + case ERR_CHART_INDICATOR_NOT_FOUND: + result = "Indicator not found on the specified chart"; + break; + + // + //--- Graphical Objects + case ERR_OBJECT_ERROR: + result = "Error working with a graphical object"; + break; + + // + case ERR_OBJECT_NOT_FOUND: + result = "Graphical object was not found"; + break; + + // + case ERR_OBJECT_WRONG_PROPERTY: + result = "Wrong ID of a graphical object property"; + break; + + // + case ERR_OBJECT_GETDATE_FAILED: + result = "Unable to get date corresponding to the value"; + break; + + // + case ERR_OBJECT_GETVALUE_FAILED: + result = "Unable to get value corresponding to the date"; + break; + + // + //--- MarketInfo + + // + case ERR_MARKET_UNKNOWN_SYMBOL: + result = "Unknown symbol"; + break; + + // + case ERR_MARKET_NOT_SELECTED: + result = "Symbol is not selected in MarketWatch"; + break; + + // + case ERR_MARKET_WRONG_PROPERTY: + result = "Wrong identifier of a symbol property"; + break; + + // + case ERR_MARKET_LASTTIME_UNKNOWN: + result = "Time of the last tick is not known (no ticks)"; + break; + + // + case ERR_MARKET_SELECT_ERROR: + result = "Error adding or deleting a symbol in MarketWatch"; + break; + + // + //--- History Access + + // + case ERR_HISTORY_NOT_FOUND: + result = "Requested history not found"; + break; + + // + case ERR_HISTORY_WRONG_PROPERTY: + result = "Wrong ID of the history property"; + break; + + // + //--- Global_Variables + + // + case ERR_GLOBALVARIABLE_NOT_FOUND: + result = "Global variable of the client terminal is not found"; + break; + + // + case ERR_GLOBALVARIABLE_EXISTS: + result = "Global variable of the client terminal with the same name already exists"; + break; + + // + case ERR_MAIL_SEND_FAILED: + result = "Email sending failed"; + break; + + // + case ERR_PLAY_SOUND_FAILED: + result = "Sound playing failed"; + break; + + // + case ERR_MQL5_WRONG_PROPERTY: + result = "Wrong identifier of the program property"; + break; + + // + case ERR_TERMINAL_WRONG_PROPERTY: + result = "Wrong identifier of the terminal property"; + break; + + // + case ERR_FTP_SEND_FAILED: + result = "File sending via ftp failed"; + break; + + // + case ERR_NOTIFICATION_SEND_FAILED: + result = "Error in sending notification"; + break; + + // + //--- Custom Indicator Buffers + + // + case ERR_BUFFERS_NO_MEMORY: + result = "Not enough memory for the distribution of indicator buffers"; + break; + + // + case ERR_BUFFERS_WRONG_INDEX: + result = "Wrong indicator buffer index"; + break; + + // + //--- Custom Indicator Properties + + // + case ERR_CUSTOM_WRONG_PROPERTY: + result = "Wrong ID of the custom indicator property"; + break; + + // + //--- Account + + // + case ERR_ACCOUNT_WRONG_PROPERTY: + result = "Wrong account property ID"; + break; + + // + case ERR_TRADE_WRONG_PROPERTY: + result = "Wrong trade property ID"; + break; + + // + case ERR_TRADE_DISABLED: + result = "Trading by Expert Advisors prohibited"; + break; + + // + case ERR_TRADE_POSITION_NOT_FOUND: + result = "Position not found"; + break; + + // + case ERR_TRADE_ORDER_NOT_FOUND: + result = "Order not found"; + break; + + // + case ERR_TRADE_DEAL_NOT_FOUND: + result = "Deal not found"; + break; + + // + case ERR_TRADE_SEND_FAILED: + result = "Trade request sending failed"; + break; + + // + //--- Indicators + + // + case ERR_INDICATOR_UNKNOWN_SYMBOL: + result = "Unknown symbol"; + break; + + // + case ERR_INDICATOR_CANNOT_CREATE: + result = "Indicator cannot be created"; + break; + + // + case ERR_INDICATOR_NO_MEMORY: + result = "Not enough memory to add the indicator"; + break; + + // + case ERR_INDICATOR_CANNOT_APPLY: + result = "The indicator cannot be applied to another indicator"; + break; + + // + case ERR_INDICATOR_CANNOT_ADD: + result = "Error applying an indicator to chart"; + break; + + // + case ERR_INDICATOR_DATA_NOT_FOUND: + result = "Requested data not found"; + break; + + // + case ERR_INDICATOR_WRONG_HANDLE: + result = "Wrong indicator handle"; + break; + + // + case ERR_INDICATOR_WRONG_PARAMETERS: + result = "Wrong number of parameters when creating an indicator"; + break; + + // + case ERR_INDICATOR_PARAMETERS_MISSING: + result = "No parameters when creating an indicator"; + break; + + // + case ERR_INDICATOR_CUSTOM_NAME: + result = "The first parameter in the array must be the name of the custom indicator"; + break; + + // + case ERR_INDICATOR_PARAMETER_TYPE: + result = "Invalid parameter type in the array when creating an indicator"; + break; + + // + case ERR_INDICATOR_WRONG_INDEX: + result = "Wrong index of the requested indicator buffer"; + break; + + // + //--- Depth of Market + + // + case ERR_BOOKS_CANNOT_ADD: + result = "Depth Of Market can not be added"; + break; + + // + case ERR_BOOKS_CANNOT_DELETE: + result = "Depth Of Market can not be removed"; + break; + + // + case ERR_BOOKS_CANNOT_GET: + result = "The data from Depth Of Market can not be obtained"; + break; + + // + case ERR_BOOKS_CANNOT_SUBSCRIBE: + result = "Error in subscribing to receive new data from Depth Of Market"; + break; + + // + //--- File Operations + + // + case ERR_TOO_MANY_FILES: + result = "More than 64 files cannot be opened at the same time"; + break; + + // + case ERR_WRONG_FILENAME: + result = "Invalid file name"; + break; + + // + case ERR_TOO_LONG_FILENAME: + result = "Too long file name"; + break; + + // + case ERR_CANNOT_OPEN_FILE: + result = "File opening error"; + break; + + // + case ERR_FILE_CACHEBUFFER_ERROR: + result = "Not enough memory for cache to read"; + break; + + // + case ERR_CANNOT_DELETE_FILE: + result = "File deleting error"; + break; + + // + case ERR_INVALID_FILEHANDLE: + result = "A file with this handle was closed, or was not opening at all"; + break; + + // + case ERR_WRONG_FILEHANDLE: + result = "Wrong file handle"; + break; + + // + case ERR_FILE_NOTTOWRITE: + result = "The file must be opened for writing"; + break; + + // + case ERR_FILE_NOTTOREAD: + result = "The file must be opened for reading"; + break; + + // + case ERR_FILE_NOTBIN: + result = "The file must be opened as a binary one"; + break; + + // + case ERR_FILE_NOTTXT: + result = "The file must be opened as a text"; + break; + + // + case ERR_FILE_NOTTXTORCSV: + result = "The file must be opened as a text or CSV"; + break; + + // + case ERR_FILE_NOTCSV: + result = "The file must be opened as CSV"; + break; + + // + case ERR_FILE_READERROR: + result = "File reading error"; + break; + + // + case ERR_FILE_BINSTRINGSIZE: + result = "String size must be specified, because the file is opened as binary"; + break; + + // + case ERR_INCOMPATIBLE_FILE: + result = "A text file must be for string arrays, for other arrays - binary"; + break; + + // + case ERR_FILE_IS_DIRECTORY: + result = "This is not a file, this is a directory"; + break; + + // + case ERR_FILE_NOT_EXIST: + result = "File does not exist"; + break; + + // + case ERR_FILE_CANNOT_REWRITE: + result = "File can not be rewritten"; + break; + + // + case ERR_WRONG_DIRECTORYNAME: + result = "Wrong directory name"; + break; + + // + case ERR_DIRECTORY_NOT_EXIST: + result = "Directory does not exist"; + break; + + // + case ERR_FILE_ISNOT_DIRECTORY: + result = "This is a file, not a directory"; + break; + + // + case ERR_CANNOT_DELETE_DIRECTORY: + result = "The directory cannot be removed"; + break; + + // + case ERR_CANNOT_CLEAN_DIRECTORY: + result = "Failed to clear the directory (probably one or more files are blocked and removal operation failed)"; + break; + + // + case ERR_FILE_WRITEERROR: + result = "Failed to write a resource to a file"; + break; + + // + //--- String Casting + + // + case ERR_NO_STRING_DATE: + result = "No date in the string"; + break; + + // + case ERR_WRONG_STRING_DATE: + result = "Wrong date in the string"; + break; + + // + case ERR_WRONG_STRING_TIME: + result = "Wrong time in the string"; + break; + + // + case ERR_STRING_TIME_ERROR: + result = "Error converting string to date"; + break; + + // + case ERR_STRING_OUT_OF_MEMORY: + result = "Not enough memory for the string"; + break; + + // + case ERR_STRING_SMALL_LEN: + result = "The string length is less than expected"; + break; + + // + case ERR_STRING_TOO_BIGNUMBER: + result = "Too large number, more than ULONG_MAX"; + break; + + // + case ERR_WRONG_FORMATSTRING: + result = "Invalid format string"; + break; + + // + case ERR_TOO_MANY_FORMATTERS: + result = "Amount of format specifiers more than the parameters"; + break; + + // + case ERR_TOO_MANY_PARAMETERS: + result = "Amount of parameters more than the format specifiers"; + break; + + // + case ERR_WRONG_STRING_PARAMETER: + result = "Damaged parameter of string type"; + break; + + // + case ERR_STRINGPOS_OUTOFRANGE: + result = "Position outside the string"; + break; + + // + case ERR_STRING_ZEROADDED: + result = "0 added to the string end, a useless operation"; + break; + + // + case ERR_STRING_UNKNOWNTYPE: + result = "Unknown data type when converting to a string"; + break; + + // + case ERR_WRONG_STRING_OBJECT: + result = "Damaged string object"; + break; + + // + //--- Operations with Arrays + + // + case ERR_INCOMPATIBLE_ARRAYS: + result = "Copying incompatible arrays. String array can be copied only to a string array, and a numeric array - in numeric array only"; + break; + + // + case ERR_SMALL_ASSERIES_ARRAY: + result = "The receiving array is declared as AS_SERIES, and it is of insufficient size"; + break; + + // + case ERR_SMALL_ARRAY: + result = "Too small array, the starting position is outside the array"; + break; + + // + case ERR_ZEROSIZE_ARRAY: + result = "An array of zero length"; + break; + + // + case ERR_NUMBER_ARRAYS_ONLY: + result = "Must be a numeric array"; + break; + + // + case ERR_ONEDIM_ARRAYS_ONLY: + result = "Must be a one-dimensional array"; + break; + + // + case ERR_SERIES_ARRAY: + result = "Timeseries cannot be used"; + break; + + // + case ERR_DOUBLE_ARRAY_ONLY: + result = "Must be an array of type double"; + break; + + // + case ERR_FLOAT_ARRAY_ONLY: + result = "Must be an array of type float"; + break; + + // + case ERR_LONG_ARRAY_ONLY: + result = "Must be an array of type long"; + break; + + // + case ERR_INT_ARRAY_ONLY: + result = "Must be an array of type int"; + break; + + // + case ERR_SHORT_ARRAY_ONLY: + result = "Must be an array of type short"; + break; + + // + case ERR_CHAR_ARRAY_ONLY: + result = "Must be an array of type char"; + break; + + // + //--- Operations with OpenCL + + // + case ERR_OPENCL_NOT_SUPPORTED: + result = "OpenCL functions are not supported on this computer"; + break; + + // + case ERR_OPENCL_INTERNAL: + result = "Internal error occurred when running OpenCL"; + break; + + // + case ERR_OPENCL_INVALID_HANDLE: + result = "Invalid OpenCL handle"; + break; + + // + case ERR_OPENCL_CONTEXT_CREATE: + result = "Error creating the OpenCL context"; + break; + + // + case ERR_OPENCL_QUEUE_CREATE: + result = "Failed to create a run queue in OpenCL"; + break; + + // + case ERR_OPENCL_PROGRAM_CREATE: + result = "Error occurred when compiling an OpenCL program"; + break; + + // + case ERR_OPENCL_TOO_LONG_KERNEL_NAME: + result = "Too long kernel name (OpenCL kernel)"; + break; + + // + case ERR_OPENCL_KERNEL_CREATE: + result = "Error creating an OpenCL kernel"; + break; + + // + case ERR_OPENCL_SET_KERNEL_PARAMETER: + result = "Error occurred when setting parameters for the OpenCL kernel"; + break; + + // + case ERR_OPENCL_EXECUTE: + result = "OpenCL program runtime error"; + break; + + // + case ERR_OPENCL_WRONG_BUFFER_SIZE: + result = "Invalid size of the OpenCL buffer"; + break; + + // + case ERR_OPENCL_WRONG_BUFFER_OFFSET: + result = "Invalid offset in the OpenCL buffer"; + break; + + // + case ERR_OPENCL_BUFFER_CREATE: + result = "Failed to create and OpenCL buffer"; + break; + + // + //--- User-Defined Errors + default: + result = "UNKNOWN Erro ..."; + break; + } + + // + return result; +} + +// +// Retrieve Specified Error Code Description ... +string GetTradeServerReturnCodeDescription(int return_code) +{ + // + string result = ""; + + // + switch (return_code) + { + // + case TRADE_RETCODE_REQUOTE: + result = "Requote"; + break; + + // + case TRADE_RETCODE_REJECT: + result = "Request rejected"; + break; + + // + case TRADE_RETCODE_CANCEL: + result = "Request canceled by trader"; + break; + + // + case TRADE_RETCODE_PLACED: + result = "Order placed"; + break; + + // + case TRADE_RETCODE_DONE: + result = "Request completed"; + break; + + // + case TRADE_RETCODE_DONE_PARTIAL: + result = "Only part of the request was completed"; + break; + + // + case TRADE_RETCODE_ERROR: + result = "Request processing error"; + break; + + // + case TRADE_RETCODE_TIMEOUT: + result = "Request canceled by timeout"; + break; + + // + case TRADE_RETCODE_INVALID: + result = "Invalid request"; + break; + + // + case TRADE_RETCODE_INVALID_VOLUME: + result = "Invalid volume in the request"; + break; + + // + case TRADE_RETCODE_INVALID_PRICE: + result = "Invalid price in the request"; + break; + + // + case TRADE_RETCODE_INVALID_STOPS: + result = "Invalid stops in the request"; + break; + + // + case TRADE_RETCODE_TRADE_DISABLED: + result = "Trade is disabled"; + break; + + // + case TRADE_RETCODE_MARKET_CLOSED: + result = "Market is closed"; + break; + + // + case TRADE_RETCODE_NO_MONEY: + result = "There is not enough money to complete the request"; + break; + + // + case TRADE_RETCODE_PRICE_CHANGED: + result = "Prices changed"; + break; + + // + case TRADE_RETCODE_PRICE_OFF: + result = "There are no quotes to process the request"; + break; + + // + case TRADE_RETCODE_INVALID_EXPIRATION: + result = "Invalid order expiration date in the request"; + break; + + // + case TRADE_RETCODE_ORDER_CHANGED: + result = "Order state changed"; + break; + + // + case TRADE_RETCODE_TOO_MANY_REQUESTS: + result = "Too frequent requests"; + break; + + // + case TRADE_RETCODE_NO_CHANGES: + result = "No changes in request"; + break; + + // + case TRADE_RETCODE_SERVER_DISABLES_AT: + result = "Autotrading disabled by server"; + break; + + // + case TRADE_RETCODE_CLIENT_DISABLES_AT: + result = "Autotrading disabled by client terminal"; + break; + + // + case TRADE_RETCODE_LOCKED: + result = "Request locked for processing"; + break; + + // + case TRADE_RETCODE_FROZEN: + result = "Order or position frozen"; + break; + + // + case TRADE_RETCODE_INVALID_FILL: + result = "Invalid order filling type"; + break; + + // + case TRADE_RETCODE_CONNECTION: + result = "No connection with the trade server"; + break; + + // + case TRADE_RETCODE_ONLY_REAL: + result = "Operation is allowed only for live accounts"; + break; + + // + case TRADE_RETCODE_LIMIT_ORDERS: + result = "The number of pending orders has reached the limit"; + break; + + // + case TRADE_RETCODE_LIMIT_VOLUME: + result = "The volume of orders and positions for the symbol has reached the limit"; + break; + + // + default: + result = "Invalid return code of the trade server"; + break; + } + + // + return result; +} diff --git a/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.models.lib.ex5 b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.models.lib.ex5 new file mode 100644 index 0000000..5b77b3d Binary files /dev/null and b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.models.lib.ex5 differ diff --git a/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.models.lib.mq5 b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.models.lib.mq5 new file mode 100644 index 0000000..ad75c82 --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.models.lib.mq5 @@ -0,0 +1,326 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Models Library +// --------------------------------------- +// Name: XModels +// Description: provides all required models ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Inputs ... +// + +// +// END Inputs ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// + +// +// How To Calculate Static Volume ... +enum ENUM_STATIC_VOLUME_METHODS +{ + // + // Based On Deposit ... + X_STATIC_VOLUME_BASED_ON_DEPOSIT, + // + // Based On Balance ... + X_STATIC_VOLUME_BASED_ON_BALANCE, +}; + +// +// START Model Definitions ... +// + +// +// OHCL Candel Model ... +enum ENUM_X_PRICE +{ + X_PRICE_HIGH, + X_PRICE_OPEN, + X_PRICE_CLOSE, + X_PRICE_LOW +}; + +// +// Swing Types Enum ... +enum ENUM_X_SWING_TYPE +{ + X_NO_SWING = 0, + X_SWING_HIGH = 1, + X_SWING_LOW = -1, +}; + +// +// Select Positions Type ... +enum ENUM_X_POSITION_SELECT_METHODS +{ + X_POSITION_SELECT_NONE, // None + X_POSITION_SELECT_MAX, // Max + X_POSITION_SELECT_MIN, // Min + X_POSITION_SELECT_ALL, // Min +}; + +// +// XPERIOD Calculation Method ... +enum ENUM_X_PERIOD_METHOD +{ + // + X_PERIOD_NOTHING, // Nothing + X_PERIOD_AUTO, // Auto Select + X_PERIOD_MANUALLY // Manually +}; + +// +enum ENUM_X_MARKET_CYCLES +{ + // + X_MARKET_CYCLE_UNKNOWN, // Unknown Cycle + X_MARKET_CYCLE_SHORT, // Short Cycle + X_MARKET_CYCLE_MEDIUM, // Medium Cycle + X_MARKET_CYCLE_LONG, // Long Cycle + X_MARKET_CYCLE_HIND, // Hind Cycle +}; + +// +// Available Guard Action ... +enum ENUM_X_GUARD_ACTIONS +{ + X_GUARD_ACTION_NOTHING, // Nothing + X_GUARD_ACTION_HEDGE, // Hedge + X_GUARD_PARTIAL_CLOSE, // Partial Close + X_GUARD_ACTION_TRAIL_STOP, // Trail StopLoss + X_GUARD_ACTION_FORCE_CLOSE, // Force Close + X_GUARD_ACTION_ADD_SUPPORT_SIGNAL, // Add Support Signal + X_GUARD_ACTION_CANCEL_PENDING_ORDERS, // Cancel Pending Orders +}; + +// +// Model Guard Info ... +struct XGuard +{ + string symbol; + string provider; + ENUM_TIMEFRAMES period; + ENUM_POSITION_TYPE type; + ENUM_X_GUARD_ACTIONS action; + + // + double dblPayLoad; + string strPayload; +}; + +// +// Describe an Specific Candle ... +struct XOHCL +{ + // + double high; + double open; + double close; + double low; + + // + string ToString() + { + // + string result = ""; + + // + result = "XOHCL(O(" + (string)open + "),H(" + (string)high + "),C(" + (string)close + "),L(" + (string)low + "))"; + + // + return result; + } +}; + +// +// Model Support and Resistance +// for Specific Bar ... +struct XOHCLSupRes +{ + // + double res[]; + + // + double sup[]; +}; + +// +struct XValueChanged +{ + datetime at; + double from; + double to; +}; + +// +// Available Order Modes ... +enum ENUM_X_ORDER_MODES +{ + X_ORDER_MODE_MARKET = 0, // Market Order + X_ORDER_MODE_STOP = 1, // Pending Stop Order + X_ORDER_MODE_LIMIT = 2, // Pending Limit Order + X_ORDER_MODE_STOP_LIMIT = 3, // Pending Stop Limit Order +}; + +// +// Model a Signal ... +struct XSignal +{ + // + string providers[]; + + // + string symbol; + + // + ENUM_TIMEFRAMES period; + + // + ENUM_POSITION_TYPE type; + + // + ENUM_X_ORDER_MODES mode; + + // + double entry; + + // + double tp; + + // + double sl; + + // + double r2r; + + // + double volume; + + // + // Support Signals ... + XSignal supports[]; + + // + XOHCLSupRes supportResistances; +}; + +// +// EXTENSION Methods ... + +// +// Clear an Specific Signal Item ... +void Clean(XSignal &item) +{ + // + Clean(item.providers); + + // + Clean(item.supports); + + // + Clean(item.supportResistances); + + // + item.symbol = ""; + item.type = NULL; + item.mode = NULL; + item.period = NULL; + + // + item.tp = 0; + item.sl = 0; + item.r2r = 0; + item.entry = 0; + item.volume = 0; +} + +// +void Clean(XOHCLSupRes &item) +{ + Clean(item.sup); + Clean(item.res); +} + +template +void Add( + T &item, + T &buffer[]) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} + +template +void Clean(T &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} + +template +void Copy( + T &source[], // Source Buffer ... + T &dest[], // Dest Buffer ... + bool cleanDest = true // Force Clen Dest Buffer ... +) +{ + // + if (cleanDest) + { + Clean(dest); + } + + // + int sourceCount = ArraySize(source); + if (sourceCount <= 0) + { + return; + } + + // + for (int i = 0; i < sourceCount; i++) + { + // + T iSource = source[i]; + + // + Add( + iSource, + dest); + } +} + +// +// END Provided Functions ... +// diff --git a/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.seriallizer.lib.ex5 b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.seriallizer.lib.ex5 new file mode 100644 index 0000000..3ee28a8 Binary files /dev/null and b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.seriallizer.lib.ex5 differ diff --git a/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.seriallizer.lib.mq5 b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.seriallizer.lib.mq5 new file mode 100644 index 0000000..c1fdd52 --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.seriallizer.lib.mq5 @@ -0,0 +1,1326 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Seriallize Library +// --------------------------------------- +// Name: XSeriallizer +// Description: provides Seriallizing EA abilities ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +#include "../Libraries/x-saherelm.models.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xtrade.class.mq5" +#include "../Classes/x-saherelm.x121.provider.class.mq5" + +// +string XProviderToken = "PRV"; +string XSupportToken = "SP"; +string XSLTrailToken = "SLT"; +string XPeriodToken = "PR"; + +// +string XConfigToken = "XPV"; +string XItemSeparator = "|"; +string XItemContentSeparator = ","; + +// +string XFirstGenToken = "0"; + +// +// PERIOD ... + +// +// Detect a Comment has period or not ... +bool HasPeriod(string comment) +{ + // + bool result = false; + + // + if (StringLen(comment) == 0) + { + return result; + } + + // + int tokenPos = StringFind( + comment, + XPeriodToken); + result = tokenPos >= 0; + + // + return result; +} + +// +// Extract Period String ... +string ExtractPeriodString(string comment) +{ + // + string result = ""; + + // + bool hasPeriod = HasPeriod(comment); + if (!hasPeriod) + { + return result; + } + + // + result = ExtractString( + comment, + XPeriodToken + "(", + ")"); + + // + return result; +} + +// +// Extract Time Frame From Comment ... +ENUM_TIMEFRAMES ExtractPeriod(string comment) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + if (StringLen(comment) <= 0) + { + return result; + } + + // + string periodStr = ExtractPeriodString(comment); + if (StringLen(periodStr) <= 0) + { + return result; + } + + // + result = ToPeriod(periodStr); + + // + return result; +} + +// +// PROVIDER ... + +// +// Extract a Provider name if exists from a Comment ... +string ExtractProvider(string comment) +{ + // + string result = ""; + if (StringLen(comment) <= 0) + { + return result; + } + + // + result = ExtractString( + comment, + XProviderToken + "(", + ")"); + + // + return result; +} + +// +// Generate Provider String for Using in Positions Comment ... +// NOTE: if there is more than One Provider, it takes first +// provider as main and the others used to increase volume ... +string GenerateProvidersString(XSignal &signal) +{ + // + string result = ""; + + // + int providersCount = ArraySize(signal.providers); + if (providersCount <= 0) + { + return result; + } + + // + result = XProviderToken + "(" + signal.providers[0] + ")"; + + // + return result; +} + +// +// SLTRAIL ... + +// +string GenerateSLTrailComment(int level) +{ + // + string result = ""; + + // + if (level <= 0) + { + return result; + } + + // + result = XSLTrailToken + "(" + ToString(level) + ")"; + + // + return result; +} + +// +int ExtractSLTrailLevel(string comment) +{ + // + int result = 0; + + // + if (StringLen(comment) == 0) + { + return result; + } + + // + string levelStr = ExtractString( + comment, + XSLTrailToken + "(", + ")"); + if (StringLen(levelStr) == 0) + { + return result; + } + + // + result = (int)levelStr; + + // + return result; +} + +// +string PrepareSLTrailComment( + const string comment // Original Position Comment ... +) +{ + // + string result = ""; + + // + if (StringLen(comment) == 0) + { + return result; + } + + // + int level = 0; + result = comment; + + // + // Check Comment Contains SL Trailing or not ... + int lastTrailLevel = ExtractSLTrailLevel(comment); + if (lastTrailLevel <= 0) + { + level++; + } + else + { + // + level = lastTrailLevel + 1; + string lastLevelStr = GenerateSLTrailComment(lastTrailLevel); + StringReplace( + result, + lastLevelStr, + ""); + } + + // + // Generate level Comment ... + string levelStr = GenerateSLTrailComment(level); + result += levelStr; + + // + return result; +} + +// +// SUPPORT ... + +// +// Generate Specific Position's Support Comment +// index is number of Supports ... +string GenerateSupportSignalComment( + ulong ticket, // Position/Order Ticket + int index // Support Index ... +) +{ + // + string result = ""; + + // + result = XSupportToken + "(" + (string)ticket + "," + ToString(index) + ")"; + + // + return result; +} + +// +// Extract Support Parameters String from specified Comment ... +string ExtractSupportParam(string comment) +{ + // + string result = ""; + if (StringLen(comment) <= 0) + { + return result; + } + + // + result = ExtractString( + comment, + XSupportToken + "(", + ")"); + + // + return result; +} + +// +// Extract Support Info as String array for Specific Comment ... +bool ExtractSupportParams( + string comment, // Specified Comment ... + string ¶ms[] // Hold Result ... +) +{ + // + bool result = false; + + // + string supParam = ExtractSupportParam(comment); + if (StringLen(supParam) == 0) + { + return result; + } + + // + SplitContent( + params, + supParam); + int paramsCount = ArraySize(params); + + // + result = paramsCount == 2; + + // + return result; +} + +// +// Extract Support Parent Ticket ... +ulong ExtractParentTicket(string comment) +{ + // + ulong result = 0; + + // + string params[]; + bool isSupport = ExtractSupportParams( + comment, + params); + if (!isSupport) + { + return result; + } + + // + result = (ulong)params[0]; + + // + return result; +} + +// +// Extract Support Index ... +int ExtractSupportIndex(string comment) +{ + // + int result = -1; + + // + string params[]; + bool isSupport = ExtractSupportParams( + comment, + params); + if (!isSupport) + { + return result; + } + + // + result = (int)params[1]; + + // + return result; +} + +// +// XCONFIG X121Provider Struct ... + +// +// Extract Signallers from User Input ... +int ExtractSignallers( + string &result[], // Hold Result + const string source // Source Content +) +{ + // + int mResult = 0; + + // + Clean(result); + + // + SplitContent( + result, + source); + + // + mResult = ArraySize(result); + + // + return mResult; +} + +// +// Validate Specified Provider Descriptor Model ... +bool IsValid(X121SignalProvider &item) +{ + // + bool result = false; + + // + result = + // + StringLen(item.symbol) > 0 && + item.period != NULL && + item.riskAmount > 0 + // + ; + + // + return result; +} + +// +// Compare Source item with Dest item to check their Same or not ... +bool IsSame( + X121SignalProvider &source, // Source Item + X121SignalProvider &dest // Dest Item +) +{ + // + bool result = false; + + // + bool isValidDest = IsValid(dest); + bool isValidSource = IsValid(source); + if (!isValidDest || + !isValidSource) + { + return result; + } + + // + result = + // + source.symbol == dest.symbol && + source.period == dest.period && + source.riskAmount == dest.riskAmount && + source.useRiskAmountAsStaticVolume == dest.useRiskAmountAsStaticVolume + // + ; + + // + return result; +} + +// +// Check Specified Provider Exists in a Collection or not ... +bool Contains( + X121SignalProvider &item, // Specified Item + X121SignalProvider &items[] // Given Collection +) +{ + // + bool result = false; + + // + int itemsCount = ArraySize(items); + if (itemsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < itemsCount; i++) + { + // + X121SignalProvider iProvider = items[i]; + + // + result = IsSame(item, iProvider); + if (result) + { + // + break; + } + } + + // + return result; +} + +// +// Extract Provider Descriptor Parts from given Source Input ... +int ExtractProviderDescriptorItems( + string &result[], // Hold Result + const string source // Source Descriptor +) +{ + // + int mResult = 0; + + // + Clean(result); + + // + SplitContent( + result, + source, + XItemSeparator); + + // + mResult = ArraySize(result); + + // + return mResult; +} + +// +// Extract Provider Descriptor Items Content from given Source Input ... +int ExtractProviderDescriptorItemsContent( + string &result[], // Hold Result + const string source // Source Descriptor +) +{ + // + int mResult = 0; + + // + Clean(result); + + // + SplitContent( + result, + source, + XItemContentSeparator); + + // + mResult = ArraySize(result); + + // + return mResult; +} + +// +// Validate and add provider to providers if not exists ... +bool AddProviderDescriptor( + X121SignalProvider &item, + X121SignalProvider &items[]) +{ + // + bool result = false; + + // + // Validate and add ... + result = IsValid(item); + if (!result) + { + return result; + } + + // + bool isExists = Contains( + item, + items); + if (isExists) + { + return result; + } + + // + result = true; + + // + Add( + item, + items); + + // + return result; +} + +// +// Extract Provider Descriptors from given Source Input ... +int ExtractProviderConfigurations( + X121SignalProvider &result[], // Hold Result + const string source, // Source String + const string defaultSignallers, // Default Available Signallers for Each Providers + const double defaultRiskAmount, // Default Risk Amount per Trade for Each Provider + const bool useRiskAmountAsStaticVolume = true // Use Provided Risk Amount as Static Volume +) +{ + // + int mResult = 0; + + // + Clean(result); + + // + // if there is no Pairs ... + // Check as One Model ... + string descriptors[]; + mResult = ExtractStrings( + descriptors, + source, + XConfigToken + "(", + ")"); + + // + // Retrieve Signallers ... + string defaultSignallersArr[]; + ExtractSignallers( + defaultSignallersArr, + defaultSignallers); + + // + if (mResult == 0) + { + // + // Here we Check given source String Length ... + // if it is bigger than zero we assuem it is one line descriptor ... + if (StringLen(source) > 0) + { + // + // One Model ... + Add( + source, + descriptors); + } + } + + // + // Each Provider Must Contains at least two things : + // - Asset; + int descriptorsCount = ArraySize(descriptors); + if (descriptorsCount > 0) + { + // + // Loop through descriptors to parse models ... + for (int i = 0; i < descriptorsCount; i++) + { + // + string iDescriptor = descriptors[i]; + + // + X121SignalProvider iProviderDescriptor; + iProviderDescriptor.symbol = ""; + iProviderDescriptor.period = NULL; + iProviderDescriptor.riskAmount = 0; + Clean(iProviderDescriptor.providers); + + // + string iParts[]; + int iPartsCount = ExtractProviderDescriptorItems( + iParts, + iDescriptor); + + // + // Check Parts Count ... + // Now we have to Decide How to Config Signal Providers using Parts ... + + // + // asset => default; + // period => default; + // risk amount => default; + // signallers => default; + // use as static volume => default; + if (iPartsCount == 0) + { + // + // Here we Instance as Current Config Descriptor ... + iProviderDescriptor.symbol = _Symbol; + iProviderDescriptor.period = _Period; + iProviderDescriptor.riskAmount = defaultRiskAmount; + iProviderDescriptor.useRiskAmountAsStaticVolume = useRiskAmountAsStaticVolume; + + // + // Add Default Signallers ... + Copy( + defaultSignallersArr, + iProviderDescriptor.providers); + + // + AddProviderDescriptor( + iProviderDescriptor, + result); + + // + continue; + } + + // + // asset => provided; + // period => default; + // risk amount => default; + // signallers => default; + // use as static volume => default; + if (iPartsCount == 1) + { + + // + iProviderDescriptor.period = _Period; + iProviderDescriptor.riskAmount = defaultRiskAmount; + iProviderDescriptor.useRiskAmountAsStaticVolume = useRiskAmountAsStaticVolume; + + // + // Add Default Signallers ... + Copy( + defaultSignallersArr, + iProviderDescriptor.providers); + + // + // Extract Provided Assets ... + string symbols[]; + int symbolsCount = ExtractProviderDescriptorItemsContent( + symbols, + iParts[0]); + for (int j = 0; j < symbolsCount; j++) + { + // + string jSymbol = symbols[j]; + + // + iProviderDescriptor.symbol = jSymbol; + + // + AddProviderDescriptor( + iProviderDescriptor, + result); + } + + // + continue; + } + + // + // asset => provided; + // period => provided; + // risk amount => default; + // signallers => default; + // use as static volume => default; + if (iPartsCount == 2) + { + // + iProviderDescriptor.riskAmount = defaultRiskAmount; + iProviderDescriptor.useRiskAmountAsStaticVolume = useRiskAmountAsStaticVolume; + + // + // Add Default Signallers ... + Copy( + defaultSignallersArr, + iProviderDescriptor.providers); + + // + // Extract Provided Assets ... + string symbols[]; + int symbolsCount = ExtractProviderDescriptorItemsContent( + symbols, + iParts[0]); + for (int j = 0; j < symbolsCount; j++) + { + // + string jSymbol = symbols[j]; + + // + iProviderDescriptor.symbol = jSymbol; + + // + // Extract Periods ... + string periods[]; + int periodsCount = ExtractProviderDescriptorItemsContent( + periods, + iParts[1]); + for (int k = 0; k < periodsCount; k++) + { + // + string kPeriodStr = periods[k]; + ENUM_TIMEFRAMES kPeriod = ToPeriod(kPeriodStr); + + // + iProviderDescriptor.period = kPeriod; + + // + AddProviderDescriptor( + iProviderDescriptor, + result); + } + } + + // + continue; + } + + // + // asset => provided; + // period => provided; + // risk amount => provided; + // signallers => default; + // use as static volume => default; + if (iPartsCount == 3) + { + // + iProviderDescriptor.useRiskAmountAsStaticVolume = useRiskAmountAsStaticVolume; + + // + // Add Default Signallers ... + Copy( + defaultSignallersArr, + iProviderDescriptor.providers); + + // + // Extract Provided Assets ... + string symbols[]; + int symbolsCount = ExtractProviderDescriptorItemsContent( + symbols, + iParts[0]); + + // + string riskAmounts[]; + int riskAmountsCount = ExtractProviderDescriptorItemsContent( + riskAmounts, + iParts[2]); + + // + for (int j = 0; j < symbolsCount; j++) + { + // + string jSymbol = symbols[j]; + + // + iProviderDescriptor.symbol = jSymbol; + + // + // Extract Periods ... + string periods[]; + int periodsCount = ExtractProviderDescriptorItemsContent( + periods, + iParts[1]); + for (int k = 0; k < periodsCount; k++) + { + // + string kPeriodStr = periods[k]; + ENUM_TIMEFRAMES kPeriod = ToPeriod(kPeriodStr); + + // + iProviderDescriptor.period = kPeriod; + + // + string selectedRiskAmount = + riskAmountsCount == 0 + ? ToString(defaultRiskAmount) + : riskAmountsCount == periodsCount + ? riskAmounts[k] + : riskAmounts[0]; + double riskAmount = (double)selectedRiskAmount; + iProviderDescriptor.riskAmount = riskAmount; + + // + AddProviderDescriptor( + iProviderDescriptor, + result); + } + } + + // + continue; + } + + // + // asset => provided; + // period => provided; + // risk amount => provided; + // signallers => provided; + // use as static volume => default; + if (iPartsCount == 4) + { + // + iProviderDescriptor.useRiskAmountAsStaticVolume = useRiskAmountAsStaticVolume; + + // + // Extract Signallers ... + string signallers[]; + int signallersCount = ExtractSignallers( + signallers, + iParts[3]); + if (signallersCount <= 0) + { + // + Copy( + defaultSignallersArr, + signallers); + } + + // + // Set Extracted Signallers in Provider Descriptor ... + Copy( + signallers, + iProviderDescriptor.providers); + + // + // + // Extract Provided Assets ... + string symbols[]; + int symbolsCount = ExtractProviderDescriptorItemsContent( + symbols, + iParts[0]); + + // + string riskAmounts[]; + int riskAmountsCount = ExtractProviderDescriptorItemsContent( + riskAmounts, + iParts[2]); + + // + for (int j = 0; j < symbolsCount; j++) + { + // + string jSymbol = symbols[j]; + + // + iProviderDescriptor.symbol = jSymbol; + + // + // Extract Periods ... + string periods[]; + int periodsCount = ExtractProviderDescriptorItemsContent( + periods, + iParts[1]); + for (int k = 0; k < periodsCount; k++) + { + // + string kPeriodStr = periods[k]; + ENUM_TIMEFRAMES kPeriod = ToPeriod(kPeriodStr); + + // + iProviderDescriptor.period = kPeriod; + + // + string selectedRiskAmount = + riskAmountsCount == 0 + ? ToString(defaultRiskAmount) + : riskAmountsCount == periodsCount + ? riskAmounts[k] + : riskAmounts[0]; + double riskAmount = (double)selectedRiskAmount; + iProviderDescriptor.riskAmount = riskAmount; + + // + AddProviderDescriptor( + iProviderDescriptor, + result); + } + } + + // + continue; + } + + // + // asset => provided; + // period => provided; + // risk amount => provided; + // signallers => provided; + // use as static volume => provided; + if (iPartsCount == 5) + { + // + // Extract Signallers ... + string signallers[]; + int signallersCount = ExtractSignallers( + signallers, + iParts[3]); + if (signallersCount <= 0) + { + // + Copy( + defaultSignallersArr, + signallers); + } + + // + // Set Extracted Signallers in Provider Descriptor ... + Copy( + signallers, + iProviderDescriptor.providers); + + // + // + // Extract Provided Assets ... + string symbols[]; + int symbolsCount = ExtractProviderDescriptorItemsContent( + symbols, + iParts[0]); + + // + string riskAmounts[]; + int riskAmountsCount = ExtractProviderDescriptorItemsContent( + riskAmounts, + iParts[2]); + + // + string useRiskAmountAsStaticVolumes[]; + int useRiskAmountAsStaticVolumesCount = ExtractProviderDescriptorItemsContent( + useRiskAmountAsStaticVolumes, + iParts[4]); + + // + for (int j = 0; j < symbolsCount; j++) + { + // + string jSymbol = symbols[j]; + + // + iProviderDescriptor.symbol = jSymbol; + + // + // Extract Periods ... + string periods[]; + int periodsCount = ExtractProviderDescriptorItemsContent( + periods, + iParts[1]); + for (int k = 0; k < periodsCount; k++) + { + // + string kPeriodStr = periods[k]; + ENUM_TIMEFRAMES kPeriod = ToPeriod(kPeriodStr); + + // + iProviderDescriptor.period = kPeriod; + + // + string selectedRiskAmount = + riskAmountsCount == 0 + ? ToString(defaultRiskAmount) + : riskAmountsCount == periodsCount + ? riskAmounts[k] + : riskAmounts[0]; + double riskAmount = (double)selectedRiskAmount; + iProviderDescriptor.riskAmount = riskAmount; + + // + string selectedUseRiskAmountAsStaticVolume = + useRiskAmountAsStaticVolumesCount == 0 + ? ToString(useRiskAmountAsStaticVolume) + : useRiskAmountAsStaticVolumesCount == periodsCount + ? useRiskAmountAsStaticVolumes[k] + : useRiskAmountAsStaticVolumes[0]; + bool useRiskAmountAsStaticVolume = ToBoolean(selectedUseRiskAmountAsStaticVolume); + iProviderDescriptor.useRiskAmountAsStaticVolume = useRiskAmountAsStaticVolume; + + // + AddProviderDescriptor( + iProviderDescriptor, + result); + } + } + + // + continue; + } + } + } + else + { + // + // Use All Defaults to Create One Instance ... + X121SignalProvider iProviderDescriptor; + iProviderDescriptor.symbol = ""; + iProviderDescriptor.period = NULL; + iProviderDescriptor.riskAmount = 0; + Clean(iProviderDescriptor.providers); + + // + iProviderDescriptor.symbol = _Symbol; + iProviderDescriptor.period = _Period; + iProviderDescriptor.riskAmount = defaultRiskAmount; + iProviderDescriptor.useRiskAmountAsStaticVolume = useRiskAmountAsStaticVolume; + + // + // Add Default Signallers ... + Copy( + defaultSignallersArr, + iProviderDescriptor.providers); + + // + AddProviderDescriptor( + iProviderDescriptor, + result); + } + + // + mResult = ArraySize(result); + + // + return mResult; +} + +// +// START XEQM Support ... +// + +// +string XEQMSupportToken = "XEQM"; + +// +// Generate String Tag for EQM Support Signals ... +string GenerateXEQMSupportComment() +{ + // + string result = XEQMSupportToken; + + // + return result; +} + +// +// Check a Comment belongs to a EQM Support or not ... +bool IsEQMSupport(string comment) +{ + // + bool result = false; + + // + if (StringLen(comment) <= 0) + { + return result; + } + + // + int tokenPosition = StringFind( + comment, + XEQMSupportToken); + result = tokenPosition >= 0; + + // + return result; +} + +// +// Select EQM Support Orders ... +int GetEQMSupportOrders( + XOrder &supports[], // Hold Result ... + XOrder &orders[], // List of All Orders ... + ENUM_TIMEFRAMES period = NULL // Specified Period ... +) +{ + // + int result = 0; + + // + // Cleanup Array ... + Clean(supports); + + // + // Count Orders ... + int ordersCount = ArraySize(orders); + if (ordersCount <= 0) + { + return result; + } + + // + // Loop through Orders ... + for (int i = 0; i < ordersCount; i++) + { + // + // Select Indexed Order ... + XOrder iOrder = orders[i]; + + // + // Check Order is Support or not ... + bool isSupport = IsEQMSupport(iOrder.comment); + if (!isSupport) + { + continue; + } + + // + // Check Order is not Triggered ... + if (iOrder.state != ORDER_STATE_PLACED) + { + continue; + } + + // + // Check Period ... + if (period != NULL && iOrder.period != period) + { + continue; + } + + // + // we now sure this order is EQM Support ... + Add( + iOrder, + supports); + } + + // + // Count Result ... + result = ArraySize(supports); + + // + return result; +} + +// +// Select EQM Support Positions ... +int GetEQMSupportPositions( + XPosition &supports[], // Hold Result ... + XPosition &positions[], // List of All Positions ... + ENUM_TIMEFRAMES period = NULL // Specified Period ... +) +{ + // + int result = 0; + + // + // Cleanup Array ... + Clean(supports); + + // + // Count Positions ... + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return result; + } + + // + // Loop through Positions ... + for (int i = 0; i < positionsCount; i++) + { + // + // Select Indexed Position ... + XPosition iPosition = positions[i]; + + // + // Check Position is Support or not ... + bool isSupport = IsEQMSupport(iPosition.comment); + if (!isSupport) + { + continue; + } + + // + // Check Period ... + if (period != NULL && iPosition.period != period) + { + continue; + } + + // + // we now sure this order is EQM Support ... + Add( + iPosition, + supports); + } + + // + // Count Result ... + result = ArraySize(supports); + + // + return result; +} + +// +// END XEQM Support ... +// + +// +// START FirstGen ... +// + +// +string GenerateFirstGenIdentifier(const string signaller) +{ + // + string result = ""; + + // + if (StringLen(signaller) <= 0) + { + return result; + } + + // + return signaller + XFirstGenToken; + + // + return result; +} + +// +bool IsFirstGenOf( + const string signaller, // Specified Signaller + const string comment // Comment +) +{ + // + bool result = false; + + // + string id = GenerateFirstGenIdentifier(signaller); + + // + int idPos = StringFind( + comment, + id + ); + result = idPos >= 0; + + // + return result; +} + +// +// END FirstGen ... +// \ No newline at end of file diff --git a/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.x121.condition.parser.lib.mq5 b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.x121.condition.parser.lib.mq5 new file mode 100644 index 0000000..8bb775b --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.x121.condition.parser.lib.mq5 @@ -0,0 +1,3841 @@ +//////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X12 Conditions Parser Library +// ----------------------------------------------------- +// Name: X121ConditionsParser +// Description: provides Market Conditions +// Parsing Requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Libraries/x-saherelm.models.lib.mq5" +#include "../Classes/x-saherelm.x121.provider.class.mq5" + +// +// START Functions ... +// + +// +// PARSE STATES ... +// + +// +// SSLC ... +// + +// +bool IsSSLCBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.sslcUps[index] > conditions.xmanInfo.sslcDowns[index] + // + ; + + // + return result; +} + +// +bool IsSSLCSwitchedToBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSSLCBullish(conditions, index) && + !IsSSLCBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsSSLCBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.sslcUps[index] < conditions.xmanInfo.sslcDowns[index] + // + ; + + // + return result; +} + +// +bool IsSSLCSwitchedToBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSSLCBearish(conditions, index) && + !IsSSLCBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// HULL ... +// + +// +bool IsHullBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHullUpBullish(conditions, index) && + IsHullDownBullish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsHullSwitchedBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHullBullish(conditions, index) && + !IsHullBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsHullBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHullUpBearish(conditions, index) && + IsHullDownBearish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsHullSwitchedBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHullBearish(conditions, index) && + !IsHullBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// UP ... + +// +// BULLISH ... + +// +bool IsHullUpBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hullUps[index] > conditions.xmanInfo.hullUps[index + 1] + // + ; + + // + return result; +} + +// +bool IsHullUpSwitchedToBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHullUpBullish(conditions, index) && + !IsHullUpBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// BEARISH ... + +// +bool IsHullUpBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hullUps[index] < conditions.xmanInfo.hullUps[index + 1] + // + ; + + // + return result; +} + +// +bool IsHullUpSwitchedToBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHullUpBearish(conditions, index) && + !IsHullUpBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// DOWN ... + +// +// BULLISH ... + +// +bool IsHullDownBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hullDowns[index] > conditions.xmanInfo.hullDowns[index + 1] + // + ; + + // + return result; +} + +// +bool IsHullDownSwitchedToBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHullDownBullish(conditions, index) && + !IsHullDownBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// BEARISH ... + +// +bool IsHullDownBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hullDowns[index] < conditions.xmanInfo.hullDowns[index + 1] + // + ; + + // + return result; +} + +// +bool IsHullDownSwitchedToBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHullDownBearish(conditions, index) && + !IsHullDownBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// TREND ... +// + +// +// Check Trend Bullish ... +bool IsTrendBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.candles[index].low > conditions.xmanInfo.trends[index] + // + ; + + // + return result; +} + +// +// Check Trend Switched To Bullish ... +bool IsTrendSwitchedToBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsTrendBullish(conditions, index) && + !IsTrendBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// Check Trend Bearish ... +bool IsTrendBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.candles[index].high < conditions.xmanInfo.trends[index] + // + ; + + // + return result; +} + +// +// Check Trend Switched To Bearish ... +bool IsTrendSwitchedToBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsTrendBearish(conditions, index) && + !IsTrendBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// RIBBON ... +// + +// +double GetRibbonMax( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + double result = 0; + + // + result = MathMax(conditions.xmanInfo.ribbon1s[index], conditions.xmanInfo.ribbon2s[index]); + result = MathMax(result, conditions.xmanInfo.ribbon3s[index]); + result = MathMax(result, conditions.xmanInfo.ribbon4s[index]); + result = MathMax(result, conditions.xmanInfo.ribbon5s[index]); + result = MathMax(result, conditions.xmanInfo.ribbon6s[index]); + + // + return result; +} + +// +double GetRibbonMin( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + double result = 0; + + // + result = MathMin(conditions.xmanInfo.ribbon1s[index], conditions.xmanInfo.ribbon2s[index]); + result = MathMin(result, conditions.xmanInfo.ribbon3s[index]); + result = MathMin(result, conditions.xmanInfo.ribbon4s[index]); + result = MathMin(result, conditions.xmanInfo.ribbon5s[index]); + result = MathMin(result, conditions.xmanInfo.ribbon6s[index]); + + // + return result; +} + +// +// Check Ribbon States ... +// Working With Price and Ribbon Values ... +bool IsRibbonBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.candles[index].low > conditions.xmanInfo.ribbon1s[index] && + conditions.candles[index].low > conditions.xmanInfo.ribbon2s[index] && + conditions.candles[index].low > conditions.xmanInfo.ribbon3s[index] && + conditions.candles[index].low > conditions.xmanInfo.ribbon4s[index] && + conditions.candles[index].low > conditions.xmanInfo.ribbon5s[index] && + conditions.candles[index].low > conditions.xmanInfo.ribbon6s[index] + // + ; + + // + return result; +} + +// +// Check Ribbons Sequntial Statements ... +// Working with Price and Ribbon Values and also Ribbon Orders +bool IsRibbonOrderBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsRibbonBullish(conditions, index) + // + && + // + GetRibbonMax(conditions, index) == conditions.xmanInfo.ribbon1s[index] + // + && + // + GetRibbonMin(conditions, index) == conditions.xmanInfo.ribbon6s[index] + // + ; + + // + return result; +} + +// +bool IsRibbonSwitchedToBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsRibbonBullish(conditions, index) && + !IsRibbonBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// Check Ribbons Sequntial Statements ... +bool IsRibbonOrderSwitchedToBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsRibbonOrderBullish(conditions, index) && + !IsRibbonOrderBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// Check Ribbon States ... +// Working With Price and Ribbon Values ... +bool IsRibbonBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.candles[index].high < conditions.xmanInfo.ribbon1s[index] && + conditions.candles[index].high < conditions.xmanInfo.ribbon2s[index] && + conditions.candles[index].high < conditions.xmanInfo.ribbon3s[index] && + conditions.candles[index].high < conditions.xmanInfo.ribbon4s[index] && + conditions.candles[index].high < conditions.xmanInfo.ribbon5s[index] && + conditions.candles[index].high < conditions.xmanInfo.ribbon6s[index] + // + ; + + // + return result; +} + +// +// Check Ribbons Sequntial Statements ... +// Working with Price and Ribbon Values and also Ribbon Orders +bool IsRibbonOrderBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsRibbonBearish(conditions, index) + // + && + // + GetRibbonMax(conditions, index) == conditions.xmanInfo.ribbon1s[index] + // + && + // + GetRibbonMin(conditions, index) == conditions.xmanInfo.ribbon6s[index] + // + ; + + // + return result; +} + +// +bool IsRibbonSwitchedToBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsRibbonBearish(conditions, index) && + !IsRibbonBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// Check Ribbons Sequntial Statements ... +bool IsRibbonOrderSwitchedToBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsRibbonOrderBearish(conditions, index) && + !IsRibbonOrderBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// PEAKS and VALES and Levels ... +// + +// +// Check Peak Same as Last ... +bool IsPeakSameAs( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0, // Array Index + int length = 5 // Comparing Period +) +{ + // + bool result = false; + + // + if (length <= 0) + { + return result; + } + + // + double selected = conditions.xmanInfo.peaks[index]; + + // + int start = index + 1; + int end = start + length; + + // + int verified = 0; + for (int i = start; i < end; i++) + { + // + double iValue = conditions.xmanInfo.peaks[i]; + + // + if (iValue == selected) + { + verified++; + } + } + + // + result = verified == length; + + // + return result; +} + +// +// Check New Peaks Happens ... +bool IsNewPeak( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.peaks[index] != EMPTY_VALUE && + conditions.xmanInfo.peaks[index] != conditions.xmanInfo.peaks[index + 1] + // + ; + + // + return result; +} + +// +// Check New Peaks Happens Over Last ... +bool IsNewPeakOverLast( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsNewPeak(conditions, index) && + conditions.xmanInfo.peaks[index] > conditions.xmanInfo.peaks[index + 1] + // + ; + + // + return result; +} + +// +// Check New Peaks Happens Under Last ... +bool IsNewPeakUnderLast( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsNewPeak(conditions, index) && + conditions.xmanInfo.peaks[index] < conditions.xmanInfo.peaks[index + 1] + // + ; + + // + return result; +} + +// +// Check Valse Same as Last ... +bool IsValeSameAs( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0, // Array Index + int length = 5 // Comparing Period +) +{ + // + bool result = false; + + // + if (length <= 0) + { + return result; + } + + // + double selected = conditions.xmanInfo.vales[index]; + + // + int start = index + 1; + int end = start + length; + + // + int verified = 0; + for (int i = start; i < end; i++) + { + // + double iValue = conditions.xmanInfo.vales[i]; + + // + if (iValue == selected) + { + verified++; + } + } + + // + result = verified == length; + + // + return result; +} + +// +// Check New Vales Happens ... +bool IsNewVale( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.vales[index] != EMPTY_VALUE && + conditions.xmanInfo.vales[index] != conditions.xmanInfo.vales[index + 1] + // + ; + + // + return result; +} + +// +// Check New Vales Happens Over Last ... +bool IsNewValeOverLast( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsNewVale(conditions, index) && + conditions.xmanInfo.vales[index] > conditions.xmanInfo.vales[index + 1] + // + ; + + // + return result; +} + +// +// Check New Vales Happens Under Last ... +bool IsNewValeUnderLast( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsNewVale(conditions, index) && + conditions.xmanInfo.vales[index] < conditions.xmanInfo.vales[index + 1] + // + ; + + // + return result; +} + +// +// Check Finbonacci Increased ... +bool IsFiboIncreased( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.fibLevel1s[index] > conditions.xmanInfo.fibLevel1s[index + 1] && + conditions.xmanInfo.fibLevel2s[index] > conditions.xmanInfo.fibLevel2s[index + 1] && + conditions.xmanInfo.fibLevel3s[index] > conditions.xmanInfo.fibLevel3s[index + 1] && + conditions.xmanInfo.fibLevel4s[index] > conditions.xmanInfo.fibLevel4s[index + 1] && + conditions.xmanInfo.fibLevel5s[index] > conditions.xmanInfo.fibLevel5s[index + 1] + // + ; + + // + return result; +} + +// +// Check Fibonacci Decreased ... +bool IsFiboDecreased( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.fibLevel1s[index] < conditions.xmanInfo.fibLevel1s[index + 1] && + conditions.xmanInfo.fibLevel2s[index] < conditions.xmanInfo.fibLevel2s[index + 1] && + conditions.xmanInfo.fibLevel3s[index] < conditions.xmanInfo.fibLevel3s[index + 1] && + conditions.xmanInfo.fibLevel4s[index] < conditions.xmanInfo.fibLevel4s[index + 1] && + conditions.xmanInfo.fibLevel5s[index] < conditions.xmanInfo.fibLevel5s[index + 1] + // + ; + + // + return result; +} + +// +// Check Fibonacci Crossed ... +bool IsFiboCrossed( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.fibLevel1s[index] == conditions.xmanInfo.fibLevel2s[index] || + conditions.xmanInfo.fibLevel1s[index] == conditions.xmanInfo.fibLevel3s[index] || + conditions.xmanInfo.fibLevel1s[index] == conditions.xmanInfo.fibLevel4s[index] || + conditions.xmanInfo.fibLevel1s[index] == conditions.xmanInfo.fibLevel5s[index] || + conditions.xmanInfo.fibLevel2s[index] == conditions.xmanInfo.fibLevel3s[index] || + conditions.xmanInfo.fibLevel2s[index] == conditions.xmanInfo.fibLevel4s[index] || + conditions.xmanInfo.fibLevel2s[index] == conditions.xmanInfo.fibLevel5s[index] || + conditions.xmanInfo.fibLevel3s[index] == conditions.xmanInfo.fibLevel4s[index] || + conditions.xmanInfo.fibLevel3s[index] == conditions.xmanInfo.fibLevel5s[index] || + conditions.xmanInfo.fibLevel4s[index] == conditions.xmanInfo.fibLevel5s[index] + // + ; + + // + return result; +} + +// +// Check Fibonacci Section Changes ... +bool IsFiboSectionChanged( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + (IsNewPeakUnderLast(conditions, index) && + IsFiboDecreased(conditions, index)) + // + || + // + (IsNewValeOverLast(conditions, index) && + IsFiboIncreased(conditions, index)) + // + ; + + // + return result; +} + +// +// Market Cycles ... + +// +// ALL Cycles ... + +// +bool IsCyclesBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCBullish(conditions, index) && + IsMCBullish(conditions, index) && + IsLCBullish(conditions, index) && + IsHCBullish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsCyclesSwitchedToBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsCyclesBullish(conditions, index) && + !IsCyclesBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsCyclesBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCBearish(conditions, index) && + IsMCBearish(conditions, index) && + IsLCBearish(conditions, index) && + IsHCBearish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsCyclesSwitchedToBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsCyclesBearish(conditions, index) && + !IsCyclesBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsCyclesLowBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCLowBullish(conditions, index) && + IsMCLowBullish(conditions, index) && + IsLCLowBullish(conditions, index) && + IsHCLowBullish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsCyclesLowSwitchedToBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsCyclesLowBullish(conditions, index) && + !IsCyclesLowBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsCyclesLowBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCLowBearish(conditions, index) && + IsMCLowBearish(conditions, index) && + IsLCLowBearish(conditions, index) && + IsHCLowBearish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsCyclesLowSwitchedToBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsCyclesLowBearish(conditions, index) && + !IsCyclesLowBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsCyclesHighBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCHighBullish(conditions, index) && + IsMCHighBullish(conditions, index) && + IsLCHighBullish(conditions, index) && + IsHCHighBullish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsCyclesHighSwitchedToBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsCyclesHighBullish(conditions, index) && + !IsCyclesHighBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsCyclesHighBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCHighBearish(conditions, index) && + IsMCHighBearish(conditions, index) && + IsLCHighBearish(conditions, index) && + IsHCHighBearish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsCyclesHighSwitchedToBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsCyclesHighBearish(conditions, index) && + !IsCyclesHighBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// INHIND Cycles ... + +// +bool IsInHindCyclesBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCBullish(conditions, index) && + IsMCBullish(conditions, index) && + IsLCBullish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsInHindCyclesSwitchedToBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsInHindCyclesBullish(conditions, index) && + !IsInHindCyclesBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsInHindCyclesBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCBearish(conditions, index) && + IsMCBearish(conditions, index) && + IsLCBearish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsInHindCyclesSwitchedToBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsInHindCyclesBearish(conditions, index) && + !IsInHindCyclesBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsInHindCyclesLowBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCLowBullish(conditions, index) && + IsMCLowBullish(conditions, index) && + IsLCLowBullish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsInHindCyclesLowSwitchedToBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsInHindCyclesLowBullish(conditions, index) && + !IsInHindCyclesLowBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsInHindCyclesHighBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCHighBullish(conditions, index) && + IsMCHighBullish(conditions, index) && + IsLCHighBullish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsInHindCyclesHighSwitchedToBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsInHindCyclesHighBullish(conditions, index) && + !IsInHindCyclesHighBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// INLONG Cycles ... + +// +bool IsInLongCyclesBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCBullish(conditions, index) && + IsMCBullish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsInLongCyclesSwitchedToBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsInLongCyclesBullish(conditions, index) && + !IsInLongCyclesBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsInLongCyclesBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCBearish(conditions, index) && + IsMCBearish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsInLongCyclesSwitchedToBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsInLongCyclesBearish(conditions, index) && + !IsInLongCyclesBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// SHORT ... + +// +bool IsSCBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCHighBullish(conditions, index) && + IsSCLowBullish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsSCSwitchedToBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCBullish(conditions, index) && + !IsSCBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsSCBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCHighBearish(conditions, index) && + IsSCLowBearish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsSCSwitchedToBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCBearish(conditions, index) && + !IsSCBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// SHORT HIGH ... + +// +bool IsSCHighBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.sHHs[index] > conditions.xmanInfo.sHHs[index + 1] + // + ; + + // + return result; +} + +// +bool IsSCHighSwitchedBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCHighBullish(conditions, index) && + !IsSCHighBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsSCHighBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.sHHs[index] < conditions.xmanInfo.sHHs[index + 1] + // + ; + + // + return result; +} + +// +bool IsSCHighSwitchedToBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCHighBearish(conditions, index) && + !IsSCHighBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// SHORT LOW ... + +// +bool IsSCLowBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.sLLs[index] > conditions.xmanInfo.sLLs[index + 1] + // + ; + + // + return result; +} + +// +bool IsSCLowSwitchedBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCLowBullish(conditions, index) && + !IsSCLowBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsSCLowBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.sLLs[index] < conditions.xmanInfo.sLLs[index + 1] + // + ; + + // + return result; +} + +// +bool IsSCLowSwitchedToBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCLowBearish(conditions, index) && + !IsSCLowBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// MEDIUM ... + +// +bool IsMCBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsMCHighBullish(conditions, index) && + IsMCLowBullish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsMCSwitchedToBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsMCBullish(conditions, index) && + !IsMCBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsMCBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsMCHighBearish(conditions, index) && + IsMCLowBearish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsMCSwitchedToBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsMCBearish(conditions, index) && + !IsMCBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// MEDIUM HIGH ... + +// +bool IsMCHighBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.mHHs[index] > conditions.xmanInfo.mHHs[index + 1] + // + ; + + // + return result; +} + +// +bool IsMCHighSwitchedBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsMCHighBullish(conditions, index) && + !IsMCHighBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsMCHighBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.mHHs[index] < conditions.xmanInfo.mHHs[index + 1] + // + ; + + // + return result; +} + +// +bool IsMCHighSwitchedToBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsMCHighBearish(conditions, index) && + !IsMCHighBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// MEDIUM LOW ... + +// +bool IsMCLowBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.mLLs[index] > conditions.xmanInfo.mLLs[index + 1] + // + ; + + // + return result; +} + +// +bool IsMCLowSwitchedBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsMCLowBullish(conditions, index) && + !IsMCLowBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsMCLowBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.mLLs[index] < conditions.xmanInfo.mLLs[index + 1] + // + ; + + // + return result; +} + +// +bool IsMCLowSwitchedToBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsMCLowBearish(conditions, index) && + !IsMCLowBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// LONG ... + +// +bool IsLCBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsLCHighBullish(conditions, index) && + IsLCLowBullish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsLCSwitchedToBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsLCBullish(conditions, index) && + !IsLCBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsLCBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsLCHighBearish(conditions, index) && + IsLCLowBearish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsLCSwitchedToBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsLCBearish(conditions, index) && + !IsLCBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// LONG HIGH ... + +// +bool IsLCHighBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.lHHs[index] > conditions.xmanInfo.lHHs[index + 1] + // + ; + + // + return result; +} + +// +bool IsLCHighSwitchedBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsLCHighBullish(conditions, index) && + !IsLCHighBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsLCHighBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.lHHs[index] < conditions.xmanInfo.lHHs[index + 1] + // + ; + + // + return result; +} + +// +bool IsLCHighSwitchedToBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsLCHighBearish(conditions, index) && + !IsLCHighBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// LONG LOW ... + +// +bool IsLCLowBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.lLLs[index] > conditions.xmanInfo.lLLs[index + 1] + // + ; + + // + return result; +} + +// +bool IsLCLowSwitchedBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsLCLowBullish(conditions, index) && + !IsLCLowBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsLCLowBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.lLLs[index] < conditions.xmanInfo.lLLs[index + 1] + // + ; + + // + return result; +} + +// +bool IsLCLowSwitchedToBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsLCLowBearish(conditions, index) && + !IsLCLowBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// HIND ... + +// +bool IsHCBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHCHighBullish(conditions, index) && + IsHCLowBullish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsHCSwitchedToBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHCBullish(conditions, index) && + !IsHCBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsHCBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHCHighBearish(conditions, index) && + IsHCLowBearish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsHCSwitchedToBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHCBearish(conditions, index) && + !IsHCBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// HIND HIGH ... + +// +bool IsHCHighBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hHHs[index] > conditions.xmanInfo.hHHs[index + 1] + // + ; + + // + return result; +} + +// +bool IsHCHighSwitchedBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHCHighBullish(conditions, index) && + !IsHCHighBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsHCHighBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hHHs[index] < conditions.xmanInfo.hHHs[index + 1] + // + ; + + // + return result; +} + +// +bool IsHCHighSwitchedToBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHCHighBearish(conditions, index) && + !IsHCHighBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// HIND LOW ... + +// +bool IsHCLowBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hLLs[index] > conditions.xmanInfo.hLLs[index + 1] + // + ; + + // + return result; +} + +// +bool IsHCLowSwitchedBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHCLowBullish(conditions, index) && + !IsHCLowBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsHCLowBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hLLs[index] < conditions.xmanInfo.hLLs[index + 1] + // + ; + + // + return result; +} + +// +bool IsHCLowSwitchedToBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHCLowBearish(conditions, index) && + !IsHCLowBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// XHK XSMHK ... + +// +double GetHKMax( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0, // Array Index + bool ignoreShadows = false // Ignore Shaddows +) +{ + // + double result = 0; + + // + result = MathMax(conditions.xmanInfo.hkOpens[index], conditions.xmanInfo.hkCloses[index]); + if (!ignoreShadows) + { + // + double selectedShadow = MathMax(conditions.xmanInfo.hkHighs[index], conditions.xmanInfo.hkLows[index]); + + // + result = MathMax(result, selectedShadow); + } + + // + return result; +} + +// +double iHKHighest( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0, // Array Index + int count = 5, // Count + ENUM_X_PRICE appliedPrice = X_PRICE_HIGH // Price Type +) +{ + // + double result = 0; + + // + // Validate Args ... + if (index < 0 || + count <= 0) + { + return result; + } + + // + int idx = -1; + double tmpArray[]; + + // + switch (appliedPrice) + { + // + case X_PRICE_HIGH: + // + ArrayCopy( + tmpArray, + conditions.xmanInfo.hkHighs, + 0, + index, + count // + ); + break; + + // + case X_PRICE_OPEN: + // + ArrayCopy( + tmpArray, + conditions.xmanInfo.hkOpens, + 0, + index, + count // + ); + break; + + // + case X_PRICE_CLOSE: + // + ArrayCopy( + tmpArray, + conditions.xmanInfo.hkCloses, + 0, + index, + count // + ); + break; + + // + case X_PRICE_LOW: + // + ArrayCopy( + tmpArray, + conditions.xmanInfo.hkLows, + 0, + index, + count // + ); + break; + } + + // + idx = ArrayMaximum(tmpArray); + if (idx < 0) + { + return result; + } + + // + result = tmpArray[idx]; + + // + return result; +} + +// +double iHKLowest( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0, // Array Index + int count = 5, // Count + ENUM_X_PRICE appliedPrice = X_PRICE_LOW // Price Type +) +{ + // + double result = 0; + + // + // Validate Args ... + if (index < 0 || + count <= 0) + { + return result; + } + + // + int idx = -1; + double tmpArray[]; + + // + switch (appliedPrice) + { + // + case X_PRICE_HIGH: + // + ArrayCopy( + tmpArray, + conditions.xmanInfo.hkHighs, + 0, + index, + count // + ); + break; + + // + case X_PRICE_OPEN: + // + ArrayCopy( + tmpArray, + conditions.xmanInfo.hkOpens, + 0, + index, + count // + ); + break; + + // + case X_PRICE_CLOSE: + // + ArrayCopy( + tmpArray, + conditions.xmanInfo.hkCloses, + 0, + index, + count // + ); + break; + + // + case X_PRICE_LOW: + // + ArrayCopy( + tmpArray, + conditions.xmanInfo.hkLows, + 0, + index, + count // + ); + break; + } + + // + idx = ArrayMinimum(tmpArray); + if (idx < 0) + { + return result; + } + + // + result = tmpArray[idx]; + + // + return result; +} + +// +double GetHKMin( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0, // Array Index + bool ignoreShadows = false // Ignore Shaddows +) +{ + // + double result = 0; + + // + result = MathMin(conditions.xmanInfo.hkOpens[index], conditions.xmanInfo.hkCloses[index]); + if (!ignoreShadows) + { + // + double selectedShadow = MathMin(conditions.xmanInfo.hkHighs[index], conditions.xmanInfo.hkLows[index]); + + // + result = MathMin(result, selectedShadow); + } + + // + return result; +} + +// +double GetSMHKMax( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0, // Array Index + bool ignoreShadows = false // Ignore Shaddows +) +{ + // + double result = 0; + + // + result = MathMax(conditions.xmanInfo.smhkOpens[index], conditions.xmanInfo.smhkCloses[index]); + if (!ignoreShadows) + { + // + double selectedShadow = MathMax(conditions.xmanInfo.smhkHighs[index], conditions.xmanInfo.smhkLows[index]); + + // + result = MathMax(result, selectedShadow); + } + + // + return result; +} + +// +double GetSMHKMin( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0, // Array Index + bool ignoreShadows = false // Ignore Shaddows +) +{ + // + double result = 0; + + // + result = MathMin(conditions.xmanInfo.smhkOpens[index], conditions.xmanInfo.smhkCloses[index]); + if (!ignoreShadows) + { + // + double selectedShadow = MathMin(conditions.xmanInfo.smhkHighs[index], conditions.xmanInfo.smhkLows[index]); + + // + result = MathMin(result, selectedShadow); + } + + // + return result; +} + +// +double iSMHKHighest( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0, // Array Index + int count = 5, // Count + ENUM_X_PRICE appliedPrice = X_PRICE_HIGH // Price Type +) +{ + // + double result = 0; + + // + // Validate Args ... + if (index < 0 || + count <= 0) + { + return result; + } + + // + int idx = -1; + double tmpArray[]; + + // + switch (appliedPrice) + { + // + case X_PRICE_HIGH: + // + ArrayCopy( + tmpArray, + conditions.xmanInfo.smhkHighs, + 0, + index, + count // + ); + break; + + // + case X_PRICE_OPEN: + // + ArrayCopy( + tmpArray, + conditions.xmanInfo.smhkOpens, + 0, + index, + count // + ); + break; + + // + case X_PRICE_CLOSE: + // + ArrayCopy( + tmpArray, + conditions.xmanInfo.smhkCloses, + 0, + index, + count // + ); + break; + + // + case X_PRICE_LOW: + // + ArrayCopy( + tmpArray, + conditions.xmanInfo.smhkLows, + 0, + index, + count // + ); + break; + } + + // + idx = ArrayMaximum(tmpArray); + if (idx < 0) + { + return result; + } + + // + result = tmpArray[idx]; + + // + return result; +} + +// +double iSMHKLowest( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0, // Array Index + int count = 5, // Count + ENUM_X_PRICE appliedPrice = X_PRICE_LOW // Price Type +) +{ + // + double result = 0; + + // + // Validate Args ... + if (index < 0 || + count <= 0) + { + return result; + } + + // + int idx = -1; + double tmpArray[]; + + // + switch (appliedPrice) + { + // + case X_PRICE_HIGH: + // + ArrayCopy( + tmpArray, + conditions.xmanInfo.smhkHighs, + 0, + index, + count // + ); + break; + + // + case X_PRICE_OPEN: + // + ArrayCopy( + tmpArray, + conditions.xmanInfo.smhkOpens, + 0, + index, + count // + ); + break; + + // + case X_PRICE_CLOSE: + // + ArrayCopy( + tmpArray, + conditions.xmanInfo.smhkCloses, + 0, + index, + count // + ); + break; + + // + case X_PRICE_LOW: + // + ArrayCopy( + tmpArray, + conditions.xmanInfo.smhkLows, + 0, + index, + count // + ); + break; + } + + // + idx = ArrayMinimum(tmpArray); + if (idx < 0) + { + return result; + } + + // + result = tmpArray[idx]; + + // + return result; +} + +// +bool IsHKBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hkOpens[index] < conditions.xmanInfo.hkCloses[index] + // + ; + + // + return result; +} + +// +bool IsHKBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hkOpens[index] > conditions.xmanInfo.hkCloses[index] + // + ; + + // + return result; +} + +// +bool IsSMHKBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.smhkOpens[index] < conditions.xmanInfo.smhkCloses[index] + // + ; + + // + return result; +} + +// +bool IsSMHKBullishAs( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0, // Array Index + int count = 5 // Count +) +{ + // + bool result = false; + + // + int verified = 0; + for (int i = index; i < index + count; i++) + { + // + bool isTrue = IsSMHKBullish(conditions, i); + if (isTrue) + { + verified++; + } + } + + // + result = verified >= count; + + // + return result; +} + +// +bool IsSMHKChangedIn( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0, // Array Index + int length = 5 // Length +) +{ + // + bool result = false; + + // + bool isCurrentBullish = IsSMHKBullish(conditions, index); + + // + int numberOfChanges = 0; + bool isLastBullish = isCurrentBullish; + for (int i = index + 1; i < index + length; i++) + { + // + bool isBullish = IsSMHKBullish(conditions, i); + bool isBearish = IsSMHKBearish(conditions, i); + + // + if ((isBullish && isLastBullish) || (!isBullish && !isLastBullish)) + { + continue; + } + else if ((isBullish && !isLastBullish) || (isBearish && isLastBullish)) + { + numberOfChanges++; + } + } + + // + result = numberOfChanges > 0; + + // + return result; +} + +// +bool IsSMHKBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.smhkOpens[index] > conditions.xmanInfo.smhkCloses[index] + // + ; + + // + return result; +} + +// +bool IsSMHKBearishAs( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0, // Array Index + int count = 5 // Count +) +{ + // + bool result = false; + + // + int verified = 0; + for (int i = index; i < index + count; i++) + { + // + bool isTrue = IsSMHKBearish(conditions, i); + if (isTrue) + { + verified++; + } + } + + // + result = verified >= count; + + // + return result; +} + +// +// END Functions ... +// + +// +// START Combination .... +// + +// +bool IsMarketBullish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHullBullish(conditions, index) && + IsSSLCBullish(conditions, index) && + IsTrendBullish(conditions, index) && + IsRibbonBullish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsMarketBearish( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHullBearish(conditions, index) && + IsSSLCBearish(conditions, index) && + IsTrendBearish(conditions, index) && + IsRibbonBearish(conditions, index) + // + ; + + // + return result; +} + +// +// END Combination .... +// + +// +// START EQM Supports ... +// + +// +// Generate a Collection Of Fib Signals ... +int GenerateSequentialSignals( + XSignal &signals[], // Hold Result ... + double &pivots[], // Required Values For Generate Signals ... + string symbol, // Trading Symbol ... + ENUM_TIMEFRAMES period, // Trading Time Frame ... + double price, // Current Price Execution ... + double volume, // Volume ... + bool placeSL = false, // Place SL for Signals ... + bool placeTP = false, // Place TP for Signals ... + bool useBoundaryForTPSL = false, // Use Boundary Max Min for TP SL ... + double staticTP = 0, // Static TP ... + bool staticTPAsPoint = false, // Detect Static TP as Point ... + double staticSL = 0, // Static SL ... + bool staticSLAsPoint = false, // Detect Static SL as Point ... + bool longSupport = true, // Generate Long Support Signals ... + bool shortSupport = true, // Generate Short Support Signals ... + bool forceCleanSignalsArray = false // Clean Result Array ... +) +{ + // + int result = 0; + + // + if (forceCleanSignalsArray) + { + Clean(signals); + } + int beforeSize = ArraySize(signals); + + // + // Validate Input States ... + int pivotsCount = ArraySize(pivots); + if ( + // + price <= 0 || + volume <= 0 || + pivotsCount <= 0 + // + ) + { + return result; + } + + // + if (pivotsCount == 1) + { + // + bool isValidSL = + !placeSL + ? true + : staticSL > 0 + ? true + : false; + + // + bool isValidTP = + !placeTP + ? true + : staticTP > 0 + ? true + : false; + + // + if (!isValidTP && !isValidSL) + { + return result; + } + } + else if ((placeSL || placeTP) && pivotsCount < 3) + { + return result; + } + + // + if (!longSupport && !shortSupport) + { + return result; + } + + // + double slValue = !placeSL + ? 0 + : staticSLAsPoint + ? PointToPrice( + symbol, + staticSL) + : staticSL + // + ; + + // + double tpValue = !placeTP + ? 0 + : staticTPAsPoint + ? PointToPrice( + symbol, + staticTP) + : staticTP + // + ; + + // + // Do Signal Generation ... + double tp = 0; + double sl = 0; + XSignal signal; + double entry = 0; + ENUM_X_ORDER_MODES mode = NULL; + ENUM_POSITION_TYPE type = NULL; + + // + double boundaryMax = pivots[ArrayMaximum(pivots)]; + double boundaryMin = pivots[ArrayMinimum(pivots)]; + + // + double tmp[]; + Copy( + pivots, + tmp); + ArraySort(tmp); + + // + double biggerThanPrice[]; + Copy( + pivots, + biggerThanPrice); + ArraySort(biggerThanPrice); + double lesserThanPrice[]; + + // + bool breaking = false; + while (!breaking) + { + // + double lesser = -1; + lesser = FindLesserThanValue( + price, + biggerThanPrice, + true); + if (lesser > -1) + { + // + Add( + lesser, + lesserThanPrice); + + // + Remove( + lesser, + biggerThanPrice); + } + + // + breaking = ArraySize(biggerThanPrice) == 0 || lesser == -1; + } + + // + // Here we have act based on Biggers and Lessers ... + // - Lessers sorted from Large to Small ... + // this means Lesser[0] is Biggest Lesser value ... + // - Biggers sort Ordered Small to Large ... + // this means Bigger[0] is Smallest Bigger Value ... + + // + int biggersCount = ArraySize(biggerThanPrice); + int lessersCount = ArraySize(lesserThanPrice); + + // + if (longSupport) + { + // + // Directional ... + if (biggersCount > 0) + { + // + for (int i = 0; i < biggersCount; i++) + { + // + double iVal = biggerThanPrice[i]; + + // + // We have to Filter Boundary Max ... + if (iVal == boundaryMax) + { + // + // TODO: + // Also we can Do Support based on Previus Support and Resistances ... + continue; + } + + // + // Now we Sure the iVal is not the Boundary Max ... + + // + entry = iVal; + + // + // TP ... + if (placeTP) + { + // + // this means Static TP Provided ... + if (tpValue > 0) + { + tp = entry + tpValue; + } + // + // Use Boundary Max for TP ... + else if (useBoundaryForTPSL) + { + tp = boundaryMax; + } + // + // Find Biggest then Entry Value and Set it as TP ... + else + { + // + tp = FindBiggerThanValue( + entry, + tmp, + true); + if (tp <= 0) + { + tp = 0; + } + } + } + else + { + tp = 0; + } + + // + // SL ... + if (placeSL) + { + // + // this means Static SL Provided ... + if (slValue > 0) + { + sl = entry - slValue; + } + // + // Use Boundary Min for SL ... + if (useBoundaryForTPSL) + { + sl = boundaryMin; + } + // + // Else Find Lesser Than Entry Value and Set it as SL ... + else + { + // + sl = FindLesserThanValue( + entry, + tmp, + true); + if (sl <= 0) + { + sl = 0; + } + } + } + else + { + sl = 0; + } + + // + // Prepare to Create Signal ... + mode = X_ORDER_MODE_STOP; + type = POSITION_TYPE_BUY; + + // + signal = CreateSignal( + symbol, + period, + type, + mode, + entry, + volume, + tp, + sl); + + // + Add( + signal, + signals); + + // + Clean(signal); + } + } + + // + // TODO Reversal ... + if (shortSupport) + { + } + } + + // + if (shortSupport) + { + // + // Directional ... + if (lessersCount > 0) + { + // + for (int i = 0; i < lessersCount; i++) + { + // + double iVal = lesserThanPrice[i]; + + // + // We Have to Filter Boundary Min ... + if (iVal == boundaryMin) + { + // + // TODO: + // Also we can Do Support based on Previus Support and Resistances ... + continue; + } + + // + // Now we sure the iVal is not the Boundary Min ... + + // + entry = iVal; + + // + // TP ... + if (placeTP) + { + // + // this means static tp provider ... + if (tpValue > 0) + { + tp = entry - tpValue; + } + // + // Use Boundary Min for TP ... + else if (useBoundaryForTPSL) + { + tp = boundaryMin; + } + // + // Find Lesser than Entry Vlue and Set it as TP ... + else + { + tp = FindLesserThanValue( + entry, + tmp, + true); + if (tp <= 0) + { + tp = 0; + } + } + } + else + { + tp = 0; + } + + // + // SL ... + if (placeSL) + { + // + // this means Static SL provided ... + if (slValue > 0) + { + sl = entry + slValue; + } + // + // Use Boundary Max for SL ... + if (useBoundaryForTPSL) + { + sl = boundaryMax; + } + // + // Find Bigger Than Entry Vakue and Set it as SL ... + else + { + // + sl = FindBiggerThanValue( + entry, + tmp, + true); + if (sl <= 0) + { + sl = 0; + } + } + } + else + { + sl = 0; + } + + // + // Prepare to Create Signal ... + mode = X_ORDER_MODE_STOP; + type = POSITION_TYPE_SELL; + + // + signal = CreateSignal( + symbol, + period, + type, + mode, + entry, + volume, + tp, + sl); + + // + Add( + signal, + signals); + + // + Clean(signal); + } + } + + // + // TODO: Reversal ... + if (longSupport) + { + } + } + + // + int afterSize = ArraySize(signals); + result = afterSize - beforeSize; + + // + return result; +} + +// +int GenerateSupportAndResistanceSignals( + XSignal &supports[], // Holds Result ... + XOHCLSupRes &supRes, // Provided Support and Resistances ... + string symbol, // Trading Symbol ... + ENUM_TIMEFRAMES period, // Trading Time Frame ... + double price, // Current Price Execution ... + double volume, // Volume ... + bool placeSL = false, // Place SL for Signals ... + bool placeTP = false, // Place TP for Signals ... + bool useBoundaryForTPSL = false, // Use Boundary Max Min for TP SL ... + double staticTP = 0, // Static TP ... + bool staticTPAsPoint = false, // Detect Static TP as Point ... + double staticSL = 0, // Static SL ... + bool staticSLAsPoint = false, // Detect Static SL as Point ... + bool forceClean = false // Clean Result Array ... +) +{ + // + int result = 0; + + // + if (forceClean) + { + Clean(supports); + } + + // + int beforeSize = ArraySize(supports); + + // + // Try to Copy all Values in same array ... + + // + double tmpPivots[]; + Copy( + supRes.sup, + tmpPivots, + false // + ); + Copy( + supRes.res, + tmpPivots, + false // + ); + + // + // Sort Temp Pivots Array ... + ArraySort(tmpPivots); + + // + GenerateSequentialSignals( + supports, + tmpPivots, + symbol, + period, + price, + volume, + placeSL, + placeTP, + useBoundaryForTPSL, + staticTP, + staticTPAsPoint, + staticSL, + staticSLAsPoint // + ); + + // + int afterSize = ArraySize(supports); + + // + result = afterSize - beforeSize; + + // + return result; +} + +// +// END EQM Supports ... +// diff --git a/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.x121.draw.lib.ex5 b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.x121.draw.lib.ex5 new file mode 100644 index 0000000..4f32623 Binary files /dev/null and b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.x121.draw.lib.ex5 differ diff --git a/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.x121.draw.lib.mq5 b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.x121.draw.lib.mq5 new file mode 100644 index 0000000..847d948 --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.x121.draw.lib.mq5 @@ -0,0 +1,284 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X12 Draw Library +// ------------------------------------------ +// Name: X121Draw +// Description: provides Draw Requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +#include "../Libraries/x-saherelm.draw.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Libraries/x-saherelm.models.lib.mq5" + +// +// START Draw Functions ... +// + +// +// Draw Signal ... +void DrawSignal(const ulong ticket, XSignal &signal) +{ + // + bool isLong = IsLong(signal.type); + + // + string prefix = (string)ticket + "_" + ToString(signal.period); + + // + // Retrieve Time ... + datetime time = iTime( + signal.symbol, + signal.period, + 0); + + // + // Retrieve 3 Time ... + datetime time3 = iTime( + signal.symbol, + signal.period, + 3); + + // + color posColor = isLong + ? clrSpringGreen + : clrTomato; + color tpColor = clrSpringGreen; + color slColor = clrTomato; + color entryColor = clrGold; + + // + ENUM_LINE_STYLE vLineStyle = STYLE_DOT; + ENUM_LINE_STYLE tpLineStyle = STYLE_SOLID; + ENUM_LINE_STYLE slLineStyle = STYLE_SOLID; + ENUM_LINE_STYLE entryLineStyle = STYLE_SOLID; + + // + int lineWidth = 2; + + // + long chartID = ChartID(); + + // + // Vertical Line ... + string vlName = prefix + "_" + (string)time; + + // + // DrawVerticalLine( + // chartID, + // vlName, + // 0, + // time, + // posColor, + // vLineStyle, + // lineWidth); + + // + // TP ... + double profit = (MathAbs(signal.tp - signal.entry)) * signal.volume; + string tpName = prefix + "_TP_" + (string)profit; + + // + DrawTrendLine( + chartID, + tpName, + 0, + time3, + signal.tp, + time, + signal.tp, + tpColor, + tpLineStyle, + lineWidth); + + // + // SL ... + double lost = (MathAbs(signal.sl - signal.entry)) * signal.volume; + string slName = prefix + "_SL_" + (string)lost; + + // + DrawTrendLine( + chartID, + slName, + 0, + time3, + signal.sl, + time, + signal.sl, + slColor, + slLineStyle, + lineWidth); + + // + // TODO: Fix this ... + return; + + // + // ENTRY ... + string entryName = prefix + "_ENTRY_" + (string)lost; + + // + DrawTrendLine( + chartID, + entryName, + 0, + time3, + signal.entry, + time, + signal.entry, + entryColor, + entryLineStyle, + lineWidth); +} + +// +void DrawSignals( + XSignal &signals[], // Signals To Draw + bool drawSupportAndResistances = false // Draw Signal Support and Resistance +) +{ + // + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + ulong iTicket = MathRand() * 10000; + + // + DrawSignal(iTicket, iSignal); + + // + // TODO: Remove this ... + return; + + // + // Check For Draw Support and Resistances ... + bool isValidSupRes = ArraySize(iSignal.supportResistances.sup) > 0 || ArraySize(iSignal.supportResistances.res) > 0; + if (drawSupportAndResistances && isValidSupRes) + { + DrawSupportResistance(0, iSignal.supportResistances); + } + } +} + +// +// Draw Support and Resistance ... +void DrawSupportResistance( + int bar_index, + XOHCLSupRes &data, + string prefix = "", + color supportColor = clrOrange, + color resistanceColor = clrOrange) +{ + // + datetime barTime = GetCandleTime( + _Symbol, + _Period, + bar_index); + + // + datetime prevBarTime = GetCandleTime( + _Symbol, + _Period, + bar_index + 5); + + // + long chID = ChartID(); + int subWindiw = 0; + int lineWidth = 1; + + // + string mPrefix = prefix + "_" + (string)barTime + "_"; + + // + // SUPPORTS ... + + // + int supCount = ArraySize(data.sup); + if (supCount > 0) + { + // + for (int i = 0; i < supCount; i++) + { + // + double iSup = data.sup[i]; + + // + string supTlName = mPrefix + "SUP[" + (string)(i + 1) + "]_(" + (string)iSup + ")"; + + // + // Draw Support ... + DrawTrendLine( + chID, + supTlName, + subWindiw, + prevBarTime, + iSup, + barTime, + iSup, + supportColor, + STYLE_DOT, + lineWidth, + true); + } + } + + // + // RESISTANCES ... + + // + int resCount = ArraySize(data.res); + if (resCount > 0) + { + // + for (int i = 0; i < resCount; i++) + { + // + double iRes = data.res[i]; + + // + string resTlName = mPrefix + "RES[" + (string)(i + 1) + "]_(" + (string)iRes + ")"; + + // + // Draw Support ... + DrawTrendLine( + chID, + resTlName, + subWindiw, + prevBarTime, + iRes, + barTime, + iRes, + resistanceColor, + STYLE_DOT, + lineWidth, + true); + } + } +} + +// +// END Draw Functions ... +// diff --git a/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.x121.x786.lib.mq5 b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.x121.x786.lib.mq5 new file mode 100644 index 0000000..f10d173 --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.x121.x786.lib.mq5 @@ -0,0 +1,436 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCX121X786 +// Description: X121 X786 Signal Provider ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +#include "../Libraries/x-saherelm.x121.condition.parser.lib.mq5" + +// +// CONDITIONS ... + +// +// Longs ... +bool IsX786HasLongSignal( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + bool long1 = + // + IsHKBullish(conditions) && + IsSMHKBullish(conditions) && + IsHullBullish(conditions, index) && + IsSSLCBullish(conditions, index) && + IsTrendBullish(conditions, index) && + IsRibbonBullish(conditions, index) && + IsBullishCandle(conditions.candles[1]) + // + ; + + // + bool long2 = + // + IsTrendBullish(conditions) && + IsNewPeakOverLast(conditions) && + // + ( + // + IsSCLowBullish(conditions) && + ( + // + IsMCLowBullish(conditions) || + IsLCLowBullish(conditions) || + IsHCLowBullish(conditions) + // + ) + // + ) + // + ; + + // + result = + // + long1 + // + || + // + long2 + // + ; + + // + return result; +} + +// +// Shorts ... +bool IsX786HasShortSignal( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + bool short1 = + // + IsHKBearish(conditions) && + IsSMHKBearish(conditions) && + IsHullBearish(conditions, index) && + IsSSLCBearish(conditions, index) && + IsTrendBearish(conditions, index) && + IsRibbonBearish(conditions, index) && + IsBearishCandle(conditions.candles[1]) + // + ; + + // + bool short2 = + // + IsTrendBearish(conditions, index) && + IsNewValeUnderLast(conditions) && + // + ( + // + IsSCHighBearish(conditions) && + ( + // + IsMCHighBearish(conditions) || + IsLCHighBearish(conditions) || + IsHCHighBearish(conditions) + // + ) + // + ) + // + ; + + // + result = + // + short1 + // + || + // + short2 + // + ; + + // + return result; +} + +// +// CALCULATIONS ... + +// +// Calculate Long Stop ... +double CalculateX786LongStop(const X121MarketConditions &conditions) +{ + // + double result = 0; + + // + double vale = conditions.xmanInfo.vales[0]; + double med = (conditions.xmanInfo.sLLs[0] + conditions.xmanInfo.mLLs[0]) / 2; + double fl1 = conditions.xmanInfo.fibLevel1s[0]; + + // + result = + // + 0 + // + ; + + // + return result; +} + +// +// Calculate Long Take Profits ... +double CalculateX786LongTarget(const X121MarketConditions &conditions, double sl, double entry, double r2r = 1) +{ + // + double result = 0; + + // + if (sl > 0 && entry > 0 && r2r > 0) + { + // + double riskPrice = MathAbs(entry - sl); + double rewardPrice = riskPrice * r2r; + + // + result = entry + rewardPrice; + } + else + { + result = entry + PointToPrice(conditions.symbol, 60); + } + + // + return result; +} + +// +// Calculate Short Stop ... +double CalculateX786ShortStop(const X121MarketConditions &conditions) +{ + // + double result = 0; + + // + return result; +} + +// +// Calculate Short Take Profits ... +double CalculateX786ShortTarget(const X121MarketConditions &conditions, double sl, double entry, double r2r = 1) +{ + // + double result = 0; + + // + if (sl > 0 && entry > 0 && r2r > 0) + { + // + double riskPrice = MathAbs(entry - sl); + double rewardPrice = riskPrice * r2r; + + // + result = entry - rewardPrice; + } + else + { + result = entry - PointToPrice(conditions.symbol, 60); + } + + // + return result; +} + +// +// SIGNALS ... + +// +// Generate Signal ... +bool GenerateX786Signal( + X121MarketConditions &conditions, // Specified Conditions which Holds Signal also ... + const XOHCLSupRes &supportAndResistances, // Specified Support and Resistances ... + ENUM_POSITION_TYPE type, // Specified Which Signal Type must be Generated ... + bool generateSupports = false // Specified Support Signals also Generated and Attached or not ... +) +{ + // + bool result = false; + + // + bool isLong = IsLong(type); + + // + // Retrieve Entry Price ... + double entry = GetEntry( + conditions.symbol, + type); + + // + result = + // + isLong + ? IsX786HasLongSignal(conditions) + : IsX786HasShortSignal(conditions) + // + ; + + // + if (result) + { + // + Add( + ToString(X786), + conditions.signal.providers); + + // + double sl = + // + isLong + ? CalculateX786LongStop(conditions) + : CalculateX786ShortStop(conditions) + // + ; + + // + double r2r = 3; + + // + double tp = + // + isLong + ? CalculateX786LongTarget(conditions, sl, entry, r2r) + : CalculateX786ShortTarget(conditions, sl, entry, r2r) + // + ; + + // + double volume = 0.01; + + // + conditions.hasSignal = true; + + // + conditions.signal.type = type; + conditions.signal.symbol = conditions.symbol; + conditions.signal.period = conditions.period; + conditions.signal.supportResistances = supportAndResistances; + + // + conditions.signal.sl = sl; + conditions.signal.tp = tp; + conditions.signal.r2r = r2r; + conditions.signal.entry = entry; + conditions.signal.volume = volume; + conditions.signal.mode = X_ORDER_MODE_MARKET; + + // + if (generateSupports) + { + // + // Generate Required Support Signals ... + GenerateX786SignalSupports(conditions); + } + } + + // + return result; +} + +// +// SUPPORTS ... + +// +// Generate Required Support Signals and Attached Them into +// Exists Signal of Conditions ... +int GenerateX786SignalSupports( + X121MarketConditions &conditions) +{ + // + int result = 0; + + // + return result; +} + +// +// GUARDS ... + +// +// Check Can Force Close All X786 Long Signals or not ... +bool CanX786ForceCloseLongs(const X121MarketConditions &conditions) +{ + // + bool result = false; + + // + // 1- HK Min above FL 1 ... + // 2- Trend Changed From Bullish To Bearish ... + + // + double minHK = GetHKMin(conditions); + bool isMinHKOverFL1 = minHK > conditions.xmanInfo.fibLevel1s[0]; + bool isTrendSwitchedToBearish = IsTrendSwitchedToBearish(conditions); + + // + result = + // + // isMinHKOverFL1 && + isTrendSwitchedToBearish + // + ; + // if (result) { + // LogMessage("Test"); + // } + + // + return result; +} + +// +// Check for Trailing Long Positions Stops ... +bool CanX786TrailLongsStop( + const X121MarketConditions &conditions, + double &newSL // +) +{ + // + bool result = false; + + // + double prev = GetRibbonMin(conditions, 1); + double current = GetRibbonMin(conditions); + + // + result = current > prev; + if (result) + { + newSL = current; + } + else + { + newSL = -1; + } + + // + return result; +} + +// +// Check For Trailing Short Positions Stops ... +bool CanX786TrailShortsStop( + const X121MarketConditions &conditions, + double &newSL // +) +{ + // + bool result = false; + + // + double prev = GetRibbonMax(conditions, 1); + double current = GetRibbonMax(conditions); + + // + result = current < prev; + if (result) + { + newSL = current; + } + else + { + newSL = -1; + } + + // + return result; +} diff --git a/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.x121.x92.lib.mq5 b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.x121.x92.lib.mq5 new file mode 100644 index 0000000..ce2270d --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.x121.x92.lib.mq5 @@ -0,0 +1,430 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCX121X92 +// Description: X121 X92 Signal Provider ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +#include "../Libraries/x-saherelm.x121.condition.parser.lib.mq5" + +// +// CONDITIONS ... + +// +// Longs ... +bool IsX92HasLongSignal( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + bool long1 = + // + IsNewPeak(conditions) && + IsValeSameAs(conditions) && + IsNewPeakUnderLast(conditions) + // + ; + + // + bool long2 = + // + IsSMHKBullish(conditions, index) && + IsTrendBullish(conditions, index) && + IsBullishCandle(conditions.candles[index + 1]) + // + && + // + (conditions.candles[index + 1].low > GetSMHKMax(conditions, index) || + conditions.candles[index + 1].close > GetSMHKMax(conditions, index)) + // + && + // + conditions.xmanInfo.smhkHighs[index] == iSMHKHighest(conditions, index) + // + && + // + IsSCLowBullish(conditions, index) + // + ; + + // + result = + // + long1 + // + || + // + long2 + // + ; + + // + return result; +} + +// +// Shorts ... +bool IsX92HasShortSignal( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + bool short1 = + // + IsNewVale(conditions) && + IsPeakSameAs(conditions) && + IsNewValeOverLast(conditions) + // + ; + + // + bool short2 = + // + IsSMHKBearish(conditions, index) && + IsTrendBearish(conditions, index) && + IsBearishCandle(conditions.candles[index + 1]) + // + && + // + (conditions.candles[index + 1].high < GetSMHKMin(conditions, index) || + conditions.candles[index + 1].open < GetSMHKMin(conditions, index)) + // + && + // + conditions.xmanInfo.smhkHighs[index] == iSMHKLowest(conditions, index) + // + && + // + IsSCHighBearish(conditions, index) + // + ; + + // + result = + // + short1 + // + || + // + short2 + // + ; + + // + return result; +} + +// +// CALCULATIONS ... + +// +// Calculate Long Stop ... +double CalculateX92LongStop(const X121MarketConditions &conditions) +{ + // + double result = 0; + + // + double vale = conditions.xmanInfo.vales[0]; + double med = (conditions.xmanInfo.sLLs[0] + conditions.xmanInfo.mLLs[0]) / 2; + double fl1 = conditions.xmanInfo.fibLevel1s[0]; + + // + result = + // + 0 + // + ; + + // + return result; +} + +// +// Calculate Long Take Profits ... +double CalculateX92LongTarget(const X121MarketConditions &conditions, double sl, double entry, double r2r = 1) +{ + // + double result = 0; + + // + if (sl > 0 && entry > 0 && r2r > 0) + { + // + double riskPrice = MathAbs(entry - sl); + double rewardPrice = riskPrice * r2r; + + // + result = entry + rewardPrice; + } + else + { + result = entry + PointToPrice(conditions.symbol, 60); + } + + // + return result; +} + +// +// Calculate Short Stop ... +double CalculateX92ShortStop(const X121MarketConditions &conditions) +{ + // + double result = 0; + + // + return result; +} + +// +// Calculate Short Take Profits ... +double CalculateX92ShortTarget(const X121MarketConditions &conditions, double sl, double entry, double r2r = 1) +{ + // + double result = 0; + + // + if (sl > 0 && entry > 0 && r2r > 0) + { + // + double riskPrice = MathAbs(entry - sl); + double rewardPrice = riskPrice * r2r; + + // + result = entry - rewardPrice; + } + else + { + result = entry - PointToPrice(conditions.symbol, 60); + } + + // + return result; +} + +// +// SIGNALS ... + +// +// Generate Signal ... +bool GenerateX92Signal( + X121MarketConditions &conditions, // Specified Conditions which Holds Signal also ... + const XOHCLSupRes &supportAndResistances, // Specified Support and Resistances ... + ENUM_POSITION_TYPE type, // Specified Which Signal Type must be Generated ... + bool generateSupports = false // Specified Support Signals also Generated and Attached or not ... +) +{ + // + bool result = false; + + // + bool isLong = IsLong(type); + + // + // Retrieve Entry Price ... + double entry = GetEntry( + conditions.symbol, + type); + + // + result = + // + isLong + ? IsX92HasLongSignal(conditions) + : IsX92HasShortSignal(conditions) + // + ; + + // + if (result) + { + // + Add( + ToString(X92), + conditions.signal.providers); + + // + double sl = + // + isLong + ? CalculateX92LongStop(conditions) + : CalculateX92ShortStop(conditions) + // + ; + + // + double r2r = 3; + + // + double tp = + // + isLong + ? CalculateX92LongTarget(conditions, sl, entry, r2r) + : CalculateX92ShortTarget(conditions, sl, entry, r2r) + // + ; + + // + double volume = 0.01; + + // + conditions.hasSignal = true; + + // + conditions.signal.type = type; + conditions.signal.symbol = conditions.symbol; + conditions.signal.period = conditions.period; + conditions.signal.supportResistances = supportAndResistances; + + // + conditions.signal.sl = sl; + conditions.signal.tp = tp; + conditions.signal.r2r = r2r; + conditions.signal.entry = entry; + conditions.signal.volume = volume; + conditions.signal.mode = X_ORDER_MODE_MARKET; + + // + if (generateSupports) + { + // + // Generate Required Support Signals ... + GenerateX92SignalSupports(conditions); + } + } + + // + return result; +} + +// +// SUPPORTS ... + +// +// Generate Required Support Signals and Attached Them into +// Exists Signal of Conditions ... +int GenerateX92SignalSupports( + X121MarketConditions &conditions) +{ + // + int result = 0; + + // + return result; +} + +// +// GUARDS ... + +// +// Check Can Force Close All X92 Long Signals or not ... +bool CanX92ForceCloseLongs(const X121MarketConditions &conditions) +{ + // + bool result = false; + + // + // 1- HK Min above FL 1 ... + // 2- Trend Changed From Bullish To Bearish ... + + // + double minHK = GetHKMin(conditions); + bool isMinHKOverFL1 = minHK > conditions.xmanInfo.fibLevel1s[0]; + bool isTrendSwitchedToBearish = IsTrendSwitchedToBearish(conditions); + + // + result = + // + // isMinHKOverFL1 && + isTrendSwitchedToBearish + // + ; + // if (result) { + // LogMessage("Test"); + // } + + // + return result; +} + +// +// Check for Trailing Long Positions Stops ... +bool CanX92TrailLongsStop( + const X121MarketConditions &conditions, + double &newSL // +) +{ + // + bool result = false; + + // + double prev = GetRibbonMin(conditions, 1); + double current = GetRibbonMin(conditions); + + // + result = current > prev; + if (result) + { + newSL = current; + } + else + { + newSL = -1; + } + + // + return result; +} + +// +// Check For Trailing Short Positions Stops ... +bool CanX92TrailShortsStop( + const X121MarketConditions &conditions, + double &newSL // +) +{ + // + bool result = false; + + // + double prev = GetRibbonMax(conditions, 1); + double current = GetRibbonMax(conditions); + + // + result = current < prev; + if (result) + { + newSL = current; + } + else + { + newSL = -1; + } + + // + return result; +} diff --git a/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.x121.xtest.lib.mq5 b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.x121.xtest.lib.mq5 new file mode 100644 index 0000000..ee752f4 --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.x121.xtest.lib.mq5 @@ -0,0 +1,354 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCX121XTEST +// Description: X121 XTEST Signal Provider ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +#include "../Libraries/x-saherelm.x121.condition.parser.lib.mq5" + +// +// CONDITIONS ... + +// +// Longs ... +bool IsXTESTHasLongSignal( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + bool isTrendBullish = IsTrendBullish(conditions, index); + bool isCandleBullish = IsBullishCandle(conditions.candles[1]); + bool isValidTrend = ArraySize(conditions.xmanInfo.trendChanges) > 2 && + conditions.xmanInfo.trends[0] > conditions.xmanInfo.trends[1] && + conditions.xmanInfo.trends[0] > conditions.xmanInfo.trendChanges[0].from; + + // + result = + // + isValidTrend && + isTrendBullish && + isCandleBullish + // + ; + + // + return result; +} + +// +// Shorts ... +bool IsXTESTHasShortSignal( + const X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + bool isTrendBearish = IsTrendBearish(conditions, index); + bool isCandleBearish = IsBearishCandle(conditions.candles[1]); + bool isValidTrend = ArraySize(conditions.xmanInfo.trendChanges) > 2 && + conditions.xmanInfo.trends[0] < conditions.xmanInfo.trends[1] && + conditions.xmanInfo.trends[0] < conditions.xmanInfo.trendChanges[0].from; + + // + result = + // + isValidTrend && + isTrendBearish && + isCandleBearish + // + ; + + // + return result; +} + +// +// CALCULATIONS ... + +// +// Calculate Long Stop ... +double CalculateXTESTLongStop(const X121MarketConditions &conditions) +{ + // + double result = 0; + + // + result = + // + conditions.xmanInfo.vales[0] + // + ; + + // + return result; +} + +// +// Calculate Long Take Profits ... +double CalculateXTESTLongTarget(const X121MarketConditions &conditions, double sl, double entry, double r2r = 1) +{ + // + double result = 0; + + // + if (sl > 0 && entry > 0 && r2r > 0) + { + // + double riskPrice = MathAbs(entry - sl); + double rewardPrice = riskPrice * r2r; + + // + result = entry + rewardPrice; + } + else + { + result = entry + PointToPrice(conditions.symbol, 60); + } + + // + double peak = conditions.xmanInfo.peaks[1]; + result = + entry >= peak + ? entry + PointToPrice(conditions.symbol, 60) + : peak; + + // + return result; +} + +// +// Calculate Short Stop ... +double CalculateXTESTShortStop(const X121MarketConditions &conditions) +{ + // + double result = 0; + + // + result = + // + conditions.xmanInfo.peaks[0] + // + ; + + // + return result; +} + +// +// Calculate Short Take Profits ... +double CalculateXTESTShortTarget(const X121MarketConditions &conditions, double sl, double entry, double r2r = 1) +{ + // + double result = 0; + + // + if (sl > 0 && entry > 0 && r2r > 0) + { + // + double riskPrice = MathAbs(entry - sl); + double rewardPrice = riskPrice * r2r; + + // + result = entry - rewardPrice; + } + else + { + result = entry - PointToPrice(conditions.symbol, 60); + } + + // + double vale = conditions.xmanInfo.vales[1]; + result = + entry <= vale + ? entry - PointToPrice(conditions.symbol, 60) + : vale; + + // + return result; +} + +// +// SIGNALS ... + +// +// Generate Signal ... +bool GenerateXTESTSignal( + X121MarketConditions &conditions, // Specified Conditions which Holds Signal also ... + const XOHCLSupRes &supportAndResistances, // Specified Support and Resistances ... + ENUM_POSITION_TYPE type, // Specified Which Signal Type must be Generated ... + bool generateSupports = false // Specified Support Signals also Generated and Attached or not ... +) +{ + // + bool result = false; + + // + bool isLong = IsLong(type); + + // + // Retrieve Entry Price ... + double entry = GetEntry( + conditions.symbol, + type); + + // + result = + // + isLong + ? IsXTESTHasLongSignal(conditions) + : IsXTESTHasShortSignal(conditions) + // + ; + + // + if (result) + { + // + Add( + ToString(XTEST), + conditions.signal.providers); + + // + double sl = + // + isLong + ? CalculateXTESTLongStop(conditions) + : CalculateXTESTShortStop(conditions) + // + ; + + // + double r2r = 1.5; + + // + double tp = + // + isLong + ? CalculateXTESTLongTarget(conditions, sl, entry, r2r) + : CalculateXTESTShortTarget(conditions, sl, entry, r2r) + // + ; + + // + double volume = 0.01; + + // + conditions.hasSignal = true; + + // + conditions.signal.type = type; + conditions.signal.symbol = conditions.symbol; + conditions.signal.period = conditions.period; + conditions.signal.supportResistances = supportAndResistances; + + // + conditions.signal.sl = 0; // sl; + conditions.signal.tp = tp; + conditions.signal.r2r = r2r; + conditions.signal.entry = entry; + conditions.signal.volume = volume; + conditions.signal.mode = X_ORDER_MODE_MARKET; + + // + if (generateSupports) + { + // + // Generate Required Support Signals ... + GenerateXTESTSignalSupports(conditions); + } + } + + // + return result; +} + +// +// SUPPORTS ... + +// +// Generate Required Support Signals and Attached Them into +// Exists Signal of Conditions ... +int GenerateXTESTSignalSupports( + X121MarketConditions &conditions) +{ + // + int result = 0; + + // + return result; +} + +// +// GUARDS ... + +// +// Check Can Force Close All XTEST Long Signals or not ... +bool CanXTESTForceCloseLongs(const X121MarketConditions &conditions) +{ + // + bool result = false; + + // + bool isTrendSwitchedToBearish = IsTrendSwitchedToBearish(conditions); + + // + result = + // + false + // + ; + + // + return result; +} + +// +// Check for Trailing Long Positions Stops ... +bool CanXTESTTrailLongsStop( + const X121MarketConditions &conditions, + double &newSL // +) +{ + // + bool result = false; + + // + return result; +} + +// +// Check For Trailing Short Positions Stops ... +bool CanXTESTTrailShortsStop( + const X121MarketConditions &conditions, + double &newSL // +) +{ + // + bool result = false; + + // + return result; +} diff --git a/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.xman.parser.lib.ex5 b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.xman.parser.lib.ex5 new file mode 100644 index 0000000..7f28790 Binary files /dev/null and b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.xman.parser.lib.ex5 differ diff --git a/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.xman.parser.lib.mq5 b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.xman.parser.lib.mq5 new file mode 100644 index 0000000..38156d2 --- /dev/null +++ b/MQLTestWorkspace/XBEEA/14030224/Libraries/x-saherelm.xman.parser.lib.mq5 @@ -0,0 +1,1663 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XMAN Parser Library +// ----------------------------------------------- +// Name: XMANParser +// Description: Parsing XMAN Config ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Candle Timer Config ... +// candleTimerColor(clrGold)candleTimerCorner(2) +// +// Chrt Style ... +// upColor(clrLime) downColor(clrRed) lineColor(clrLime) bearishColor(clrRed) bullishColor(clrLime) volumesColor(clrGreen) chartMode(1) +// +// Market Cycles ... +// +// Short ... +// l1Method(1)l1Period(NULL) +// +// Medium ... +// l2Method(1)l2Period(NULL) +// +// Long ... +// l3Method(1)l3Period(NULL) +// +// Hind ... +// l4Method(1)l4Period(NULL) +// +// Fibonacci ... +// fiboLevel1(0.236)fiboLevel2(0.382)fiboLevel3(0.5)fiboLevel4(0.618)fiboLevel5(0.764) +// +// Boundary Detection Mode ... +// hhMode(2)llMode(1) +// +// Trend Detection ... +// trendMultiplier(3)trendPriceAppliedTo(4) +// +// Ribbon Detection ... +// ribbonMode(5) +// +// Hull Trend Detection ... +// hullDivisor(2.0)hullUpAppliedTo(3)hullDownAppliedTo(4) +// +// SSL Channel ... +// sslcMode(1)sslcUpAppliedTo(3)sslcDownAppliedTo(4) +// +// Style Presentation Config ... +// showCandleTimer(true)showCandles(true)showHKCandles(false)showSMHKCandles(false) +// +// +// PV Presentation Config ... +// showPeaksAndVales(true)showLevels(false)showConsolidations(false) +// +// +// Trend Presentation Config ... +// showHull(false)showTrends(false)fillTrends(false)showRibbons(false)showSSLChannel(false) +// +// +// Fibo Presentation Config ... +// showFibo1Levels(false)showFibo2Levels(false)showFibo3Levels(false)showFibo4Levels(false)showFibo5Levels(false) +// +#include "../Libraries/x-saherelm.models.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +enum ENUM_X_MA_METHOD +{ + X_MA_NOTHING, // Nothing + X_MA_SMA, // Simple + X_MA_EMA, // Expotential + X_MA_SMMA, // Smoothed Simple + X_MA_LWMA, // Linear Weighted + X_MA_AMA // Adaptive +}; + +// +// PARSERS ... + +// +// CTIMER ... + +// +string candleTimerColorToken = "candleTimerColor"; +string candleTimerCornerToken = "candleTimerCorner"; + +// +struct XCTimerConfig +{ + color candleTimerColor; // Text Color + ENUM_BASE_CORNER candleTimerCorner; // Text Position +}; + +// +string GenerateCTimerConfig( + color mCandleTimerColor = clrGold, // Text Color + ENUM_BASE_CORNER mCandleTimerCorner = CORNER_RIGHT_UPPER // Text Position +) +{ + // + string result = + candleTimerColorToken + "(" + ToString(mCandleTimerColor) + ")" + + candleTimerCornerToken + "(" + ToString((int)mCandleTimerCorner) + ")"; + + // + return result; +} + +// +string ToString(XCTimerConfig &config) +{ + // + return GenerateCTimerConfig( + config.candleTimerColor, + config.candleTimerCorner); +} + +// +XCTimerConfig ParseCTimerConfig( + string config // Source Config +) +{ + // + XCTimerConfig result; + + // + // CandleTimerColor ... + string candleTimerColorStr = + // + ExtractString( + config, + candleTimerColorToken + "(", + ")"); + // + ; + if (StringLen(candleTimerColorStr) > 0) + { + // + color mCandleTimerColor = (color)candleTimerColorStr; + result.candleTimerColor = mCandleTimerColor; + } + + // + // CandleTimerCorner ... + string candleTimerCornerStr = + // + ExtractString( + config, + candleTimerCornerToken + "(", + ")"); + // + ; + if (StringLen(candleTimerCornerStr) > 0) + { + // + ENUM_BASE_CORNER mCandleTimerCorner = (ENUM_BASE_CORNER)((int)candleTimerCornerStr); + result.candleTimerCorner = mCandleTimerCorner; + } + + // + return result; +} + +// +// CHARTSTYLE ... + +// +string upColorToken = "upColor"; +string downColorToken = "downColor"; +string lineColorToken = "lineColor"; +string bearishColorToken = "bearishColor"; +string bullishColorToken = "bullishColor"; +string volumesColorToken = "volumesColor"; +string chartModeToken = "chartMode"; + +// +struct XChartStyleConfig +{ + color upColor; // Up Color + color downColor; // Down Color + color lineColor; // Line mode and Doji candlestick Color + color bearishColor; // Bullish Color + color bullishColor; // Bearish Color + color volumesColor; // Volumes Color + ENUM_CHART_MODE chartMode; // Chart Mode +}; + +// +string GenerateChartStyleConfig( + color mUpColor = clrLime, // Up Color + color mDownColor = clrRed, // Down Color + color mLineColor = clrLime, // Line mode and Doji candlestick Color + color mBearishColor = clrRed, // Bullish Color + color mBullishColor = clrLime, // Bearish Color + color mVolumesColor = clrGreen, // Volumes Color + ENUM_CHART_MODE mChartMode = CHART_CANDLES // Chart Mode +) +{ + // + string result = ""; + + // + result = + // + upColorToken + "(" + ToString(mUpColor) + ")" + + downColorToken + "(" + ToString(mDownColor) + ")" + + lineColorToken + "(" + ToString(mLineColor) + ")" + + bearishColorToken + "(" + ToString(mBearishColor) + ")" + + bullishColorToken + "(" + ToString(mBullishColor) + ")" + + volumesColorToken + "(" + ToString(mVolumesColor) + ")" + + chartModeToken + "(" + ToString((int)mChartMode) + ")" + // + ; + + // + return result; +} + +// +string ToString(XChartStyleConfig &config) +{ + return GenerateChartStyleConfig( + config.upColor, + config.downColor, + config.lineColor, + config.bearishColor, + config.bullishColor, + config.volumesColor, + config.chartMode); +} + +// +XChartStyleConfig ParseChartStyleConfig(string config) +{ + // + XChartStyleConfig result; + + // + string upColorStr = + // + ExtractString( + config, + upColorToken + "(", + ")") + // + ; + if (StringLen(upColorStr) > 0) + { + // + color mUpColor = (color)upColorStr; + result.upColor = mUpColor; + } + + // + string downColorStr = + // + ExtractString( + config, + downColorToken + "(", + ")") + // + ; + if (StringLen(downColorStr) > 0) + { + // + color mDownColor = (color)downColorStr; + result.downColor = mDownColor; + } + + // + string lineColorStr = + // + ExtractString( + config, + lineColorToken + "(", + ")") + // + ; + if (StringLen(lineColorStr) > 0) + { + // + color mLineColor = (color)lineColorStr; + result.lineColor = mLineColor; + } + + // + string bearishColorStr = + // + ExtractString( + config, + bearishColorToken + "(", + ")") + // + ; + if (StringLen(bearishColorStr) > 0) + { + // + color mBearishColor = (color)bearishColorStr; + result.bearishColor = mBearishColor; + } + + // + string bullishColorStr = + // + ExtractString( + config, + bullishColorToken + "(", + ")") + // + ; + if (StringLen(bullishColorStr) > 0) + { + // + color mBullishColor = (color)bullishColorStr; + result.bullishColor = mBullishColor; + } + + // + string volumesColorStr = + // + ExtractString( + config, + volumesColorToken + "(", + ")") + // + ; + if (StringLen(volumesColorStr) > 0) + { + // + color mVolumesColor = (color)volumesColorStr; + result.volumesColor = mVolumesColor; + } + + // + string chartModeStr = + // + ExtractString( + config, + chartModeToken + "(", + ")") + // + ; + if (StringLen(chartModeStr) > 0) + { + // + ENUM_CHART_MODE mChartMode = (ENUM_CHART_MODE)((int)chartModeStr); + result.chartMode = mChartMode; + } + + // + return result; +} + +// +// MARKETCYCLES ... + +// +// SHORT ... + +// +string l1MethodToken = "l1Method"; +string l1PeriodToken = "l1Period"; + +// +struct XSCConfig +{ + ENUM_X_PERIOD_METHOD l1Method; // How to Find Period + ENUM_TIMEFRAMES l1Period; // Time Period +}; + +// +string GenerateSCConfig( + ENUM_X_PERIOD_METHOD mML1Method = X_PERIOD_AUTO, // How to Find Period + ENUM_TIMEFRAMES mML1Period = NULL // Time Period +) +{ + // + string result = ""; + + // + result = + // + l1MethodToken + "(" + ToString(mML1Method) + ")" + + l1PeriodToken + "(" + ToString(mML1Period) + ")" + // + ; + + // + return result; +} + +// +string ToString(XSCConfig &config) +{ + return GenerateSCConfig( + config.l1Method, + config.l1Period); +} + +// +XSCConfig PrseSCConfig(string config) +{ + // + XSCConfig result; + + // + string l1MethodStr = ExtractString( + config, + l1MethodToken + "(", + ")"); + if (StringLen(l1MethodStr) > 0) + { + // + ENUM_X_PERIOD_METHOD mML1Method = (ENUM_X_PERIOD_METHOD)((int)l1MethodStr); + result.l1Method = mML1Method; + } + + // + string l1PeriodStr = ExtractString( + config, + l1PeriodToken + "(", + ")"); + if (StringLen(l1PeriodStr) > 0) + { + // + ENUM_TIMEFRAMES mML1Period = (ENUM_TIMEFRAMES)((int)l1PeriodStr); + result.l1Period = mML1Period; + } + + // + return result; +} + +// +// MEDIUM ... + +// +string l2MethodToken = "l2Method"; +string l2PeriodToken = "l2Period"; + +// +struct XMCConfig +{ + ENUM_X_PERIOD_METHOD l2Method; // How to Find Period + ENUM_TIMEFRAMES l2Period; // Time Period +}; + +// +string GenerateMCConfig( + ENUM_X_PERIOD_METHOD mML2Method = X_PERIOD_AUTO, // How to Find Period + ENUM_TIMEFRAMES mML2Period = NULL // Time Period +) +{ + // + string result = ""; + + // + result = + // + l2MethodToken + "(" + ToString(mML2Method) + ")" + + l2PeriodToken + "(" + ToString(mML2Period) + ")" + // + ; + + // + return result; +} + +// +string ToString(XMCConfig &config) +{ + return GenerateSCConfig( + config.l2Method, + config.l2Period); +} + +// +XMCConfig PrseMCConfig(string config) +{ + // + XMCConfig result; + + // + string l2MethodStr = ExtractString( + config, + l2MethodToken + "(", + ")"); + if (StringLen(l2MethodStr) > 0) + { + // + ENUM_X_PERIOD_METHOD mML2Method = (ENUM_X_PERIOD_METHOD)((int)l2MethodStr); + result.l2Method = mML2Method; + } + + // + string l2PeriodStr = ExtractString( + config, + l2PeriodToken + "(", + ")"); + if (StringLen(l2PeriodStr) > 0) + { + // + ENUM_TIMEFRAMES mML2Period = (ENUM_TIMEFRAMES)((int)l2PeriodStr); + result.l2Period = mML2Period; + } + + // + return result; +} + +// +// LONG ... + +// +string l3MethodToken = "l3Method"; +string l3PeriodToken = "l3Period"; + +// +struct XLCConfig +{ + ENUM_X_PERIOD_METHOD l3Method; // How to Find Period + ENUM_TIMEFRAMES l3Period; // Time Period +}; + +// +string GenerateLCConfig( + ENUM_X_PERIOD_METHOD mML3Method = X_PERIOD_AUTO, // How to Find Period + ENUM_TIMEFRAMES mML3Period = NULL // Time Period +) +{ + // + string result = ""; + + // + result = + // + l3MethodToken + "(" + ToString(mML3Method) + ")" + + l3PeriodToken + "(" + ToString(mML3Period) + ")" + // + ; + + // + return result; +} + +// +string ToString(XLCConfig &config) +{ + return GenerateSCConfig( + config.l3Method, + config.l3Period); +} + +// +XLCConfig PrseLCConfig(string config) +{ + // + XLCConfig result; + + // + string l3MethodStr = ExtractString( + config, + l3MethodToken + "(", + ")"); + if (StringLen(l3MethodStr) > 0) + { + // + ENUM_X_PERIOD_METHOD mML3Method = (ENUM_X_PERIOD_METHOD)((int)l3MethodStr); + result.l3Method = mML3Method; + } + + // + string l3PeriodStr = ExtractString( + config, + l3PeriodToken + "(", + ")"); + if (StringLen(l3PeriodStr) > 0) + { + // + ENUM_TIMEFRAMES mML3Period = (ENUM_TIMEFRAMES)((int)l3PeriodStr); + result.l3Period = mML3Period; + } + + // + return result; +} + +// +// HIND ... + +// +string l4MethodToken = "l4Method"; +string l4PeriodToken = "l4Period"; + +// +struct XHCConfig +{ + ENUM_X_PERIOD_METHOD l4Method; // How to Find Period + ENUM_TIMEFRAMES l4Period; // Time Period +}; + +// +string GenerateHCConfig( + ENUM_X_PERIOD_METHOD mML4Method = X_PERIOD_AUTO, // How to Find Period + ENUM_TIMEFRAMES mML4Period = NULL // Time Period +) +{ + // + string result = ""; + + // + result = + // + l4MethodToken + "(" + ToString(mML4Method) + ")" + + l4PeriodToken + "(" + ToString(mML4Period) + ")" + // + ; + + // + return result; +} + +// +string ToString(XHCConfig &config) +{ + return GenerateSCConfig( + config.l4Method, + config.l4Period); +} + +// +XHCConfig PrseHCConfig(string config) +{ + // + XHCConfig result; + + // + string l4MethodStr = ExtractString( + config, + l4MethodToken + "(", + ")"); + if (StringLen(l4MethodStr) > 0) + { + // + ENUM_X_PERIOD_METHOD mML4Method = (ENUM_X_PERIOD_METHOD)((int)l4MethodStr); + result.l4Method = mML4Method; + } + + // + string l4PeriodStr = ExtractString( + config, + l4PeriodToken + "(", + ")"); + if (StringLen(l4PeriodStr) > 0) + { + // + ENUM_TIMEFRAMES mML4Period = (ENUM_TIMEFRAMES)((int)l4PeriodStr); + result.l4Period = mML4Period; + } + + // + return result; +} + +// +// XFIBONACCI ... + +// +string fiboLevel1Token = "fiboLevel1"; +string fiboLevel2Token = "fiboLevel2"; +string fiboLevel3Token = "fiboLevel3"; +string fiboLevel4Token = "fiboLevel4"; +string fiboLevel5Token = "fiboLevel5"; + +// +struct XFiboConfig +{ + double fiboLevel1; // Fibio 1st Level + double fiboLevel2; // Fibio 2st Level + double fiboLevel3; // Fibio 3rd Level + double fiboLevel4; // Fibio 4th Level + double fiboLevel5; // Fibio 5th Level +}; + +// +string GenerateFibonacciConfig( + double mFiboLevel1 = 0.236, // Fibio 1st Level + double mFiboLevel2 = 0.382, // Fibio 2st Level + double mFiboLevel3 = 0.5, // Fibio 3rd Level + double mFiboLevel4 = 0.618, // Fibio 4th Level + double mFiboLevel5 = 0.764 // Fibio 5th Level +) +{ + // + string result = ""; + + // + result = + // + fiboLevel1Token + "(" + ToString(mFiboLevel1) + ")" + + fiboLevel2Token + "(" + ToString(mFiboLevel2) + ")" + + fiboLevel3Token + "(" + ToString(mFiboLevel3) + ")" + + fiboLevel4Token + "(" + ToString(mFiboLevel4) + ")" + + fiboLevel5Token + "(" + ToString(mFiboLevel5) + ")" + // + ; + + // + return result; +} + +// +string ToString(XFiboConfig &config) +{ + return GenerateFibonacciConfig( + config.fiboLevel1, + config.fiboLevel2, + config.fiboLevel3, + config.fiboLevel4, + config.fiboLevel5); +} + +// +XFiboConfig PrseFiboConfig(string config) +{ + // + XFiboConfig result; + + // + string fiboLevel1Str = ExtractString( + config, + fiboLevel1Token + "(", + ")"); + if (StringLen(fiboLevel1Str) > 0) + { + // + double mFiboLevel1 = (double)fiboLevel1Str; + result.fiboLevel1 = mFiboLevel1; + } + + // + string fiboLevel2Str = ExtractString( + config, + fiboLevel2Token + "(", + ")"); + if (StringLen(fiboLevel2Str) > 0) + { + // + double mFiboLevel2 = (double)fiboLevel2Str; + result.fiboLevel2 = mFiboLevel2; + } + + // + string fiboLevel3Str = ExtractString( + config, + fiboLevel3Token + "(", + ")"); + if (StringLen(fiboLevel3Str) > 0) + { + // + double mFiboLevel3 = (double)fiboLevel3Str; + result.fiboLevel3 = mFiboLevel3; + } + + // + string fiboLevel4Str = ExtractString( + config, + fiboLevel4Token + "(", + ")"); + if (StringLen(fiboLevel4Str) > 0) + { + // + double mFiboLevel4 = (double)fiboLevel4Str; + result.fiboLevel4 = mFiboLevel4; + } + + // + string fiboLevel5Str = ExtractString( + config, + fiboLevel5Token + "(", + ")"); + if (StringLen(fiboLevel5Str) > 0) + { + // + double mFiboLevel5 = (double)fiboLevel5Str; + result.fiboLevel5 = mFiboLevel5; + } + + // + return result; +} + +// +// BOUNDARYDETECTION ... + +// +string hhModeToken = "hhMode"; +string llModeToken = "llMode"; + +// +struct XBDConfig +{ + ENUM_SERIESMODE hhMode; // Highest High Calculation Method + ENUM_SERIESMODE llMode; // Lowest Low Calculation Method +}; + +// +string GenerateBDConfig( + ENUM_SERIESMODE mHhMode = MODE_HIGH, // Highest High Calculation Method + ENUM_SERIESMODE mLlMode = MODE_LOW // Lowest Low Calculation Method +) +{ + // + string result = ""; + + // + result = + // + hhModeToken + "(" + ToString((int)mHhMode) + ")" + + llModeToken + "(" + ToString((int)mLlMode) + ")" + // + ; + + // + return result; +} + +// +string ToString(XBDConfig &config) +{ + return GenerateBDConfig( + config.hhMode, + config.llMode); +} + +// +XBDConfig ParseBDConfig(string config) +{ + // + XBDConfig result; + + // + string hhModeStr = ExtractString( + config, + hhModeToken + "(", + ")"); + if (StringLen(hhModeStr) > 0) + { + // + ENUM_SERIESMODE mHhMode = (ENUM_SERIESMODE)((int)hhModeStr); + result.hhMode = mHhMode; + } + + // + string llModeStr = ExtractString( + config, + llModeToken + "(", + ")"); + if (StringLen(llModeStr) > 0) + { + // + ENUM_SERIESMODE mLlMode = (ENUM_SERIESMODE)((int)llModeStr); + result.llMode = mLlMode; + } + + // + return result; +} + +// +// TREND ... + +// +string trendMultiplierToken = "trendMultiplier"; +string trendPriceAppliedToToken = "trendPriceAppliedTo"; + +// +struct XTDConfig +{ + double trendMultiplier; // Multiplier + ENUM_APPLIED_PRICE trendPriceAppliedTo; // Applied To +}; + +// +string GenerateTDConfig( + double mTrendMultiplier = 3, // Multiplier + ENUM_APPLIED_PRICE mTrendPriceAppliedTo = PRICE_MEDIAN // Applied To +) +{ + // + string result = ""; + + // + result = + // + trendMultiplierToken + "(" + ToString(mTrendMultiplier) + ")" + + trendPriceAppliedToToken + "(" + ToString(mTrendPriceAppliedTo) + ")" + // + ; + + // + return result; +} + +// +string ToString(XTDConfig &config) +{ + return GenerateTDConfig( + config.trendMultiplier, + config.trendPriceAppliedTo); +} + +// +XTDConfig ParseTDConfig(string config) +{ + // + XTDConfig result; + + // + string trendMultiplierStr = ExtractString( + config, + trendMultiplierToken + "(", + ")"); + if (StringLen(trendMultiplierStr) > 0) + { + // + double mTrendMultiplier = (double)trendMultiplierStr; + result.trendMultiplier = mTrendMultiplier; + } + + // + string trendPriceAppliedToStr = ExtractString( + config, + trendPriceAppliedToToken + "(", + ")"); + if (StringLen(trendPriceAppliedToStr) > 0) + { + // + ENUM_APPLIED_PRICE mTrendPriceAppliedTo = (ENUM_APPLIED_PRICE)((int)trendPriceAppliedToStr); + // + result.trendPriceAppliedTo = mTrendPriceAppliedTo; + } + + // + return result; +} + +// +// RIBBON RB ... + +// +string ribbonModeToken = "ribbonMode"; + +// +struct XRBConfig +{ + ENUM_X_MA_METHOD ribbonMode; // How to Calculate +}; + +// +string GenerateRBConfig( + ENUM_X_MA_METHOD mRibbonMode = X_MA_AMA // How to Calculate +) +{ + // + string result = ""; + + // + result = + // + ribbonModeToken + "(" + ToString(mRibbonMode) + ")" + // + ; + + // + return result; +} + +// +string ToString(XRBConfig &config) +{ + // + return GenerateRBConfig( + config.ribbonMode); +} + +// +XRBConfig ParseRBConfig(string config) +{ + // + XRBConfig result; + + // + string ribbonModeStr = ExtractString( + config, + ribbonModeToken + "(", + ")"); + if (StringLen(ribbonModeStr) > 0) + { + // + ENUM_X_MA_METHOD mRibbonMode = (ENUM_X_MA_METHOD)((int)ribbonModeStr); + result.ribbonMode = mRibbonMode; + } + + // + return result; +} + +// +// HULL ... + +// +string hullDivisorToken = "hullDivisor"; +string hullUpAppliedToToken = "hullUpAppliedTo"; +string hullDownAppliedToToken = "hullDownAppliedTo"; + +// +struct XHullConfig +{ + double hullDivisor; // Divisor (Speed) + ENUM_APPLIED_PRICE hullUpAppliedTo; // Up Zone Applied to + ENUM_APPLIED_PRICE hullDownAppliedTo; // Down Zone Applied to +}; + +// +string GenerateHullConfig( + double mHullDivisor = 2.0, // Divisor (Speed) + ENUM_APPLIED_PRICE mHullUpAppliedTo = PRICE_HIGH, // Up Zone Applied to + ENUM_APPLIED_PRICE mHullDownAppliedTo = PRICE_LOW // Down Zone Applied to +) +{ + // + string result = ""; + + // + result = + // + hullDivisorToken + "(" + ToString(mHullDivisor) + ")" + + hullUpAppliedToToken + "(" + ToString(mHullUpAppliedTo) + ")" + + hullDownAppliedToToken + "(" + ToString(mHullDownAppliedTo) + ")" + // + ; + + // + return result; +} + +// +string ToString(XHullConfig &config) +{ + // + return GenerateHullConfig( + config.hullDivisor, + config.hullUpAppliedTo, + config.hullDownAppliedTo); +} + +// +XHullConfig ParseHullConfig(string config) +{ + // + XHullConfig result; + + // + string hullDivisorStr = ExtractString( + config, + hullDivisorToken + "(", + ")"); + if (StringLen(hullDivisorStr) > 0) + { + // + double mHullDivisor = (double)hullDivisorStr; + result.hullDivisor = mHullDivisor; + } + + // + string hullUpAppliedToStr = ExtractString( + config, + hullUpAppliedToToken + "(", + ")"); + if (StringLen(hullUpAppliedToStr) > 0) + { + // + ENUM_APPLIED_PRICE mHullUpAppliedTo = (ENUM_APPLIED_PRICE)((int)hullUpAppliedToStr); + result.hullUpAppliedTo = mHullUpAppliedTo; + } + + // + string hullDownAppliedToStr = ExtractString( + config, + hullDownAppliedToToken + "(", + ")"); + if (StringLen(hullDownAppliedToStr) > 0) + { + // + ENUM_APPLIED_PRICE mHullDownAppliedTo = (ENUM_APPLIED_PRICE)((int)hullDownAppliedToStr); + result.hullDownAppliedTo = mHullDownAppliedTo; + } + + // + return result; +} + +// +// SSLC ... + +// +string sslcModeToken = "sslcMode"; +string sslcUpAppliedToToken = "sslcUpAppliedTo"; +string sslcDownAppliedToToken = "sslcDownAppliedTo"; + +// +struct XSSLCConfig +{ + ENUM_X_MA_METHOD sslcMode; // How to Calculate + ENUM_APPLIED_PRICE sslcUpAppliedTo; // Up Applied To + ENUM_APPLIED_PRICE sslcDownAppliedTo; // Down Applied To +}; + +// +string GenerateSSLCConfig( + ENUM_X_MA_METHOD mSslcMode = X_MA_SMA, // How to Calculate + ENUM_APPLIED_PRICE mSslcUpAppliedTo = PRICE_HIGH, // Up Applied To + ENUM_APPLIED_PRICE mSslcDownAppliedTo = PRICE_LOW // Down Applied To +) +{ + // + string result; + + // + result = + // + sslcModeToken + "(" + ToString(mSslcMode) + ")" + + sslcUpAppliedToToken + "(" + ToString(mSslcUpAppliedTo) + ")" + + sslcDownAppliedToToken + "(" + ToString(mSslcDownAppliedTo) + ")" + // + ; + + // + return result; +} + +// +string ToString(XSSLCConfig &config) +{ + return GenerateSSLCConfig( + config.sslcMode, + config.sslcUpAppliedTo, + config.sslcDownAppliedTo); +} + +// +XSSLCConfig ParseSSLCConfig(string config) +{ + // + XSSLCConfig result; + + // + string sslcModeStr = ExtractString( + config, + sslcModeToken + "(", + ")"); + if (StringLen(sslcModeStr) > 0) + { + // + ENUM_X_MA_METHOD mSslcMode = (ENUM_X_MA_METHOD)((int)sslcModeStr); + result.sslcMode = mSslcMode; + } + + // + string sslcUpAppliedToStr = ExtractString( + config, + sslcUpAppliedToToken + "(", + ")"); + if (StringLen(sslcUpAppliedToStr) > 0) + { + // + ENUM_APPLIED_PRICE mSslcUpAppliedTo = (ENUM_APPLIED_PRICE)((int)sslcUpAppliedToStr); + result.sslcUpAppliedTo = mSslcUpAppliedTo; + } + + // + string sslcDownAppliedToStr = ExtractString( + config, + sslcDownAppliedToToken + "(", + ")"); + if (StringLen(sslcDownAppliedToStr) > 0) + { + // + ENUM_APPLIED_PRICE mSslcDownAppliedTo = (ENUM_APPLIED_PRICE)((int)sslcDownAppliedToStr); + result.sslcDownAppliedTo = mSslcDownAppliedTo; + } + + // + return result; +} + +// +// PRESENTATION ... + +// +string showCandleTimerToken = "showCandleTimer"; +string showCandlesToken = "showCandles"; +string showHKCandlesToken = "showHKCandles"; +string showSMHKCandlesToken = "showSMHKCandles"; +string showPeaksAndValesToken = "showPeaksAndVales"; +string showTrendsToken = "showTrends"; +string fillTrendsToken = "fillTrends"; +string showLevelsToken = "showLevels"; +string showConsolidationsToken = "showConsolidations"; +string showRibbonsToken = "showRibbons"; +string showHullToken = "showHull"; +string showSSLChannelToken = "showSSLChannel"; +string showFibo1LevelsToken = "showFibo1Levels"; +string showFibo2LevelsToken = "showFibo2Levels"; +string showFibo3LevelsToken = "showFibo3Levels"; +string showFibo4LevelsToken = "showFibo4Levels"; +string showFibo5LevelsToken = "showFibo5Levels"; + +// +struct XStylePresentationConfig +{ + bool showCandleTimer; // Show Candle Time + bool showCandles; // Show Candles + bool showHKCandles; // Draw Hiken Ashi Candle + bool showSMHKCandles; // Draw Smoothed Hiken Ashi Candle +}; + +// +string GenerateStylePresentationConfig( + bool mShowCandleTimer = true, // Show Candle Time + bool mShowCandles = true, // Show Candles + bool mShowHKCandles = false, // Draw Hiken Ashi Candle + bool mShowSMHKCandles = false // Draw Smoothed Hiken Ashi Candle +) +{ + // + string result = ""; + + // + result = + // + showCandleTimerToken + "(" + ToString(mShowCandleTimer) + ")" + + showCandlesToken + "(" + ToString(mShowCandles) + ")" + + showHKCandlesToken + "(" + ToString(mShowHKCandles) + ")" + + showSMHKCandlesToken + "(" + ToString(mShowSMHKCandles) + ")" + // + ; + + // + return result; +} + +// +XStylePresentationConfig ParseStylePresentationConfig(string config) +{ + // + XStylePresentationConfig result; + + // + string showCandleTimerStr = ExtractString( + config, + showCandleTimerToken + "(", + ")"); + if (StringLen(showCandleTimerStr) > 0) + { + // + bool mShowCandleTimer = ToBoolean(showCandleTimerStr); + result.showCandleTimer = mShowCandleTimer; + } + + // + string showCandlesStr = ExtractString( + config, + showCandlesToken + "(", + ")"); + if (StringLen(showCandlesStr) > 0) + { + // + bool mShowCandles = ToBoolean(showCandlesStr); + result.showCandles = mShowCandles; + } + + // + string showHKCandlesStr = ExtractString( + config, + showHKCandlesToken + "(", + ")"); + if (StringLen(showHKCandlesStr) > 0) + { + // + bool mShowHKCandles = ToBoolean(showHKCandlesStr); + result.showHKCandles = mShowHKCandles; + } + + // + string showSMHKCandlesStr = ExtractString( + config, + showSMHKCandlesToken + "(", + ")"); + if (StringLen(showSMHKCandlesStr) > 0) + { + // + bool mShowSMHKCandles = ToBoolean(showSMHKCandlesStr); + result.showSMHKCandles = mShowSMHKCandles; + } + + // + return result; +} + +// +string ToString(XStylePresentationConfig &config) +{ + // + return GenerateStylePresentationConfig( + config.showCandleTimer, + config.showCandles, + config.showHKCandles, + config.showSMHKCandles); +} + +// +struct XPVPresentationConfig +{ + bool showPeaksAndVales; // Show Peaks and Vales + bool showLevels; // Show Levels + bool showConsolidations; // Show Consolidations +}; + +// +string GeneratePVPresentationConfig( + bool mShowPeaksAndVales = true, // Show Peaks and Vales + bool mShowLevels = false, // Show Levels + bool mShowConsolidations = false // Show Consolidations +) +{ + // + string result; + + // + result = + // + showPeaksAndValesToken + "(" + ToString(mShowPeaksAndVales) + ")" + + showLevelsToken + "(" + ToString(mShowLevels) + ")" + + showConsolidationsToken + "(" + ToString(mShowConsolidations) + ")" + // + ; + + // + return result; +} + +// +string ToString(XPVPresentationConfig &config) +{ + // + return GeneratePVPresentationConfig( + config.showPeaksAndVales, + config.showLevels, + config.showConsolidations); +} + +// +XPVPresentationConfig ParsePVPresentationConfig(string config) +{ + // + XPVPresentationConfig result; + + // + string showPeaksAndValesStr = ExtractString( + config, + showPeaksAndValesToken + "(", + ")"); + if (StringLen(showPeaksAndValesStr) > 0) + { + // + bool mShowPeaksAndVales = ToBoolean(showPeaksAndValesStr); + result.showPeaksAndVales = mShowPeaksAndVales; + } + + // + string showLevelsStr = ExtractString( + config, + showLevelsToken + "(", + ")"); + if (StringLen(showLevelsStr) > 0) + { + // + bool mShowLevels = ToBoolean(showLevelsStr); + result.showLevels = mShowLevels; + } + + // + string showConsolidationsStr = ExtractString( + config, + showConsolidationsToken + "(", + ")"); + if (StringLen(showConsolidationsStr) > 0) + { + // + bool mShowConsolidations = ToBoolean(showConsolidationsStr); + result.showConsolidations = mShowConsolidations; + } + + // + return result; +} + +// +struct XTrendPresentationConfig +{ + bool showHull; // Show Hull + bool showTrends; // Show Trends + bool fillTrends; // Fill Trends + bool showRibbons; // Show Ribbons + bool showSSLChannel; // Show SSL Channel +}; + +// +string GenerateTrendPresentationConfig( + bool mShowTrends = true, // Show Trends + bool mFillTrends = false, // Fill Trends + bool mShowRibbons = false, // Show Ribbons + bool mShowHull = false, // Show Hull + bool mShowSSLChannel = false // Show SSL Channel +) +{ + // + string result; + + // + result = + // + showTrendsToken + "(" + ToString(mShowTrends) + ")" + + fillTrendsToken + "(" + ToString(mFillTrends) + ")" + + showRibbonsToken + "(" + ToString(mShowRibbons) + ")" + + showHullToken + "(" + ToString(mShowHull) + ")" + + showSSLChannelToken + "(" + ToString(mShowSSLChannel) + ")" + // + ; + + // + return result; +} + +// +string ToString(XTrendPresentationConfig &config) +{ + // + return GenerateTrendPresentationConfig( + config.showHull, + config.showTrends, + config.fillTrends, + config.showRibbons, + config.showSSLChannel); +} + +// +XTrendPresentationConfig ParseTrendPresentationConfig(string config) +{ + // + XTrendPresentationConfig result; + + // + string showTrendsStr = ExtractString( + config, + showTrendsToken + "(", + ")"); + if (StringLen(showTrendsStr) > 0) + { + // + bool mShowTrends = ToBoolean(showTrendsStr); + result.showTrends = mShowTrends; + } + + // + string fillTrendsStr = ExtractString( + config, + fillTrendsToken + "(", + ")"); + if (StringLen(fillTrendsStr) > 0) + { + // + bool mFillTrends = ToBoolean(fillTrendsStr); + result.fillTrends = mFillTrends; + } + + // + string showRibbonsStr = ExtractString( + config, + showRibbonsToken + "(", + ")"); + if (StringLen(showRibbonsStr) > 0) + { + // + bool mShowRibbons = ToBoolean(showRibbonsStr); + result.showRibbons = mShowRibbons; + } + + // + string showHullStr = ExtractString( + config, + showHullToken + "(", + ")"); + if (StringLen(showHullStr) > 0) + { + // + bool mShowHull = ToBoolean(showHullStr); + result.showHull = mShowHull; + } + + // + string showSSLChannelStr = ExtractString( + config, + showSSLChannelToken + "(", + ")"); + if (StringLen(showSSLChannelStr) > 0) + { + // + bool mShowSSLChannel = ToBoolean(showSSLChannelStr); + result.showSSLChannel = mShowSSLChannel; + } + + // + return result; +} + +// +struct XFiboPresentationConfig +{ + bool showFibo1Levels; // Show Fibo 1st Level + bool showFibo2Levels; // Show Fibo 2nd Level + bool showFibo3Levels; // Show Fibo 3rd Level + bool showFibo4Levels; // Show Fibo 4th Level + bool showFibo5Levels; // Show Fibo 5th Level +}; + +// +string GenerateFiboPresentationConfig( + bool mShowFibo1Levels = false, // Show Fibo 1st Level + bool mShowFibo2Levels = false, // Show Fibo 2nd Level + bool mShowFibo3Levels = false, // Show Fibo 3rd Level + bool mShowFibo4Levels = false, // Show Fibo 4th Level + bool mShowFibo5Levels = false // Show Fibo 5th Level +) +{ + // + string result = ""; + + // + result = + // + showFibo1LevelsToken + "(" + ToString(mShowFibo1Levels) + ")" + + showFibo2LevelsToken + "(" + ToString(mShowFibo2Levels) + ")" + + showFibo3LevelsToken + "(" + ToString(mShowFibo3Levels) + ")" + + showFibo4LevelsToken + "(" + ToString(mShowFibo4Levels) + ")" + + showFibo5LevelsToken + "(" + ToString(mShowFibo5Levels) + ")" + // + ; + + // + return result; +} + +// +string ToString(XFiboPresentationConfig &config) +{ + // + return GenerateFiboPresentationConfig( + config.showFibo1Levels, + config.showFibo2Levels, + config.showFibo3Levels, + config.showFibo4Levels, + config.showFibo5Levels); +} + +// +XFiboPresentationConfig ParePresentationConfig(string config) +{ + // + XFiboPresentationConfig result; + + // + string showFibo1LevelsStr = ExtractString( + config, + showFibo1LevelsToken + "(", + ")"); + if (StringLen(showFibo1LevelsStr) > 0) + { + // + bool mShowFibo1Levels = ToBoolean(showFibo1LevelsStr); + result.showFibo1Levels = mShowFibo1Levels; + } + + // + string showFibo2LevelsStr = ExtractString( + config, + showFibo2LevelsToken + "(", + ")"); + if (StringLen(showFibo2LevelsStr) > 0) + { + // + bool mShowFibo2Levels = ToBoolean(showFibo2LevelsStr); + result.showFibo2Levels = mShowFibo2Levels; + } + + // + string showFibo3LevelsStr = ExtractString( + config, + showFibo3LevelsToken + "(", + ")"); + if (StringLen(showFibo3LevelsStr) > 0) + { + // + bool mShowFibo3Levels = ToBoolean(showFibo3LevelsStr); + result.showFibo3Levels = mShowFibo3Levels; + } + + // + string showFibo4LevelsStr = ExtractString( + config, + showFibo4LevelsToken + "(", + ")"); + if (StringLen(showFibo4LevelsStr) > 0) + { + // + bool mShowFibo4Levels = ToBoolean(showFibo4LevelsStr); + result.showFibo4Levels = mShowFibo4Levels; + } + + // + string showFibo5LevelsStr = ExtractString( + config, + showFibo5LevelsToken + "(", + ")"); + if (StringLen(showFibo5LevelsStr) > 0) + { + // + bool mShowFibo5Levels = ToBoolean(showFibo5LevelsStr); + result.showFibo5Levels = mShowFibo5Levels; + } + + // + return result; +} + +// +// +//