diff --git a/Helpers/x-saherelm.x3ma.helper.mq5 b/Helpers/x-saherelm.x3ma.helper.mq5 new file mode 100644 index 00000000..b03ee756 --- /dev/null +++ b/Helpers/x-saherelm.x3ma.helper.mq5 @@ -0,0 +1,752 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCX3MAHelper +// 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 + +// +// Imports ... +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_X3MA_BUFFERS +{ + // + X3MA_FAST_LINE = 0, + X3MA_MID_LINE = 1, + X3MA_SLOW_LINE = 2, +}; + +// +// Input Models ... +struct X3MAInputs +{ + // + // Props ... + + // + // Market ... + int fastLength; // Fast Length + int midLength; // Mid Length + int slowLength; // Slow Length + int shiftLength; // Shift + ENUM_MA_METHOD method; // Mode + ENUM_APPLIED_PRICE appliedTo; // Applied To + + // + // Presentation ... + + // + bool showFast; // Show Fast + bool showMid; // Show Mid + bool showSlow; // Show Slow + + // + // Constructor(s) ... + X3MAInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + fastLength = 0; + midLength = 0; + slowLength = 0; + shiftLength = 0; + method = MODE_SMA; + appliedTo = PRICE_CLOSE; + + // + showFast = false; + showMid = false; + showSlow = false; + } + + // + // Default ... + void Default() + { + // + fastLength = 50; + midLength = 100; + slowLength = 200; + shiftLength = 0; + method = MODE_SMA; + appliedTo = PRICE_CLOSE; + + // + showFast = true; + showMid = true; + showSlow = true; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + fastLength > 2 && + midLength > fastLength && + slowLength > midLength && + // + shiftLength >= 0 + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(fastLength, midLength); + result = MathMax(result, slowLength); + + // + return result; + } +}; + +// +// Define Conditions ... +struct X3MAConditions +{ + // + // Common ... + string symbol; + ENUM_TIMEFRAMES period; + datetime time; + + // + // Buffers ... + + // + double fasts[]; + double mids[]; + double slows[]; + + // + // Conditions ... + + // + bool isFastOverMid; + bool isMidOverSlow; + + // + bool isFastUnderMid; + bool isMidUnderSlow; + + // + bool isBullishOrdered; + bool isBearishOrdered; + + // + bool isSwitchedToBullishOrdered; + bool isSwitchedToBearishOrdered; + + // + void Clean() + { + // + Clean(fasts); + Clean(mids); + Clean(slows); + + // + ArraySetAsSeries(fasts, true); + ArraySetAsSeries(mids, true); + ArraySetAsSeries(slows, true); + + // + isFastOverMid = false; + isMidOverSlow = false; + isFastUnderMid = false; + isMidUnderSlow = false; + isBullishOrdered = false; + isBearishOrdered = false; + isSwitchedToBullishOrdered = false; + isSwitchedToBearishOrdered = false; + } + + // + void GenerateScore( + double &bullishScore, + double &bearishScore // + ) + { + // + bullishScore = 0; + bearishScore = 0; + + // + // Since We have to Use this + // Only for Filtering Signals ... + // We Can Ignore Scoring ... + // or Complete this later ... + } + + // + string GenerateSummary( + bool onlyCommons = false, + bool onlyConditions = false, + bool includeScores = true, + bool ignoreFalseConditions = true, + string separator = "\n" // + ) + { + // + string result = NULL; + + // + double bullishScore = 0; + double bearishScore = 0; + GenerateScore( + bullishScore, + bearishScore // + ); + + // + string scoresStr = + // + "Scores: " + separator + + "---------------" + separator + + "Bullish: " + ToString(bullishScore) + separator + + "Bearish: " + ToString(bearishScore) + separator + + "" + // + ; + + // + string commonStr = GenerateSpecifiedCommonSummary( + this, + separator, + includeScores // + ); + + // + string conditionsStr = + // + "" + // + ; + + // + result = + // + "[" + GetTag() + "]" + separator + + (onlyConditions + ? "" + : commonStr) + + (!includeScores + ? "" + : scoresStr) + + " " + separator + + (onlyCommons + ? "" + : conditionsStr) + + "" + // + ; + + // + return result; + } + + // + string GetTag() + { + return "X3MA"; + } +}; + +// +// Class ... +class XSCX3MAHelper : public XSCBaseHelper +{ + // + // Public ... + public: + // + // Props ... + + // + // Constructors ... + XSCX3MAHelper() + : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCX3MAHelper() + { + // + Clean(fastBuffer); + Clean(midBuffer); + Clean(slowBuffer); + } + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + X3MAInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(fastBuffer, true); + ArraySetAsSeries(midBuffer, true); + ArraySetAsSeries(slowBuffer, true); + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.x3ma", + // + // Inputs ... + // + // Market ... + "", + mInputs.fastLength, + mInputs.midLength, + mInputs.slowLength, + mInputs.shiftLength, + mInputs.method, + mInputs.appliedTo, + // + // Presentation ... + "", + // + mInputs.showFast, + mInputs.showMid, + mInputs.showSlow + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + X3MAInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + X3MAInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Buffers ... + + // + double GetFast( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(fastBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return fastBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyFast( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + fastBuffer, + buffer, + forceClean + // + ); + } + + // + double GetMid( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(midBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return midBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyMid( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + midBuffer, + buffer, + forceClean + // + ); + } + + // + double GetSlow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(slowBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return slowBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopySlow( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + slowBuffer, + buffer, + forceClean + // + ); + } + + // + // Conditions ... + + // + bool GetConditions( + X3MAConditions &conditions, // + int barIndex = 0, // + int loopback = 5 // + ) + { + // + bool result = true; + + // + if (loopback < 3) + { + loopback = 3; + } + + // + conditions.Clean(); + + // + conditions.symbol = mSymbol; + conditions.period = mPeriod; + conditions.time = TimeCurrent(); + + // + int zIndex = barIndex; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + // Buffers ... + + // + // Fast ... + CopyFast( + zIndex, + loopback, + conditions.fasts // + ); + + // + // Mid ... + CopyMid( + zIndex, + loopback, + conditions.mids // + ); + + // + // Slow ... + CopySlow( + zIndex, + loopback, + conditions.slows // + ); + + // + // Conditions ... + + // + bool isFastOverMid = + conditions.fasts[cIndex] > conditions.mids[cIndex]; + bool isFastOverMidPrev = + conditions.fasts[pIndex] > conditions.mids[pIndex]; + + // + bool isMidOverSlow = + conditions.mids[cIndex] > conditions.slows[cIndex]; + bool isMidOverSlowPrev = + conditions.mids[pIndex] > conditions.slows[pIndex]; + + // + bool isFastUnderMid = + conditions.fasts[cIndex] < conditions.mids[cIndex]; + bool isFastUnderMidPrev = + conditions.fasts[pIndex] < conditions.mids[pIndex]; + + // + bool isMidUnderSlow = + conditions.mids[cIndex] < conditions.slows[cIndex]; + bool isMidUnderSlowPrev = + conditions.mids[pIndex] < conditions.slows[pIndex]; + + // + bool isBullishOrdered = isFastOverMid && + isMidOverSlow; + bool isBullishOrderedPrev = isFastOverMidPrev && + isMidOverSlowPrev; + + // + bool isBearishOrdered = isFastUnderMid && + isMidUnderSlow; + bool isBearishOrderedPrev = isFastUnderMidPrev && + isMidUnderSlowPrev; + + // + bool isSwitchedToBullishOrdered = isBullishOrdered && + !isBullishOrderedPrev; + bool isSwitchedToBearishOrdered = isBearishOrdered && + !isBearishOrderedPrev; + + // + conditions.isFastOverMid = isFastOverMid; + conditions.isMidOverSlow = isMidOverSlow; + conditions.isFastUnderMid = isFastUnderMid; + conditions.isMidUnderSlow = isMidUnderSlow; + conditions.isBullishOrdered = isBullishOrdered; + conditions.isBearishOrdered = isBearishOrdered; + conditions.isSwitchedToBullishOrdered = isSwitchedToBullishOrdered; + conditions.isSwitchedToBearishOrdered = isSwitchedToBearishOrdered; + + // + return result; + } + + // + // Protected ... + protected: + // + // Private ... + private: + // + // Props ... + X3MAInputs mInputs; // Inputs ... + + // + // Buffers ... + double fastBuffer[]; + double midBuffer[]; + double slowBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + if (totalBars > 1000) + { + totalBars = 1000; + } + + // + // Fast ... + CopyBuffer( + mHandler, + X3MA_FAST_LINE, + 0, + totalBars, + fastBuffer + // + ); + + // + // Mid ... + CopyBuffer( + mHandler, + X3MA_MID_LINE, + 0, + totalBars, + midBuffer + // + ); + + // + // Slow ... + CopyBuffer( + mHandler, + X3MA_SLOW_LINE, + 0, + totalBars, + slowBuffer + // + ); + } +}; + +// \ No newline at end of file diff --git a/Helpers/x-saherelm.x3vwap.helper.mq5 b/Helpers/x-saherelm.x3vwap.helper.mq5 new file mode 100644 index 00000000..5d958913 --- /dev/null +++ b/Helpers/x-saherelm.x3vwap.helper.mq5 @@ -0,0 +1,1140 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCX3VWAPHelper +// 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 + +// +// Imports ... +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_X3VWAP_BUFFERS +{ + // + X3VWAP_FAST_LINE = 0, + X3VWAP_FAST_STATE_LINE = 8, + X3VWAP_MID_LINE = 1, + X3VWAP_MID_STATE_LINE = 9, + X3VWAP_SLOW_LINE = 2, + X3VWAP_SLOW_STATE_LINE = 10, +}; + +// +enum ENUM_X3VWAP_STATES +{ + // + X3VWAP_STATE_BULLISH = 1, + X3VWAP_STATE_BEARISH = 2, + X3VWAP_STATE_NEUTURAL = 3, +}; + +// +// Input Models ... +struct X3VWAPInputs +{ + // + // Props ... + + // + // Market ... + int fastLength; // Fast Length + int midLength; // Mid Length + int slowLength; // Slow Length + + // + // Presentation ... + + // + bool showFast; // Show Fast + bool showMid; // Show Mid + bool showSlow; // Show Slow + + // + // Constructor(s) ... + X3VWAPInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + fastLength = 0; + midLength = 0; + slowLength = 0; + + // + showFast = false; + showMid = false; + showSlow = false; + } + + // + // Default ... + void Default() + { + // + fastLength = 50; + midLength = 100; + slowLength = 200; + + // + showFast = true; + showMid = true; + showSlow = true; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + fastLength > 2 && + midLength > fastLength && + slowLength > midLength + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(fastLength, midLength); + result = MathMax(result, slowLength); + + // + return result; + } +}; + +// +// Define Conditions ... +struct X3VWAPConditions +{ + // + // Common ... + string symbol; + ENUM_TIMEFRAMES period; + datetime time; + + // + // Buffers ... + + // + double fasts[]; + double fastStates[]; + double mids[]; + double midStates[]; + double slows[]; + double slowStates[]; + + // + // Conditions ... + + // + bool isFastBullish; + bool isFastBearish; + bool isFastNeutural; + + // + bool isMidBullish; + bool isMidBearish; + bool isMidNeutural; + + // + bool isSlowBullish; + bool isSlowBearish; + bool isSlowNeutural; + + // + bool isFastOverMid; + bool isMidOverSlow; + + // + bool isFastUnderMid; + bool isMidUnderSlow; + + // + bool isBullishState; + bool isBearishState; + bool isNeuturalState; + + // + bool isBullishOrdered; + bool isBearishOrdered; + + // + bool isSwitchedToBullishOrdered; + bool isSwitchedToBearishOrdered; + + // + bool isSwitchedToBullishState; + bool isSwitchedToBearishState; + bool isSwitchedToNeuturalState; + + // + void Clean() + { + // + Clean(fasts); + Clean(mids); + Clean(slows); + + // + Clean(fastStates); + Clean(midStates); + Clean(slowStates); + + // + ArraySetAsSeries(fasts, true); + ArraySetAsSeries(mids, true); + ArraySetAsSeries(slows, true); + + // + ArraySetAsSeries(fastStates, true); + ArraySetAsSeries(midStates, true); + ArraySetAsSeries(slowStates, true); + + // + isFastBullish = false; + isFastBearish = false; + isFastNeutural = false; + isMidBullish = false; + isMidBearish = false; + isMidNeutural = false; + isSlowBullish = false; + isSlowBearish = false; + isSlowNeutural = false; + isFastOverMid = false; + isMidOverSlow = false; + isFastUnderMid = false; + isMidUnderSlow = false; + isBullishState = false; + isBearishState = false; + isNeuturalState = false; + isBullishOrdered = false; + isBearishOrdered = false; + isSwitchedToBullishOrdered = false; + isSwitchedToBearishOrdered = false; + isSwitchedToBullishState = false; + isSwitchedToBearishState = false; + isSwitchedToNeuturalState = false; + } + + // + void GenerateScore( + double &bullishScore, + double &bearishScore // + ) + { + // + bullishScore = 0; + bearishScore = 0; + + // + // Since We have to Use this + // Only for Filtering Signals ... + // We Can Ignore Scoring ... + // or Complete this later ... + } + + // + string GenerateSummary( + bool onlyCommons = false, + bool onlyConditions = false, + bool includeScores = true, + bool ignoreFalseConditions = true, + string separator = "\n" // + ) + { + // + string result = NULL; + + // + double bullishScore = 0; + double bearishScore = 0; + GenerateScore( + bullishScore, + bearishScore // + ); + + // + string scoresStr = + // + "Scores: " + separator + + "---------------" + separator + + "Bullish: " + ToString(bullishScore) + separator + + "Bearish: " + ToString(bearishScore) + separator + + "" + // + ; + + // + string commonStr = GenerateSpecifiedCommonSummary( + this, + separator, + includeScores // + ); + + // + string conditionsStr = + // + "" + // + ; + + // + result = + // + "[" + GetTag() + "]" + separator + + (onlyConditions + ? "" + : commonStr) + + (!includeScores + ? "" + : scoresStr) + + " " + separator + + (onlyCommons + ? "" + : conditionsStr) + + "" + // + ; + + // + return result; + } + + // + string GetTag() + { + return "X3VWAP"; + } +}; + +// +// Class ... +class XSCX3VWAPHelper : public XSCBaseHelper +{ + // + // Public ... + public: + // + // Props ... + + // + // Constructors ... + XSCX3VWAPHelper() + : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCX3VWAPHelper() + { + // + Clean(fastBuffer); + Clean(midBuffer); + Clean(slowBuffer); + } + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + X3VWAPInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(fastBuffer, true); + ArraySetAsSeries(fastStateBuffer, true); + + // + ArraySetAsSeries(midBuffer, true); + ArraySetAsSeries(midStateBuffer, true); + + // + ArraySetAsSeries(slowBuffer, true); + ArraySetAsSeries(slowStateBuffer, true); + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.x3vwap", + // + // Inputs ... + // + // Market ... + "", + mInputs.fastLength, + mInputs.midLength, + mInputs.slowLength, + // + // Presentation ... + "", + // + mInputs.showFast, + mInputs.showMid, + mInputs.showSlow + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + X3VWAPInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + X3VWAPInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Buffers ... + + // + double GetFast( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(fastBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return fastBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyFast( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + fastBuffer, + buffer, + forceClean + // + ); + } + + // + double GetFastState( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(fastStateBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return fastStateBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyFastState( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + fastStateBuffer, + buffer, + forceClean + // + ); + } + + // + double GetMid( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(midBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return midBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyMid( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + midBuffer, + buffer, + forceClean + // + ); + } + + // + double GetMidState( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(midStateBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return midStateBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyMidState( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + midStateBuffer, + buffer, + forceClean + // + ); + } + + // + double GetSlow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(slowBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return slowBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopySlow( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + slowBuffer, + buffer, + forceClean + // + ); + } + + // + double GetSlowState( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(slowStateBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return slowStateBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopySlowState( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + slowStateBuffer, + buffer, + forceClean + // + ); + } + + // + // Converts to State ... + ENUM_X3VWAP_STATES ToState(double value) + { + // + ENUM_X3VWAP_STATES result = + value == 1 + ? X3VWAP_STATE_BULLISH + : value == 2 + ? X3VWAP_STATE_BEARISH + : X3VWAP_STATE_NEUTURAL; + + // + return result; + } + + // + bool IsBullish(double value) + { + // + bool result = false; + + // + result = ToState(value) == X3VWAP_STATE_BULLISH; + + // + return result; + } + + // + bool IsBearish(double value) + { + // + bool result = false; + + // + result = ToState(value) == X3VWAP_STATE_BEARISH; + + // + return result; + } + + // + bool IsNeutural(double value) + { + // + bool result = false; + + // + result = ToState(value) == X3VWAP_STATE_NEUTURAL; + + // + return result; + } + + // + // Conditions ... + + // + bool GetConditions( + X3VWAPConditions &conditions, // + int barIndex = 0, // + int loopback = 5 // + ) + { + // + bool result = true; + + // + if (loopback < 3) + { + loopback = 3; + } + + // + conditions.Clean(); + + // + conditions.symbol = mSymbol; + conditions.period = mPeriod; + conditions.time = TimeCurrent(); + + // + int zIndex = barIndex; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + // Buffers ... + + // + // Fast ... + CopyFast( + zIndex, + loopback, + conditions.fasts // + ); + CopyFastState( + zIndex, + loopback, + conditions.fastStates // + ); + + // + // Mid ... + CopyMid( + zIndex, + loopback, + conditions.mids // + ); + CopyMidState( + zIndex, + loopback, + conditions.midStates // + ); + + // + // Slow ... + CopySlow( + zIndex, + loopback, + conditions.slows // + ); + CopySlowState( + zIndex, + loopback, + conditions.slowStates // + ); + + // + // Conditions ... + + // + bool isFastBullish = IsBullish(conditions.fastStates[cIndex]); + bool isFastBullishPrev = IsBullish(conditions.fastStates[pIndex]); + + // + bool isFastBearish = IsBearish(conditions.fastStates[cIndex]); + bool isFastBearishPrev = IsBearish(conditions.fastStates[pIndex]); + + // + bool isFastNeutural = IsNeutural(conditions.fastStates[cIndex]); + bool isFastNeuturalPrev = IsNeutural(conditions.fastStates[pIndex]); + + // + bool isMidBullish = IsBullish(conditions.midStates[cIndex]); + bool isMidBullishPrev = IsBullish(conditions.midStates[pIndex]); + + // + bool isMidBearish = IsBearish(conditions.midStates[cIndex]); + bool isMidBearishPrev = IsBearish(conditions.midStates[pIndex]); + + // + bool isMidNeutural = IsNeutural(conditions.midStates[cIndex]); + bool isMidNeuturalPrev = IsNeutural(conditions.midStates[pIndex]); + + // + bool isSlowBullish = IsBullish(conditions.slowStates[cIndex]); + bool isSlowBullishPrev = IsBullish(conditions.slowStates[pIndex]); + + // + bool isSlowBearish = IsBearish(conditions.slowStates[cIndex]); + bool isSlowBearishPrev = IsBearish(conditions.slowStates[pIndex]); + + // + bool isSlowNeutural = IsNeutural(conditions.slowStates[cIndex]); + bool isSlowNeuturalPrev = IsNeutural(conditions.slowStates[pIndex]); + + // + bool isFastOverMid = + conditions.fasts[cIndex] > conditions.mids[cIndex]; + bool isFastOverMidPrev = + conditions.fasts[pIndex] > conditions.mids[pIndex]; + + // + bool isMidOverSlow = + conditions.mids[cIndex] > conditions.slows[cIndex]; + bool isMidOverSlowPrev = + conditions.mids[pIndex] > conditions.slows[pIndex]; + + // + bool isFastUnderMid = + conditions.fasts[cIndex] < conditions.mids[cIndex]; + bool isFastUnderMidPrev = + conditions.fasts[pIndex] < conditions.mids[pIndex]; + + // + bool isMidUnderSlow = + conditions.mids[cIndex] < conditions.slows[cIndex]; + bool isMidUnderSlowPrev = + conditions.mids[pIndex] < conditions.slows[pIndex]; + + // + bool isBullishState = isFastBullish && + isMidBullish && + isSlowBullish; + bool isBullishStatePrev = isFastBullishPrev && + isMidBullishPrev && + isSlowBullishPrev; + + // + bool isBearishState = isFastBearish && + isMidBearish && + isSlowBearish; + bool isBearishStatePrev = isFastBearishPrev && + isMidBearishPrev && + isSlowBearishPrev; + + // + bool isNeuturalState = isFastNeutural && + isMidNeutural && + isSlowNeutural; + bool isNeuturalStatePrev = isFastNeuturalPrev && + isMidNeuturalPrev && + isSlowNeuturalPrev; + + // + bool isBullishOrdered = isFastOverMid && + isMidOverSlow; + bool isBullishOrderedPrev = isFastOverMidPrev && + isMidOverSlowPrev; + + // + bool isBearishOrdered = isFastUnderMid && + isMidUnderSlow; + bool isBearishOrderedPrev = isFastUnderMidPrev && + isMidUnderSlowPrev; + + // + bool isSwitchedToBullishOrdered = isBullishOrdered && + !isBullishOrderedPrev; + bool isSwitchedToBearishOrdered = isBearishOrdered && + !isBearishOrderedPrev; + + // + bool isSwitchedToBullishState = isBullishState && + !isBullishStatePrev; + bool isSwitchedToBearishState = isBearishState && + !isBearishStatePrev; + bool isSwitchedToNeuturalState = isNeuturalState && + !isNeuturalStatePrev; + + // + conditions.isFastBullish = isFastBullish; + conditions.isFastBearish = isFastBearish; + conditions.isFastNeutural = isFastNeutural; + conditions.isMidBullish = isMidBullish; + conditions.isMidBearish = isMidBearish; + conditions.isMidNeutural = isMidNeutural; + conditions.isSlowBullish = isSlowBullish; + conditions.isSlowBearish = isSlowBearish; + conditions.isSlowNeutural = isSlowNeutural; + conditions.isFastOverMid = isFastOverMid; + conditions.isMidOverSlow = isMidOverSlow; + conditions.isFastUnderMid = isFastUnderMid; + conditions.isMidUnderSlow = isMidUnderSlow; + conditions.isBullishState = isBullishState; + conditions.isBearishState = isBearishState; + conditions.isNeuturalState = isNeuturalState; + conditions.isBullishOrdered = isBullishOrdered; + conditions.isBearishOrdered = isBearishOrdered; + conditions.isSwitchedToBullishOrdered = isSwitchedToBullishOrdered; + conditions.isSwitchedToBearishOrdered = isSwitchedToBearishOrdered; + conditions.isSwitchedToBullishState = isSwitchedToBullishState; + conditions.isSwitchedToBearishState = isSwitchedToBearishState; + conditions.isSwitchedToNeuturalState = isSwitchedToNeuturalState; + + // + return result; + } + + // + // Protected ... + protected: + // + // Private ... + private: + // + // Props ... + X3VWAPInputs mInputs; // Inputs ... + + // + // Buffers ... + double fastBuffer[]; + double fastStateBuffer[]; + double midBuffer[]; + double midStateBuffer[]; + double slowBuffer[]; + double slowStateBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + if (totalBars > 1000) + { + totalBars = 1000; + } + + // + // Fast ... + CopyBuffer( + mHandler, + X3VWAP_FAST_LINE, + 0, + totalBars, + fastBuffer + // + ); + CopyBuffer( + mHandler, + X3VWAP_FAST_STATE_LINE, + 0, + totalBars, + fastStateBuffer + // + ); + + // + // Mid ... + CopyBuffer( + mHandler, + X3VWAP_MID_LINE, + 0, + totalBars, + midBuffer + // + ); + CopyBuffer( + mHandler, + X3VWAP_MID_STATE_LINE, + 0, + totalBars, + midStateBuffer + // + ); + + // + // Slow ... + CopyBuffer( + mHandler, + X3VWAP_SLOW_LINE, + 0, + totalBars, + slowBuffer + // + ); + CopyBuffer( + mHandler, + X3VWAP_SLOW_STATE_LINE, + 0, + totalBars, + slowStateBuffer + // + ); + } +}; + +// \ No newline at end of file diff --git a/Indicators/x-saherelm.x3ma.mq5 b/Indicators/x-saherelm.x3ma.mq5 new file mode 100644 index 00000000..399a9c3c --- /dev/null +++ b/Indicators/x-saherelm.x3ma.mq5 @@ -0,0 +1,394 @@ +/////////////////////////////////////////////////////// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------- +// Name: X3MA +// Description: X3MA Trend Detector ... +// +// 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 X3MA Indicator" +#property strict + +// +#define ShortName "X3MA" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Inputs ... + +// +// Market ... +input group "Market"; +input int fastLength = 50; // Fast Length +input int midLength = 100; // Mid Length +input int slowLength = 200; // Slow Length +input int shiftLength = 0; // Shift +input ENUM_MA_METHOD method = MODE_SMA; // Mode +input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Applied To + +// +// Presentation ... +input group "Presentation"; + +// +// Parts ... +input bool showFast = true; // Show Fast +input bool showMid = true; // Show Mid +input bool showSlow = true; // Show Slow + +// +// Buffers ... + +// +#property indicator_chart_window + +// +#property indicator_buffers 3 +#property indicator_plots 3 + +// +// Current ... + +// +// Fast ... +#define fastBufferIndex 0 +double fastBuffer[]; + +// +#property indicator_label1 "X3MA F" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrAqua +#property indicator_style1 STYLE_DOT +#property indicator_width1 1 + +// +// Mid ... +#define midBufferIndex 1 +double midBuffer[]; + +// +#property indicator_label2 "X3MA M" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrOrange +#property indicator_style2 STYLE_DOT +#property indicator_width2 1 + +// +// Slow ... +#define slowBufferIndex 2 +double slowBuffer[]; + +// +#property indicator_label3 "X3MA S" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrMagenta +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +// Variables ... + +// +int maxLength; + +// +// Handlers ... +int fastHandler = INVALID_HANDLE; +int midHandler = INVALID_HANDLE; +int slowHandler = INVALID_HANDLE; + +// +// EVENT Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + if (!InitHandlers()) + { + 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 + + // + // Release Handlers ... + IndicatorRelease(fastHandler); + IndicatorRelease(midHandler); + IndicatorRelease(slowHandler); +} + +// +// Calculating what we want ... +int OnCalculate( + const int rates_total, // Total Bars on Chart ... + const int prev_calculated, // Total Calculated Bars on Charts ... + const datetime &time[], // History of Open Time ... + const double &open[], // History of Open Price ... + const double &high[], // History of High Price ... + const double &low[], // History of Low Price ... + const double &close[], // History of Close Price ... + const long &tick_volume[], // History of Tick Volumes on Bar ... + const long &volume[], // History of Trade Volumes ... + const int &spread[] // History of Spread Price ... +) +{ + // + ArraySetAsSeries(low, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(close, true); + + // + // this counts Available Bars ... + int limit; + + // + // Validate Calculated Bars ... + bool isPassedRequiredCalculatedBars = + // + BarsCalculated(fastHandler) >= maxLength && + BarsCalculated(midHandler) >= maxLength && + BarsCalculated(slowHandler) >= maxLength + // + ; + if (!isPassedRequiredCalculatedBars) + { + return prev_calculated; + } + + // + limit = + (prev_calculated > rates_total || prev_calculated <= 0) + ? rates_total + : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + + // + int copiedFasts = CopyBuffer(fastHandler, 0, 0, limit, fastBuffer); + int copiedMids = CopyBuffer(midHandler, 0, 0, limit, midBuffer); + int copiedSlows = CopyBuffer(slowHandler, 0, 0, limit, slowBuffer); + + // + // Validate Copied Items ... + bool isPassedRequiredCopiedItems = + // + copiedFasts > 0 && + copiedMids > 0 && + copiedSlows > 0 + // + ; + if (!isPassedRequiredCopiedItems) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + } + + // + return rates_total; +} + +// +// CUSTOM Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + fastLength > 2 && + midLength > fastLength && + slowLength > midLength && + // + shiftLength >= 0 + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Current ... + result = MathMax(fastLength, midLength); + result = MathMax(result, slowLength); + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + IndicatorSetInteger(INDICATOR_DIGITS, _Digits); + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Fast ... + bool canShowFast = showFast; + ENUM_DRAW_TYPE fastDrawType = canShowFast ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(fastBuffer, true); + SetIndexBuffer(fastBufferIndex, fastBuffer, INDICATOR_DATA); + PlotIndexSetDouble(fastBufferIndex, PLOT_EMPTY_VALUE, 0); + PlotIndexSetInteger(fastBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fastBufferIndex, PLOT_SHOW_DATA, canShowFast); + PlotIndexSetInteger(fastBufferIndex, PLOT_DRAW_TYPE, fastDrawType); + + // + // Mid ... + bool canShowMid = showMid; + ENUM_DRAW_TYPE midDrawType = canShowMid ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(midBuffer, true); + SetIndexBuffer(midBufferIndex, midBuffer, INDICATOR_DATA); + PlotIndexSetDouble(midBufferIndex, PLOT_EMPTY_VALUE, 0); + PlotIndexSetInteger(midBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(midBufferIndex, PLOT_SHOW_DATA, canShowMid); + PlotIndexSetInteger(midBufferIndex, PLOT_DRAW_TYPE, midDrawType); + + // + // Slow ... + bool canShowSlow = showSlow; + ENUM_DRAW_TYPE slowDrawType = canShowSlow ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(slowBuffer, true); + SetIndexBuffer(slowBufferIndex, slowBuffer, INDICATOR_DATA); + PlotIndexSetDouble(slowBufferIndex, PLOT_EMPTY_VALUE, 0); + PlotIndexSetInteger(slowBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slowBufferIndex, PLOT_SHOW_DATA, canShowSlow); + PlotIndexSetInteger(slowBufferIndex, PLOT_DRAW_TYPE, slowDrawType); +} + +// +// Initial Indicator Handlers ... +bool InitHandlers() +{ + // + bool result = false; + + // + // Initialize Handlers ... + + // + // Fast ... + fastHandler = iMA( + _Symbol, + _Period, + fastLength, + shiftLength, + method, + appliedTo // + ); + + // + // Mid ... + midHandler = iMA( + _Symbol, + _Period, + midLength, + shiftLength, + method, + appliedTo // + ); + + // + // Slow ... + slowHandler = iMA( + _Symbol, + _Period, + slowLength, + shiftLength, + method, + appliedTo // + ); + + // + result = + // + fastHandler != INVALID_HANDLE && + midHandler != INVALID_HANDLE && + slowHandler != INVALID_HANDLE + // + ; + + // + return result; +} + +// \ No newline at end of file diff --git a/Indicators/x-saherelm.x3vwap.mq5 b/Indicators/x-saherelm.x3vwap.mq5 new file mode 100644 index 00000000..7cfceaae --- /dev/null +++ b/Indicators/x-saherelm.x3vwap.mq5 @@ -0,0 +1,566 @@ +/////////////////////////////////////////////////////// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------- +// Name: X3VWAP +// Description: X3VWAP Trend Detector ... +// +// 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 X3VWAP Indicator" +#property strict + +// +#define ShortName "X3VWAP" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Inputs ... + +// +// Market ... +input group "Market"; +input int fastLength = 50; // Fast Length +input int midLength = 100; // Mid Length +input int slowLength = 200; // Slow Length + +// +// Presentation ... +input group "Presentation"; + +// +// Parts ... +input bool showFast = true; // Show Fast +input bool showMid = true; // Show Mid +input bool showSlow = true; // Show Slow + +// +// Buffers ... + +// +#property indicator_chart_window + +// +#property indicator_buffers 11 +#property indicator_plots 3 + +// +#define hideColorIDX 0 +#define bullishColorIDX 1 +#define bearishColorIDX 2 +#define neuturalColorIDX 3 + +// +// Current ... + +// +// Fast ... +#define fastBufferIndex 0 +double fastBuffer[]; + +#define fastColorBufferIndex 1 +double fastColorBuffer[]; + +// +#define fastPlotBufferIndex 0 +#property indicator_label1 "X3VWAP F" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 CLR_NONE, clrGreen, clrRed, clrGray +#property indicator_style1 STYLE_DOT +#property indicator_width1 1 + +// +// Mid ... +#define midBufferIndex 2 +double midBuffer[]; + +#define midColorBufferIndex 3 +double midColorBuffer[]; + +// +#define midPlotBufferIndex 1 +#property indicator_label2 "X3VWAP M" +#property indicator_type2 DRAW_COLOR_LINE +#property indicator_color2 CLR_NONE, clrGreen, clrRed, clrGray +#property indicator_style2 STYLE_DOT +#property indicator_width2 1 + +// +// Slow ... +#define slowBufferIndex 4 +double slowBuffer[]; + +#define slowColorBufferIndex 5 +double slowColorBuffer[]; + +// +#define slowPlotBufferIndex 2 +#property indicator_label3 "X3VWAP S" +#property indicator_type3 DRAW_COLOR_LINE +#property indicator_color3 CLR_NONE, clrGreen, clrRed, clrGray +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +// Data Buffers ... + +// +// Volumes ... +#define volumeBufferIndex 6 +double volumeBuffer[]; + +// +// Price ... +#define priceBufferIndex 7 +double priceBuffer[]; + +// +// Fast State ... +#define fastStateBufferIndex 8 +double fastStateBuffer[]; + +// +// Mid State ... +#define midStateBufferIndex 9 +double midStateBuffer[]; + +// +// Slow State ... +#define slowStateBufferIndex 10 +double slowStateBuffer[]; + +// +// Variables ... + +// +int maxLength; + +// +// 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 +} + +// +// Calculating what we want ... +int OnCalculate( + const int rates_total, // Total Bars on Chart ... + const int prev_calculated, // Total Calculated Bars on Charts ... + const datetime &time[], // History of Open Time ... + const double &open[], // History of Open Price ... + const double &high[], // History of High Price ... + const double &low[], // History of Low Price ... + const double &close[], // History of Close Price ... + const long &tick_volume[], // History of Tick Volumes on Bar ... + const long &volume[], // History of Trade Volumes ... + const int &spread[] // History of Spread Price ... +) +{ + // + ArraySetAsSeries(low, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + + // + // this counts Available Bars ... + int limit; + + // + limit = + (prev_calculated > rates_total || prev_calculated <= 0) + ? rates_total + : (rates_total - prev_calculated) + 1; + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers( + i, + prev_calculated, + rates_total, + // + open, + high, + close, + low, + tick_volume // + ); + } + + // + return rates_total; +} + +// +// CUSTOM Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + fastLength > 2 && + midLength > fastLength && + slowLength > midLength + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Current ... + result = MathMax(fastLength, midLength); + result = MathMax(result, slowLength); + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + IndicatorSetInteger(INDICATOR_DIGITS, _Digits); + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Fast ... + ArraySetAsSeries(fastBuffer, true); + ArraySetAsSeries(fastColorBuffer, true); + SetIndexBuffer(fastBufferIndex, fastBuffer, INDICATOR_DATA); + SetIndexBuffer(fastColorBufferIndex, fastColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Mid ... + ArraySetAsSeries(midBuffer, true); + ArraySetAsSeries(midColorBuffer, true); + SetIndexBuffer(midBufferIndex, midBuffer, INDICATOR_DATA); + SetIndexBuffer(midColorBufferIndex, midColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Slow ... + ArraySetAsSeries(slowBuffer, true); + ArraySetAsSeries(slowColorBuffer, true); + SetIndexBuffer(slowBufferIndex, slowBuffer, INDICATOR_DATA); + SetIndexBuffer(slowColorBufferIndex, slowColorBuffer, INDICATOR_COLOR_INDEX); + // + // Data Buffers ... + + // + // Volumes ... + ArraySetAsSeries(volumeBuffer, true); + SetIndexBuffer(volumeBufferIndex, volumeBuffer, INDICATOR_CALCULATIONS); + + // + // Price ... + ArraySetAsSeries(priceBuffer, true); + SetIndexBuffer(priceBufferIndex, priceBuffer, INDICATOR_CALCULATIONS); + + // + // Fast State ... + ArraySetAsSeries(fastStateBuffer, true); + SetIndexBuffer(fastStateBufferIndex, fastStateBuffer, INDICATOR_CALCULATIONS); + + // + // Mid State ... + ArraySetAsSeries(midStateBuffer, true); + SetIndexBuffer(midStateBufferIndex, midStateBuffer, INDICATOR_CALCULATIONS); + + // + // Slow State ... + ArraySetAsSeries(slowStateBuffer, true); + SetIndexBuffer(slowStateBufferIndex, slowStateBuffer, INDICATOR_CALCULATIONS); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + // Calculate Volumes and Price ... + + // + if (ratesTotal - bar_index <= maxLength) + { + // + CalculateDataBuffers( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + return; + } + + // + CalculateDataBuffers( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + CalculateVWAPS( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); +} + +// +// Calculate Required Data Buffers ... +void CalculateDataBuffers( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + double price = GetAppliedPrice( + appliedTo, + open, + high, + low, + close, + bar_index // + ); + priceBuffer[bar_index] = price; + volumeBuffer[bar_index] = (double)tickVolume[bar_index]; +} + +// +// Calculate Different VWaps ... +void CalculateVWAPS( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + // Fast ... + CalculateVWAP( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume, + // + fastLength, + showFast, + fastBuffer, + fastColorBuffer, + fastStateBuffer // + ); + + // + // Mid ... + CalculateVWAP( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume, + // + midLength, + showMid, + midBuffer, + midColorBuffer, + midStateBuffer // + ); + + // + // Fast ... + CalculateVWAP( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume, + // + slowLength, + showSlow, + slowBuffer, + slowColorBuffer, + slowStateBuffer // + ); +} + +// +// Calculate VWAP ... +void CalculateVWAP( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[], + // + int _length, // Calculation Length + bool _show, + double &_buffer[], + double &_colorBuffer[], + double &_stateBuffer[] // +) +{ + // + double vSum = 0; + double pSum = 0; + double mSum = 0; + for (int x = 0; x < _length; x++) + { + // + pSum += priceBuffer[x + bar_index]; + vSum += volumeBuffer[x + bar_index]; + mSum += priceBuffer[x + bar_index] * volumeBuffer[x + bar_index]; + } + + // + double iValue = mSum / vSum; + iValue = NormalizeDouble(iValue, _Digits); + + // + _buffer[bar_index] = iValue; + + // + bool isBullish = low[bar_index] > iValue; + bool isBearish = high[bar_index] < iValue; + + // + double iColor = + isBullish + ? bullishColorIDX + : isBearish + ? bearishColorIDX + : neuturalColorIDX; + + // + _colorBuffer[bar_index] = hideColorIDX; + _stateBuffer[bar_index] = iColor; + if (_show) + { + _colorBuffer[bar_index] = iColor; + } +} + +// \ No newline at end of file diff --git a/X121SMCEA/Helpers/x-saherelm.x3ma.helper.mq5 b/X121SMCEA/Helpers/x-saherelm.x3ma.helper.mq5 new file mode 100644 index 00000000..b03ee756 --- /dev/null +++ b/X121SMCEA/Helpers/x-saherelm.x3ma.helper.mq5 @@ -0,0 +1,752 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCX3MAHelper +// 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 + +// +// Imports ... +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_X3MA_BUFFERS +{ + // + X3MA_FAST_LINE = 0, + X3MA_MID_LINE = 1, + X3MA_SLOW_LINE = 2, +}; + +// +// Input Models ... +struct X3MAInputs +{ + // + // Props ... + + // + // Market ... + int fastLength; // Fast Length + int midLength; // Mid Length + int slowLength; // Slow Length + int shiftLength; // Shift + ENUM_MA_METHOD method; // Mode + ENUM_APPLIED_PRICE appliedTo; // Applied To + + // + // Presentation ... + + // + bool showFast; // Show Fast + bool showMid; // Show Mid + bool showSlow; // Show Slow + + // + // Constructor(s) ... + X3MAInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + fastLength = 0; + midLength = 0; + slowLength = 0; + shiftLength = 0; + method = MODE_SMA; + appliedTo = PRICE_CLOSE; + + // + showFast = false; + showMid = false; + showSlow = false; + } + + // + // Default ... + void Default() + { + // + fastLength = 50; + midLength = 100; + slowLength = 200; + shiftLength = 0; + method = MODE_SMA; + appliedTo = PRICE_CLOSE; + + // + showFast = true; + showMid = true; + showSlow = true; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + fastLength > 2 && + midLength > fastLength && + slowLength > midLength && + // + shiftLength >= 0 + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(fastLength, midLength); + result = MathMax(result, slowLength); + + // + return result; + } +}; + +// +// Define Conditions ... +struct X3MAConditions +{ + // + // Common ... + string symbol; + ENUM_TIMEFRAMES period; + datetime time; + + // + // Buffers ... + + // + double fasts[]; + double mids[]; + double slows[]; + + // + // Conditions ... + + // + bool isFastOverMid; + bool isMidOverSlow; + + // + bool isFastUnderMid; + bool isMidUnderSlow; + + // + bool isBullishOrdered; + bool isBearishOrdered; + + // + bool isSwitchedToBullishOrdered; + bool isSwitchedToBearishOrdered; + + // + void Clean() + { + // + Clean(fasts); + Clean(mids); + Clean(slows); + + // + ArraySetAsSeries(fasts, true); + ArraySetAsSeries(mids, true); + ArraySetAsSeries(slows, true); + + // + isFastOverMid = false; + isMidOverSlow = false; + isFastUnderMid = false; + isMidUnderSlow = false; + isBullishOrdered = false; + isBearishOrdered = false; + isSwitchedToBullishOrdered = false; + isSwitchedToBearishOrdered = false; + } + + // + void GenerateScore( + double &bullishScore, + double &bearishScore // + ) + { + // + bullishScore = 0; + bearishScore = 0; + + // + // Since We have to Use this + // Only for Filtering Signals ... + // We Can Ignore Scoring ... + // or Complete this later ... + } + + // + string GenerateSummary( + bool onlyCommons = false, + bool onlyConditions = false, + bool includeScores = true, + bool ignoreFalseConditions = true, + string separator = "\n" // + ) + { + // + string result = NULL; + + // + double bullishScore = 0; + double bearishScore = 0; + GenerateScore( + bullishScore, + bearishScore // + ); + + // + string scoresStr = + // + "Scores: " + separator + + "---------------" + separator + + "Bullish: " + ToString(bullishScore) + separator + + "Bearish: " + ToString(bearishScore) + separator + + "" + // + ; + + // + string commonStr = GenerateSpecifiedCommonSummary( + this, + separator, + includeScores // + ); + + // + string conditionsStr = + // + "" + // + ; + + // + result = + // + "[" + GetTag() + "]" + separator + + (onlyConditions + ? "" + : commonStr) + + (!includeScores + ? "" + : scoresStr) + + " " + separator + + (onlyCommons + ? "" + : conditionsStr) + + "" + // + ; + + // + return result; + } + + // + string GetTag() + { + return "X3MA"; + } +}; + +// +// Class ... +class XSCX3MAHelper : public XSCBaseHelper +{ + // + // Public ... + public: + // + // Props ... + + // + // Constructors ... + XSCX3MAHelper() + : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCX3MAHelper() + { + // + Clean(fastBuffer); + Clean(midBuffer); + Clean(slowBuffer); + } + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + X3MAInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(fastBuffer, true); + ArraySetAsSeries(midBuffer, true); + ArraySetAsSeries(slowBuffer, true); + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.x3ma", + // + // Inputs ... + // + // Market ... + "", + mInputs.fastLength, + mInputs.midLength, + mInputs.slowLength, + mInputs.shiftLength, + mInputs.method, + mInputs.appliedTo, + // + // Presentation ... + "", + // + mInputs.showFast, + mInputs.showMid, + mInputs.showSlow + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + X3MAInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + X3MAInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Buffers ... + + // + double GetFast( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(fastBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return fastBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyFast( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + fastBuffer, + buffer, + forceClean + // + ); + } + + // + double GetMid( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(midBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return midBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyMid( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + midBuffer, + buffer, + forceClean + // + ); + } + + // + double GetSlow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(slowBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return slowBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopySlow( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + slowBuffer, + buffer, + forceClean + // + ); + } + + // + // Conditions ... + + // + bool GetConditions( + X3MAConditions &conditions, // + int barIndex = 0, // + int loopback = 5 // + ) + { + // + bool result = true; + + // + if (loopback < 3) + { + loopback = 3; + } + + // + conditions.Clean(); + + // + conditions.symbol = mSymbol; + conditions.period = mPeriod; + conditions.time = TimeCurrent(); + + // + int zIndex = barIndex; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + // Buffers ... + + // + // Fast ... + CopyFast( + zIndex, + loopback, + conditions.fasts // + ); + + // + // Mid ... + CopyMid( + zIndex, + loopback, + conditions.mids // + ); + + // + // Slow ... + CopySlow( + zIndex, + loopback, + conditions.slows // + ); + + // + // Conditions ... + + // + bool isFastOverMid = + conditions.fasts[cIndex] > conditions.mids[cIndex]; + bool isFastOverMidPrev = + conditions.fasts[pIndex] > conditions.mids[pIndex]; + + // + bool isMidOverSlow = + conditions.mids[cIndex] > conditions.slows[cIndex]; + bool isMidOverSlowPrev = + conditions.mids[pIndex] > conditions.slows[pIndex]; + + // + bool isFastUnderMid = + conditions.fasts[cIndex] < conditions.mids[cIndex]; + bool isFastUnderMidPrev = + conditions.fasts[pIndex] < conditions.mids[pIndex]; + + // + bool isMidUnderSlow = + conditions.mids[cIndex] < conditions.slows[cIndex]; + bool isMidUnderSlowPrev = + conditions.mids[pIndex] < conditions.slows[pIndex]; + + // + bool isBullishOrdered = isFastOverMid && + isMidOverSlow; + bool isBullishOrderedPrev = isFastOverMidPrev && + isMidOverSlowPrev; + + // + bool isBearishOrdered = isFastUnderMid && + isMidUnderSlow; + bool isBearishOrderedPrev = isFastUnderMidPrev && + isMidUnderSlowPrev; + + // + bool isSwitchedToBullishOrdered = isBullishOrdered && + !isBullishOrderedPrev; + bool isSwitchedToBearishOrdered = isBearishOrdered && + !isBearishOrderedPrev; + + // + conditions.isFastOverMid = isFastOverMid; + conditions.isMidOverSlow = isMidOverSlow; + conditions.isFastUnderMid = isFastUnderMid; + conditions.isMidUnderSlow = isMidUnderSlow; + conditions.isBullishOrdered = isBullishOrdered; + conditions.isBearishOrdered = isBearishOrdered; + conditions.isSwitchedToBullishOrdered = isSwitchedToBullishOrdered; + conditions.isSwitchedToBearishOrdered = isSwitchedToBearishOrdered; + + // + return result; + } + + // + // Protected ... + protected: + // + // Private ... + private: + // + // Props ... + X3MAInputs mInputs; // Inputs ... + + // + // Buffers ... + double fastBuffer[]; + double midBuffer[]; + double slowBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + if (totalBars > 1000) + { + totalBars = 1000; + } + + // + // Fast ... + CopyBuffer( + mHandler, + X3MA_FAST_LINE, + 0, + totalBars, + fastBuffer + // + ); + + // + // Mid ... + CopyBuffer( + mHandler, + X3MA_MID_LINE, + 0, + totalBars, + midBuffer + // + ); + + // + // Slow ... + CopyBuffer( + mHandler, + X3MA_SLOW_LINE, + 0, + totalBars, + slowBuffer + // + ); + } +}; + +// \ No newline at end of file diff --git a/X121SMCEA/Helpers/x-saherelm.x3vwap.helper.mq5 b/X121SMCEA/Helpers/x-saherelm.x3vwap.helper.mq5 new file mode 100644 index 00000000..5d958913 --- /dev/null +++ b/X121SMCEA/Helpers/x-saherelm.x3vwap.helper.mq5 @@ -0,0 +1,1140 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCX3VWAPHelper +// 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 + +// +// Imports ... +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_X3VWAP_BUFFERS +{ + // + X3VWAP_FAST_LINE = 0, + X3VWAP_FAST_STATE_LINE = 8, + X3VWAP_MID_LINE = 1, + X3VWAP_MID_STATE_LINE = 9, + X3VWAP_SLOW_LINE = 2, + X3VWAP_SLOW_STATE_LINE = 10, +}; + +// +enum ENUM_X3VWAP_STATES +{ + // + X3VWAP_STATE_BULLISH = 1, + X3VWAP_STATE_BEARISH = 2, + X3VWAP_STATE_NEUTURAL = 3, +}; + +// +// Input Models ... +struct X3VWAPInputs +{ + // + // Props ... + + // + // Market ... + int fastLength; // Fast Length + int midLength; // Mid Length + int slowLength; // Slow Length + + // + // Presentation ... + + // + bool showFast; // Show Fast + bool showMid; // Show Mid + bool showSlow; // Show Slow + + // + // Constructor(s) ... + X3VWAPInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + fastLength = 0; + midLength = 0; + slowLength = 0; + + // + showFast = false; + showMid = false; + showSlow = false; + } + + // + // Default ... + void Default() + { + // + fastLength = 50; + midLength = 100; + slowLength = 200; + + // + showFast = true; + showMid = true; + showSlow = true; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + fastLength > 2 && + midLength > fastLength && + slowLength > midLength + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(fastLength, midLength); + result = MathMax(result, slowLength); + + // + return result; + } +}; + +// +// Define Conditions ... +struct X3VWAPConditions +{ + // + // Common ... + string symbol; + ENUM_TIMEFRAMES period; + datetime time; + + // + // Buffers ... + + // + double fasts[]; + double fastStates[]; + double mids[]; + double midStates[]; + double slows[]; + double slowStates[]; + + // + // Conditions ... + + // + bool isFastBullish; + bool isFastBearish; + bool isFastNeutural; + + // + bool isMidBullish; + bool isMidBearish; + bool isMidNeutural; + + // + bool isSlowBullish; + bool isSlowBearish; + bool isSlowNeutural; + + // + bool isFastOverMid; + bool isMidOverSlow; + + // + bool isFastUnderMid; + bool isMidUnderSlow; + + // + bool isBullishState; + bool isBearishState; + bool isNeuturalState; + + // + bool isBullishOrdered; + bool isBearishOrdered; + + // + bool isSwitchedToBullishOrdered; + bool isSwitchedToBearishOrdered; + + // + bool isSwitchedToBullishState; + bool isSwitchedToBearishState; + bool isSwitchedToNeuturalState; + + // + void Clean() + { + // + Clean(fasts); + Clean(mids); + Clean(slows); + + // + Clean(fastStates); + Clean(midStates); + Clean(slowStates); + + // + ArraySetAsSeries(fasts, true); + ArraySetAsSeries(mids, true); + ArraySetAsSeries(slows, true); + + // + ArraySetAsSeries(fastStates, true); + ArraySetAsSeries(midStates, true); + ArraySetAsSeries(slowStates, true); + + // + isFastBullish = false; + isFastBearish = false; + isFastNeutural = false; + isMidBullish = false; + isMidBearish = false; + isMidNeutural = false; + isSlowBullish = false; + isSlowBearish = false; + isSlowNeutural = false; + isFastOverMid = false; + isMidOverSlow = false; + isFastUnderMid = false; + isMidUnderSlow = false; + isBullishState = false; + isBearishState = false; + isNeuturalState = false; + isBullishOrdered = false; + isBearishOrdered = false; + isSwitchedToBullishOrdered = false; + isSwitchedToBearishOrdered = false; + isSwitchedToBullishState = false; + isSwitchedToBearishState = false; + isSwitchedToNeuturalState = false; + } + + // + void GenerateScore( + double &bullishScore, + double &bearishScore // + ) + { + // + bullishScore = 0; + bearishScore = 0; + + // + // Since We have to Use this + // Only for Filtering Signals ... + // We Can Ignore Scoring ... + // or Complete this later ... + } + + // + string GenerateSummary( + bool onlyCommons = false, + bool onlyConditions = false, + bool includeScores = true, + bool ignoreFalseConditions = true, + string separator = "\n" // + ) + { + // + string result = NULL; + + // + double bullishScore = 0; + double bearishScore = 0; + GenerateScore( + bullishScore, + bearishScore // + ); + + // + string scoresStr = + // + "Scores: " + separator + + "---------------" + separator + + "Bullish: " + ToString(bullishScore) + separator + + "Bearish: " + ToString(bearishScore) + separator + + "" + // + ; + + // + string commonStr = GenerateSpecifiedCommonSummary( + this, + separator, + includeScores // + ); + + // + string conditionsStr = + // + "" + // + ; + + // + result = + // + "[" + GetTag() + "]" + separator + + (onlyConditions + ? "" + : commonStr) + + (!includeScores + ? "" + : scoresStr) + + " " + separator + + (onlyCommons + ? "" + : conditionsStr) + + "" + // + ; + + // + return result; + } + + // + string GetTag() + { + return "X3VWAP"; + } +}; + +// +// Class ... +class XSCX3VWAPHelper : public XSCBaseHelper +{ + // + // Public ... + public: + // + // Props ... + + // + // Constructors ... + XSCX3VWAPHelper() + : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCX3VWAPHelper() + { + // + Clean(fastBuffer); + Clean(midBuffer); + Clean(slowBuffer); + } + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + X3VWAPInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(fastBuffer, true); + ArraySetAsSeries(fastStateBuffer, true); + + // + ArraySetAsSeries(midBuffer, true); + ArraySetAsSeries(midStateBuffer, true); + + // + ArraySetAsSeries(slowBuffer, true); + ArraySetAsSeries(slowStateBuffer, true); + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.x3vwap", + // + // Inputs ... + // + // Market ... + "", + mInputs.fastLength, + mInputs.midLength, + mInputs.slowLength, + // + // Presentation ... + "", + // + mInputs.showFast, + mInputs.showMid, + mInputs.showSlow + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + X3VWAPInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + X3VWAPInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Buffers ... + + // + double GetFast( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(fastBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return fastBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyFast( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + fastBuffer, + buffer, + forceClean + // + ); + } + + // + double GetFastState( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(fastStateBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return fastStateBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyFastState( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + fastStateBuffer, + buffer, + forceClean + // + ); + } + + // + double GetMid( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(midBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return midBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyMid( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + midBuffer, + buffer, + forceClean + // + ); + } + + // + double GetMidState( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(midStateBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return midStateBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyMidState( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + midStateBuffer, + buffer, + forceClean + // + ); + } + + // + double GetSlow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(slowBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return slowBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopySlow( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + slowBuffer, + buffer, + forceClean + // + ); + } + + // + double GetSlowState( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(slowStateBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return slowStateBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopySlowState( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + slowStateBuffer, + buffer, + forceClean + // + ); + } + + // + // Converts to State ... + ENUM_X3VWAP_STATES ToState(double value) + { + // + ENUM_X3VWAP_STATES result = + value == 1 + ? X3VWAP_STATE_BULLISH + : value == 2 + ? X3VWAP_STATE_BEARISH + : X3VWAP_STATE_NEUTURAL; + + // + return result; + } + + // + bool IsBullish(double value) + { + // + bool result = false; + + // + result = ToState(value) == X3VWAP_STATE_BULLISH; + + // + return result; + } + + // + bool IsBearish(double value) + { + // + bool result = false; + + // + result = ToState(value) == X3VWAP_STATE_BEARISH; + + // + return result; + } + + // + bool IsNeutural(double value) + { + // + bool result = false; + + // + result = ToState(value) == X3VWAP_STATE_NEUTURAL; + + // + return result; + } + + // + // Conditions ... + + // + bool GetConditions( + X3VWAPConditions &conditions, // + int barIndex = 0, // + int loopback = 5 // + ) + { + // + bool result = true; + + // + if (loopback < 3) + { + loopback = 3; + } + + // + conditions.Clean(); + + // + conditions.symbol = mSymbol; + conditions.period = mPeriod; + conditions.time = TimeCurrent(); + + // + int zIndex = barIndex; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + // Buffers ... + + // + // Fast ... + CopyFast( + zIndex, + loopback, + conditions.fasts // + ); + CopyFastState( + zIndex, + loopback, + conditions.fastStates // + ); + + // + // Mid ... + CopyMid( + zIndex, + loopback, + conditions.mids // + ); + CopyMidState( + zIndex, + loopback, + conditions.midStates // + ); + + // + // Slow ... + CopySlow( + zIndex, + loopback, + conditions.slows // + ); + CopySlowState( + zIndex, + loopback, + conditions.slowStates // + ); + + // + // Conditions ... + + // + bool isFastBullish = IsBullish(conditions.fastStates[cIndex]); + bool isFastBullishPrev = IsBullish(conditions.fastStates[pIndex]); + + // + bool isFastBearish = IsBearish(conditions.fastStates[cIndex]); + bool isFastBearishPrev = IsBearish(conditions.fastStates[pIndex]); + + // + bool isFastNeutural = IsNeutural(conditions.fastStates[cIndex]); + bool isFastNeuturalPrev = IsNeutural(conditions.fastStates[pIndex]); + + // + bool isMidBullish = IsBullish(conditions.midStates[cIndex]); + bool isMidBullishPrev = IsBullish(conditions.midStates[pIndex]); + + // + bool isMidBearish = IsBearish(conditions.midStates[cIndex]); + bool isMidBearishPrev = IsBearish(conditions.midStates[pIndex]); + + // + bool isMidNeutural = IsNeutural(conditions.midStates[cIndex]); + bool isMidNeuturalPrev = IsNeutural(conditions.midStates[pIndex]); + + // + bool isSlowBullish = IsBullish(conditions.slowStates[cIndex]); + bool isSlowBullishPrev = IsBullish(conditions.slowStates[pIndex]); + + // + bool isSlowBearish = IsBearish(conditions.slowStates[cIndex]); + bool isSlowBearishPrev = IsBearish(conditions.slowStates[pIndex]); + + // + bool isSlowNeutural = IsNeutural(conditions.slowStates[cIndex]); + bool isSlowNeuturalPrev = IsNeutural(conditions.slowStates[pIndex]); + + // + bool isFastOverMid = + conditions.fasts[cIndex] > conditions.mids[cIndex]; + bool isFastOverMidPrev = + conditions.fasts[pIndex] > conditions.mids[pIndex]; + + // + bool isMidOverSlow = + conditions.mids[cIndex] > conditions.slows[cIndex]; + bool isMidOverSlowPrev = + conditions.mids[pIndex] > conditions.slows[pIndex]; + + // + bool isFastUnderMid = + conditions.fasts[cIndex] < conditions.mids[cIndex]; + bool isFastUnderMidPrev = + conditions.fasts[pIndex] < conditions.mids[pIndex]; + + // + bool isMidUnderSlow = + conditions.mids[cIndex] < conditions.slows[cIndex]; + bool isMidUnderSlowPrev = + conditions.mids[pIndex] < conditions.slows[pIndex]; + + // + bool isBullishState = isFastBullish && + isMidBullish && + isSlowBullish; + bool isBullishStatePrev = isFastBullishPrev && + isMidBullishPrev && + isSlowBullishPrev; + + // + bool isBearishState = isFastBearish && + isMidBearish && + isSlowBearish; + bool isBearishStatePrev = isFastBearishPrev && + isMidBearishPrev && + isSlowBearishPrev; + + // + bool isNeuturalState = isFastNeutural && + isMidNeutural && + isSlowNeutural; + bool isNeuturalStatePrev = isFastNeuturalPrev && + isMidNeuturalPrev && + isSlowNeuturalPrev; + + // + bool isBullishOrdered = isFastOverMid && + isMidOverSlow; + bool isBullishOrderedPrev = isFastOverMidPrev && + isMidOverSlowPrev; + + // + bool isBearishOrdered = isFastUnderMid && + isMidUnderSlow; + bool isBearishOrderedPrev = isFastUnderMidPrev && + isMidUnderSlowPrev; + + // + bool isSwitchedToBullishOrdered = isBullishOrdered && + !isBullishOrderedPrev; + bool isSwitchedToBearishOrdered = isBearishOrdered && + !isBearishOrderedPrev; + + // + bool isSwitchedToBullishState = isBullishState && + !isBullishStatePrev; + bool isSwitchedToBearishState = isBearishState && + !isBearishStatePrev; + bool isSwitchedToNeuturalState = isNeuturalState && + !isNeuturalStatePrev; + + // + conditions.isFastBullish = isFastBullish; + conditions.isFastBearish = isFastBearish; + conditions.isFastNeutural = isFastNeutural; + conditions.isMidBullish = isMidBullish; + conditions.isMidBearish = isMidBearish; + conditions.isMidNeutural = isMidNeutural; + conditions.isSlowBullish = isSlowBullish; + conditions.isSlowBearish = isSlowBearish; + conditions.isSlowNeutural = isSlowNeutural; + conditions.isFastOverMid = isFastOverMid; + conditions.isMidOverSlow = isMidOverSlow; + conditions.isFastUnderMid = isFastUnderMid; + conditions.isMidUnderSlow = isMidUnderSlow; + conditions.isBullishState = isBullishState; + conditions.isBearishState = isBearishState; + conditions.isNeuturalState = isNeuturalState; + conditions.isBullishOrdered = isBullishOrdered; + conditions.isBearishOrdered = isBearishOrdered; + conditions.isSwitchedToBullishOrdered = isSwitchedToBullishOrdered; + conditions.isSwitchedToBearishOrdered = isSwitchedToBearishOrdered; + conditions.isSwitchedToBullishState = isSwitchedToBullishState; + conditions.isSwitchedToBearishState = isSwitchedToBearishState; + conditions.isSwitchedToNeuturalState = isSwitchedToNeuturalState; + + // + return result; + } + + // + // Protected ... + protected: + // + // Private ... + private: + // + // Props ... + X3VWAPInputs mInputs; // Inputs ... + + // + // Buffers ... + double fastBuffer[]; + double fastStateBuffer[]; + double midBuffer[]; + double midStateBuffer[]; + double slowBuffer[]; + double slowStateBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + if (totalBars > 1000) + { + totalBars = 1000; + } + + // + // Fast ... + CopyBuffer( + mHandler, + X3VWAP_FAST_LINE, + 0, + totalBars, + fastBuffer + // + ); + CopyBuffer( + mHandler, + X3VWAP_FAST_STATE_LINE, + 0, + totalBars, + fastStateBuffer + // + ); + + // + // Mid ... + CopyBuffer( + mHandler, + X3VWAP_MID_LINE, + 0, + totalBars, + midBuffer + // + ); + CopyBuffer( + mHandler, + X3VWAP_MID_STATE_LINE, + 0, + totalBars, + midStateBuffer + // + ); + + // + // Slow ... + CopyBuffer( + mHandler, + X3VWAP_SLOW_LINE, + 0, + totalBars, + slowBuffer + // + ); + CopyBuffer( + mHandler, + X3VWAP_SLOW_STATE_LINE, + 0, + totalBars, + slowStateBuffer + // + ); + } +}; + +// \ No newline at end of file diff --git a/X121SMCEA/Helpers/x-saherelm.xcc.helper.mq5 b/X121SMCEA/Helpers/x-saherelm.xcc.helper.mq5 new file mode 100644 index 00000000..98bec867 --- /dev/null +++ b/X121SMCEA/Helpers/x-saherelm.xcc.helper.mq5 @@ -0,0 +1,245 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXCCHelper +// 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 + +// +// Imports ... +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +// Input Models ... +struct XCCInputs +{ + // + // Props ... + + // + // Chart Style ... + ENUM_CHART_MODE mode; // Mode + 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 + + // + // Presentation ... + bool showCandles; // Show Candles + + // + // Constructor(s) ... + XCCInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + mode = CHART_CANDLES; + + // + upColor = CLR_NONE; + downColor = CLR_NONE; + lineColor = CLR_NONE; + bearishColor = CLR_NONE; + bullishColor = CLR_NONE; + volumesColor = CLR_NONE; + + // + showCandles = false; + } + + // + // Default ... + void Default() + { + // + mode = CHART_CANDLES; + + // + upColor = clrLime; + downColor = clrRed; + lineColor = clrLime; + bearishColor = clrRed; + bullishColor = clrLime; + volumesColor = clrGreen; + // + showCandles = true; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + true + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(0, 0); + + // + return result; + } +}; + +// +// Class ... +class XSCXCCHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXCCHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXCCHelper() {} + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XCCInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xcc", + // + // Inputs ... + // + // Chart Style ... + "", + mInputs.mode, // Mode + mInputs.upColor, // Up Color + mInputs.downColor, // Down Color + mInputs.lineColor, // Line mode and Doji candlestick Color + mInputs.bearishColor, // Bullish Color + mInputs.bullishColor, // Bearish Color + mInputs.volumesColor, // Volumes Color + // + // Presentation ... + "", + mInputs.showCandles // Show Candles + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XCCInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XCCInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XCCInputs mInputs; // Inputs ... +}; + +// +// Tools ... \ No newline at end of file diff --git a/X121SMCEA/Helpers/x-saherelm.xct.helper.mq5 b/X121SMCEA/Helpers/x-saherelm.xct.helper.mq5 new file mode 100644 index 00000000..315857a4 --- /dev/null +++ b/X121SMCEA/Helpers/x-saherelm.xct.helper.mq5 @@ -0,0 +1,220 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXCTHelper +// 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 + +// +// Imports ... +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +// Input Models ... +struct XCTInputs +{ + // + // Props ... + + // + color clr; // Text Color + ENUM_BASE_CORNER corner; // Text Position + + // + // Presentation ... + bool showCandleTime; // Show Candle Time + + // + // Constructor(s) ... + XCTInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + clr = CLR_NONE; + corner = CORNER_RIGHT_LOWER; + + // + // Presentation ... + showCandleTime = false; + } + + // + // Default ... + void Default() + { + // + clr = clrYellow; + corner = CORNER_RIGHT_LOWER; + + // + // Presentation ... + showCandleTime = true; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + true + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(0, 0); + + // + return result; + } +}; + +// +// Class ... +class XSCXCTHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXCTHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXCTHelper() {} + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XCTInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xct", + // + // Inputs ... + mInputs.clr, // Text Color + mInputs.corner, // Text Position + // + // Presentation ... + "", + mInputs.showCandleTime // Show Candle Time + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XCTInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XCTInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XCTInputs mInputs; // Inputs ... +}; + +// +// Tools ... \ No newline at end of file diff --git a/X121SMCEA/Indicators/x-saherelm.x3ma.mq5 b/X121SMCEA/Indicators/x-saherelm.x3ma.mq5 new file mode 100644 index 00000000..399a9c3c --- /dev/null +++ b/X121SMCEA/Indicators/x-saherelm.x3ma.mq5 @@ -0,0 +1,394 @@ +/////////////////////////////////////////////////////// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------- +// Name: X3MA +// Description: X3MA Trend Detector ... +// +// 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 X3MA Indicator" +#property strict + +// +#define ShortName "X3MA" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Inputs ... + +// +// Market ... +input group "Market"; +input int fastLength = 50; // Fast Length +input int midLength = 100; // Mid Length +input int slowLength = 200; // Slow Length +input int shiftLength = 0; // Shift +input ENUM_MA_METHOD method = MODE_SMA; // Mode +input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Applied To + +// +// Presentation ... +input group "Presentation"; + +// +// Parts ... +input bool showFast = true; // Show Fast +input bool showMid = true; // Show Mid +input bool showSlow = true; // Show Slow + +// +// Buffers ... + +// +#property indicator_chart_window + +// +#property indicator_buffers 3 +#property indicator_plots 3 + +// +// Current ... + +// +// Fast ... +#define fastBufferIndex 0 +double fastBuffer[]; + +// +#property indicator_label1 "X3MA F" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrAqua +#property indicator_style1 STYLE_DOT +#property indicator_width1 1 + +// +// Mid ... +#define midBufferIndex 1 +double midBuffer[]; + +// +#property indicator_label2 "X3MA M" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrOrange +#property indicator_style2 STYLE_DOT +#property indicator_width2 1 + +// +// Slow ... +#define slowBufferIndex 2 +double slowBuffer[]; + +// +#property indicator_label3 "X3MA S" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrMagenta +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +// Variables ... + +// +int maxLength; + +// +// Handlers ... +int fastHandler = INVALID_HANDLE; +int midHandler = INVALID_HANDLE; +int slowHandler = INVALID_HANDLE; + +// +// EVENT Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + if (!InitHandlers()) + { + 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 + + // + // Release Handlers ... + IndicatorRelease(fastHandler); + IndicatorRelease(midHandler); + IndicatorRelease(slowHandler); +} + +// +// Calculating what we want ... +int OnCalculate( + const int rates_total, // Total Bars on Chart ... + const int prev_calculated, // Total Calculated Bars on Charts ... + const datetime &time[], // History of Open Time ... + const double &open[], // History of Open Price ... + const double &high[], // History of High Price ... + const double &low[], // History of Low Price ... + const double &close[], // History of Close Price ... + const long &tick_volume[], // History of Tick Volumes on Bar ... + const long &volume[], // History of Trade Volumes ... + const int &spread[] // History of Spread Price ... +) +{ + // + ArraySetAsSeries(low, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(close, true); + + // + // this counts Available Bars ... + int limit; + + // + // Validate Calculated Bars ... + bool isPassedRequiredCalculatedBars = + // + BarsCalculated(fastHandler) >= maxLength && + BarsCalculated(midHandler) >= maxLength && + BarsCalculated(slowHandler) >= maxLength + // + ; + if (!isPassedRequiredCalculatedBars) + { + return prev_calculated; + } + + // + limit = + (prev_calculated > rates_total || prev_calculated <= 0) + ? rates_total + : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + + // + int copiedFasts = CopyBuffer(fastHandler, 0, 0, limit, fastBuffer); + int copiedMids = CopyBuffer(midHandler, 0, 0, limit, midBuffer); + int copiedSlows = CopyBuffer(slowHandler, 0, 0, limit, slowBuffer); + + // + // Validate Copied Items ... + bool isPassedRequiredCopiedItems = + // + copiedFasts > 0 && + copiedMids > 0 && + copiedSlows > 0 + // + ; + if (!isPassedRequiredCopiedItems) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + } + + // + return rates_total; +} + +// +// CUSTOM Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + fastLength > 2 && + midLength > fastLength && + slowLength > midLength && + // + shiftLength >= 0 + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Current ... + result = MathMax(fastLength, midLength); + result = MathMax(result, slowLength); + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + IndicatorSetInteger(INDICATOR_DIGITS, _Digits); + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Fast ... + bool canShowFast = showFast; + ENUM_DRAW_TYPE fastDrawType = canShowFast ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(fastBuffer, true); + SetIndexBuffer(fastBufferIndex, fastBuffer, INDICATOR_DATA); + PlotIndexSetDouble(fastBufferIndex, PLOT_EMPTY_VALUE, 0); + PlotIndexSetInteger(fastBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fastBufferIndex, PLOT_SHOW_DATA, canShowFast); + PlotIndexSetInteger(fastBufferIndex, PLOT_DRAW_TYPE, fastDrawType); + + // + // Mid ... + bool canShowMid = showMid; + ENUM_DRAW_TYPE midDrawType = canShowMid ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(midBuffer, true); + SetIndexBuffer(midBufferIndex, midBuffer, INDICATOR_DATA); + PlotIndexSetDouble(midBufferIndex, PLOT_EMPTY_VALUE, 0); + PlotIndexSetInteger(midBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(midBufferIndex, PLOT_SHOW_DATA, canShowMid); + PlotIndexSetInteger(midBufferIndex, PLOT_DRAW_TYPE, midDrawType); + + // + // Slow ... + bool canShowSlow = showSlow; + ENUM_DRAW_TYPE slowDrawType = canShowSlow ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(slowBuffer, true); + SetIndexBuffer(slowBufferIndex, slowBuffer, INDICATOR_DATA); + PlotIndexSetDouble(slowBufferIndex, PLOT_EMPTY_VALUE, 0); + PlotIndexSetInteger(slowBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slowBufferIndex, PLOT_SHOW_DATA, canShowSlow); + PlotIndexSetInteger(slowBufferIndex, PLOT_DRAW_TYPE, slowDrawType); +} + +// +// Initial Indicator Handlers ... +bool InitHandlers() +{ + // + bool result = false; + + // + // Initialize Handlers ... + + // + // Fast ... + fastHandler = iMA( + _Symbol, + _Period, + fastLength, + shiftLength, + method, + appliedTo // + ); + + // + // Mid ... + midHandler = iMA( + _Symbol, + _Period, + midLength, + shiftLength, + method, + appliedTo // + ); + + // + // Slow ... + slowHandler = iMA( + _Symbol, + _Period, + slowLength, + shiftLength, + method, + appliedTo // + ); + + // + result = + // + fastHandler != INVALID_HANDLE && + midHandler != INVALID_HANDLE && + slowHandler != INVALID_HANDLE + // + ; + + // + return result; +} + +// \ No newline at end of file diff --git a/X121SMCEA/Indicators/x-saherelm.x3vwap.mq5 b/X121SMCEA/Indicators/x-saherelm.x3vwap.mq5 new file mode 100644 index 00000000..549040af --- /dev/null +++ b/X121SMCEA/Indicators/x-saherelm.x3vwap.mq5 @@ -0,0 +1,569 @@ +/////////////////////////////////////////////////////// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------- +// Name: X3VWAP +// Description: X3VWAP Trend Detector ... +// +// 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 X3VWAP Indicator" +#property strict + +// +#define ShortName "X3VWAP" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Inputs ... + +// +// Market ... +input group "Market"; +input int fastLength = 50; // Fast Length +input int midLength = 100; // Mid Length +input int slowLength = 200; // Slow Length +input int shiftLength = 0; // Shift +input ENUM_MA_METHOD method = MODE_SMA; // Mode +input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Applied To + +// +// Presentation ... +input group "Presentation"; + +// +// Parts ... +input bool showFast = true; // Show Fast +input bool showMid = true; // Show Mid +input bool showSlow = true; // Show Slow + +// +// Buffers ... + +// +#property indicator_chart_window + +// +#property indicator_buffers 11 +#property indicator_plots 3 + +// +#define hideColorIDX 0 +#define bullishColorIDX 1 +#define bearishColorIDX 2 +#define neuturalColorIDX 3 + +// +// Current ... + +// +// Fast ... +#define fastBufferIndex 0 +double fastBuffer[]; + +#define fastColorBufferIndex 1 +double fastColorBuffer[]; + +// +#define fastPlotBufferIndex 0 +#property indicator_label1 "X3VWAP F" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 CLR_NONE, clrGreen, clrRed, clrGray +#property indicator_style1 STYLE_DOT +#property indicator_width1 1 + +// +// Mid ... +#define midBufferIndex 2 +double midBuffer[]; + +#define midColorBufferIndex 3 +double midColorBuffer[]; + +// +#define midPlotBufferIndex 1 +#property indicator_label2 "X3VWAP M" +#property indicator_type2 DRAW_COLOR_LINE +#property indicator_color2 CLR_NONE, clrGreen, clrRed, clrGray +#property indicator_style2 STYLE_DOT +#property indicator_width2 1 + +// +// Slow ... +#define slowBufferIndex 4 +double slowBuffer[]; + +#define slowColorBufferIndex 5 +double slowColorBuffer[]; + +// +#define slowPlotBufferIndex 2 +#property indicator_label3 "X3VWAP S" +#property indicator_type3 DRAW_COLOR_LINE +#property indicator_color3 CLR_NONE, clrGreen, clrRed, clrGray +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +// Data Buffers ... + +// +// Volumes ... +#define volumeBufferIndex 6 +double volumeBuffer[]; + +// +// Price ... +#define priceBufferIndex 7 +double priceBuffer[]; + +// +// Fast State ... +#define fastStateBufferIndex 8 +double fastStateBuffer[]; + +// +// Mid State ... +#define midStateBufferIndex 9 +double midStateBuffer[]; + +// +// Slow State ... +#define slowStateBufferIndex 10 +double slowStateBuffer[]; + +// +// Variables ... + +// +int maxLength; + +// +// 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 +} + +// +// Calculating what we want ... +int OnCalculate( + const int rates_total, // Total Bars on Chart ... + const int prev_calculated, // Total Calculated Bars on Charts ... + const datetime &time[], // History of Open Time ... + const double &open[], // History of Open Price ... + const double &high[], // History of High Price ... + const double &low[], // History of Low Price ... + const double &close[], // History of Close Price ... + const long &tick_volume[], // History of Tick Volumes on Bar ... + const long &volume[], // History of Trade Volumes ... + const int &spread[] // History of Spread Price ... +) +{ + // + ArraySetAsSeries(low, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + + // + // this counts Available Bars ... + int limit; + + // + limit = + (prev_calculated > rates_total || prev_calculated <= 0) + ? rates_total + : (rates_total - prev_calculated) + 1; + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers( + i, + prev_calculated, + rates_total, + // + open, + high, + close, + low, + tick_volume // + ); + } + + // + return rates_total; +} + +// +// CUSTOM Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + fastLength > 2 && + midLength > fastLength && + slowLength > midLength + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Current ... + result = MathMax(fastLength, midLength); + result = MathMax(result, slowLength); + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + IndicatorSetInteger(INDICATOR_DIGITS, _Digits); + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Fast ... + ArraySetAsSeries(fastBuffer, true); + ArraySetAsSeries(fastColorBuffer, true); + SetIndexBuffer(fastBufferIndex, fastBuffer, INDICATOR_DATA); + SetIndexBuffer(fastColorBufferIndex, fastColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Mid ... + ArraySetAsSeries(midBuffer, true); + ArraySetAsSeries(midColorBuffer, true); + SetIndexBuffer(midBufferIndex, midBuffer, INDICATOR_DATA); + SetIndexBuffer(midColorBufferIndex, midColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Slow ... + ArraySetAsSeries(slowBuffer, true); + ArraySetAsSeries(slowColorBuffer, true); + SetIndexBuffer(slowBufferIndex, slowBuffer, INDICATOR_DATA); + SetIndexBuffer(slowColorBufferIndex, slowColorBuffer, INDICATOR_COLOR_INDEX); + // + // Data Buffers ... + + // + // Volumes ... + ArraySetAsSeries(volumeBuffer, true); + SetIndexBuffer(volumeBufferIndex, volumeBuffer, INDICATOR_CALCULATIONS); + + // + // Price ... + ArraySetAsSeries(priceBuffer, true); + SetIndexBuffer(priceBufferIndex, priceBuffer, INDICATOR_CALCULATIONS); + + // + // Fast State ... + ArraySetAsSeries(fastStateBuffer, true); + SetIndexBuffer(fastStateBufferIndex, fastStateBuffer, INDICATOR_CALCULATIONS); + + // + // Mid State ... + ArraySetAsSeries(midStateBuffer, true); + SetIndexBuffer(midStateBufferIndex, midStateBuffer, INDICATOR_CALCULATIONS); + + // + // Slow State ... + ArraySetAsSeries(slowStateBuffer, true); + SetIndexBuffer(slowStateBufferIndex, slowStateBuffer, INDICATOR_CALCULATIONS); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + // Calculate Volumes and Price ... + + // + if (ratesTotal - bar_index <= maxLength) + { + // + CalculateDataBuffers( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + return; + } + + // + CalculateDataBuffers( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + CalculateVWAPS( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); +} + +// +// Calculate Required Data Buffers ... +void CalculateDataBuffers( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + double price = GetAppliedPrice( + appliedTo, + open, + high, + low, + close, + bar_index // + ); + priceBuffer[bar_index] = price; + volumeBuffer[bar_index] = (double)tickVolume[bar_index]; +} + +// +// Calculate Different VWaps ... +void CalculateVWAPS( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + // Fast ... + CalculateVWAP( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume, + // + fastLength, + showFast, + fastBuffer, + fastColorBuffer, + fastStateBuffer // + ); + + // + // Mid ... + CalculateVWAP( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume, + // + midLength, + showMid, + midBuffer, + midColorBuffer, + midStateBuffer // + ); + + // + // Fast ... + CalculateVWAP( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume, + // + slowLength, + showSlow, + slowBuffer, + slowColorBuffer, + slowStateBuffer // + ); +} + +// +// Calculate VWAP ... +void CalculateVWAP( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[], + // + int _length, // Calculation Length + bool _show, + double &_buffer[], + double &_colorBuffer[], + double &_stateBuffer[] // +) +{ + // + double vSum = 0; + double pSum = 0; + double mSum = 0; + for (int x = 0; x < _length; x++) + { + // + pSum += priceBuffer[x + bar_index]; + vSum += volumeBuffer[x + bar_index]; + mSum += priceBuffer[x + bar_index] * volumeBuffer[x + bar_index]; + } + + // + double iValue = mSum / vSum; + iValue = NormalizeDouble(iValue, _Digits); + + // + _buffer[bar_index] = iValue; + + // + bool isBullish = low[bar_index] > iValue; + bool isBearish = high[bar_index] < iValue; + + // + double iColor = + isBullish + ? bullishColorIDX + : isBearish + ? bearishColorIDX + : neuturalColorIDX; + + // + _colorBuffer[bar_index] = hideColorIDX; + _stateBuffer[bar_index] = iColor; + if (_show) + { + _colorBuffer[bar_index] = iColor; + } +} + +// \ No newline at end of file diff --git a/X121SMCEA/Indicators/x-saherelm.xcc.mq5 b/X121SMCEA/Indicators/x-saherelm.xcc.mq5 new file mode 100644 index 00000000..ebc45174 --- /dev/null +++ b/X121SMCEA/Indicators/x-saherelm.xcc.mq5 @@ -0,0 +1,437 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Candle Styles +// --------------------------------------------------- +// Name: XCC +// Description: Candle Styles ... +// +// +// 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 XCC Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "XCC" + +// +// 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; +}; + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Chart Style"; +input ENUM_CHART_MODE mode = CHART_CANDLES; // Mode +input color upColor = clrLime; // Up Color +input color downColor = clrRed; // Down Color +input color lineColor = clrLime; // Line mode and Doji candlestick Color +input color bearishColor = clrRed; // Bullish Color +input color bullishColor = clrLime; // Bearish Color +input color volumesColor = clrGreen; // Volumes Color + +// +input group "Presentation"; +input bool showCandles = true; // Show Candles + +// +// END Inputs ... +// + +// +// 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 0 +#property indicator_plots 0 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +XChartStyle chartStyle; +XChartStyle clearStyle; + +// +// 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(); + + // + // 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 +} + +// +// Calculating what we want ... +int OnCalculate( + const int rates_total, // Total Bars on Chart ... + const int prev_calculated, // Total Calculated Bars on Charts ... + const datetime &time[], // History of Open Time ... + const double &open[], // History of Open Price ... + const double &high[], // History of High Price ... + const double &low[], // History of Low Price ... + const double &close[], // History of Close Price ... + const long &tick_volume[], // History of Tick Volumes on Bar ... + const long &volume[], // History of Trade Volumes ... + const int &spread[] // History of Spread Price ... +) +{ + // + // 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 : (rates_total - prev_calculated) + 1; + + // + // 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 = true; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ +} + +// +// 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 +) +{ +} + +// +// 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 = mode; + chartStyle.upColor = upColor; + chartStyle.downColor = downColor; + chartStyle.lineColor = lineColor; + chartStyle.bearishColor = bearishColor; + chartStyle.bullishColor = bullishColor; + chartStyle.volumesColor = volumesColor; +} + +// +// 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 Functions ... +// diff --git a/X121SMCEA/Indicators/x-saherelm.xct.mq5 b/X121SMCEA/Indicators/x-saherelm.xct.mq5 new file mode 100644 index 00000000..92fbb28b --- /dev/null +++ b/X121SMCEA/Indicators/x-saherelm.xct.mq5 @@ -0,0 +1,270 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: XCT +// Description: Trend Magic 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 XCT Indicator" +#property strict + +// +// START Constants ... +// + +// +#define ShortName "XCT" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input color clr = clrYellow; // Text Color +input ENUM_BASE_CORNER corner = CORNER_RIGHT_LOWER; // Text Position + +// +input group "Presentation"; +input bool showCandleTime = true; // Show Candle Time + +// +// END Inputs ... +// + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 0 +#property indicator_plots 0 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (showCandleTime) + { + CreateIndicatorObject(); + } + else + { + ObjectDelete(0, ShortName); + } + + // + // 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 + + // + ulong chID = FindChartID( + _Symbol, + _Period + // + ); + + // + // Delete Object ... + ObjectDelete(chID, ShortName); + + // + Comment(""); +} + +// +// Calculating what we want ... +int OnCalculate( + const int rates_total, // Total Bars on Chart ... + const int prev_calculated, // Total Calculated Bars on Charts ... + const datetime &time[], // History of Open Time ... + const double &open[], // History of Open Price ... + const double &high[], // History of High Price ... + const double &low[], // History of Low Price ... + const double &close[], // History of Close Price ... + const long &tick_volume[], // History of Tick Volumes on Bar ... + const long &volume[], // History of Trade Volumes ... + const int &spread[] // History of Spread Price ... +) +{ + // + ArraySetAsSeries(time, true); + + // + if (!showCandleTime) + { + return rates_total; + } + + // + ulong chID = FindChartID( + _Symbol, + _Period + // + ); + + // + XBarRemainsTime barRemains; + barRemains.Init( + _Symbol, + _Period + // + ); + + // + string msg = barRemains + .ToString( + "", + "", + "", + "", + "", + ":", + true + // + ); + + // + long mSpread = SymbolInfoInteger(Symbol(), SYMBOL_SPREAD); + + // + string _sp = ""; + if (mSpread < 10) + _sp = ".."; + else if (mSpread < 100) + _sp = "."; + + // + // int offset = TimeGMTOffset(); + // string timeString = + // ", Time: " + string(TimeCurrent()) + "\n" + + // ", ServerTime: " + string(TimeTradeServer()) + "\n" + + // ", GMT Offset: " + (string)offset; + // timeString = timeString; + // Comment(timeString); + + // + string objText = "Spread: " + IntegerToString(mSpread) + _sp + ", Next Bar in: " + msg; + + // + ObjectSetInteger(chID, ShortName, OBJPROP_COLOR, clr); + ObjectSetString(chID, ShortName, OBJPROP_TEXT, objText); + ObjectSetInteger(chID, ShortName, OBJPROP_FONTSIZE, 10); + ObjectSetString(chID, ShortName, OBJPROP_FONT, "Courier"); + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +void CreateIndicatorObject() +{ + // + if (!showCandleTime) + { + return; + } + + // + ObjectCreate(0, ShortName, OBJ_LABEL, 0, 0, 0); + ObjectSetInteger(0, ShortName, OBJPROP_CORNER, corner); + ObjectSetInteger(0, ShortName, OBJPROP_XDISTANCE, 10); + ObjectSetInteger(0, ShortName, OBJPROP_YDISTANCE, 2); + + // + ENUM_ANCHOR_POINT Anchor = ANCHOR_LEFT_UPPER; + switch (corner) + { + 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); +} + +// +// END Functions ... +// diff --git a/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 b/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 index 9c2ab8ce..d5b7b6f7 100644 Binary files a/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 and b/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 differ