diff --git a/MQLTestWorkspace/BKPS/BKP/sc.mq5 b/MQLTestWorkspace/BKPS/BKP/sc.mq5 new file mode 100644 index 0000000..8a3ee8b --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/sc.mq5 @@ -0,0 +1,216 @@ + + // + // Level 1 ... + + // + ENUM_XMAN_STATES scHState = (ENUM_XMAN_STATES)sHHStateBuffer[barIndex]; + ENUM_XMAN_STATES scHStatePrev = (ENUM_XMAN_STATES)sHHStateBuffer[barIndex + 1]; + ENUM_XMAN_STATES scLState = (ENUM_XMAN_STATES)sLLStateBuffer[barIndex]; + ENUM_XMAN_STATES scLStatePrev = (ENUM_XMAN_STATES)sLLStateBuffer[barIndex + 1]; + + // + bool isSCHBullish = + // + scHState = XMAN_STATE_BULLISH + // + ; + // + bool isSCHPrevBullish = + // + scHStatePrev = XMAN_STATE_BULLISH + // + ; + + // + bool isSCLBullish = + // + scLState == XMAN_STATE_BULLISH + // + ; + + // + bool isSCLPrevBullish = + // + scLStatePrev == XMAN_STATE_BULLISH + // + ; + + // + bool isSCBullish = + // + isSCHBullish && + isSCLBullish + // + ; + + // + bool isSCPrevBullish = + // + isSCHPrevBullish && + isSCLPrevBullish + // + ; + + // + bool isSCSwitchedToBullish = + // + isSCBullish && + !isSCPrevBullish + // + ; + + // + bool isSCHSwitchedToBullish = + // + isSCHBullish && + !isSCHPrevBullish + // + ; + + // + bool isSCLSwitchedToBullish = + // + isSCLBullish && + !isSCLPrevBullish + // + ; + + // + bool isSCHBearish = + // + scHState == XMAN_STATE_BEARISH + // + ; + + // + bool isSCHPrevBearish = + // + scHStatePrev == XMAN_STATE_BEARISH + // + ; + + // + bool isSCLBearish = + // + scLState == XMAN_STATE_BEARISH + // + ; + + // + bool isSCLPrevBearish = + // + scLStatePrev == XMAN_STATE_BEARISH + // + ; + + // + bool isSCBearish = + // + isSCHBearish && + isSCLBearish + // + ; + + // + bool isSCPrevBearish = + // + isSCHPrevBearish && + isSCLPrevBearish + // + ; + + // + bool isSCSwitchedToBearish = + // + isSCBearish && + !isSCPrevBearish + // + ; + + // + bool isSCHSwitchedToBearish = + // + isSCHBearish && + !isSCHPrevBearish + // + ; + + // + bool isSCLSwitchedToBearish = + // + isSCLBearish && + !isSCLPrevBearish + // + ; + + // + bool isSCNeutural = + // + !isSCBullish && + !isSCBearish + // + ; + + // + bool isSCPrevNeutural = + // + !isSCPrevBullish && + !isSCPrevBearish + // + ; + + // + bool isSCHNeutural = + // + !isSCHBullish && + !isSCHBearish + // + ; + + // + bool isSCHPrevNeutural = + // + !isSCHPrevBullish && + !isSCHPrevBearish + // + ; + + // + bool isSCLNeutural = + // + !isSCLBullish && + !isSCLBearish + // + ; + + // + bool isSCLPrevNeutural = + // + !isSCLPrevBullish && + !isSCLPrevBearish + // + ; + + // + bool isSCSwitchedToNeutural = + // + isSCNeutural && + !isSCPrevNeutural + // + ; + + // + bool isSCHSwitchedToNeutural = + // + isSCHNeutural && + !isSCHPrevNeutural + // + ; + + // + bool isSCLSwitchedToNeutural = + // + isSCLNeutural && + !isSCLPrevNeutural + // + ; diff --git a/MQLTestWorkspace/X121/Old/Classes/x-saherelm.http.class.ex5 b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.http.class.ex5 new file mode 100644 index 0000000..fbc2a39 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.http.class.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Classes/x-saherelm.http.class.mq5 b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.http.class.mq5 new file mode 100644 index 0000000..e28342d --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.http.class.mq5 @@ -0,0 +1,385 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCHttp +// Description: provides all HTTP requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +enum X_HTTP_METHOD +{ + X_HTTP_GET, + X_HTTP_POST +}; + +// +// Convert enum to String ... +string ToString(X_HTTP_METHOD method) +{ + // + string result = ""; + + // + switch (method) + { + // + case X_HTTP_GET: + result = "GET"; + break; + + // + case X_HTTP_POST: + result = "POST"; + break; + } + + // + return result; +} + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Manage Account ... +class XSCHttp +{ + // + // Public ... +public: + // + // Constructor ... + void XSCHttp() + { + XSCHttp("", 10000); + } + void XSCHttp( + string path, // Base Folder to Store Data + int timeout // base timeout for Requests + ) + { + // + Path(path); + Timeout(timeout); + } + + // + // Deconstructor ... + void ~XSCHttp() + { + } + + // + // START Getter(s)/Setter(s) ... + // + + // + // Path ... + void Path(string value) + { + mPath = value; + } + + string Path() + { + return mPath; + } + + // + // Timeout ... + void Timeout(int value) + { + mTimeout = value; + } + + // + int Timeout() + { + return mTimeout; + } + + // + // Error ... + int Error() + { + return mError; + } + + // + // Response ... + string Response() + { + return mResponse; + } + + // + // END Getter(s)/Setter(s) ... + // + + // + // START Provided Functions ... + // + + // + // Send Global Request ... + int SendRequest( + X_HTTP_METHOD method, // Httm Request Method + const string url, // Server Address + const string headers, // Headers providing + const char &payload[], // the Data which needs to Send + char &response[], // Response of request + string responseHeaders, // Response Headers + int timeout = 500 // Timeout for response default is 500 + ) + { + // + int result = -1; + + // + string strMethod = ToString(method); + if (StringLen(strMethod) == 0) + { + return result; + } + + // + // Reset State ... + ResetState(); + + // + result = WebRequest( + strMethod, + url, + headers, + timeout, + payload, + response, + responseHeaders); + + // + if (result < 0) + { + mError = GetLastError(); + } + else + { + mResponse = CharArrayToString(response); + } + + // + return result; + } + + // + // Get Request ... + int GetRequest( + const string url, // Server Address + const string headers, // Headers providing + const char &payload[], // the Data which needs to Send + char &response[], // Response of request + string responseHeaders, // Response Headers + int timeout = 500 // Timeout for response default is 500 + ) + { + // + int result = SendRequest( + X_HTTP_GET, + url, + headers, + payload, + response, + responseHeaders, + timeout); + + // + return result; + } + + // + // Post Request ... + int PostRequest( + const string url, // Server Address + const string headers, // Headers providing + const char &payload[], // the Data which needs to Send + char &response[], // Response of request + string responseHeaders, // Response Headers + int timeout = 500 // Timeout for response default is 500 + ) + { + // + int result = SendRequest( + X_HTTP_POST, + url, + headers, + payload, + response, + responseHeaders, + timeout); + + // + return result; + } + + // + // Handle Download Specific URL Content to Specific Path and File Name ... + bool Download( + string url, // the URL address which going to download + string fileName // Specify Destination file name to Store Response + ) + { + // + bool result = false; + + // + string filePath = GetFilePath(fileName); + string cookie = NULL; + string referer = NULL; + int timeout = Timeout(); + + // + char payload[]; + string headers; + char response[]; + string responseHeaders; + + // + // Send Request ... + int requestResult = GetRequest( + url, + headers, + payload, + response, + responseHeaders, + timeout); + + // + // Define File Handler ... + int mFileHandler = FileOpen( + filePath, + FILE_WRITE | FILE_BIN); + if (mFileHandler == INVALID_HANDLE) + { + // + mError = GetLastError(); + return result; + } + + // + // Write Response to File ... + uint writed = FileWriteArray( + mFileHandler, + response, + 0, + ArraySize(response)); + FileFlush(mFileHandler); + FileClose(mFileHandler); + + // + result = writed > 0; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Destintion Folder Path ... + string mPath; + + // + // WEB Request Timeout Value ... + int mTimeout; + + // + // WEB Request's Response ... + string mResponse; + + // + // Error Value ... + int mError; + + // + // Private ... +private: + // + // Reset Errors State ... + void ResetState() + { + // + // Reset Errors ... + mError = -1; + mResponse = ""; + ResetLastError(); + } + + // + // Generate Full File Path ... + string GetFilePath(string fileName) + { + // + string result = ""; + + // + result = + // + Path() + "\\" + fileName + // + ; + + // + return result; + } +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Classes/x-saherelm.x121.provider.class.ex5 b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.x121.provider.class.ex5 new file mode 100644 index 0000000..e331dfe Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.x121.provider.class.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Classes/x-saherelm.x121.provider.class.mq5 b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.x121.provider.class.mq5 new file mode 100644 index 0000000..43f9fdc --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.x121.provider.class.mq5 @@ -0,0 +1,2939 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCX121Provider +// Description: X121 Signal Provider ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Classes/x-saherelm.xprovider.class.mq5" +#include "../Helpers/x-saherelm.x121.xct.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xcc.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xhk.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xtm.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xpv.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xstr.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xfbb.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xosc.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xama.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xmrb.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xche.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xich.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xdema.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xtrnd.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xsslc.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xhull.helper.class.mq5" + +// +// Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5" +#include "../Libraries/x-saherelm.seriallizer.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// Here we Have to Define an Input Structure Model +// for Provider Class to Handle Helpers Definitions ... +struct X121ProviderInputs +{ + // + // XCT ... + // Candle Timer ... + XCTInputs xctConfig; + + // + // XCC ... + // Candle Styling ... + XCCInputs xccConfig; + + // + // XHK ... + // HikenAshi Candle Representing ... + XHKInputs xhkConfig; + + // + // XTM ... + // Trend Magic ... + XTMInputs xtmConfig; + + // + // XPV ... + // Peaks And Vales ... + XPVInputs xpvConfig; + + // + // XOSC ... + // OSCILLATORS ... + XOSCInputs xoscConfig; + + // + // XAMA ... + // Adaptive Moving Average ... + XAMAInputs xamaConfig; + + // + // XMRB ... + // Moving Average Ribbon ... + XMRBInputs xmrbConfig; + + // + // XCHE ... + // Chandelier Exit Points ... + XCHEInputs xcheConfig; + + // + // XICH ... + // Ichimopku Kinko Hyo ... + XICHInputs xichConfig; + + // + // XTRND ... + // Trend Detector ... + XTRNDInputs xtrndConfig; + + // + // XSSLC ... + // SSL Channel ... + XSSLCInputs xsslcConfig; + + // + // XHULL ... + // Hull Trend Detection Channel ... + XHULLInputs xhullConfig; + + // + // XFBB ... + XFBBInputs xfbbConfig; + + // + // XSTR ... + XSTRInputs xstrConfig; + + // + // XDEMA ... + XDEMAInputs xdemaConfig; +}; + +// +// Model Market Sense based On Current Captured conditions ... +struct X121MarketConditions +{ + // + // Commonly Used Info ... + + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + XCandleRemains barRemains; + + // + // Bar Index ... + int barIndex; + + // + // Check Current Market Condition has Signal or not ... + bool hasSignal; + + // + // If has any Signal, Models it's related info here ... + XSignal signal; + + // + // Support and Resistances ... + // if provides Signal ... + XOHCLSupRes supportResistances; + + // + // Change Price Steps ... + double momentumStep; + + // + XOHCL candles[]; + + // + // INDICATORS Market Sense ... + + // + // XCT ... + // there is not any Info provided here ... + + // + // XCC ... + // there is not any Info provided here ... + + // + // XHK ... + XHKInfo xhkInfo; + + // + // XTM ... + XTMInfo xtmInfo; + + // + // XPV ... + XPVInfo xpvInfo; + + // + // XOSC ... + XOSCInfo xoscInfo; + + // + // XAMA ... + XAMAInfo xamaInfo; + + // + // XMRB ... + XMRBInfo xmrbInfo; + + // + // XCHE ... + XCHEInfo xcheInfo; + + // + // XICH ... + XICHInfo xichInfo; + + // + // XTRND ... + XTRNDInfo xtrndInfo; + + // + // XSSLC ... + XSSLCInfo xsslcInfo; + + // + // XHULL ... + XHULLInfo xhullInfo; + + // + // XSTR ... + XSTRInfo xstrInfo; + + // + // XFBB ... + XFBBInfo xfbbInfo; + + // + // XDEMA ... + XDEMAInfo xdemaInfo; +}; + +// +// Notified a Signal was Appears ... +typedef void (*TOnSignalConditions)( + X121MarketConditions &info); + +// +// All Available Signal Types ... +enum ENUM_X121_SIGNAL_PROVIDERS +{ + NONE, // NONE ... + X786, // Hadi Khazaee Asl ... + X92, // Hadi Khazaee Asl ... + X110, // AmirAli Khazaee ... + X121, // Hadi Khazaee Asl ... + X128, // Farhad Farahmand ... +}; + +// +// END Definitions ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Base Class for All of our EA's ... +class XSCX121Provider : public XSCEABaseProvider +{ + // + // Public ... +public: + // + // Props ... + X121ProviderInputs providedConfig; + X121ProviderInputs currentConfig; + X121ProviderInputs cleanConfig; + + // + // Indicator Helper Classes Instance ... + + // + // XCT ... + XSCXCTHelper *mXCTHelper; + + // + // XCC ... + XSCXCCHelper *mXCCHelper; + + // + // XHK ... + XSCXHKHelper *mXHKHelper; + + // + // XTM ... + XSCXTMHelper *mXTMHelper; + + // + // XPV ... + XSCXPVHelper *mXPVHelper; + + // + // XOSC ... + XSCXOSCHelper *mXOSCHelper; + + // + // XAMA ... + XSCXAMAHelper *mXAMAHelper; + + // + // XMRB ... + XSCXMRBHelper *mXMRBHelper; + + // + // XCHE ... + XSCXCHEHelper *mXCHEHelper; + + // + // XICH ... + XSCXICHHelper *mXICHHelper; + + // + // XTRND ... + XSCXTRNDHelper *mXTRNDHelper; + + // + // XSSLC ... + XSCXSSLCHelper *mXSSLCHelper; + + // + // XHULL ... + XSCXHULLHelper *mXHULLHelper; + + // + // XSTR ... + XSCXSTRHelper *mXSTRHelper; + + // + // XFBB ... + XSCXFBBHelper *mXFBBHelper; + + // + // XDEMA ... + XSCXDEMAHelper *mXDEMAHelper; + + // + // Hull Pivot Points ... + double upZonePivots[]; + double downZonePivots[]; + + // + // Peaks and Vales Verifications Number ... + double peaksPivots[]; + double valesPivots[]; + + // + double ichPivots[]; + + // + double fiboPivots[]; + + // + int pvConsequences; + + // + // Constructor ... + void XSCX121Provider( + string symbol, // Trading Symbol ... + ENUM_TIMEFRAMES period // Trading Time Frame ... + ) + { + // + mMinPivots = 100; + pvConsequences = 26; + + // + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCX121Provider() + { + // + IndicatorRelease(mCTimerHandler); + + // + // De construct Helpers ... + delete mXCTHelper; + delete mXCCHelper; + delete mXHKHelper; + delete mXTMHelper; + delete mXPVHelper; + delete mXOSCHelper; + delete mXAMAHelper; + delete mXMRBHelper; + delete mXCHEHelper; + delete mXICHHelper; + delete mXSTRHelper; + delete mXFBBHelper; + delete mXTRNDHelper; + delete mXSSLCHelper; + delete mXHULLHelper; + delete mXDEMAHelper; + } + + // + virtual void PrepareTag() + { + mTag = "X121Provider((" + mSymbol + ")(" + ToString(mPeriod) + ")"; + } + + // + virtual bool Init() + { + // + bool result = false; + + // + // Instantiate all Indicators Helper Classes ... + + // + // XCT ... + mXCTHelper = new XSCXCTHelper( + mSymbol, + mPeriod); + result = mXCTHelper.SetConfig(currentConfig.xctConfig); + if (!result) + { + return result; + } + + // + // XCC ... + mXCCHelper = new XSCXCCHelper( + mSymbol, + mPeriod); + result = mXCCHelper.SetConfig(currentConfig.xccConfig); + if (!result) + { + return result; + } + + // + // XHK ... + mXHKHelper = new XSCXHKHelper( + mSymbol, + mPeriod); + result = mXHKHelper.SetConfig(currentConfig.xhkConfig); + if (!result) + { + return result; + }; + + // + // XTM ... + mXTMHelper = new XSCXTMHelper( + mSymbol, + mPeriod); + result = mXTMHelper.SetConfig(currentConfig.xtmConfig); + if (!result) + { + return result; + }; + + // + // XPV ... + mXPVHelper = new XSCXPVHelper( + mSymbol, + mPeriod); + result = mXPVHelper.SetConfig(currentConfig.xpvConfig); + if (!result) + { + return result; + }; + + // + // XOSC ... + mXOSCHelper = new XSCXOSCHelper( + mSymbol, + mPeriod); + result = mXOSCHelper.SetConfig(currentConfig.xoscConfig); + if (!result) + { + return result; + }; + + // + // XAMA ... + mXAMAHelper = new XSCXAMAHelper( + mSymbol, + mPeriod); + result = mXAMAHelper.SetConfig(currentConfig.xamaConfig); + if (!result) + { + return result; + }; + + // + // XMRB ... + mXMRBHelper = new XSCXMRBHelper( + mSymbol, + mPeriod); + result = mXMRBHelper.SetConfig(currentConfig.xmrbConfig); + if (!result) + { + return result; + }; + + // + // XCHE ... + mXCHEHelper = new XSCXCHEHelper( + mSymbol, + mPeriod); + result = mXCHEHelper.SetConfig(currentConfig.xcheConfig); + if (!result) + { + return result; + }; + + // + // XICH ... + mXICHHelper = new XSCXICHHelper( + mSymbol, + mPeriod); + result = mXICHHelper.SetConfig(currentConfig.xichConfig); + if (!result) + { + return result; + }; + + // + // XTRND ... + mXTRNDHelper = new XSCXTRNDHelper( + mSymbol, + mPeriod); + result = mXTRNDHelper.SetConfig(currentConfig.xtrndConfig); + if (!result) + { + return result; + }; + + // + // XSSLC ... + mXSSLCHelper = new XSCXSSLCHelper( + mSymbol, + mPeriod); + result = mXSSLCHelper.SetConfig(currentConfig.xsslcConfig); + if (!result) + { + return result; + }; + + // + // XHULL ... + mXHULLHelper = new XSCXHULLHelper( + mSymbol, + mPeriod); + result = mXHULLHelper.SetConfig(currentConfig.xhullConfig); + if (!result) + { + return result; + }; + + // + // XSTR ... + mXSTRHelper = new XSCXSTRHelper( + mSymbol, + mPeriod); + result = mXSTRHelper.SetConfig(currentConfig.xstrConfig); + if (!result) + { + return result; + }; + + // + // XFBB ... + mXFBBHelper = new XSCXFBBHelper( + mSymbol, + mPeriod); + result = mXFBBHelper.SetConfig(currentConfig.xfbbConfig); + if (!result) + { + return result; + }; + + // + // XDEMA ... + mXDEMAHelper = new XSCXDEMAHelper( + mSymbol, + mPeriod); + result = mXDEMAHelper.SetConfig(currentConfig.xdemaConfig); + if (!result) + { + return result; + }; + + // + return result; + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = MathMax(result, mXCTHelper.GetMaxLength()); + result = MathMax(result, mXCCHelper.GetMaxLength()); + result = MathMax(result, mXHKHelper.GetMaxLength()); + result = MathMax(result, mXTMHelper.GetMaxLength()); + result = MathMax(result, mXPVHelper.GetMaxLength()); + result = MathMax(result, mXOSCHelper.GetMaxLength()); + result = MathMax(result, mXAMAHelper.GetMaxLength()); + result = MathMax(result, mXMRBHelper.GetMaxLength()); + result = MathMax(result, mXCHEHelper.GetMaxLength()); + result = MathMax(result, mXICHHelper.GetMaxLength()); + result = MathMax(result, mXTRNDHelper.GetMaxLength()); + result = MathMax(result, mXSSLCHelper.GetMaxLength()); + result = MathMax(result, mXHULLHelper.GetMaxLength()); + result = MathMax(result, mXSTRHelper.GetMaxLength()); + result = MathMax(result, mXFBBHelper.GetMaxLength()); + result = MathMax(result, mXDEMAHelper.GetMaxLength()); + + // + return result; + } + + // + virtual int GetCalculatedBars() + { + // + int result = -1; + + // + int mXCTBars = mXCTHelper.GetCalculatedBars(); + int mXCCBars = mXCCHelper.GetCalculatedBars(); + int mXHKBars = mXHKHelper.GetCalculatedBars(); + int mXTMBars = mXTMHelper.GetCalculatedBars(); + int mXPVBars = mXPVHelper.GetCalculatedBars(); + int mXOSCBars = mXOSCHelper.GetCalculatedBars(); + int mXAMABars = mXAMAHelper.GetCalculatedBars(); + int mXMRBBars = mXMRBHelper.GetCalculatedBars(); + int mXCHEBars = mXCHEHelper.GetCalculatedBars(); + int mXICHBars = mXICHHelper.GetCalculatedBars(); + int mXTRNDBars = mXTRNDHelper.GetCalculatedBars(); + int mXSSLCBars = mXSSLCHelper.GetCalculatedBars(); + int mXHULLBars = mXHULLHelper.GetCalculatedBars(); + int mXSTRBars = mXSTRHelper.GetCalculatedBars(); + int mXFBBBars = mXFBBHelper.GetCalculatedBars(); + int mXDEMABars = mXDEMAHelper.GetCalculatedBars(); + + // + int min = MathMin(mXCTBars, mXCCBars); + min = MathMin(min, mXHKBars); + min = MathMin(min, mXTMBars); + min = MathMin(min, mXPVBars); + min = MathMin(min, mXOSCBars); + min = MathMin(min, mXAMABars); + min = MathMin(min, mXMRBBars); + min = MathMin(min, mXCHEBars); + min = MathMin(min, mXICHBars); + min = MathMin(min, mXTRNDBars); + min = MathMin(min, mXSSLCBars); + min = MathMin(min, mXHULLBars); + min = MathMin(min, mXSTRBars); + min = MathMin(min, mXFBBBars); + min = MathMin(min, mXDEMABars); + + // + int max = MathMax(mXCTBars, mXCCBars); + max = MathMax(max, mXHKBars); + max = MathMax(max, mXTMBars); + max = MathMax(max, mXPVBars); + max = MathMax(max, mXOSCBars); + max = MathMax(max, mXAMABars); + max = MathMax(max, mXMRBBars); + max = MathMax(max, mXCHEBars); + max = MathMax(max, mXICHBars); + max = MathMax(max, mXTRNDBars); + max = MathMax(max, mXSSLCBars); + max = MathMax(max, mXHULLBars); + max = MathMax(max, mXSTRBars); + max = MathMax(max, mXFBBBars); + max = MathMax(max, mXDEMABars); + + // + result = min; + + // + return result; + } + + // + virtual void ProcessBuffers() + { + UpdatePivotPoints(); + } + + // + virtual bool ProcessTick(X121MarketConditions &conditions) + { + // + if (CanIgnoreTick()) + { + return false; + } + + // + return ProcessSignals(conditions); + } + + // + int GetMinPivots() + { + return mMinPivots; + } + + // + X121ProviderInputs GetConfig() + { + // + X121ProviderInputs result; + + // + result = currentConfig; + + // + return result; + } + + // + // Set Available Signallers ... + bool SetSignallers( + string &signallers[]) + { + // + bool result = false; + + // + result = ArraySize(signallers) > 0; + if (!result) + { + return result; + } + + // + Copy( + signallers, + mSignallers); + + // + return result; + } + + // + bool SetConfig(X121ProviderInputs &config) + { + // + bool result = false; + + // + PrepareConfig(config); + + // + result = Init(); + + // + return result; + } + + // + bool ResetDefaultConfig() + { + // + bool result = SetConfig(providedConfig); + + // + return result; + } + + // + bool ShowCleanConfig() + { + // + currentConfig = cleanConfig; + + // + bool result = Init(); + + // + return result; + } + + // + bool ShowDefaultConfig() + { + // + currentConfig = providedConfig; + + // + bool result = Init(); + + // + return result; + } + + // + bool IsAllowdSignaller( + ENUM_X121_SIGNAL_PROVIDERS provider // Signal Provider + ) + { + // + bool result = false; + + // + string providerStr = ToString(provider); + + // + result = Contains( + providerStr, + mSignallers); + + // + return result; + } + + // + // Generate Market Sense ... + X121MarketConditions GetMarketConditions( + int barIndex // Specified Bar Index + ) + { + // + X121MarketConditions result; + + // + // Fill Common Data ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barIndex = barIndex; + + // + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + result.barTime = barTime; + + // + int remainedCandle = barIndex > 0 + ? barIndex - 1 + : barIndex; + GetCandleRemainsTime( + result.barRemains, + mSymbol, + mPeriod, + remainedCandle); + + // + // Attach Candles Info in XOHCL Model to Conditions ... + int mLoopBackBars = mXHKHelper.Loopback(); + XOHCL candles[]; + GetCandles( + candles, + mSymbol, + mPeriod, + 0, + mLoopBackBars); + Copy( + candles, + result.candles); + Clean(candles); + + // + result.xhkInfo = mXHKHelper.GetInfo(barIndex); + result.xtmInfo = mXTMHelper.GetInfo(barIndex); + result.xpvInfo = mXPVHelper.GetInfo(barIndex); + result.xoscInfo = mXOSCHelper.GetInfo(barIndex); + result.xamaInfo = mXAMAHelper.GetInfo(barIndex); + result.xmrbInfo = mXMRBHelper.GetInfo(barIndex); + result.xcheInfo = mXCHEHelper.GetInfo(barIndex); + result.xichInfo = mXICHHelper.GetInfo(barIndex); + result.xtrndInfo = mXTRNDHelper.GetInfo(barIndex); + result.xsslcInfo = mXSSLCHelper.GetInfo(barIndex); + result.xhullInfo = mXHULLHelper.GetInfo(barIndex); + result.xstrInfo = mXSTRHelper.GetInfo(barIndex); + result.xfbbInfo = mXFBBHelper.GetInfo(barIndex); + result.xdemaInfo = mXDEMAHelper.GetInfo(barIndex); + + // + return result; + } + + // + bool GuardCheck(XGuard &guards[]) + { + // + bool result = false; + + // + Clean(guards); + + // + // Implement Guards Check ... + X121MarketConditions mConditions = GetMarketConditions(1); + X121MarketConditions mConditions2 = GetMarketConditions(2); + + // + XOHCL c0 = GetCandle( + mSymbol, + mPeriod, + 0); + double c0Price = MathMin(c0.low, c0.close); + + // + double ll1 = GetLowestLow( + mSymbol, + mPeriod, + 3, + 1); + double ll2 = GetLowestLow( + mSymbol, + mPeriod, + 3, + 2); + + // + bool isXAMACrossedUnderXTM = + // + mConditions.xamaInfo.value < mConditions.xtmInfo.value && + mConditions2.xamaInfo.value >= mConditions2.xtmInfo.value + // + ; + + // + // X786 ... + bool canCheckX786 = IsAllowdSignaller(X786); + if (canCheckX786) + { + // + } + + // + // X92 ... + bool canCheckX92 = IsAllowdSignaller(X92); + if (canCheckX92) + { + } + + // + // X110 ... + bool canCheckX110 = IsAllowdSignaller(X110); + if (canCheckX110) + { + // + } + + // + // X121 ... + bool canCheckX121 = IsAllowdSignaller(X121); + if (canCheckX121) + { + // + } + + // + // X128 ... + bool canCheckX128 = IsAllowdSignaller(X128); + if (canCheckX128) + { + // + } + + // + result = ArraySize(guards) > 0; + + // + return result; + } + + // + // Add Specific On SignalConditions Event Handler ... + int AddOnSignalConditionEventHandler(TOnSignalConditions handler) + { + // + ArrayResize( + mSignalConditionsEventHandlers, + ArraySize(mSignalConditionsEventHandlers) + 1); + + // + int result = ArraySize(mSignalConditionsEventHandlers) - 1; + mSignalConditionsEventHandlers[result] = handler; + + // + return result; + } + + // + // Remove All On Signal Event Handler ... + void ReoveOnSignalEventHandlers() + { + // + ArrayFree(mSignalConditionsEventHandlers); + } + + // + // Notify a Signal Found on all Event Listeners ... + void NotifyOnSignalConditionsEvent(X121MarketConditions &info) + { + // + int listenerCount = ArraySize(mSignalConditionsEventHandlers); + if (listenerCount <= 0) + { + return; + } + + // + // Loop Through Listeners ... + for (int i = 0; i < listenerCount; i++) + { + // + TOnSignalConditions listener = mSignalConditionsEventHandlers[i]; + + // + listener(info); + } + } + + // + // PIVOTS ... + + // + void ProccessPivotPoints() + { + // + if (mStartPivotScan) + { + return; + } + + // + mStartPivotScan = true; + + // + int maxLength = GetMaxLength(); + int cBars = GetCalculatedBars(); + int scanSize = cBars - maxLength - 1; + for (int i = 1; i < scanSize; i++) + { + // + UpdatePivotPoints(i); + + // + int pivotsCount = CountPivots(); + if (pivotsCount >= mMinPivots) + { + break; + } + } + } + + // + int CountPivots() + { + // + int pivotSizes[]; + int upZoneCount = ArraySize(upZonePivots); + if (upZoneCount > 0) + { + // + Add( + upZoneCount, + pivotSizes); + } + + // + int downZoneCount = ArraySize(downZonePivots); + if (downZoneCount > 0) + { + // + Add( + downZoneCount, + pivotSizes); + } + + // + int peaksCount = ArraySize(peaksPivots); + if (peaksCount > 0) + { + // + Add( + peaksCount, + pivotSizes); + } + + // + int valesCount = ArraySize(valesPivots); + if (valesCount > 0) + { + // + Add( + valesCount, + pivotSizes); + } + + // + int fibsCount = ArraySize(fiboPivots); + if (fibsCount > 0) + { + // + Add( + fibsCount, + pivotSizes); + } + + // + int ichsCount = ArraySize(ichPivots); + if (ichsCount > 0) + { + // + Add( + ichsCount, + pivotSizes); + } + + // + int result = ArraySize(pivotSizes) > 0 + ? pivotSizes[ArrayMaximum(pivotSizes)] + : 0; + + // + return result; + } + + // + // Generate Exists Support and Resistance based on Given Price ... + XOHCLSupRes GenerateSupportAndResistance( + double price, // Specified Price + int count = 10 // Number of Pivots in Each Side + ) + { + // + XOHCLSupRes result; + + // + UpdatePivotPoints(0); + + // + double pivots[]; + FillPivotPoints(pivots); + + // + // Generate Support and Resistances ... + result = ExtractSupportAndResistance( + price, + pivots, + count); + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // CCandle Timer ... + int mCTimerHandler; + + // + // Signal Event Handlers ... + TOnSignalConditions mSignalConditionsEventHandlers[]; + + // + // Make Provided Config in Clean Style ... + void PrepareConfig(X121ProviderInputs &config) + { + // + cleanConfig = config; + + // + // XCT ... + // Candle Timing ... + cleanConfig.xctConfig.showCandleTime = false; + + // + // XCC ... + // Candle Styling ... + cleanConfig.xccConfig.showCandles = true; + + // + // XHK ... + // HikenAshi Candle Representing ... + cleanConfig.xhkConfig.drawCandles = false; + cleanConfig.xhkConfig.drawCandleLines = false; + + // + // XTM ... + // Trend Magic ... + cleanConfig.xtmConfig.showLine = false; + + // + // XPV ... + // Peaks And Vales ... + cleanConfig.xpvConfig.showPeaksAndVales = false; + cleanConfig.xpvConfig.showLevels = false; + cleanConfig.xpvConfig.showFibo1Levels = false; + cleanConfig.xpvConfig.showFibo2Levels = false; + cleanConfig.xpvConfig.showFibo3Levels = false; + + // + // XAMA ... + // Adaptive Moving Average ... + cleanConfig.xamaConfig.showLine = false; + + // + // XMRB ... + // Moving Average Ribbon ... + cleanConfig.xmrbConfig.showFastMa = false; + cleanConfig.xmrbConfig.showSlowMa = false; + cleanConfig.xmrbConfig.showRibbon = false; + + // + // XCHE ... + // Chandelier Exit Points ... + cleanConfig.xcheConfig.showLongExit1Line = false; + cleanConfig.xcheConfig.showShortExit1Line = false; + cleanConfig.xcheConfig.showLongExit2Line = false; + cleanConfig.xcheConfig.showShortExit2Line = false; + + // + // XICH ... + // Ichimopku Kinko Hyo ... + cleanConfig.xichConfig.showTenkanSen = false; + cleanConfig.xichConfig.showKijunSen = false; + cleanConfig.xichConfig.showKijunSenPlus = false; + cleanConfig.xichConfig.showKijunSenNegative = false; + cleanConfig.xichConfig.showChikouSpan = false; + cleanConfig.xichConfig.showSenkouSpanA = false; + cleanConfig.xichConfig.showSenkouSpanB = false; + cleanConfig.xichConfig.showKumo = false; + + // + // XTRND ... + // Trend Detector ... + cleanConfig.xtrndConfig.showConsolidations = false; + cleanConfig.xtrndConfig.showTrend = false; + cleanConfig.xtrndConfig.showL1Trend = false; + cleanConfig.xtrndConfig.showL2Trend = false; + cleanConfig.xtrndConfig.showL3Trend = false; + + // + // XSSLC ... + // SSL Channel ... + cleanConfig.xsslcConfig.showUp = false; + cleanConfig.xsslcConfig.showDown = false; + + // + // XHULL ... + // Hull Trend Detection Channel ... + cleanConfig.xhullConfig.showUpZone = false; + cleanConfig.xhullConfig.showDownZone = false; + + // + // XSTR ... + cleanConfig.xstrConfig.showTrends = false; + cleanConfig.xstrConfig.fillTrends = false; + + // + // XFBB ... + cleanConfig.xfbbConfig.showBand = false; + cleanConfig.xfbbConfig.showGoldenArea = false; + cleanConfig.xfbbConfig.showOthers = false; + + // + // XDEMA ... + cleanConfig.xdemaConfig.showDema = false; + cleanConfig.xdemaConfig.showEMA = false; + cleanConfig.xdemaConfig.showEMAOfEMA = false; + + // + providedConfig = config; + currentConfig = config; + } + + // + void Calculate(int barIndex) + { + // + mXCTHelper.Calculate(barIndex); + mXCCHelper.Calculate(barIndex); + mXHKHelper.Calculate(barIndex); + mXTMHelper.Calculate(barIndex); + mXPVHelper.Calculate(barIndex); + mXAMAHelper.Calculate(barIndex); + mXMRBHelper.Calculate(barIndex); + mXCHEHelper.Calculate(barIndex); + mXICHHelper.Calculate(barIndex); + mXTRNDHelper.Calculate(barIndex); + mXSSLCHelper.Calculate(barIndex); + mXHULLHelper.Calculate(barIndex); + mXOSCHelper.Calculate(barIndex); + mXSTRHelper.Calculate(barIndex); + mXFBBHelper.Calculate(barIndex); + mXDEMAHelper.Calculate(barIndex); + } + + // + int mMinPivots; + bool mStartPivotScan; + double mLastMomentumStep; + + // + // Find Required Pivots for Support and Resistance ... + void UpdatePivotPoints( + int barIndex = 1 // Specified Candle ... + ) + { + // + Calculate(barIndex); + + // + // Detect Peask and Vales Pivots ... + + // + // Detect Hull Pivots ... + // find Hull Trend Changes ... + int idx = 1; + bool isHullUpChanged = + // + ( + // + (XHULL_ZONE_STATES)mXHULLHelper.upStateBuffer[idx] == XHULL_STATE_BULLISH && + (XHULL_ZONE_STATES)mXHULLHelper.upStateBuffer[idx + 1] != XHULL_STATE_BULLISH + // + ) + // + || + // + ( + // + (XHULL_ZONE_STATES)mXHULLHelper.upStateBuffer[idx] == XHULL_STATE_BEARISH && + (XHULL_ZONE_STATES)mXHULLHelper.upStateBuffer[idx + 1] != XHULL_STATE_BEARISH + // + ) + // + ; + + // + bool isHullDownChanged = + // + ( + // + (XHULL_ZONE_STATES)mXHULLHelper.downStateBuffer[idx] == XHULL_STATE_BULLISH && + (XHULL_ZONE_STATES)mXHULLHelper.downStateBuffer[idx + 1] != XHULL_STATE_BULLISH + // + ) + // + || + // + ( + // + (XHULL_ZONE_STATES)mXHULLHelper.downStateBuffer[idx] == XHULL_STATE_BEARISH && + (XHULL_ZONE_STATES)mXHULLHelper.downStateBuffer[idx + 1] != XHULL_STATE_BEARISH + // + ) + // + ; + + // + // Find Change State ... + if (isHullUpChanged || + isHullDownChanged) + { + // + AddIfNotExists( + mXHULLHelper.upBuffer[idx], + upZonePivots); + + // + AddIfNotExists( + mXHULLHelper.downBuffer[idx], + downZonePivots); + } + + // + // Find Momentom Step ... + if (isHullUpChanged && + isHullDownChanged) + { + // + mLastMomentumStep = MathAbs(mXHULLHelper.upBuffer[idx] - mXHULLHelper.downBuffer[idx]); + mLastMomentumStep = NormalizePrice( + mLastMomentumStep, + mSymbol); + } + + // + // Find Peaks and Vales ... + double selectedFib1 = mXPVHelper.fl1Buffer[idx]; + double selectedFib2 = mXPVHelper.fl2Buffer[idx]; + double selectedFib3 = mXPVHelper.fl3Buffer[idx]; + double selectedPeak = mXPVHelper.peaksBuffer[idx]; + double selectedVale = mXPVHelper.valesBuffer[idx]; + + // + double selectedTenkanSen = mXICHHelper.tenkanSenBuffer[idx]; + double selectedKijunSen = mXICHHelper.kijunSenBuffer[idx]; + + // + int fib1Verified = 0; + int fib2Verified = 0; + int fib3Verified = 0; + int peaksVerified = 0; + int valesVerified = 0; + int kijunSenVerified = 0; + int tenkanSenVerified = 0; + int senkouSpanAVerified = 0; + int senkouSpanBVerified = 0; + for (int i = barIndex + 1; i < pvConsequences + barIndex + 1; i++) + { + // + int idx = i - barIndex; + + // + // PEAKS and VALES ... + + // + if (selectedPeak == mXPVHelper.peaksBuffer[idx]) + { + peaksVerified++; + } + else + { + peaksVerified = 0; + } + + // + if (selectedVale == mXPVHelper.valesBuffer[idx]) + { + valesVerified++; + } + else + { + valesVerified = 0; + } + + // + if (selectedFib1 == mXPVHelper.fl1Buffer[idx]) + { + fib1Verified++; + } + else + { + fib1Verified = 0; + } + + // + if (selectedFib2 == mXPVHelper.fl2Buffer[idx]) + { + fib2Verified++; + } + else + { + fib2Verified = 0; + } + + // + if (selectedFib3 == mXPVHelper.fl3Buffer[idx]) + { + fib3Verified++; + } + else + { + fib3Verified = 0; + } + + // + // ICHIMOKU Kinko Hyo ... + + // + if (selectedTenkanSen == mXICHHelper.tenkanSenBuffer[idx]) + { + tenkanSenVerified++; + } + else + { + tenkanSenVerified = 0; + } + + // + if (selectedKijunSen == mXICHHelper.kijunSenBuffer[idx]) + { + kijunSenVerified++; + } + else + { + kijunSenVerified++; + } + } + + // + if (peaksVerified >= pvConsequences) + { + // + AddIfNotExists( + selectedPeak, + peaksPivots); + } + + // + if (valesVerified >= pvConsequences) + { + // + AddIfNotExists( + selectedVale, + valesPivots); + } + + // + if (fib1Verified >= pvConsequences) + { + // + AddIfNotExists( + selectedFib1, + fiboPivots); + } + + // + if (fib2Verified >= pvConsequences) + { + // + AddIfNotExists( + selectedFib2, + fiboPivots); + } + + // + if (fib3Verified >= pvConsequences) + { + // + AddIfNotExists( + selectedFib3, + fiboPivots); + } + + // + if (tenkanSenVerified >= pvConsequences) + { + // + AddIfNotExists( + selectedTenkanSen, + ichPivots); + } + + // + if (kijunSenVerified >= pvConsequences) + { + // + AddIfNotExists( + selectedKijunSen, + ichPivots); + } + + // // + // if (senkouSpanAVerified >= pvConsequences) + // { + // // + // AddIfNotExists( + // selectedSenkouSpanA, + // ichPivots); + // } + + // // + // if (senkouSpanBVerified >= pvConsequences) + // { + // // + // AddIfNotExists( + // selectedSenkouSpanB, + // ichPivots); + // } + } + + // + void FillPivotPoints( + double &result[]) + { + // + Clean(result); + + // + int pCount = CountPivots(); + if (pCount <= 0) + { + return; + } + + // + AddsIfNotExists( + upZonePivots, + result); + + // + AddsIfNotExists( + downZonePivots, + result); + + // + AddsIfNotExists( + peaksPivots, + result); + + // + AddsIfNotExists( + valesPivots, + result); + + // + AddsIfNotExists( + fiboPivots, + result); + + // + AddsIfNotExists( + ichPivots, + result); + } + + // + // Available Signallers ... + string mSignallers[]; + + // + // Here we are Capture Conditions and Check Signals ... + // The Signals Must be Unique for each providers ... + bool ProcessSignals(X121MarketConditions &conditions) + { + // + X121MarketConditions mConditions = GetMarketConditions(1); + + // + // BUY ... + + // + Clean(mConditions.signal); + bool hasLongSignal = HasLongSignal(mConditions); + if (hasLongSignal) + { + // + NotifyOnSignalEvent( + mConditions.signal); + NotifyOnSignalConditionsEvent(mConditions); + mWaitUntilNewCandle = true; + + // + conditions = mConditions; + return true; + } + + // + // SELL ... + + // + Clean(mConditions.signal); + bool hasShortignal = HasShortSignal(mConditions); + if (hasShortignal) + { + // + NotifyOnSignalEvent( + mConditions.signal); + NotifyOnSignalConditionsEvent(mConditions); + mWaitUntilNewCandle = true; + + // + conditions = mConditions; + return true; + } + + // + return false; + } + + // + // Check has Long Signal on Each Strategies ... + bool HasLongSignal(X121MarketConditions &conditions) + { + // + bool result = false; + + // + double xTPPoint = 10; + + // + double entry = GetEntry( + mSymbol, + POSITION_TYPE_BUY); + + // + XOHCL c0 = GetCandle( + mSymbol, + mPeriod, + 0); + + // + double c0SelectedPrice = MathMin(c0.close, c0.low); + c0SelectedPrice = MathMin(c0SelectedPrice, c0.open); + + // + XOHCL c1 = GetCandle( + mSymbol, + mPeriod, + 1); + bool isC1Bullish = IsBullishCandle(c1); + + // + XOHCL c2 = GetCandle( + mSymbol, + mPeriod, + 2); + bool isC2Bullish = IsBullishCandle(c2); + + // + XOHCL c3 = GetCandle( + mSymbol, + mPeriod, + 3); + bool isC3Bullish = IsBullishCandle(c3); + + // + double pivots[]; + FillPivotPoints(pivots); + XOHCLSupRes supRes = ExtractSupportAndResistance( + 1, + pivots, + 15); + X121MarketConditions mConditions = GetMarketConditions(1); + X121MarketConditions mConditions2 = GetMarketConditions(2); + + // + bool isMRBFastCrossedOverPVFL3 = + // + mConditions.xmrbInfo.fast > mConditions.xpvInfo.fl3 && + mConditions2.xmrbInfo.fast <= mConditions2.xpvInfo.fl3 + // + ; + + // + bool isMRBFastCrossedUnderPVFL3 = + // + mConditions.xmrbInfo.fast < mConditions.xpvInfo.fl3 && + mConditions2.xmrbInfo.fast >= mConditions2.xpvInfo.fl3 + // + ; + + // + bool isMRBFastCrossedWithPVFL3 = + // + isMRBFastCrossedOverPVFL3 || + isMRBFastCrossedUnderPVFL3 + // + ; + + // + bool isPeakHappens = + // + mConditions.xpvInfo.peak != mConditions2.xpvInfo.peak + // + ; + + // + bool isHKBullishCandle = + mConditions.xhkInfo.open < mConditions.xhkInfo.close; + + // + // DEMA Vale ... + double mDemaVale[]; + double mDeamPeak[]; + ArraySetAsSeries(mDemaVale, true); + ArraySetAsSeries(mDeamPeak, true); + ArrayCopy( + mDemaVale, + mXDEMAHelper.demaBuffer, + 0, + 5); + bool isDemaVale = IsInVale( + ArraySize(mDemaVale) - 1, + mDemaVale); + + // + Clean(mConditions.signal); + + // + // X786 ... + bool x786HasSignal = false; + bool canCheckX786 = IsAllowdSignaller(X786); + if (canCheckX786) + { + // + x786HasSignal = + // + ( + // + isPeakHappens && + mConditions.xpvInfo.isNewPeak && + mConditions.xpvInfo.peak > mConditions2.xpvInfo.peak + // + ) + // + && + // + ( + // + mConditions.xmrbInfo.isFastOverSlow && + ( + // + mConditions.xmrbInfo.isR1FastOverSlow && + (mConditions.xmrbInfo.isR1FastOverSlow || + mConditions.xmrbInfo.isR2FastOverSlow) + // + ) + // + ) + // + && + // + ( + // + mConditions.xcheInfo.longExit1 != EMPTY_VALUE && + mConditions.xcheInfo.longExit2 != EMPTY_VALUE && + mConditions2.xcheInfo.longExit1 != EMPTY_VALUE && + mConditions2.xcheInfo.longExit2 != EMPTY_VALUE + // + ) + // + && + // + ( + // + mConditions.xhullInfo.isUpBullish && + mConditions.xhullInfo.isDownBullish + // + ) + // + && + // + ( + // + c1.low > mConditions.xdemaInfo.dema && + c2.low > mConditions.xdemaInfo.dema && + c3.low > mConditions.xdemaInfo.dema + // + ) + // + && + // + ( + // + mConditions.xstrInfo.isTrendBullish + // + ) + // + ; + + // + if (x786HasSignal) + { + // + Add( + ToString(X786), + mConditions.signal.providers); + + // + // double slPoint = 15; + // double slPrice = PointToPrice( + // mConditions.symbol, + // slPoint); + // double sl = entry - slPrice; + + // + double tpPoint = xTPPoint; + double tpPrice = PointToPrice( + mConditions.symbol, + tpPoint); + double tp = entry + tpPrice; + + // + mConditions.signal.r2r = 1; + mConditions.signal.riskAmount = 0.01; + mConditions.signal.mode = X_ORDER_MODE_MARKET; + mConditions.signal.entry = entry; + mConditions.signal.sl = 0; + mConditions.signal.tp = tp; + + // + mConditions.signal.ignoreSL = true; + mConditions.signal.useRiskAmountAsVolume = true; + } + } + + // + // X92 ... + bool x92HasSignal = false; + bool canCheckX92 = IsAllowdSignaller(X92); + if (canCheckX92) + { + // + x92HasSignal = + // + mConditions.xtrndInfo.isTrendDownBullish && + mConditions.xtrndInfo.isL1TrendDownBullish && + mConditions.xtrndInfo.isL2TrendDownBullish + // + ; + + // + if (x92HasSignal) + { + // + Add( + ToString(X92), + mConditions.signal.providers); + + // + double tpPoint = xTPPoint; + double tpPrice = PointToPrice( + mConditions.symbol, + tpPoint); + double tp = entry + tpPrice; + + // + double sl = 0; + + // + mConditions.signal.sl = sl; + mConditions.signal.tp = tp; + mConditions.signal.r2r = 1.5; + mConditions.signal.entry = entry; + mConditions.signal.riskAmount = 0.01; + mConditions.signal.mode = X_ORDER_MODE_MARKET; + + // + mConditions.signal.ignoreSL = false; + mConditions.signal.ignoreTP = false; + mConditions.signal.calculateTP = false; + mConditions.signal.useRiskAmountAsVolume = true; + } + } + + // + // X110 ... + bool x110HasSignal = false; + bool canCheckX110 = IsAllowdSignaller(X110); + if (canCheckX110) + { + // + x110HasSignal = + // + isMRBFastCrossedWithPVFL3 && + mConditions.xtmInfo.isBullish + // + ; + + // + if (x110HasSignal) + { + // + Add( + ToString(X110), + mConditions.signal.providers); + + // + // double slPoint = 10; + // double slPrice = PointToPrice( + // mConditions.symbol, + // slPoint); + // double sl = entry + slPrice; + + // + double tpPoint = xTPPoint; + double tpPrice = PointToPrice( + mConditions.symbol, + tpPoint); + double tp = entry + tpPrice; + + // + mConditions.signal.r2r = 1; + mConditions.signal.riskAmount = 0.005; + mConditions.signal.mode = X_ORDER_MODE_MARKET; + mConditions.signal.entry = entry; + mConditions.signal.sl = 0; + mConditions.signal.tp = tp; + + // + mConditions.signal.ignoreSL = true; + mConditions.signal.useRiskAmountAsVolume = true; + } + } + + // + // X121 ... + bool x121HasSignal = false; + bool canCheckX121 = IsAllowdSignaller(X121); + if (canCheckX121) + { + // + x121HasSignal = + // + ( + // + ( + // + isC1Bullish && + (isC2Bullish || + isC3Bullish) + // + ) + // + && + // + c2.open > c3.open && + c1.open > c2.open + // + ) + // + && + // + (mConditions.xpvInfo.fl3 == mConditions2.xpvInfo.fl3) + // + && + // + ( + // + c3.low < mConditions.xpvInfo.fl3 && + c2.low >= mConditions.xpvInfo.fl3 && + ( + // + c2.high >= mConditions.xpvInfo.fl1 + // + || + // + ( + // + c2.high < mConditions.xpvInfo.fl1 && + c2.high > mConditions.xpvInfo.fl2 && + c1.low < mConditions.xpvInfo.fl1 && + c1.high > mConditions.xpvInfo.fl1 + // + ) + // + ) + // + && + // + c0SelectedPrice > mConditions.xpvInfo.fl1 + // + ) + // + ; + + // + if (x121HasSignal) + { + // + Add( + ToString(X121), + mConditions.signal.providers); + + // + // double slPoint = 15; + // double slPrice = PointToPrice( + // mConditions.symbol, + // slPoint); + // double sl = entry - slPrice; + + // + double tpPoint = xTPPoint; + double tpPrice = PointToPrice( + mConditions.symbol, + tpPoint); + double tp = entry + tpPrice; + + // + mConditions.signal.r2r = 1; + mConditions.signal.riskAmount = 0.01; + mConditions.signal.mode = X_ORDER_MODE_MARKET; + mConditions.signal.entry = entry; + mConditions.signal.sl = 0; + mConditions.signal.tp = tp; + + // + mConditions.signal.ignoreSL = true; + mConditions.signal.useRiskAmountAsVolume = true; + } + } + + // + // X128 ... + bool x128HasSignal = false; + bool canCheckX128 = IsAllowdSignaller(X128); + if (canCheckX128) + { + // + x128HasSignal = + // + isPeakHappens && + mConditions.xamaInfo.value > mConditions.xtmInfo.value + // + ; + + // + if (x128HasSignal) + { + // + Add( + ToString(X128), + mConditions.signal.providers); + + // + // double slPoint = 15; + // double slPrice = PointToPrice( + // mConditions.symbol, + // slPoint); + // double sl = entry - slPrice; + + // + double tpPoint = xTPPoint; + double tpPrice = PointToPrice( + mConditions.symbol, + tpPoint); + double tp = entry + tpPrice; + + // + mConditions.signal.r2r = 1; + mConditions.signal.riskAmount = 0.01; + mConditions.signal.mode = X_ORDER_MODE_MARKET; + mConditions.signal.entry = entry; + mConditions.signal.sl = 0; + mConditions.signal.tp = tp; + + // + mConditions.signal.ignoreSL = true; + mConditions.signal.useRiskAmountAsVolume = true; + } + } + + // + result = + // + x786HasSignal + // + || + // + x92HasSignal + // + || + // + x110HasSignal + // + || + // + x121HasSignal + // + || + // + x128HasSignal + // + ; + + // + if (result) + { + // + conditions = mConditions; + + // + conditions.supportResistances = supRes; + conditions.momentumStep = mLastMomentumStep; + + // + conditions.signal.symbol = mSymbol; + conditions.signal.period = mPeriod; + conditions.signal.type = POSITION_TYPE_BUY; + + // + conditions.hasSignal = true; + + // + bool drawVLine = false; + if (drawVLine) + { + // + ulong tick = MathRand() * 10000; + + // + DrawVerticalLine( + 0, + ToString(tick), + 0, + iTime( + mSymbol, + mPeriod, + 0), + clrYellow); + } + } + + // + return result; + } + + // + // Check has Short Signal on Each Strategies ... + bool HasShortSignal(X121MarketConditions &conditions) + { + // + bool result = false; + + // + double xTPPoint = 10; + + // + double entry = GetEntry( + mSymbol, + POSITION_TYPE_SELL); + + // + XOHCL c0 = GetCandle( + mSymbol, + mPeriod, + 0); + + // + double c0SelectedPrice = MathMin(c0.close, c0.low); + c0SelectedPrice = MathMin(c0SelectedPrice, c0.open); + + // + XOHCL c1 = GetCandle( + mSymbol, + mPeriod, + 1); + bool isC1Bearish = IsBearishCandle(c1); + + // + XOHCL c2 = GetCandle( + mSymbol, + mPeriod, + 2); + bool isC2Bearish = IsBearishCandle(c2); + + // + XOHCL c3 = GetCandle( + mSymbol, + mPeriod, + 3); + bool isC3Bearish = IsBearishCandle(c3); + + // + double pivots[]; + FillPivotPoints(pivots); + XOHCLSupRes supRes = ExtractSupportAndResistance( + 1, + pivots, + 15); + X121MarketConditions mConditions = GetMarketConditions(1); + X121MarketConditions mConditions2 = GetMarketConditions(2); + + // + bool isMRBSlowCrossedOverPVFL3 = + // + mConditions.xmrbInfo.slow > mConditions.xpvInfo.fl3 && + mConditions2.xmrbInfo.slow <= mConditions2.xpvInfo.fl3 + // + ; + + // + bool isMRBSlowCrossedUnderPVFL3 = + // + mConditions.xmrbInfo.slow < mConditions.xpvInfo.fl3 && + mConditions2.xmrbInfo.slow >= mConditions2.xpvInfo.fl3 + // + ; + + // + bool isMRBSlowCrossedWithPVFL3 = + // + isMRBSlowCrossedOverPVFL3 || + isMRBSlowCrossedUnderPVFL3 + // + ; + + // + bool isValeHappens = + // + mConditions.xpvInfo.vale != mConditions2.xpvInfo.vale + // + ; + + // + Clean(mConditions.signal); + + // + // X786 ... + bool x786HasSignal = false; + bool canCheckX786 = IsAllowdSignaller(X786); + if (canCheckX786) + { + // + x786HasSignal = + // + ( + // + isValeHappens && + mConditions.xpvInfo.isNewVale && + mConditions.xpvInfo.vale < mConditions2.xpvInfo.vale + // + ) + // + && + // + ( + // + mConditions.xmrbInfo.isFastUnderSlow && + ( + // + mConditions.xmrbInfo.isR1FastUnderSlow && + (mConditions.xmrbInfo.isR1FastUnderSlow || + mConditions.xmrbInfo.isR2FastUnderSlow) + // + ) + // + ) + // + && + // + ( + // + mConditions.xcheInfo.shortExit1 != EMPTY_VALUE && + mConditions.xcheInfo.shortExit2 != EMPTY_VALUE && + mConditions2.xcheInfo.shortExit1 != EMPTY_VALUE && + mConditions2.xcheInfo.shortExit2 != EMPTY_VALUE + // + ) + // + && + // + ( + // + mConditions.xhullInfo.isUpBearish && + mConditions.xhullInfo.isDownBearish + // + ) + // + && + // + ( + // + c1.high < mConditions.xdemaInfo.dema && + c2.high < mConditions.xdemaInfo.dema && + c3.high < mConditions.xdemaInfo.dema + // + ) + // + && + // + ( + // + mConditions.xstrInfo.isTrendBearish + // + ) + // + ; + + // + if (x786HasSignal) + { + // + Add( + ToString(X786), + mConditions.signal.providers); + + // + // double slPoint = 15; + // double slPrice = PointToPrice( + // mConditions.symbol, + // slPoint); + // double sl = entry - slPrice; + + // + double tpPoint = xTPPoint; + double tpPrice = PointToPrice( + mConditions.symbol, + tpPoint); + double tp = entry - tpPrice; + + // + mConditions.signal.r2r = 1; + mConditions.signal.riskAmount = 0.01; + mConditions.signal.mode = X_ORDER_MODE_MARKET; + mConditions.signal.entry = entry; + mConditions.signal.sl = 0; + mConditions.signal.tp = tp; + + // + mConditions.signal.ignoreSL = true; + mConditions.signal.useRiskAmountAsVolume = true; + } + } + + // + // X92 ... + bool x92HasSignal = false; + bool canCheckX92 = IsAllowdSignaller(X92); + if (canCheckX92) + { + // + x92HasSignal = + // + mConditions.xtrndInfo.isTrendUpBearish && + mConditions.xtrndInfo.isL1TrendUpBearish && + mConditions.xtrndInfo.isL2TrendUpBearish && + false + // + ; + + // + if (x92HasSignal) + { + // + Add( + ToString(X92), + mConditions.signal.providers); + + // + double tpPoint = xTPPoint; + double tpPrice = PointToPrice( + mConditions.symbol, + tpPoint); + double tp = entry - tpPrice; + + // + mConditions.signal.sl = 0; + mConditions.signal.tp = tp; + mConditions.signal.r2r = 1.5; + mConditions.signal.entry = entry; + mConditions.signal.riskAmount = 0.01; + mConditions.signal.mode = X_ORDER_MODE_MARKET; + + // + mConditions.signal.ignoreSL = false; + mConditions.signal.ignoreTP = false; + mConditions.signal.calculateTP = false; + mConditions.signal.useRiskAmountAsVolume = true; + } + } + + // + // X110 ... + bool x110HasSignal = false; + bool canCheckX110 = IsAllowdSignaller(X110); + if (canCheckX110) + { + // + x110HasSignal = + // + isMRBSlowCrossedWithPVFL3 && + mConditions.xtmInfo.isBearish + // + ; + + // + if (x110HasSignal) + { + // + Add( + ToString(X110), + mConditions.signal.providers); + + // + // double slPoint = 15; + // double slPrice = PointToPrice( + // mConditions.symbol, + // slPoint); + // double sl = entry + slPrice; + + // + double tpPoint = xTPPoint; + double tpPrice = PointToPrice( + mConditions.symbol, + tpPoint); + double tp = entry - tpPrice; + + // + mConditions.signal.r2r = 1; + mConditions.signal.riskAmount = 0.005; + mConditions.signal.mode = X_ORDER_MODE_MARKET; + mConditions.signal.entry = entry; + mConditions.signal.sl = 0; + mConditions.signal.tp = tp; + + // + mConditions.signal.ignoreSL = true; + mConditions.signal.useRiskAmountAsVolume = true; + } + } + + // + // X121 ... + bool x121HasSignal = false; + bool canCheckX121 = IsAllowdSignaller(X121); + if (canCheckX121) + { + // + x121HasSignal = + // + ( + // + ( + // + isC1Bearish && + (isC2Bearish || + isC3Bearish) + // + ) + // + && + // + c2.open < c3.open && + c1.open < c2.open + // + ) + // + && + // + (mConditions.xpvInfo.fl3 == mConditions2.xpvInfo.fl3) + // + && + // + ( + // + c3.high > mConditions.xpvInfo.fl1 && + c2.low <= mConditions.xpvInfo.fl1 && + ( + // + c2.low <= mConditions.xpvInfo.fl3 + // + || + // + ( + // + c2.low > mConditions.xpvInfo.fl3 && + c2.low < mConditions.xpvInfo.fl2 && + c1.high > mConditions.xpvInfo.fl3 && + c1.low < mConditions.xpvInfo.fl3 + // + ) + // + ) + // + && + // + c0SelectedPrice < mConditions.xpvInfo.fl3 + // + ) + // + ; + + // + if (x121HasSignal) + { + // + Add( + ToString(X121), + mConditions.signal.providers); + + // + // double slPoint = 15; + // double slPrice = PointToPrice( + // mConditions.symbol, + // slPoint); + // double sl = entry - slPrice; + + // + double tpPoint = xTPPoint; + double tpPrice = PointToPrice( + mConditions.symbol, + tpPoint); + double tp = entry - tpPrice; + + // + mConditions.signal.r2r = 1; + mConditions.signal.riskAmount = 0.01; + mConditions.signal.mode = X_ORDER_MODE_MARKET; + mConditions.signal.entry = entry; + mConditions.signal.sl = 0; + mConditions.signal.tp = tp; + + // + mConditions.signal.ignoreSL = true; + mConditions.signal.useRiskAmountAsVolume = true; + } + } + + // + // X128 ... + bool x128HasSignal = false; + bool canCheckX128 = IsAllowdSignaller(X128); + if (canCheckX128) + { + // + x128HasSignal = + // + isValeHappens && + mConditions.xamaInfo.value < mConditions.xtmInfo.value + // + ; + + // + if (x128HasSignal) + { + // + Add( + ToString(X128), + mConditions.signal.providers); + + // + // double slPoint = 15; + // double slPrice = PointToPrice( + // mConditions.symbol, + // slPoint); + // double sl = entry + slPrice; + + // + double tpPoint = xTPPoint; + double tpPrice = PointToPrice( + mConditions.symbol, + tpPoint); + double tp = entry - tpPrice; + + // + mConditions.signal.r2r = 1; + mConditions.signal.riskAmount = 0.005; + mConditions.signal.mode = X_ORDER_MODE_MARKET; + mConditions.signal.entry = entry; + mConditions.signal.sl = 0; + mConditions.signal.tp = tp; + + // + mConditions.signal.ignoreSL = true; + mConditions.signal.useRiskAmountAsVolume = true; + } + } + + // + result = + // + x786HasSignal + // + || + // + x92HasSignal + // + || + // + x110HasSignal + // + || + // + x121HasSignal + // + || + // + x128HasSignal + // + ; + + // + if (result) + { + // + conditions = mConditions; + + // + conditions.supportResistances = supRes; + conditions.momentumStep = mLastMomentumStep; + + // + conditions.signal.symbol = mSymbol; + conditions.signal.period = mPeriod; + conditions.signal.type = POSITION_TYPE_SELL; + + // + conditions.hasSignal = true; + } + + // + return result; + } +}; + +// +// START Definitions ... +// + +// +// Model Signal Providers Definitions ... +struct X121SignalProvider +{ + // + // Provider use Which Symbol ... + string symbol; + + // + // Allowed Providers ... + string providers[]; + + // + // Provider use Which Time Frame ... + ENUM_TIMEFRAMES period; + + // + // Risk Amount Per Trades Related to Time Frames ... + // Percent of Available Balance ... + double riskAmount; + + // + // Provider ... + XSCX121Provider *provider; +}; + +// +// END Definitions ... +// + +// +// START Usefull Functions ... +// + +// +// Add Specific Provider to List ... +void Add( + X121SignalProvider &item, // item want to add + X121SignalProvider &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} + +// +// Generate Identifier Tag ... +string GenerateTag(X121SignalProvider &descriptor) +{ + // + string result = ""; + + // + result = descriptor.symbol + "," + ToString(descriptor.period); + + // + return result; +} + +// +// Converts a Signal provider to String ... +string ToString(ENUM_X121_SIGNAL_PROVIDERS provider) +{ + return EnumToString(provider); +} + +// +// convert an String to Signal provider ... +ENUM_X121_SIGNAL_PROVIDERS ToProvider(string provider) +{ + // + ENUM_X121_SIGNAL_PROVIDERS result = NONE; + + // + if (ToString(NONE) == provider) + { + result = NONE; + } + else if (ToString(X786) == provider) + { + result = X786; + } + else if (ToString(X92) == provider) + { + result = X92; + } + else if (ToString(X110) == provider) + { + result = X110; + } + else if (ToString(X121) == provider) + { + result = X121; + } + else if (ToString(X128) == provider) + { + result = X128; + } + + // + return result; +} + +// +// Extract Provider Type from Signal Commnet ... +ENUM_X121_SIGNAL_PROVIDERS ExtractPositionProvider(XPosition &position) +{ + // + ENUM_X121_SIGNAL_PROVIDERS result = NONE; + + // + string providerStr = + ExtractString( + position.comment, + XProviderToken + "(", + ")"); + if (StringLen(providerStr) <= 0) + { + return result; + } + + // + result = ToProvider(providerStr); + + // + return result; +} + +// +// List All Available Providers ... +void GetAllProviders( + ENUM_X121_SIGNAL_PROVIDERS &result[] // Hold Result ... +) +{ + // + Clean(result); + + // + // X786 ... + ArrayResize( + result, + ArraySize(result) + 1); + result[ArraySize(result) - 1] = X786; + + // + // X92 ... + ArrayResize( + result, + ArraySize(result) + 1); + result[ArraySize(result) - 1] = X92; + + // + // X110 ... + ArrayResize( + result, + ArraySize(result) + 1); + result[ArraySize(result) - 1] = X110; + + // + // X121 ... + ArrayResize( + result, + ArraySize(result) + 1); + result[ArraySize(result) - 1] = X121; + + // + // X128 ... + ArrayResize( + result, + ArraySize(result) + 1); + result[ArraySize(result) - 1] = X128; +} + +// +// Lis All Available Providers ... +void GetAllProviders( + string &result[] // Hold Result ... +) +{ + // + Clean(result); + + // + ENUM_X121_SIGNAL_PROVIDERS providers[]; + GetAllProviders(providers); + int providersCount = ArraySize(providers); + if (providersCount <= 0) + { + return; + } + + // + for (int i = 0; i < providersCount; i++) + { + // + ENUM_X121_SIGNAL_PROVIDERS iProvider = providers[i]; + + // + Add( + ToString(iProvider), + result); + } +} + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Classes/x-saherelm.x121.xea.class.ex5 b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.x121.xea.class.ex5 new file mode 100644 index 0000000..b720932 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.x121.xea.class.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Classes/x-saherelm.x121.xea.class.mq5 b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.x121.xea.class.mq5 new file mode 100644 index 0000000..1406413 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.x121.xea.class.mq5 @@ -0,0 +1,1631 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCX121EA +// Description: an Expert Class which +// used X121 Setup ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Classes/x-saherelm.xea.class.mq5" +#include "../Libraries/x-saherelm.x121.draw.lib.mq5" +#include "../Libraries/x-saherelm.x121.support.lib.mq5" +#include "../Libraries/x-saherelm.x121.signaller.lib.mq5" +#include "../Classes/x-saherelm.x121.provider.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Definitions ... +// + +// +// an Structure to Holds a Support of Support ... +struct XSupport +{ + // + // Supported Position ... + XPosition position; + + // + // Last Support Date ... + ulong lastSupport; + + // + // Last SUpported Volume ... + double lastSupportVolume; +}; + +// +// END Definitions ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// an Expert Advisor Class by X121Provider ... +class XSCX121EA : public XSCBaseEA +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructor ... + void XSCX121EA( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + ulong magic, // Magic Number + int slippage, // Slippgae + TOnStopLoss onStopLossTriggered = NULL, // On StopLoass Triggered Event Handler + TOnTakeProfit onTakeProfitTriggered = NULL, // On TakeProfit Triggered Event Handler + TOnDealsChanged onDealsChangedHandler = NULL, // On Deals Changed Event Handler + TOnOrdersChanged onOrdersChangedHandler = NULL, // On Orders Changed Event Handler + TOnPositionsChanged onPositionsChangedHandler = NULL, // On Positions Changed Event Handler + TOnTradeStateChanged onTradeStateChangedHandler = NULL, // On Trade State Changed Event Handler + TOnSignalConditions onSignalConditions = NULL // On SignalConditions Event Handler + ) : XSCBaseEA(symbol, + period, + magic, + slippage, + onStopLossTriggered, + onTakeProfitTriggered, + onDealsChangedHandler, + onOrdersChangedHandler, + onPositionsChangedHandler, + onTradeStateChangedHandler) + { + mOnSignalConditions = onSignalConditions; + } + + // + // DeConstructor ... + void ~XSCX121EA() + { + // + int providersCount = ArraySize(mProviders); + if (providersCount > 0) + { + // + for (int i = 0; i < providersCount; i++) + { + // + X121SignalProvider iProvider = mProviders[i]; + + // + delete iProvider.provider; + } + } + } + + // + // START Properties ... + // + + // + // Add Provider ... + bool AddProvider( + X121SignalProvider &provider // Specific Provider ... + ) + { + // + bool result = false; + + // + // Validate Provider ... + if (provider.symbol == NULL || + provider.period == NULL || + provider.riskAmount <= 0 || + StringLen(provider.symbol) == 0 || + ArraySize(provider.providers) == 0) + { + return result; + } + + // + // Check Exists or not ... + int idx = GetProviderIndex( + provider.symbol, + provider.period); + if (idx >= 0) + { + return result; + } + + // + PrepareProviderConfig(); + + // + // Make Instance of X121Provider Class ... + provider.provider = new XSCX121Provider( + mSymbol, + mPeriod); + + // + // Attach Event Listener ... + if (mOnSignalConditions != NULL) + { + // + // Attach Event Handlers ... + provider.provider.AddOnSignalConditionEventHandler(mOnSignalConditions); + } + + // + // Set Signallers to Provider Class ... + result = provider.provider.SetSignallers(provider.providers); + if (!result) + { + return result; + } + + // + // Initialize Provider ... + result = provider.provider.SetConfig(mProviderConfig); + + // + // Add Prepared Provider to Providers ... + Add( + provider, + mProviders); + + // + return result; + } + + // + // Add Providers ... + int AddProviders( + X121SignalProvider &providers[] // Specific Providers ... + ) + { + // + int result = 0; + + // + int providersCount = ArraySize(providers); + if (providersCount <= 0) + { + return result; + } + + // + for (int i = 0; i < providersCount; i++) + { + // + X121SignalProvider iProvider = providers[i]; + + // + bool isAdded = AddProvider(iProvider); + if (isAdded) + { + result++; + } + } + + // + return result; + } + + // + // END Properties ... + // + + // + // START Overrides ... + // + + // + void OnPositionsChangedHandler(int count) + { + // + XPosition positions[]; + mTrader.GetPositions(positions); + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + XPositionPack pack; + bool hasPositionPack = mTrader.GetPositionPack( + iPosition.ticket, + pack); + if (hasPositionPack) + { + continue; + } + } + } + + // + // Handle TakeProfit Event ... + void OnTakeProfitTriggered(const XDeal &deal) + { + // + // Get Take Profit Position ... + ulong ticket = deal.positionId; + string symbol = deal.symbol; + + // + XOrder supportOrders[]; + + // + XOrder orders[]; + mTrader.GetOrders( + orders, + symbol, + NULL, + ORDER_STATE_PLACED); + int ordersCount = ArraySize(orders); + if (ordersCount <= 0) + { + return; + } + + // + for (int i = 0; i < ordersCount; i++) + { + // + XOrder iOrder = orders[i]; + + // + string params[]; + bool isSupport = ExtractSupportParams( + iOrder.comment, + params); + if (!isSupport) + { + continue; + } + + // + ulong parentTicket = ExtractParentTicket(iOrder.comment); + if (parentTicket != ticket) + { + continue; + } + + // + Add( + iOrder, + supportOrders); + } + + // + int supportOrdersCount = ArraySize(supportOrders); + if (supportOrdersCount <= 0) + { + return; + } + + // + bool isCanceled = mTrader.CancelOrders(supportOrders); + if (isCanceled) + { + // + string message = "Close (" + ToString(supportOrdersCount) + ") Support of: (" + ToString(ticket) + ") due it's Take Profit ..."; + + // + LogMessage(message); + } + } + + // + // END Overrides ... + // + + // + // START Inheritance Functions ... + // + + // + void PrepareTag() + { + mTag = "X121EA:" + mSymbol + "," + ToString(mPeriod) + (string)mMagic; + } + + // + // Check Providers Guard States ... + bool CheckGuard(XGuard &guards[]) + { + // + bool result = false; + + // + Clean(guards); + + // + int providersCount = ArraySize(mProviders); + if (providersCount <= 0) + { + return result; + } + + // + for (int i = 0; i < providersCount; i++) + { + // + X121SignalProvider iProvider = mProviders[i]; + + // + XGuard iGuards[]; + bool iHasGuard = iProvider.provider.GuardCheck(iGuards); + if (iHasGuard) + { + // + Copy( + iGuards, + guards, + false); + } + } + + // + // Here we Can Implement Custom Guards Senario ... + + // + // Do Management Equity ... + HandleEquityManagement(); + + // + result = ArraySize(guards) > 0; + + // + return result; + } + + // + // Check Providers for Signals ... + bool SignalCheck(XSignal &signals[]) + { + // + bool result = false; + + // + Clean(signals); + + // + // Check Max Allowed Positions ... + result = ChecPositionsForTrade(); + if (!result) + { + return result; + } + + // + // Check Equity ... + result = CheckEquityForTrade(); + if (!result) { + return result; + } + + // + int providersCount = ArraySize(mProviders); + if (providersCount <= 0) + { + return result; + } + + // + for (int i = 0; i < providersCount; i++) + { + // + X121SignalProvider iProvider = mProviders[i]; + + // + int iFoundedPivots = iProvider.provider.CountPivots(); + int iReuiredPivots = iProvider.provider.GetMinPivots(); + if (iFoundedPivots < iReuiredPivots) + { + // + iProvider.provider.ProccessPivotPoints(); + + // + continue; + } + + // + X121MarketConditions iConditions; + // + // By Use this Template we Can Test Signallers + // then Make Them Traditional ... + bool iHasSignal = XTMPProcessSignal( + iConditions, + iProvider.provider); + + // + // TODO: Fix this ... + // iProvider.provider.ProcessTick(iConditions); + + // + if (iHasSignal && iConditions.hasSignal) + { + // + // Check Signalling is Enabled by Signal type ... + bool isiSignalLong = IsLong(iConditions.signal.type); + if ((isiSignalLong && !mEnableLongs) || (!isiSignalLong && !mEnableShorts)) + { + continue; + } + + // + PrepareConditionsSignal(iConditions); + + // + // Generate Support Signals ... + // GenerateSignalSupports( + // iConditions.signal, + // iProvider.provider); + + // + // DrawConditionsSignalOnChart(iConditions); + + // + Add( + iConditions.signal, + signals); + } + } + + // + result = ArraySize(signals) > 0; + + // + // IMPORTANT: + // Since we have to Implement our Signal Execution Senario + // Ignore this here for Default behaviour and implememt or Execution ... + if (result) + { + // + XSignal allowedSignals[]; + + // + // Select Which Signal need To Execute ... + bool hasEquity = CheckEquityForTrade(); + if (hasEquity) + { + // + // Since we have necessary Equity for Trade ... + // Accept all incomming Signals ... + Copy( + signals, + allowedSignals); + + // + // TODO: + // Implement Trade Policies ... + } + else + { + // + // How to Select Signals when there is no Equity for Trade ... + LogMessage("No Equity ..."); + } + + // + int allowedSignalsCount = ArraySize(allowedSignals); + if (allowedSignalsCount > 0) + { + // + // Execute Signals oly when allowed ... + mTrader.ExecuteSignals(allowedSignals); + } + + // + // Prevent Default Base Signal Execution ... + + // + Clean(signals); + + // + return false; + } + + // + return result; + } + + // + // END Inheritance Functions ... + // + + // + // START Provided Actions ... + // + + // + // END Provided Actions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + X121SignalProvider mProviders[]; + X121ProviderInputs mProviderConfig; + TOnSignalConditions mOnSignalConditions; + + // + // Actions ... + + // + // SUPPORT ... + // + + // + // EQUITYMANAGEMENT ... + // Supported Positions ... + XSupport mSupports[]; + + // + // EQUITYMANAGEMENT ... + // Check Support of Supports Exists or ot ... + bool HasSuppors() + { + return CountSupports() > 0; + } + + // + // EQUITYMANAGEMENT ... + // Count Exists Support of Supports ... + int CountSupports() + { + return ArraySize(mSupports); + } + + // + // EQUITYMANAGEMENT ... + // Retrieve Supported of Supports ... + int GetSupportsIndex( + ulong ticket // Desired Support Position Ticket ... + ) + { + // + int result = -1; + + // + int supportsCount = CountSupports(); + if (supportsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < supportsCount; i++) + { + // + XSupport iSupport = mSupports[i]; + + // + if (iSupport.position.ticket != 0 && + iSupport.position.ticket == ticket) + { + // + result = i; + break; + } + } + + // + return result; + } + + // + // EQUITYMANAGEMENT ... + // Add Supported of Supports ... + bool AddSupports( + XSupport &support // Support item ... + ) + { + // + bool result = false; + + // + // Check Support Exists or not ... + int supIndex = GetSupportsIndex(support.position.ticket); + if (supIndex < 0) + { + // + // Add New ... + Add(support, + mSupports); + + // + result = true; + } + else + { + // + // Update Exists ... + + // + int supportsCount = CountSupports(); + XSupport collection[]; + for (int i = 0; i < supportsCount; i++) + { + // + XSupport iSupport = mSupports[i]; + + // + if (iSupport.position.ticket == support.position.ticket) + { + continue; + } + + // + Add(iSupport, + collection); + } + + // + Add(support, + collection); + + // + Copy( + collection, + mSupports, + true); + + // + Clean(collection); + + // + result = true; + } + + // + return result; + } + + // + // EQUITYMANAGEMENT ... + // Remove Supported Of Supports ... + bool RemoveSupports( + XSupport &support // Support item ... + ) + { + // + bool result = false; + + // + // Check Support Exists or not ... + int supIndex = GetSupportsIndex(support.position.ticket); + if (supIndex < 0) + { + return result; + } + + // + int supportsCount = CountSupports(); + XSupport collection[]; + for (int i = 0; i < supportsCount; i++) + { + // + XSupport iSupport = mSupports[i]; + + // + if (iSupport.position.ticket == support.position.ticket) + { + continue; + } + + // + Add(iSupport, + collection); + } + + // + Copy( + collection, + mSupports, + true); + + // + Clean(collection); + + // + result = true; + + // + return result; + } + + // + // EQUITYMANAGEMENT ... + int GetSupportAge( + int index // Supported Index + ) + { + // + int result = -1; + + // + int supportsCount = CountSupports(); + if (index < 0 || index > supportsCount - 1) + { + return result; + } + + // + // Retrieve Required Info ... + string symbol = mSupports[index].position.symbol; + ENUM_TIMEFRAMES period = mSupports[index].position.period; + datetime lastDate = MilliSecondsToTiem(mSupports[index].lastSupport); + + // + // Calculate Age ... + result = iBarShift( + symbol, + period, + lastDate); + + // + return result; + } + + // + // EQUITYMANAGEMENT ... + // + + // + // Do All Equity Management Works here ... + void HandleEquityManagement() + { + + // + // Handle Hedging Positions ... + HandleHedging(); + + // + return; + + // + // Close All Long Time Placed Support Signals + // Which doesn't Triggered yest ... + HandleCancelAllUntriggeredSupports(); + + // + // Check Equity ... + bool hasEquity = CheckEquityForTrade(); + if (hasEquity) + { + return; + } + + // + // Retrieve Provider Count ... + int providersCount = ArraySize(mProviders); + if (providersCount <= 0) + { + // + // We Have at least two Position for Hedging ... + return; + } + + // + // Loop Through Registered Provider Instances ... + for (int i = 0; i < providersCount; i++) + { + // + bool canIgnoreSupporting = false; + + // + X121SignalProvider iSProvider = mProviders[i]; + + // + string symbol = iSProvider.symbol; + ENUM_TIMEFRAMES period = iSProvider.period; + XSCX121Provider *analyzer = iSProvider.provider; + + // + // We Have to Detect Each Providers In DrawDown Signals and then + // Found any Support Signals for them ... + // 1- must have at least TWO Support Signal without tp ... + // 2- there are some signals by providing tp ... + // 3- Trend base and Conditional Supports by tp ... + + // + XPosition inDrawdownPositions[]; + GetInDrawdownPositions( + inDrawdownPositions, // Result ... + symbol, + NULL, // All Types ... + period, + NULL, // All Providers ... + NULL // Select All ... + ); + int inDrawdownPositionsCount = ArraySize(inDrawdownPositions); + if (inDrawdownPositionsCount <= 0) + { + continue; + } + + // + // Find Oldest Position to CHeck Trade Age ... + XPosition oldestInDrawdownPosition; + int oldestInDrawdownPositionAge = GetOldest( + oldestInDrawdownPosition, + inDrawdownPositions); + bool isTooOldForSupport = oldestInDrawdownPositionAge >= oldAgePositionForSupportFactor; + if (!isTooOldForSupport) + { + continue; + } + + // + // Now we Have to Check Exists EQM Supports ... + XOrder orders[]; + GetOrders( + orders, + symbol, + NULL, // All Types ... + NULL, // All States ... + period, + NULL // All Providers ... + ); + int ordersCount = ArraySize(orders); + if (ordersCount > 0) + { + // + // Extract EQM Support Signals ... + XOrder supportOrders[]; + ordersCount = GetEQMSupportOrders( + supportOrders, + orders, + period); + if (ordersCount > 0) + { + // + // Since there are EQM Untriggere Support Orders here ... + // we have to check theirs longest Age ... + XOrder longestUntriggeredSupportOrder; + int longestUntriggeredSupportOrderAge = GetOldest( + longestUntriggeredSupportOrder, + supportOrders); + canIgnoreSupporting = longestUntriggeredSupportOrderAge < oldAgeSupportForReNewFactor; + if (canIgnoreSupporting) + { + continue; + } + } + } + + // + // Here we Have To Generate new Support Signals and Execute them ... + XSignal supports[]; + int supportsCount = GenerateMarketSupports( + supports, + symbol, // Trading Symbol ... + period, // Trading Timeframe ... + analyzer // Market Analizer ( Signal Provider Instance ) ... + ); + if (supportsCount <= 0) + { + continue; + } + + // + PrepareSignals(supports); + + // + string comment = GenerateXEQMSupportComment(period); + int executed = mTrader.ExecuteSignals( + supports, + comment); + } + } + + // + // Close All Positions in Summary Profit ... + bool HandleHedging() + { + // + bool result = false; + + // + // List All Open Positions and Calculate Profit Summary ... + + // + double profit = 0; + double requiredProfit = 0; + + // + XPosition positions[]; + GetPositions( + positions, // Result ... + NULL, // All Symbols ... + NULL, // All Types ... + NULL, // All Period ... + NULL // All Providers ... + ); + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + profit += iPosition.profit; + requiredProfit += ((iPosition.volume / minProfitPerVolumeFactor) * minProfitPerTrade) + (-1 * iPosition.swap); + } + + // + // Check We Can Hedge or not ... + result = profit >= requiredProfit; + if (!result) + { + // + // Here we Have to Close Long In Profit Trades ... + // Open Positions ... + XPosition longestInProfitPosition; + int longestInProfitPositionAge = GetOldest( + longestInProfitPosition, + positions); + double requireProfit = minProfitPerTrade * (longestInProfitPosition.profit / minProfitPerVolumeFactor) + -1 * (longestInProfitPosition.swap); + bool canClose = + longestInProfitPositionAge >= oldAgePositionForSupportFactor && + longestInProfitPosition.profit > 0 && longestInProfitPosition.profit > requireProfit; + if (canClose) + { + // + string comment = "EQM Close In Profit ..."; + + // + bool isClosed = mTrader.Close( + longestInProfitPosition.ticket, + comment); + if (isClosed) + { + // + // Force Cancel All Pending Orders ... + HandleCancelAllUntriggeredSupports(true); + + // + string message = "EQM Close Position (" + ToString(longestInProfitPosition.ticket) + ") by: " + ToString(longestInProfitPosition.profit); + + // + LogMessage(message); + + // + result = true; + } + } + + // + // Check if one Position is Open and it's in Drawdown and ore than + // longest age ... + // close it ... + // if (!result) + // { + // // + // if (longestInProfitPositionAge >= oldAgePositionForSupportFactor) + // { + // // + // string comment = "EQM Close In DD ..."; + + // // + // int closed = mTrader.ClosePositions( + // positions, + // comment); + // result = closed == positionsCount; + // } + // } + + // + return result; + } + + // + string comment = "EQM Hedge ..."; + int closed = mTrader.ClosePositions( + positions, + comment); + + // + result = closed == positionsCount; + if (result) + { + // + // Force Cancel All Pending Orders ... + HandleCancelAllUntriggeredSupports(true); + + // + string message = "EQM Close (" + ToString(closed) + ") Positions due HEDGE by: " + ToString(profit); + + // + LogMessage(message); + } + + // + return result; + } + + // + // We Have To Cancell All Untriggered Supports ... + void HandleCancelAllUntriggeredSupports( + bool force = false // Force Close All ... + ) + { + // + // Retrieve all Placed EQM Supports ... + XOrder orders[]; + GetOrders( + orders, + NULL, // All Symbols ... + NULL, // All Types ... + NULL, // All State ... + NULL, // All Periods ... + NULL // All Providers ... + ); + int ordersCount = ArraySize(orders); + if (ordersCount <= 0) + { + return; + } + + // + XOrder supports[]; + int supportsCount = GetEQMSupportOrders( + supports, + orders, + NULL // All Time Frames ... + ); + if (supportsCount <= 0) + { + return; + } + + // + XOrder oldest; + int oldestAge = GetOldest( + oldest, + orders); + bool isTooOldForCancel = oldestAge >= oldAgeSupportForReNewFactor; + if (!force && !isTooOldForCancel) + { + return; + } + + // + bool isCanceled = mTrader.CancelOrders( + supports); + } + + // + // Pepare a Collection Of Signals ... + void PrepareSignals(XSignal &signals[]) + { + // + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + for (int i = 0; i < signalsCount; i++) + { + // + PrepareSignal(signals[i]); + } + } + + // + // PROVIDERS ... + // + + // + // Find Specific Provider Index by using give symbol and period ... + int GetProviderIndex( + string symbol, // Trading Symbol ... + ENUM_TIMEFRAMES period // Trading Time frame ... + ) + { + // + int result = -1; + + // + // Validate Args ... + if (period == NULL || + symbol == NULL || + StringLen(symbol) == 0) + { + return result; + } + + // + int providersCount = ArraySize(mProviders); + if (providersCount <= 0) + { + return result; + } + + // + for (int i = 0; i < providersCount; i++) + { + // + X121SignalProvider iProvider = mProviders[i]; + + // + if (iProvider.symbol == symbol && iProvider.period == period) + { + // + result = i; + break; + } + } + + // + return result; + } + + // + // Prepare Default Configurations for X121Provider Setup ... + void PrepareProviderConfig() + { + // + // XCT ... + // Candle Timing ... + mProviderConfig.xctConfig.clr = clrBlueViolet; + mProviderConfig.xctConfig.corner = CORNER_RIGHT_UPPER; + mProviderConfig.xctConfig.showCandleTime = true; + + // + // XCC ... + // Candle Styling ... + mProviderConfig.xccConfig.upColor = clrLime; + mProviderConfig.xccConfig.downColor = clrRed; + mProviderConfig.xccConfig.lineColor = clrLime; + mProviderConfig.xccConfig.bearishColor = clrRed; + mProviderConfig.xccConfig.bullishColor = clrLime; + mProviderConfig.xccConfig.volumesColor = clrGreen; + mProviderConfig.xccConfig.showCandles = true; + + // + // XHK ... + // HikenAshi Candle Representing ... + mProviderConfig.xhkConfig.drawCandleLines = false; + + // + // XTM ... + // Trend Magic ... + mProviderConfig.xtmConfig.length = 35; + mProviderConfig.xtmConfig.shift = 0; + mProviderConfig.xtmConfig.method = MODE_SMA; + mProviderConfig.xtmConfig.appliedTo = PRICE_LOW; + mProviderConfig.xtmConfig.showLine = false; + + // + // XPV ... + // Peaks And Vales ... + mProviderConfig.xpvConfig.shortLength = 9; + mProviderConfig.xpvConfig.mediumLength = 17; + mProviderConfig.xpvConfig.longLength = 26; + mProviderConfig.xpvConfig.hindLength = 35; + mProviderConfig.xpvConfig.fiboLevel1 = 0.382; + mProviderConfig.xpvConfig.fiboLevel2 = 0.5; + mProviderConfig.xpvConfig.fiboLevel3 = 0.618; + mProviderConfig.xpvConfig.hhMode = MODE_HIGH; + mProviderConfig.xpvConfig.llMode = MODE_LOW; + mProviderConfig.xpvConfig.showPeaksAndVales = false; + mProviderConfig.xpvConfig.showLevels = false; + mProviderConfig.xpvConfig.showFibo1Levels = false; + mProviderConfig.xpvConfig.showFibo2Levels = false; + mProviderConfig.xpvConfig.showFibo3Levels = false; + + // + // XAMA ... + // Adaptive Moving Average ... + mProviderConfig.xamaConfig.length = 52; + mProviderConfig.xamaConfig.fastEMA = 2; + mProviderConfig.xamaConfig.slowEMA = 30; + mProviderConfig.xamaConfig.maShift = 0; + mProviderConfig.xamaConfig.appliedTo = PRICE_LOW; + mProviderConfig.xamaConfig.showLine = false; + + // + // XMRB ... + // Moving Average Ribbon ... + mProviderConfig.xmrbConfig.fast1Length = 3; + mProviderConfig.xmrbConfig.slow1Length = 5; + mProviderConfig.xmrbConfig.fast2Length = 8; + mProviderConfig.xmrbConfig.slow2Length = 13; + mProviderConfig.xmrbConfig.fast3Length = 21; + mProviderConfig.xmrbConfig.slow3Length = 34; + mProviderConfig.xmrbConfig.fast4Length = 55; + mProviderConfig.xmrbConfig.slow4Length = 89; + mProviderConfig.xmrbConfig.fast5Length = 144; + mProviderConfig.xmrbConfig.slow5Length = 233; + mProviderConfig.xmrbConfig.ribbonMode = MODE_EMA; + mProviderConfig.xmrbConfig.ribbonAppliedTo = PRICE_CLOSE; + mProviderConfig.xmrbConfig.showFastMa = false; + mProviderConfig.xmrbConfig.showSlowMa = false; + mProviderConfig.xmrbConfig.showRibbon = false; + + // + // XCHE ... + // Chandelier Exit Points ... + mProviderConfig.xcheConfig.length = 35; + mProviderConfig.xcheConfig.loopback = 26; + mProviderConfig.xcheConfig.multiplier1 = 3; + mProviderConfig.xcheConfig.multiplier2 = 3.5; + mProviderConfig.xcheConfig.upAppliedTo = PRICE_HIGH; + mProviderConfig.xcheConfig.downAppliedTo = PRICE_LOW; + mProviderConfig.xcheConfig.showLongExit1Line = false; + mProviderConfig.xcheConfig.showShortExit1Line = false; + mProviderConfig.xcheConfig.showLongExit2Line = false; + mProviderConfig.xcheConfig.showShortExit2Line = false; + + // + // XICH ... + // Ichimopku Kinko Hyo ... + mProviderConfig.xichConfig.tenkanSenLength = 9; + mProviderConfig.xichConfig.tenkanSenMode = X_XICH_HH_LL_MODE; + mProviderConfig.xichConfig.kijunSenLength = 26; + mProviderConfig.xichConfig.kijunSenMode = X_XICH_HH_LL_MODE; + mProviderConfig.xichConfig.senkouSpanBLength = 52; + mProviderConfig.xichConfig.senkouSpanBMode = X_XICH_HH_LL_MODE; + mProviderConfig.xichConfig.chikuoSpanAppliedTo = PRICE_CLOSE; + mProviderConfig.xichConfig.showTenkanSen = false; + mProviderConfig.xichConfig.showKijunSen = false; + mProviderConfig.xichConfig.showKijunSenPlus = false; + mProviderConfig.xichConfig.showKijunSenNegative = false; + mProviderConfig.xichConfig.showChikouSpan = false; + mProviderConfig.xichConfig.showSenkouSpanA = false; + mProviderConfig.xichConfig.showSenkouSpanB = false; + mProviderConfig.xichConfig.showKumo = false; + mProviderConfig.xichConfig.shiftKumo = true; + + // + // XTRND ... + // Trend Detector ... + mProviderConfig.xtrndConfig.cycleLength = 2; + mProviderConfig.xtrndConfig.numberOfVerifications = 2; + mProviderConfig.xtrndConfig.hhMode = MODE_HIGH; + mProviderConfig.xtrndConfig.llMode = MODE_LOW; + mProviderConfig.xtrndConfig.l1Method = X_PERIOD_AUTO; + mProviderConfig.xtrndConfig.l1Period = NULL; + mProviderConfig.xtrndConfig.l2Method = X_PERIOD_AUTO; + mProviderConfig.xtrndConfig.l2Period = NULL; + mProviderConfig.xtrndConfig.l3Method = X_PERIOD_AUTO; + mProviderConfig.xtrndConfig.l3Period = NULL; + mProviderConfig.xtrndConfig.showConsolidations = false; + mProviderConfig.xtrndConfig.showTrend = false; + mProviderConfig.xtrndConfig.showL1Trend = false; + mProviderConfig.xtrndConfig.showL2Trend = false; + mProviderConfig.xtrndConfig.showL3Trend = false; + + // + // XSSLC ... + // SSL Channel ... + mProviderConfig.xsslcConfig.length = 36; + mProviderConfig.xsslcConfig.method = MODE_SMA; + mProviderConfig.xsslcConfig.upAppliedTo = PRICE_HIGH; + mProviderConfig.xsslcConfig.downAppliedTo = PRICE_LOW; + mProviderConfig.xsslcConfig.showUp = false; + mProviderConfig.xsslcConfig.showDown = false; + + // + // XHULL ... + // Hull Trend Detection Channel ... + mProviderConfig.xhullConfig.length = 72; + mProviderConfig.xhullConfig.divisor = 2; + mProviderConfig.xhullConfig.upAppliedTo = PRICE_HIGH; + mProviderConfig.xhullConfig.downAppliedTo = PRICE_LOW; + mProviderConfig.xhullConfig.showUpZone = false; + mProviderConfig.xhullConfig.showDownZone = false; + + // + // XOSC ... + mProviderConfig.xoscConfig.atrLength = 14; + mProviderConfig.xoscConfig.rviLength = 10; + mProviderConfig.xoscConfig.bullpLength = 13; + mProviderConfig.xoscConfig.bearpLength = 13; + mProviderConfig.xoscConfig.volumeAppliedTo = VOLUME_TICK; + mProviderConfig.xoscConfig.rsiLength = 14; + mProviderConfig.xoscConfig.rsiAppliedTo = PRICE_CLOSE; + mProviderConfig.xoscConfig.cciLength = 14; + mProviderConfig.xoscConfig.cciAppliedTo = PRICE_TYPICAL; + mProviderConfig.xoscConfig.stddevLength = 20; + mProviderConfig.xoscConfig.stddevShift = 0; + mProviderConfig.xoscConfig.stddevMethod = MODE_SMA; + mProviderConfig.xoscConfig.stddevAppliedTo = PRICE_CLOSE; + mProviderConfig.xoscConfig.momentumLength = 14; + mProviderConfig.xoscConfig.momentumAppliedTo = PRICE_CLOSE; + mProviderConfig.xoscConfig.sarStep = 0.02; + mProviderConfig.xoscConfig.sarMaximum = 0.2; + mProviderConfig.xoscConfig.macdFastLength = 12; + mProviderConfig.xoscConfig.macdSlowLength = 26; + mProviderConfig.xoscConfig.macdSignaLength = 9; + mProviderConfig.xoscConfig.macdAppliedTo = PRICE_CLOSE; + mProviderConfig.xoscConfig.stochKLength = 5; + mProviderConfig.xoscConfig.stochDLength = 3; + mProviderConfig.xoscConfig.stochSlowing = 3; + mProviderConfig.xoscConfig.stochMaMethod = MODE_SMA; + mProviderConfig.xoscConfig.stochMode = STO_LOWHIGH; + + // + // XSTR ... + mProviderConfig.xstrConfig.atrLength = 12; + mProviderConfig.xstrConfig.atrMultiplier = 3.0; + mProviderConfig.xstrConfig.atrAppliedTo = PRICE_MEDIAN; + mProviderConfig.xstrConfig.showTrends = false; + mProviderConfig.xstrConfig.fillTrends = false; + + // + // XFBB ... + mProviderConfig.xfbbConfig.length = 200; + mProviderConfig.xfbbConfig.multiplier = 3.0; + mProviderConfig.xfbbConfig.appliedTo = PRICE_TYPICAL; + mProviderConfig.xfbbConfig.showBase = false; + mProviderConfig.xfbbConfig.showBand = false; + mProviderConfig.xfbbConfig.showGoldenArea = false; + mProviderConfig.xfbbConfig.showOthers = false; + + // + // XDEMA ... + mProviderConfig.xdemaConfig.length = 200; + mProviderConfig.xdemaConfig.shift = 0; + mProviderConfig.xdemaConfig.showDema = false; + mProviderConfig.xdemaConfig.showEMA = false; + mProviderConfig.xdemaConfig.showEMAOfEMA = false; + + // + PreDefineProviderConfig(); + } + + // + void PreDefineProviderConfig() + { + // + // Default Configs For Different States ... + bool showPV = false; + bool showHK = false; + bool showTM = false; + bool showCHE = false; + bool showSTR = false; + bool showFBB = false; + bool showMRB = false; + bool showTRND = false; + bool showDEMA = false; + bool showHULL = false; + bool showSimpleIchi = false; + + // + // Predefine ... + + // + // X786 ... + showPV = true; + // showTM = false; + // showHK = false; + showCHE = true; + // showSTR = false; + // showDEMA = true; + showTRND = true; + // showHULL = false; + // showSimpleIchi = false; + + // + if (showHK) + { + // + // Hiken Ashi ... + mProviderConfig.xccConfig.showCandles = false; + mProviderConfig.xhkConfig.drawCandles = true; + } + if (showPV) + { + // + // Peaks and Vales ... + mProviderConfig.xpvConfig.showLevels = true; + mProviderConfig.xpvConfig.showFibo1Levels = true; + mProviderConfig.xpvConfig.showFibo2Levels = true; + mProviderConfig.xpvConfig.showFibo3Levels = true; + mProviderConfig.xpvConfig.showPeaksAndVales = true; + } + if (showSimpleIchi) + { + // + // Simple Ichimoku Kinko Hyo ... + mProviderConfig.xichConfig.showKijunSen = true; + mProviderConfig.xichConfig.showTenkanSen = true; + mProviderConfig.xichConfig.showSenkouSpanA = true; + mProviderConfig.xichConfig.showSenkouSpanB = true; + } + if (showCHE) + { + // + // Chandelier Exit ... + mProviderConfig.xcheConfig.showLongExit1Line = true; + mProviderConfig.xcheConfig.showLongExit2Line = true; + mProviderConfig.xcheConfig.showShortExit1Line = true; + mProviderConfig.xcheConfig.showShortExit2Line = true; + } + if (showTRND) + { + // + // Show Trend ... + mProviderConfig.xtrndConfig.showTrend = true; + mProviderConfig.xtrndConfig.showL1Trend = true; + mProviderConfig.xtrndConfig.showL2Trend = true; + mProviderConfig.xtrndConfig.showL3Trend = true; + mProviderConfig.xtrndConfig.showConsolidations = false; + } + if (showSTR) + { + // + // Show Super Trend ... + mProviderConfig.xstrConfig.showTrends = true; + } + if (showFBB) + { + // + // Show Fibonacci Band ... + mProviderConfig.xfbbConfig.showBase = true; + mProviderConfig.xfbbConfig.showBand = true; + mProviderConfig.xfbbConfig.showGoldenArea = true; + } + if (showDEMA) + { + // + // Show Double EMA ... + mProviderConfig.xdemaConfig.showDema = true; + } + if (showMRB) + { + // + mProviderConfig.xmrbConfig.showFastMa = true; + mProviderConfig.xmrbConfig.showSlowMa = true; + mProviderConfig.xmrbConfig.showRibbon = false; + } + if (showTM) + { + mProviderConfig.xtmConfig.showLine = true; + } + if (showHULL) + { + // + mProviderConfig.xhullConfig.showUpZone = true; + mProviderConfig.xhullConfig.showDownZone = true; + } + + // + // X128 ... + // + // XTM ... + // Trend Magic ... + // mProviderConfig.xtmConfig.length = 17; + // mProviderConfig.xtmConfig.shift = 0; + // mProviderConfig.xtmConfig.method = MODE_SMA; + // mProviderConfig.xtmConfig.appliedTo = PRICE_CLOSE; + // mProviderConfig.xtmConfig.showLine = false; + + // + // XAMA ... + // Adaptive Moving Average ... + // mProviderConfig.xamaConfig.length = 52; + // mProviderConfig.xamaConfig.fastEMA = 2; + // mProviderConfig.xamaConfig.slowEMA = 6; + // mProviderConfig.xamaConfig.maShift = 0; + // mProviderConfig.xamaConfig.appliedTo = PRICE_CLOSE; + // mProviderConfig.xamaConfig.showLine = false; + } + + // + void PrepareConditionsSignal(X121MarketConditions &conditions) + { + // + if (!conditions.hasSignal) + { + return; + } + + // + bool isLong = IsLong(conditions.signal.type); + + // + // Check Calculate TP ... + if ( + conditions.signal.sl > 0 && + conditions.signal.r2r > 0 && + conditions.signal.entry > 0 && + conditions.signal.calculateTP) + { + // + double riskPrice = MathAbs(conditions.signal.entry - conditions.signal.sl); + double riskPoint = PriceToPoint( + conditions.signal.symbol, + riskPrice); + double rewardPoint = riskPoint * conditions.signal.r2r; + double rewardPrice = PointToPrice( + conditions.signal.symbol, + rewardPoint); + + // + double tp = + isLong + ? conditions.signal.entry + rewardPrice + : conditions.signal.entry - rewardPrice; + + // + conditions.signal.tp = tp; + } + + // + PrepareSignal(conditions.signal); + } + + // + void DrawConditionsSignalOnChart(X121MarketConditions &conditions) + { + // + ulong mTicket = MathRand() * 100000; + + // + DrawSignal( + mTicket, + conditions.signal); + + // + DrawSupportResistance( + 0, + conditions.supportResistances, + conditions.signal.providers[0]); + } +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xaccount.class.ex5 b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xaccount.class.ex5 new file mode 100644 index 0000000..2da986c Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xaccount.class.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xaccount.class.mq5 b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xaccount.class.mq5 new file mode 100644 index 0000000..4425f0b --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xaccount.class.mq5 @@ -0,0 +1,398 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCAccount +// Description: provides all Account requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Manage Account ... +class XSCAccount +{ + // + // Public ... +public: + // + // Constructor ... + void XSCAccount() + { + // + mAccountInfo = new CAccountInfo(); + } + + // + // Deconstructor ... + void ~XSCAccount() + { + } + + // + // START Provided Functions ... + // + + // + // User Account ... + long GetUserAccount() + { + return mAccountInfo.Login(); + } + + // + // Account Leverage ... + long GetLeverage() + { + return mAccountInfo.Leverage(); + } + + // + // Get Trade Expert State ... + bool CanExpertTrade() + { + return mAccountInfo.TradeExpert(); + } + + // + // User Account Trade Mopde (ENUM_ACCOUNT_TRADE_MODE) ... + // -------------------------- + // ACCOUNT_TRADE_MODE_DEMO + // ACCOUNT_TRADE_MODE_CONTEST + // ACCOUNT_TRADE_MODE_REAL + ENUM_ACCOUNT_TRADE_MODE GetTradeMode() + { + return mAccountInfo.TradeMode(); + } + + // + // Get Account Balance ... + double GetBalance() + { + return mAccountInfo.Balance(); + } + + // + // Get the amount of give Credit ... + double GetCredit() + { + return mAccountInfo.Credit(); + } + + // + // Get the amount of current Profit on account ... + double GetProfit() + { + return mAccountInfo.Profit(); + } + + // + // Get the amount of current Equity on account ... + double GetEquity() + { + return mAccountInfo.Equity(); + } + + // + // Get the amount of reserved Margin ... + double GetMargin() + { + return mAccountInfo.Margin(); + } + + // + // Get the amount of free Margin ... + double GetFreeMargin() + { + return mAccountInfo.FreeMargin(); + } + + // + // Get the Level of Margin ... + double GetMarginLevel() + { + return mAccountInfo.MarginLevel(); + } + + // + // Get the Level Of Margin for a Deposit ... + double GetMarginCall() + { + return mAccountInfo.MarginCall(); + } + + // + // Get the Level of Margin for Stop out ... + double GetMarginStopOut() + { + return mAccountInfo.MarginStopOut(); + } + + // + // Get the Client Name ... + string GetName() + { + return mAccountInfo.Name(); + } + + // + // Get the Trade Server Name ... + string GetServerName() + { + return mAccountInfo.Server(); + } + + // + // Get deposit Currency Name ... + string GetCurrency() + { + return mAccountInfo.Currency(); + } + + // + // Get the Company Name that serves an Account ... + string GetCompany() + { + return mAccountInfo.Company(); + } + + // + // Calculate Profits for the current account based on passed parameters ... + double CalculateTradeProfit( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double volume, // volume + double entry, // open price + double exit // close price + ) + { + // + double result = mAccountInfo.OrderProfitCheck( + symbol, + type, + volume, + entry, + exit); + + // + return result; + } + + // + // Calculate amount of margin which required for trade operation ... + double CalculateMarging( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double volume, // volume + double entry // open price + ) + { + // + double result = mAccountInfo.MarginCheck( + symbol, + type, + volume, + entry); + + // + return result; + } + + // + // Calculate amount of free margin left after trade operation ... + double CalculateFreeMarging( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double volume, // volume + double entry // open price + ) + { + // + double result = mAccountInfo.FreeMarginCheck( + symbol, + type, + volume, + entry); + + // + return result; + } + + // + // Calculate the Maximum possible volume of trade operation ... + double CalculateMaxVolume( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double entry, // open price + double percent = 100 // percent of available margin + ) + { + // + double result = mAccountInfo.MaxLotCheck( + symbol, + type, + entry, + percent); + + // + return result; + } + + // + // Calculate Point Value for Given Symbol based on Account ... + double GetPointValue( + string symbol // trading symbol + ) + { + // + double result = 0; + + // + double tickSize = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE); + double tickValue = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_VALUE); + double point = SymbolInfoDouble(symbol, SYMBOL_POINT); + + // + double ticksPerPoint = tickSize / point; + + // + result = tickValue / ticksPerPoint; + + // + return result; + } + + // + // Calculate Risk Amount based on account Currency by Providing: + // Points and Volume ... + double CalculateRiskAmount( + string symbol, // trading symbol + double points, // amount of Risk Points + double volume // position Volume + ) + { + // + double result = 0; + + // + double pointValue = GetPointValue(symbol); + + // + result = pointValue * volume * points; + + // + return result; + } + + // + // Calculate Risk Points based on account Currency by Providing: + // Volume and Amount ... + double CalculateRiskPoints( + string symbol, // trading symbol + double volume, // position Volume + double amount // amount of Risk based on Account Currency + ) + { + // + double result = 0; + + // + double pointValue = GetPointValue(symbol); + + // + result = amount / (pointValue * volume); + + // + return result; + } + + // + // Calculate Volume based on account Currency by Providing: + // Amount and Risk Points ... + double CalculateVolume( + string symbol, // trading symbol + double amount, // amount of Risk based on Account Currency + double points // amount of Risk Points + ) + { + // + double result = 0; + + // + points = + points <= 0 + ? 10 + : points; + + // + double pointValue = GetPointValue(symbol); + + // + result = amount / (pointValue * points); + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Account Info ... + CAccountInfo mAccountInfo; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xea.class.ex5 b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xea.class.ex5 new file mode 100644 index 0000000..1a1d89f Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xea.class.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xea.class.mq5 b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xea.class.mq5 new file mode 100644 index 0000000..4344f30 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xea.class.mq5 @@ -0,0 +1,1573 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCBaseEA +// Description: provides all Base EA requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.alert.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xtrade.class.mq5" +#include "../Classes/x-saherelm.xaccount.class.mq5" +#include "../Classes/x-saherelm.xprovider.class.mq5" +#include "../Libraries/x-saherelm.seriallizer.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Handle base requirements ... +// for indicators ... +class XSCBaseEA +{ + // + // Public ... +public: + // + // Props ... + XSCTrade *mTrader; + XSCAccount *mAccount; + + // + bool isNewHour; + bool isNewDay; + bool isNewWeek; + bool isNewMonth; + bool isNewCandle; + + // + bool isInTestMode; + + // + bool mWaitsUntilNewCandle; + + // + // Constructor ... + void XSCBaseEA( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + ulong magic, // Magic Number + int slippage, // Slippgae + TOnStopLoss onStopLossTriggered = NULL, // On StopLoass Triggered Event Handler + TOnTakeProfit onTakeProfitTriggered = NULL, // On TakeProfit Triggered Event Handler + TOnDealsChanged onDealsChangedHandler = NULL, // On Deals Changed Event Handler + TOnOrdersChanged onOrdersChangedHandler = NULL, // On Orders Changed Event Handler + TOnPositionsChanged onPositionsChangedHandler = NULL, // On Positions Changed Event Handler + TOnTradeStateChanged onTradeStateChangedHandler = NULL // On Trade State Changed Event Handler + ) + { + // + mSymbol = symbol; + mPeriod = period; + + // + mMagic = magic; + mSlippage = slippage; + + // + mOnStopLossTriggered = onStopLossTriggered; + mOnTakeProfitTriggered = onTakeProfitTriggered; + mOnDealsChangedHandler = onDealsChangedHandler; + mOnOrdersChangedHandler = onOrdersChangedHandler; + mOnPositionsChangedHandler = onPositionsChangedHandler; + mOnTradeStateChangedHandler = onTradeStateChangedHandler; + + // + // Reset Timings ... + ResetTiming(); + + // + EnableLongs(true); + EnableShorts(true); + + // + MaxAllowedPositions(0); + MaxAllowedDrawDownFactor(0); + + // + InitRequirements(); + } + + // + // Deconstructor ... + void ~XSCBaseEA() + { + // + delete mTrader; + delete mAccount; + } + + // + // START Properties ... + // + + // + // Symbol ... + string GetSymbol() + { + return mSymbol; + } + + // + // Period ... + ENUM_TIMEFRAMES GetPeriod() + { + return mPeriod; + } + + // + // Tag ... + string GetTag() + { + return mTag; + } + + // + ulong GetMagic() + { + return mMagic; + } + + // + int GetSlippage() + { + return mSlippage; + } + + // + // Check Long Signalling State ... + bool EnableLongs() + { + return mEnableLongs; + } + + // + // Set Long Signalling State ... + void EnableLongs(bool enable) + { + // + if (enable == mEnableLongs) + { + return; + } + + // + mEnableLongs = enable; + } + + // + // Check Short Signalling State ... + bool EnableShorts() + { + return mEnableShorts; + } + + // + // Set Short Signalling State ... + void EnableShorts(bool enable) + { + // + if (enable == mEnableShorts) + { + return; + } + + // + mEnableShorts = enable; + } + + // + // Get Max Allowed Positions at Same Time ... + int MaxAllowedPositions() + { + return mMaxAllowedPositions; + } + + // + // Set Max Allowed Positions at Same Time ... + void MaxAllowedPositions(int value) + { + // + if (value < 0 || + value == mMaxAllowedPositions) + { + return; + } + + // + mMaxAllowedPositions = value; + } + + // + // Get Max Allowed DrawDown Factor ... + double MaxAllowedDrawDownFactor() + { + return mMaxAllowedDrawDownFactor; + } + + // + // Set Max Allowed Positions at Same Time ... + void MaxAllowedDrawDownFactor(double value) + { + // + if (value < 0 || + value == mMaxAllowedDrawDownFactor) + { + return; + } + + // + mMaxAllowedDrawDownFactor = value; + } + + // + // Check Acocunt Balance is Allow new Trades or not ... + bool CheckEquityForTrade() + { + // + bool result = false; + + // + if (mMaxAllowedDrawDownFactor <= 0) + { + // + result = true; + return result; + } + + // + double equity = mAccount.GetEquity(); + double balance = mAccount.GetBalance(); + + // + double selectedBalance = MathMax(equity, balance) - MathMin(equity, balance); + + // + double balanceForFactor = MathAbs(equity - balance); + if (balanceForFactor <= 0) + { + balanceForFactor = balance; + } + else + { + balanceForFactor = equity; + } + + // + double maxAllowedBalanceDrawDown = balanceForFactor * mMaxAllowedDrawDownFactor; + + // + result = equity > balance || + (equity <= balance && + selectedBalance <= maxAllowedBalanceDrawDown); + + // + return result; + } + + // + // Check Max Allowed Positions Policy for Trade ... + bool ChecPositionsForTrade() + { + // + bool result = false; + + // + if (mMaxAllowedPositions <= 0) + { + // + result = true; + return result; + } + + // + int positionsCount = mTrader.CountPositions(); + if (positionsCount <= 0) + { + // + result = true; + return result; + } + + // + result = positionsCount <= mMaxAllowedPositions; + + // + return result; + } + + // + // Check Account Policies ... + bool CheckAccountPolicies() + { + // + bool result = false; + + // + // Check Equity for Trade ... + result = CheckEquityForTrade(); + if (!result) + { + // + string message = "not enough Equity for Trade ..."; + + // + LogMessage(message); + + // // + // // Handle Force Close Positions on Max Drawdown ... + // HandleGuardForceCloseAction( + // NULL, // All Providers ... + // NULL, // All Symbols ... + // NULL, // All Type of Positions ... + // NULL // All Periods ... + // ); + + // + return result; + } + + // + // Check Max Allowed Position for Trade ... + result = ChecPositionsForTrade(); + if (!result) + { + // + string message = "max allowed Positions reached ..."; + + // + LogMessage(message); + + // // + // HandleGuardCloseInProfitAction( + // NULL, // All Providers ... + // NULL, // All Symbols ... + // NULL, // All Type of Positions ... + // NULL, // All Periods ... + // X_POSITION_SELECT_MAX // Select Max Position ... + // ); + + // // + // HandleGuardCloseInDrawdownAction( + // NULL, // All Providers ... + // NULL, // All Symbols ... + // NULL, // All Type of Positions ... + // NULL, // All Periods ... + // X_POSITION_SELECT_MAX // Select Max Position ... + // ); + + // + return result; + } + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XEA" + mSymbol + "," + ToString(mPeriod) + (string)mMagic; + } + + // + // Handle Chart Events ... + virtual void OnChartEvent( + const int id, // event ID + const long &lparam, // long type event parameter + const double &dparam, // double type event parameter + const string &sparam // string type event parameter + ) + { + } + + // + // Check any Registered Providers Signalling ... + virtual bool SignalCheck(XSignal &signals[]) + { + return false; + } + + // + // Check for any Custom Guard Actions Guard Actions ... + virtual bool CheckGuard(XGuard &guards[]) + { + return false; + } + + // + // NOTE: you have to call these Functions on Static Classes to Handle Works ... + + // + // Handle StopLoss Event ... + virtual void OnStopLossTriggered(const XDeal &deal) {} + + // + // Handle TakeProfit Event ... + virtual void OnTakeProfitTriggered(const XDeal &deal) {} + + // + // Handle Deals Changed Event ... + virtual void OnDealsChangedHandler(int count) {} + + // + // Handle Order Changed Event ... + virtual void OnOrdersChangedHandler(int count) {} + + // + // Handle Position Changed Event ... + virtual void OnPositionsChangedHandler(int count) {} + + // + // Handle Trade State Changed ... + virtual void OnTradeStateChangedHandler(const XOnTradeHandlerState &state) {} + + // + // Implemented Actions ... + + // + // OnTick Handler ... + void OnTick() + { + // + // Check Account Policies ... + bool isAccountPassed = CheckAccountPolicies(); + if (!isAccountPassed) + { + return; + } + + // + // First Check Guards .... + // Only when Open Positions Exists or Has Pending Order ... + XGuard guards[]; + bool hasGuard = CheckGuard(guards); + if (hasGuard) + { + DoGuards(guards); + } + + // + XSignal signals[]; + bool hasSignal = SignalCheck(signals); + if (hasSignal) + { + // + // Here we have to Check Signals and also it's State ... + XSignal enabledSignals[]; + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + // Filter Signals by their type and + // also Check EA Enable their type ... + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + bool isLong = IsLong(iSignal.type); + if ((isLong && mEnableLongs) || + (!isLong && mEnableShorts)) + { + // + PrepareSignal(iSignal); + + // + Add( + iSignal, + enabledSignals); + } + } + + // + int enabledSignalsCount = ArraySize(enabledSignals); + if (enabledSignalsCount <= 0) + { + return; + } + + // + // Check Trade Policies ... + + // + // Check Equity for Trade ... + bool canDoTrade = CheckEquityForTrade(); + if (!canDoTrade) + { + // + string message = "not enough Equity for Trade ..."; + + // + LogMessage(message); + return; + } + + // + // Check Max Allowed Position for Trade ... + canDoTrade = ChecPositionsForTrade(); + if (!canDoTrade) + { + // + string message = "max allowed Positions reached ..."; + + // + LogMessage(message); + + // + // Check How to Act with Signals if Max In Drawdown Reached ... + // TODO: Here we Have to Define Max In Draw Down Position type ... + return; + } + + // + mTrader.ExecuteSignals(enabledSignals); + } + } + + // + // Handle On Trade ... + void OnTrade() + { + // + XOnTradeHandlerState state = mTrader.HandleOnTrade(); + + // + if ( + !state.hasNewDeal && + !state.hasNewOrder && + !state.hasNewPosition && + !state.hasNewHistoryOrder) + { + return; + } + + // + // STATE ... + + // + // Notfy Trade State Changed Event ... + OnTradeStateChangedHandler(state); + + // + // DEALS ... + if (state.hasNewDeal) + { + // + // Notfy Deals Changed Event ... + OnDealsChangedHandler(state.newDeals); + + // + // Retrieve Last Deal ... + XDeal deals[]; + mTrader.GetDeals(deals); + int dealsCount = ArraySize(deals); + if (dealsCount > 0) + { + // + XDeal lastDeal = deals[0]; + + // + if (lastDeal.reason == DEAL_REASON_TP) + { + OnTakeProfitTriggered(lastDeal); + } + else if (lastDeal.reason == DEAL_REASON_SL) + { + OnStopLossTriggered(lastDeal); + } + } + } + + // + // ORDERS ... + if (state.hasNewOrder || state.hasNewHistoryOrder) + { + // + // Notfy Orders Changed Event ... + OnOrdersChangedHandler(state.newOrders + state.newHistoryOrders); + } + + // + // POSITIONS ... + if (state.hasNewPosition) + { + // + // Notfy Positions Changed Event ... + OnPositionsChangedHandler(state.newPositions); + } + } + + // + // Retrieve Dept Of Market ... + void OnBookEvent(const string &symbol) + { + // + // TODO: Implement this ... + } + + // + // TOOLS ... + + // + // Prepare a Signal and Do Calculations ... + void PrepareSignal( + XSignal &signal // a Signal for Preparation ... + ) + { + // + // Calculate Volume ... + if (signal.useRiskAmountAsVolume && signal.riskAmount > 0) + { + signal.volume = signal.riskAmount; + } + else if ( + signal.sl > 0 && + signal.tp > 0 && + signal.volume == 0 && + signal.riskAmount > 0 && + !signal.useSupportAndResistance) + { + // + // Calculate Risk Point ... + double riskPoint = MathAbs(signal.entry - signal.sl); + riskPoint = PriceToPoint( + signal.symbol, + riskPoint); + + // + double volume = mAccount.CalculateVolume( + signal.symbol, + signal.riskAmount, + riskPoint); + + // + signal.volume = volume; + } + else if (signal.useSupportAndResistance) + { + // + // Calculate Everything using Supports and Resistances ... + // TODO: Implement Later ... + } + + // + if (signal.ignoreTP) + { + signal.tp = 0; + } + + // + if (signal.ignoreSL) + { + signal.sl = 0; + } + + // + // Normalize Signal ... + NormalizeSignal(signal); + } + + // + // Get All Open Trades ... + void GetPositions( + XPosition &result[], // Hold Result ... + string symbol = NULL, // Trading Symbol ... + ENUM_POSITION_TYPE type = NULL, // Trading Type ... + ENUM_TIMEFRAMES period = NULL, // Trading Period ... + string provider = NULL // Signal Provider ... + ) + { + // + Clean(result); + + // + bool hasSymbol = !(symbol == NULL || StringLen(symbol) == 0); + bool hasProvider = !(provider == NULL || StringLen(provider) == 0); + + // + int positionsCount = mTrader.CountPositions(); + if (positionsCount <= 0) + { + return; + } + + // + XPosition positions[]; + mTrader.GetPositions( + positions, + symbol, + period); + positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return; + } + + // + if (!hasProvider && type == NULL) + { + // + Copy( + positions, + result); + + // + return; + } + + // + if (type == NULL) + { + // + ArrayResize( + result, + ArraySize(positions)); + + // + for (int i = 0; i < positionsCount; i++) + { + // + Add( + positions[i], + result); + } + + // + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + string iProvider = ExtractProvider(iPosition.comment); + if (hasProvider && iProvider != provider) + { + continue; + } + + // + if (type == NULL || iPosition.type == type) + { + // + Add( + iPosition, + result); + } + } + } + + // + // Get All In Profit Trades ... + void GetInProfitPositions( + XPosition &result[], // Hold Result ... + string symbol = NULL, // Trading Symbol ... + ENUM_POSITION_TYPE type = NULL, // Trading Type ... + ENUM_TIMEFRAMES period = NULL, // Trading Period ... + string provider = NULL, // Signal Provider ... + ENUM_X_POSITION_SELECT_METHODS method = NULL // Select Method ... + ) + { + // + Clean(result); + + // + if (method == NULL) + { + method = X_POSITION_SELECT_ALL; + } + + // + // Prevent Going Forwars Since selection type is NONE ... + if (method == X_POSITION_SELECT_NONE) + { + return; + } + + // + bool isMinSelectable = method == X_POSITION_SELECT_MIN; + bool isMaxSelectable = method == X_POSITION_SELECT_MAX; + + // + XPosition positions[]; + GetPositions( + positions, + symbol, + type, + period, + provider); + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return; + } + + // + // Define Temp Position for Selecting Max Position ... + XPosition maxPos; + maxPos.profit = INVALID_HANDLE; + + // + // Define Temp Position for Selecting Min Position ... + XPosition minPos; + minPos.profit = INVALID_HANDLE; + + // + // Loop through available Positions for Selecting Positions ... + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + // Check Profit State ... + if (iPosition.profit <= 0) + { + continue; + } + + // + // Check Selection State ... + if (isMinSelectable) + { + // + if (minPos.profit == INVALID_HANDLE || + minPos.profit > iPosition.profit) + { + minPos = iPosition; + } + + // + continue; + } + else if (isMaxSelectable) + { + // + if (maxPos.profit == INVALID_HANDLE || + maxPos.profit < iPosition.profit) + { + maxPos = iPosition; + } + + // + continue; + } + else + { + // + Add( + iPosition, + result); + } + } + + // + // Add Selected Position if Provided to Results ... + if (isMinSelectable) + { + // + Add( + minPos, + result); + } + else if (isMaxSelectable) + { + // + Add( + maxPos, + result); + } + } + + // + // Get All In Drawdown Trades ... + void GetInDrawdownPositions( + XPosition &result[], // Hold Result ... + string symbol = NULL, // Trading Symbol ... + ENUM_POSITION_TYPE type = NULL, // Trading Type ... + ENUM_TIMEFRAMES period = NULL, // Trading Period ... + string provider = NULL, // Signal Provider ... + ENUM_X_POSITION_SELECT_METHODS method = NULL // Select Method ... + ) + { + // + Clean(result); + + // + if (method == NULL) + { + method = X_POSITION_SELECT_ALL; + } + + // + // Prevent Going Forwars Since selection type is NONE ... + if (method == X_POSITION_SELECT_NONE) + { + return; + } + + // + bool isMinSelectable = method == X_POSITION_SELECT_MIN; + bool isMaxSelectable = method == X_POSITION_SELECT_MAX; + + // + XPosition positions[]; + GetPositions( + positions, + symbol, + type, + period, + provider); + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return; + } + + // + // Define Temp Position for Selecting Max Position ... + XPosition maxPos; + maxPos.profit = INVALID_HANDLE; + + // + // Define Temp Position for Selecting Min Position ... + XPosition minPos; + minPos.profit = INVALID_HANDLE; + + // + // Loop through available Positions for Selecting Positions ... + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + // Check Profit State ... + if (iPosition.profit >= 0) + { + continue; + } + + // + // Check Selection State ... + if (isMinSelectable) + { + // + if (minPos.profit == INVALID_HANDLE || + minPos.profit < iPosition.profit) + { + minPos = iPosition; + } + + // + continue; + } + else if (isMaxSelectable) + { + // + if (maxPos.profit == INVALID_HANDLE || + maxPos.profit > iPosition.profit) + { + maxPos = iPosition; + } + + // + continue; + } + else + { + // + Add( + iPosition, + result); + } + } + + // + // Add Selected Position if Provided to Results ... + if (isMinSelectable) + { + // + Add( + minPos, + result); + } + else if (isMaxSelectable) + { + // + Add( + maxPos, + result); + } + } + + // + // Retrieve Orders ... + void GetOrders( + XOrder &result[], // Hold Result ... + string symbol = NULL, // Trading Symbol ... + ENUM_ORDER_TYPE type = NULL, // Trading Type ... + ENUM_ORDER_STATE state = NULL, // Trading State ... + ENUM_TIMEFRAMES period = NULL, // Trading Period ... + string provider = NULL // Signal Provider ... + ) + { + // + Clean(result); + + // + XOrder orders[]; + mTrader.GetOrders( + orders, + symbol, + period, + state); + int ordersCount = ArraySize(orders); + if (ordersCount <= 0) + { + return; + } + + // + if (type == NULL && + (provider == NULL || + StringLen(provider) == 0)) + { + // + Copy( + orders, + result); + + // + return; + } + + // + for (int i = 0; i < ordersCount; i++) + { + // + XOrder iOrder = orders[i]; + + // + if (type != NULL && iOrder.type != type) + { + continue; + } + + // + if (provider != NULL && + StringLen(provider) > 0) + { + // + // Generate Order Provider ... + string iProvider = ExtractProvider(iOrder.comment); + if (iProvider != provider) + { + continue; + } + } + + // + Add( + iOrder, + result); + } + } + + // + // GUARD Handlers ... + + // + // Parse Recievd Guards and Do them ... + void DoGuards(XGuard &guards[]) + { + int guardsCount = ArraySize(guards); + if (guardsCount <= 0) + { + return; + } + + // + for (int i = 0; i < guardsCount; i++) + { + // + XGuard iGuard = guards[i]; + + // + switch (iGuard.action) + { + // + // Hedge In Profit Specified Positions ... + case X_GUARD_ACTION_HEDGE: + HandleGuardHedgeAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period); + break; + + // + // Trail Stop Loss in Specified Positions ... + case X_GUARD_ACTION_TRAIL_STOP: + HandleGuardTrailingStopAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period, + iGuard.dblPayLoad); + break; + + // + // Force Close Specified Positions ... + case X_GUARD_ACTION_FORCE_CLOSE: + HandleGuardForceCloseAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period); + break; + + // + // Generate and Place Support Signals ... + case X_GUARD_ACTION_ADD_SUPPORT_SIGNAL: + HandleGuardAddSupportPositionAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period); + break; + + // + // Delete All Placed Pending Orders ... + case X_GUARD_ACTION_CANCEL_PENDING_ORDERS: + HandleGuardCancelPendingOrdersAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period); + break; + } + } + } + + // + // Close All Specified Provider's Positions in Profit Summary ... + void HandleGuardHedgeAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period, // Specified Time Frame + double minProfitForHedging = 1 // Specified Profit for Hedge + ) + { + // + } + + // + // Close Max In Profit Trade Guard Action ... + void HandleGuardCloseInProfitAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period, // Specified Time Frame + ENUM_X_POSITION_SELECT_METHODS method = NULL // Select Method + ) + { + // + XPosition positions[]; + GetInProfitPositions( + positions, + symbol, + type, + period, + provider, + method); + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return; + } + + // + string comment = "Close InProfit ..."; + mTrader.ClosePositions( + positions, + comment); + + // + string message = "Guard Close (" + ToString(positionsCount) + ") Postion(s) In Profit ..."; + LogMessage(message); + } + + // + // Close Max In Drawdown Trade Guard Action ... + void HandleGuardCloseInDrawdownAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period, // Specified Time Frame + ENUM_X_POSITION_SELECT_METHODS method = NULL // Select Method + ) + { + // + XPosition positions[]; + GetInDrawdownPositions( + positions, + symbol, + type, + period, + provider, + method); + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return; + } + + // + string comment = "Close InDrawdown ..."; + mTrader.ClosePositions( + positions, + comment); + + // + string message = "Guard Close (" + ToString(positionsCount) + ") Position(s) In Drawdown ..."; + LogMessage(message); + } + + // + // Force Close Specified Set Of Position ... + void HandleGuardForceCloseAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period, // Specified Time Frame + ulong ticket = 0 // Specific Ticket + ) + { + // + string comment = ""; + + // + // Close All Positions ... + if (ticket == 0) + { + // + XPosition positions[]; + GetPositions( + positions, + symbol, + type, + period, + provider); + if (ArraySize(positions) <= 0) + { + return; + } + + // + comment = provider + " Force Close Guard ..."; + + // + mTrader.ClosePositions( + positions, + comment); + } + // + // Close Specific Position ... + else + { + // + XPosition position; + bool hasPosition = mTrader.GetPosition( + position, + ticket); + + // + if (hasPosition) + { + // + comment = provider + "(" + ToString(ticket) + ")" + " Force Close Guard ..."; + + // + mTrader.Close( + ticket, + comment); + } + } + + // + if (StringLen(comment) > 0) + { + LogMessage(comment); + } + } + + // + // Trailing Specified Set Of Positions Stop Losses ... + void HandleGuardTrailingStopAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period, // Specified Time Frame + double sl // Desired SL Value ... + ) + { + // + if (sl <= 0) + { + return; + } + + // + NormalizePrice( + sl, + symbol); + + // + XPosition positions[]; + GetPositions( + positions, + symbol, + type, + period, + provider); + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return; + } + + // + int modified = 0; + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + string comment = PrepareSLTrailComment(iPosition.comment); + + // + bool isModified = mTrader.Modify( + iPosition.ticket, + sl, + iPosition.tp, + comment); + if (isModified) + { + modified++; + } + } + + // + if (modified > 0) + { + // + string msg = "(" + ToString(modified) + ") Position's Stop Trailed Successfully ..."; + + // + LogMessage(msg); + } + } + + // + // Add Support Signal for Specified Positions ... + void HandleGuardAddSupportPositionAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period // Specified Time Frame + ) + { + // + // TODO: Implement this ... + } + + // + // Cancel all Placed Orders ... + void HandleGuardCancelPendingOrdersAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period // Specified Time Frame + ) + { + // + // TODO: Implement this ... + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + string GetTagPrefix() + { + // + string result = "(" + mSymbol + ")(" + ToString(mPeriod) + ")"; + + // + return result; + } + + // + // Symbol ... + string mSymbol; + + // + // Period ... + ENUM_TIMEFRAMES mPeriod; + + // + // ExpertAdviser MAgic Number ... + ulong mMagic; + + // + // Slipppage ... + int mSlippage; + + // + // Tag Identifier ... + string mTag; + + // + bool mEnableLongs; + bool mEnableShorts; + + // + int mMaxAllowedPositions; + double mMaxAllowedDrawDownFactor; + + // + // Private ... +private: + // + // Define Requirements ... + + // + // XSCTrade Event Handlers ... + TOnStopLoss mOnStopLossTriggered; + TOnTakeProfit mOnTakeProfitTriggered; + TOnDealsChanged mOnDealsChangedHandler; + TOnOrdersChanged mOnOrdersChangedHandler; + TOnPositionsChanged mOnPositionsChangedHandler; + TOnTradeStateChanged mOnTradeStateChangedHandler; + + // + // Initi Requirements ... + void InitRequirements() + { + // + // Account Manager ... + mAccount = new XSCAccount(); + + // + // Trader ... + mTrader = new XSCTrade( + mSlippage, + mMagic); + + // + // Attach Event Handlers ... + + // + if (mOnStopLossTriggered != NULL) + { + mTrader.AddOnStopLossEventHandler(mOnStopLossTriggered); + } + + // + if (mOnTakeProfitTriggered != NULL) + { + mTrader.AddOnTakeProfitEventHandler(mOnTakeProfitTriggered); + } + + // + if (mOnDealsChangedHandler != NULL) + { + mTrader.AddOnDealsChangedEventHandler(mOnDealsChangedHandler); + } + + // + if (mOnOrdersChangedHandler != NULL) + { + mTrader.AddOnOrdersChangedEventHandler(mOnOrdersChangedHandler); + } + + // + if (mOnPositionsChangedHandler != NULL) + { + mTrader.AddOnPositionsChangedEventHandler(mOnPositionsChangedHandler); + } + + // + if (mOnTradeStateChangedHandler != NULL) + { + mTrader.AddOnTradeStateChangedEventHandler(mOnTradeStateChangedHandler); + } + } +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xhelper.class.ex5 b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xhelper.class.ex5 new file mode 100644 index 0000000..c24b0d7 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xhelper.class.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xhelper.class.mq5 b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xhelper.class.mq5 new file mode 100644 index 0000000..d9cea8b --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xhelper.class.mq5 @@ -0,0 +1,209 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCBaseHelper +// Description: provides all Base Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Handle base requirements ... +// for indicators ... +class XSCBaseHelper +{ + // + // Public ... +public: + // + // Constructor ... + void XSCBaseHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) + { + // + mSymbol = symbol; + mPeriod = period; + + // + LoopBack(52); + } + + // + // Deconstructor ... + void ~XSCBaseHelper() + { + IndicatorRelease(mHandler); + } + + // + // START Properties ... + // + + // + // Loopback Bars ... + void LoopBack(int value) + { + mLoopbackBars = value; + } + + int Loopback() + { + return mLoopbackBars; + } + + // + // Symbol ... + string GetSymbol() + { + return mSymbol; + } + + // + // Period ... + ENUM_TIMEFRAMES GetPeriod() + { + return mPeriod; + } + + // + // Tag ... + string GetTag() + { + return mTag; + } + + // + // Retrieve Bars ... + int GetBars() + { + // + int result = + Bars( + mSymbol, + mPeriod); + + // + return result; + } + + // + int GetCalculatedBars() + { + return BarsCalculated(mHandler); + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() {} + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ); + + // + // Retrieve MAx Required Length for Calculations ... + virtual int GetMaxLength(); + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + string GetTagPrefix() + { + // + string result = "(" + mSymbol + ")(" + ToString(mPeriod) + ")"; + + // + return result; + } + + // + // Symbol ... + string mSymbol; + + // + // Period ... + ENUM_TIMEFRAMES mPeriod; + + // + // Indicator Handler ... + int mHandler; + + // + // Number Of Items Read Per Tick ... + int mLoopbackBars; + + // + // Tag Identifier ... + string mTag; + + // + // Private ... +private: + // +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xnotifier.class.ex5 b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xnotifier.class.ex5 new file mode 100644 index 0000000..6dbc041 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xnotifier.class.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xprovider.class.ex5 b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xprovider.class.ex5 new file mode 100644 index 0000000..d9f0543 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xprovider.class.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xprovider.class.mq5 b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xprovider.class.mq5 new file mode 100644 index 0000000..e60bb27 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xprovider.class.mq5 @@ -0,0 +1,304 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCEABaseProvider +// Description: provides base requirements for +// Specific Sgnal Provider ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.draw.lib.mq5" +#include "../Libraries/x-saherelm.models.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Definitions ... +// + +// +// Notified a Signal was Appears ... +typedef void (*OnSignal)( + XSignal &signal); + +// +// Notified a Guard Appears ... +typedef void (*OnGuard)(XGuard &guard); + +// +// END Definitions ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Base Class for All of our EA's ... +class XSCEABaseProvider +{ + // + // Public ... +public: + // + // Constructor ... + void XSCEABaseProvider() + { + mSymbol = _Symbol; + mPeriod = _Period; + } + void XSCEABaseProvider( + string symbol, + ENUM_TIMEFRAMES period) + { + // + mSymbol = symbol; + mPeriod = period; + + // + mTag = mSymbol + "," + ToString(mPeriod); + + // + mIsInTestMode = IsRunningOnTestMode(); + } + + // + // Deconstructor ... + void ~XSCEABaseProvider() + { + } + + // + bool CanIgnoreTick() { + // + mIsNewCandle = IsNewCandle( + mSymbol, + mPeriod); + bool result = mIsInTestMode + ? !mIsNewCandle + : !mIsNewCandle && mWaitUntilNewCandle; + + // + return result; + } + + // + // Prepare State ... + void OnTick() + { + // + mIsNewCandle = IsNewCandle( + mSymbol, + mPeriod); + mCanIgnoreTick = mIsInTestMode + ? !mIsNewCandle + : !mIsNewCandle && mWaitUntilNewCandle; + + // + ProcessBuffers(); + + // + if (mCanIgnoreTick) + { + return; + } + + // + mWaitUntilNewCandle = false; + + // + ProcessTick(); + } + + // + virtual void PrepareTag(); + + // + // Initialize Indicators and Requirements ... + virtual bool Init(); + + // + virtual int GetMaxLength(); + + // + virtual int GetCalculatedBars(); + + // + // Handle Update Buffers ... + virtual void ProcessBuffers() + { + return; + } + + // + // Handle On Tick Event ... + virtual void ProcessTick() + { + return; + } + + // + // Check for Guards ... + virtual bool GuardCheck(XGuard &guards[]); + + // + // Add Specific On Signal Event Handler ... + int AddOnSignalEventHandler(OnSignal handler) + { + // + ArrayResize( + mSignalEventHandlers, + ArraySize(mSignalEventHandlers) + 1); + + // + int result = ArraySize(mSignalEventHandlers) - 1; + mSignalEventHandlers[result] = handler; + + // + return result; + } + + // + // Remove All On Signal Event Handler ... + void ReoveOnSignalEventHandlers() + { + // + ArrayFree(mSignalEventHandlers); + } + + // + // Notify a Signal Found on all Event Listeners ... + void NotifyOnSignalEvent(XSignal &info) + { + // + int listenerCount = ArraySize(mSignalEventHandlers); + if (listenerCount <= 0) + { + return; + } + + // + // Loop Through Listeners ... + for (int i = 0; i < listenerCount; i++) + { + // + OnSignal listener = mSignalEventHandlers[i]; + + // + listener(info); + } + } + + // + // Protected ... +protected: + // + string mSymbol; + + // + ENUM_TIMEFRAMES mPeriod; + + // + string mTag; + + // + bool mIsNewCandle; + bool mIsInTestMode; + bool mCanIgnoreTick; + bool mWaitUntilNewCandle; + + // + // Private ... +private: + // + // Signal Event Handlers ... + OnSignal mSignalEventHandlers[]; +}; + +// +// START Definitions ... +// + +// +// Model Signal Providers Definitions ... +struct XBaseSignalProvider +{ + // + // Provider use Which Symbol ... + string symbol; + + // + // Provider use Which Time Frame ... + ENUM_TIMEFRAMES period; + + // + // Risk Amount Per Trades Related to Time Frames ... + // Percent of Available Balance ... + double riskAmount; + + // + // Desired Magic Number ... + ulong magicNumber; +}; + +// +struct XLastSignal +{ + datetime at; + string provider; +}; + +// +// END Definitions ... +// + +// +// START Usefull Functions ... +// + +// +// Add Specific Provider to List ... +void Add( + XBaseSignalProvider &item, // item want to add + XBaseSignalProvider &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xtrade.class.ex5 b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xtrade.class.ex5 new file mode 100644 index 0000000..8b4746e Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xtrade.class.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xtrade.class.mq5 b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xtrade.class.mq5 new file mode 100644 index 0000000..0b25f8d --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Classes/x-saherelm.xtrade.class.mq5 @@ -0,0 +1,4193 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCTrade +// Description: provides all Trade requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// Model an Open Position ... +struct XPosition +{ + // + // Magic Number ... + ulong magic; + + // + // Ticket ID ... + ulong ticket; + + // + // Tradinng Symbol ... + string symbol; + + // + // Trading Period ... + ENUM_TIMEFRAMES period; + + // + // Position Type ... + ENUM_POSITION_TYPE type; + + // + // Take Profit ... + double tp; + + // + // Stop Loss ... + double sl; + + // + // Position Current Profit ... + double profit; + + // + // Position Open Price ... + double entry; + + // + // Current Symbol Price ... + double price; + + // + // Position Swap ... + double swap; + + // + // Position Commission ... + double commission; + + // + // Volume ... + double volume; + + // + // Position Open Time ... + datetime openAt; + + // + // Position Comment ... + string comment; +}; + +// +// Model an Order ... +struct XOrder +{ + // + // Time of order placement ... + datetime setupAt; + + // + // Time of order expiration ... + datetime expiredAt; + + // + // Time of order execution or cancellation ... + datetime executedAt; + + // + // Order type ... + ENUM_ORDER_TYPE type; + + // + // Order state ... + ENUM_ORDER_STATE state; + + // + // Type of execution by remainder ... + ENUM_ORDER_TYPE_FILLING filling; + + // + // Order lifetime ... + ENUM_ORDER_TYPE_TIME lifetime; + + // + // Order ticket ... + ulong ticket; + + // + // Magic Number ... + long magic; + + // + // Position id, that is placed on order, + // when it is executed. Each executed order invokes a + // deal, that opens new or changes existing + // position. Id of that position is placed on + // executed order in this moment. + long pocitionID; + + // + // Initial volume on order placement ... + double initialVolume; + + // + // Unfilled volume ... + double currentVolume; + + // + // Price, specified in the order ... + double openPrice; + + // + // Current price by order symbol ... + double currentPrice; + + // + // Price of placing Limit order when StopLimit order is triggered ... + double stopLimitPrice; + + // + // Take Profit level ... + double tp; + + // + // Stop Loss level ... + double sl; + + // + // Trading Symbol ... + string smybol; + + // + // Order Comment ... + string comment; + + // + ENUM_TIMEFRAMES period; +}; + +// +// Model a Deal ... +struct XDeal +{ + // + // the ID of the Expert Advisor, that executed the deal ... + ulong magic; + + // + // the ID of position, in which the deal was involved ... + ulong positionId; + + // + // Ticket ... + ulong ticket; + + // + // the name of the deal symbol ... + string symbol; + + // + // order by which the deal is executed ... + ulong order; + + // + // the time of deal execution ... + datetime time; + + // + // Deal price ... + double price; + + // + // the financial result of the deal (in deposit currency) ... + double profit; + + // + // the amount of swap when position is closed ... + double swap; + + // + // the amount of commission of the deal ... + double commission; + + // + // the volume of deal ... + double volume; + + // + // the deal comment ... + string comment; + + // + // the deal type ... + // ------------------------------------------------------------------ + // DEAL_TYPE_BUY => Buy ... + // DEAL_TYPE_SELL => Sell ... + // DEAL_TYPE_BUY_CANCELED => Canceled buy deal ... + // There can be a situation when a previously executed buy deal is canceled. In this case, + // the type of the previously executed deal (DEAL_TYPE_BUY) is changed to DEAL_TYPE_BUY_CANCELED, + // and its profit/loss is zeroized. Previously obtained profit/loss is charged/withdrawn using a separated balance operation ... + // + // DEAL_TYPE_SELL_CANCELED => Canceled sell deal ... + // There can be a situation when a previously executed sell deal is canceled. In this case, + // the type of the previously executed deal (DEAL_TYPE_SELL) is changed to DEAL_TYPE_SELL_CANCELED, + // and its profit/loss is zeroized. Previously obtained profit/loss is charged/withdrawn using a separated balance operation + // + // DEAL_TYPE_BALANCE => Balance ... + // DEAL_TYPE_CREDIT => Credit ... + // DEAL_TYPE_CHARGE => Additional charge ... + // DEAL_TYPE_CORRECTION => Correction ... + // DEAL_TAX => Tax charges ... + // DEAL_TYPE_BONUS => Bonus ... + // DEAL_TYPE_INTEREST => Interest rate ... + // DEAL_DIVIDEND => Dividend operations... + // DEAL_DIVIDEND_FRANKED => Franked (non-taxable) dividend operations ... + // DEAL_TYPE_COMMISSION => Additional commission ... + // DEAL_TYPE_COMMISSION_DAILY => Daily commission ... + // DEAL_TYPE_COMMISSION_MONTHLY => Monthly commission ... + // DEAL_TYPE_COMMISSION_AGENT_DAILY => Daily agent commission ... + // DEAL_TYPE_COMMISSION_AGENT_MONTHLY => Monthly agent commission + ENUM_DEAL_TYPE type; + + // + // the deal direction ... + // ---------------------------------- + // DEAL_ENTRY_IN => Entry in ... + // DEAL_ENTRY_OUT => Entry out ... + // DEAL_ENTRY_INOUT => Reverse ... + // DEAL_ENTRY_OUT_BY => Close a position by an opposite one ... + ENUM_DEAL_ENTRY entry; + + // + // deal reson ... + // --------------------- + // DEAL_REASON_SL => The deal was executed as a result of Stop Loss activation ... + // DEAL_REASON_TP => The deal was executed as a result of Take Profit activation ... + // DEAL_REASON_SO => The deal was executed as a result of the Stop Out event ... + // DEAL_REASON_WEB => The deal was executed as a result of activation of an order placed from the web platform ... + // DEAL_REASON_SPLIT => The deal was executed after the split (price reduction) of an instrument, which had an open position during split announcement ... + // DEAL_REASON_CLIENT => The deal was executed as a result of activation of an order placed from a desktop terminal ... + // DEAL_REASON_MOBILE => The deal was executed as a result of activation of an order placed from a mobile application ... + // DEAL_REASON_EXPERT => The deal was executed as a result of activation of an order placed from an MQL5 program, i.e. an Expert Advisor or a script ... + // DEAL_REASON_VMARGIN => The deal was executed after charging the variation margin ... + // DEAL_REASON_ROLLOVER => The deal was executed due to a rollover ... + ENUM_DEAL_REASON reason; +}; + +// +// Model a Position with all of it's Supports ... +struct XPositionPack +{ + // + ulong ticket; + + // + XPosition position; + + // + int supportOrdersCount; + int supportPositionsCount; + + // + XOrder supportOrders[]; + XPosition supportPositions[]; +}; + +// +// Model OnTrade Event Handler Result on XCTrade Class ... +struct XOnTradeHandlerState +{ + // + bool hasNewDeal; + int newDeals; + + // + bool hasNewOrder; + int newOrders; + + // + bool hasNewPosition; + int newPositions; + + // + bool hasNewHistoryOrder; + int newHistoryOrders; +}; + +// +typedef void (*TOnDealsChanged)(int count); + +// +typedef void (*TOnOrdersChanged)(int count); + +// +typedef void (*TOnPositionsChanged)(int count); + +// +typedef void (*TOnStopLoss)(const XDeal &deal); +typedef void (*TOnTakeProfit)(const XDeal &deal); + +// +typedef void (*TOnTradeStateChanged)(const XOnTradeHandlerState &state); + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Libraries/x-saherelm.seriallizer.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// XCTrade Base Class ... +class XSCTradeBase : public CTrade +{ +public: + // + // Modify Specific Position, by Specific Comment ... + bool PositionModify( + const string symbol, // Symbol + const double sl, // Stop Loss + const double tp, // Take Profit + const string comment = "" // Comment For Modify + ) + { + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // check position existence + if (!SelectPosition(symbol)) + { + return (false); + } + + // + // clean + ClearStructures(); + + // + // setting request + m_request.action = TRADE_ACTION_SLTP; + m_request.symbol = symbol; + m_request.magic = m_magic; + m_request.sl = sl; + m_request.tp = tp; + m_request.position = PositionGetInteger(POSITION_TICKET); + + // + // Specified Comment ... + if (StringLen(comment) > 0) + { + m_request.comment = comment; + } + + // + // action and return the result + return (OrderSend(m_request, m_result)); + } + bool PositionModify( + const ulong ticket, // Position Ticket + const double sl, // Stop Loss + const double tp, // Take Profit + const string comment = "" // Comment For Modify + ) + { + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // check position existence + if (!PositionSelectByTicket(ticket)) + { + return (false); + } + + // + // clean + ClearStructures(); + + // + // setting request + m_request.action = TRADE_ACTION_SLTP; + m_request.position = ticket; + m_request.symbol = PositionGetString(POSITION_SYMBOL); + m_request.magic = m_magic; + m_request.sl = sl; + m_request.tp = tp; + + // + // Specified Comment ... + if (StringLen(comment) > 0) + { + m_request.comment = comment; + } + + // + // action and return the result + return (OrderSend(m_request, m_result)); + } + + // + // Close Specific Position, by Specific Comment ... + bool PositionClose( + const string symbol, // Symbol + const ulong deviation, // Deviation + const string comment = "" // Comment For Close + ) + { + // + bool partial_close = false; + int retry_count = 10; + uint retcode = TRADE_RETCODE_REJECT; + + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // clean + ClearStructures(); + + // + // check filling + if (!FillingCheck(symbol)) + { + return (false); + } + + // + do + { + // + // check + if (SelectPosition(symbol)) + { + // + if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) + { + // + // prepare request for close BUY position + m_request.type = ORDER_TYPE_SELL; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); + } + else + { + // + // prepare request for close SELL position + m_request.type = ORDER_TYPE_BUY; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); + } + } + else + { + // + // position not found + m_result.retcode = retcode; + return (false); + } + + // + // setting request + m_request.action = TRADE_ACTION_DEAL; + m_request.symbol = symbol; + m_request.volume = PositionGetDouble(POSITION_VOLUME); + m_request.magic = m_magic; + m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; + m_request.position = PositionGetInteger(POSITION_TICKET); + + // + // Specify Comment ... + m_request.comment = comment; + + // + // check volume + double max_volume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX); + if (m_request.volume > max_volume) + { + // + m_request.volume = max_volume; + partial_close = true; + } + else + { + partial_close = false; + } + + // + // hedging? just send order + if (IsHedging()) + { + return (OrderSend(m_request, m_result)); + } + + // + // order send + if (!OrderSend(m_request, m_result)) + { + // + if (--retry_count != 0) + { + continue; + } + + // + if (retcode == TRADE_RETCODE_DONE_PARTIAL) + { + m_result.retcode = retcode; + } + + // + return (false); + } + + // + //--- WARNING. If position volume exceeds the maximum volume allowed for deal, + //--- and when the asynchronous trade mode is on, for safety reasons, position is closed not completely, + //--- but partially. It is decreased by the maximum volume allowed for deal. + if (m_async_mode) + { + break; + } + + // + retcode = TRADE_RETCODE_DONE_PARTIAL; + if (partial_close) + { + Sleep(1000); + } + } while (partial_close); + + // + // succeed + return (true); + } + bool PositionClose( + const ulong ticket, // Position Ticket + const ulong deviation, // Deviation + const string comment = "" // Comment For Close + ) + { + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // check position existence + if (!PositionSelectByTicket(ticket)) + { + return (false); + } + + // + string symbol = PositionGetString(POSITION_SYMBOL); + + // + // clean + ClearStructures(); + + // + // check filling + if (!FillingCheck(symbol)) + { + return (false); + } + + // + // check + if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) + { + // + // prepare request for close BUY position + m_request.type = ORDER_TYPE_SELL; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); + } + else + { + // + // prepare request for close SELL position + m_request.type = ORDER_TYPE_BUY; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); + } + + // + // setting request + m_request.action = TRADE_ACTION_DEAL; + m_request.position = ticket; + m_request.symbol = symbol; + m_request.volume = PositionGetDouble(POSITION_VOLUME); + m_request.magic = m_magic; + m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; + + // + // Specify Comment ... + m_request.comment = comment; + + // + // close position + return (OrderSend(m_request, m_result)); + } + + // + // Partial Close Specific Position, by Specific Comment ... + bool PositionClosePartial( + const string symbol, // Symbol + const double volume, // Partial Closing Volume + const ulong deviation, // Deviation + const string comment = "" // Comment For Close + ) + { + // + uint retcode = TRADE_RETCODE_REJECT; + + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // for hedging mode only + if (!IsHedging()) + { + return (false); + } + + // + // clean + ClearStructures(); + + // + // check filling + if (!FillingCheck(symbol)) + { + return (false); + } + + // + // check + if (SelectPosition(symbol)) + { + // + if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) + { + // + // prepare request for close BUY position + m_request.type = ORDER_TYPE_SELL; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); + } + else + { + // + // prepare request for close SELL position + m_request.type = ORDER_TYPE_BUY; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); + } + } + else + { + // + // position not found + m_result.retcode = retcode; + return (false); + } + + // + // check volume + double position_volume = PositionGetDouble(POSITION_VOLUME); + if (position_volume > volume) + { + position_volume = volume; + } + + // + // setting request + m_request.action = TRADE_ACTION_DEAL; + m_request.symbol = symbol; + m_request.volume = position_volume; + m_request.magic = m_magic; + m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; + m_request.position = PositionGetInteger(POSITION_TICKET); + + // + // Specifieng Comment ... + m_request.comment = comment; + + // + // hedging? just send order + return (OrderSend(m_request, m_result)); + } + bool PositionClosePartial( + const ulong ticket, // Position Ticket + const double volume, // Partial Closing Volume + const ulong deviation, // Deviation + const string comment = "" // Comment For Close + ) + { + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // for hedging mode only + if (!IsHedging()) + { + return (false); + } + + // + // check position existence + if (!PositionSelectByTicket(ticket)) + { + return (false); + } + + // + string symbol = PositionGetString(POSITION_SYMBOL); + + // + // clean + ClearStructures(); + + // + // check filling + if (!FillingCheck(symbol)) + { + return (false); + } + + // + // check + if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) + { + // + // prepare request for close BUY position + m_request.type = ORDER_TYPE_SELL; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); + } + else + { + // + // prepare request for close SELL position + m_request.type = ORDER_TYPE_BUY; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); + } + + // + // check volume + double position_volume = PositionGetDouble(POSITION_VOLUME); + if (position_volume > volume) + { + position_volume = volume; + } + + // + // setting request + m_request.action = TRADE_ACTION_DEAL; + m_request.position = ticket; + m_request.symbol = symbol; + m_request.volume = position_volume; + m_request.magic = m_magic; + m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; + + // + // Specifieng Comment ... + m_request.comment = comment; + + // + // close position + return (OrderSend(m_request, m_result)); + } +}; + +// +// END Overrides ... +// + +// +// a Class for Manage Trades ... +class XSCTrade +{ + // + // Public ... +public: + // + // Constructor ... + void XSCTrade( + int slippage, // Specify Slippage + ulong magicNumber // Specify Magic Number + ) + { + // + mSlippage = slippage; + mMagicNumber = magicNumber; + + // + mPeriodPrefix = "PR"; + + // + mTrader = new XSCTradeBase(); + + // + mTrader.SetAsyncMode(false); + mTrader.SetDeviationInPoints(mSlippage); + mTrader.SetExpertMagicNumber(mMagicNumber); + + // + // Setting Log Level ... + mTrader.LogLevel(LOG_LEVEL_ERRORS); + + // + // Prepare Trade Event Materials ... + // + mDaysForRead = 1; + mScanStarted = false; + + // + // Reset On Trade Counter ... + ResetOnTradeContext(); + + // + // Init On Trade Context ... + InitOnTradeContext(); + } + + // + // Deconstructor ... + void ~XSCTrade() + { + } + + // + // START Event Processing ... + // + + // + // This Must be Called Every time OnTrade Event Happening ... + XOnTradeHandlerState HandleOnTrade() + { + // + // Handle OnTrade Event ... + XOnTradeHandlerState state = {}; + HandleOnTradeEvent(state); + if ( + !state.hasNewDeal && + !state.hasNewOrder && + !state.hasNewPosition && + !state.hasNewHistoryOrder) + { + return state; + } + + // + // STATE ... + + // + // Notfy Trade State Changed Event ... + NotifyTradeStateChangeEvent(state); + + // + // DEALS ... + if (state.hasNewDeal) + { + // + // Notfy Deals Changed Event ... + NotifyDealsChangeEvent(state.newDeals); + + // + // Retrieve Last Deal ... + XDeal deals[]; + GetDeals(deals); + int dealsCount = ArraySize(deals); + if (dealsCount > 0) + { + // + XDeal lastDeal = deals[0]; + + // + if (lastDeal.reason == DEAL_REASON_TP) + { + NotifyTakeProfitEvent(lastDeal); + } + else if (lastDeal.reason == DEAL_REASON_SL) + { + NotifyStopLossEvent(lastDeal); + } + } + } + + // + // ORDERS ... + if (state.hasNewOrder || state.hasNewHistoryOrder) + { + // + // Notfy Orders Changed Event ... + NotifyOrdersChangeEvent(state.newOrders + state.newHistoryOrders); + } + + // + // POSITIONS ... + if (state.hasNewPosition) + { + // + // Notfy Positions Changed Event ... + NotifyPositionsChangeEvent(state.newPositions); + } + + // + return state; + } + + // + // Process On Trade Requirement + void HandleOnTradeEvent( + XOnTradeHandlerState &result // Hold's Result + ) + { + // + if (mScanStarted) + { + ProcessOnTradeContext(result); + } + else + { + InitOnTradeContext(); + } + } + + // + // Event Emitters ... + + // + // STATE Changed ... + + // + // Clear Trade State Changed Event Handlers ... + void ClearOnTradeStateChangedEventHandlers() + { + // + ArrayFree(mTradeStateChangedEventHandlers); + + // + ArrayResize(mTradeStateChangedEventHandlers, 0); + } + + // + // Add New Deals Changed Event Handler ... + void AddOnTradeStateChangedEventHandler(TOnTradeStateChanged handler) + { + // + ArrayResize( + mTradeStateChangedEventHandlers, + ArraySize(mTradeStateChangedEventHandlers) + 1); + + // + mTradeStateChangedEventHandlers[ArraySize(mTradeStateChangedEventHandlers) - 1] = handler; + } + + // + // DEALS ... + + // + // Clear Deals Changed Event Handlers ... + void ClearOnDealsChangedEventHandlers() + { + // + ArrayFree(mDealsChangedEventHandlers); + + // + ArrayResize(mDealsChangedEventHandlers, 0); + } + + // + // Add New Deals Changed Event Handler ... + void AddOnDealsChangedEventHandler(TOnDealsChanged handler) + { + // + ArrayResize( + mDealsChangedEventHandlers, + ArraySize(mDealsChangedEventHandlers) + 1); + + // + mDealsChangedEventHandlers[ArraySize(mDealsChangedEventHandlers) - 1] = handler; + } + + // + // ORDERS ... + + // + // Clear Orders Changed Event Handlers ... + void ClearOnOrdersChangedEventHandlers() + { + // + ArrayFree(mOrdersChangedEventHandlers); + + // + ArrayResize(mOrdersChangedEventHandlers, 0); + } + + // + // Add New Orders Changed Event Handler ... + void AddOnOrdersChangedEventHandler(TOnOrdersChanged handler) + { + // + ArrayResize( + mOrdersChangedEventHandlers, + ArraySize(mOrdersChangedEventHandlers) + 1); + + // + mOrdersChangedEventHandlers[ArraySize(mOrdersChangedEventHandlers) - 1] = handler; + } + + // + // POSITIONS ... + + // + // Clear Positions Changed Event Handlers ... + void ClearOnPositionsChangedEventHandlers() + { + // + ArrayFree(mPositionsChangedEventHandlers); + + // + ArrayResize(mPositionsChangedEventHandlers, 0); + } + + // + // Add New Positions Changed Event Handler ... + void AddOnPositionsChangedEventHandler(TOnPositionsChanged handler) + { + // + ArrayResize( + mPositionsChangedEventHandlers, + ArraySize(mPositionsChangedEventHandlers) + 1); + + // + mPositionsChangedEventHandlers[ArraySize(mPositionsChangedEventHandlers) - 1] = handler; + } + + // + // TPSL ... + + // + // Clear Stop Loss Event Handlers ... + void ClearOnStopLossEventHandlers() + { + // + ArrayFree(mStopLossEventHandlers); + + // + ArrayResize(mStopLossEventHandlers, 0); + } + + // + // Add New Stop Loss Event Handler ... + void AddOnStopLossEventHandler(TOnStopLoss handler) + { + // + ArrayResize( + mStopLossEventHandlers, + ArraySize(mStopLossEventHandlers) + 1); + + // + mStopLossEventHandlers[ArraySize(mStopLossEventHandlers) - 1] = handler; + } + + // + // Clear Take Profit Event Handlers ... + void ClearOnTakeProfitEventHandlers() + { + // + ArrayFree(mTakeProfitEventHandlers); + + // + ArrayResize(mTakeProfitEventHandlers, 0); + } + + // + // Add New Stop Loss Event Handler ... + void AddOnTakeProfitEventHandler(TOnTakeProfit handler) + { + // + ArrayResize( + mTakeProfitEventHandlers, + ArraySize(mTakeProfitEventHandlers) + 1); + + // + mTakeProfitEventHandlers[ArraySize(mTakeProfitEventHandlers) - 1] = handler; + } + + // + // END Event Processing ... + // + + // + // START Provided Functions ... + // + + // + // Count Currently Open Positions ... + int CountPositions( + string symbol = "", // Specified Symbol + ENUM_POSITION_TYPE type = NULL // Specified Type + ) + { + // + int result = 0; + + // + int allPositions = 0; + int longPositions = 0; + int shortPositions = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + string positionSymbol = mPositionInfo.Symbol(); + + // + ENUM_POSITION_TYPE positionType = mPositionInfo.PositionType(); + + // + if ( + type == NULL && + StringLen(symbol) <= 0) + { + // + allPositions++; + + // + continue; + } + else if ( + type != NULL && + StringLen(symbol) > 0) + { + // + if (type == positionType && + symbol == positionSymbol) + { + // + if (type == POSITION_TYPE_BUY) + { + longPositions++; + } + else + { + shortPositions++; + } + + // + continue; + } + } + else if (StringLen(symbol) > 0) + { + // + if (positionSymbol == symbol) + { + // + allPositions++; + + // + continue; + } + } + else if (type != NULL) + { + // + if (type == positionType) + { + // + if (type == POSITION_TYPE_BUY) + { + longPositions++; + } + else + { + shortPositions++; + } + + // + continue; + } + } + } + + // + // Specify Result ... + if ( + type == NULL && + StringLen(symbol) <= 0) + { + // + result = allPositions; + } + else if ( + type != NULL && + StringLen(symbol) > 0) + { + // + if (type == POSITION_TYPE_BUY) + { + result = longPositions; + } + else + { + result = shortPositions++; + } + } + else if (StringLen(symbol) > 0) + { + // + result = allPositions; + } + else if (type != NULL) + { + // + if (type == POSITION_TYPE_BUY) + { + result = longPositions; + } + else + { + result = shortPositions; + } + } + + // + return result; + } + + // + // Retrieve Max In Profit Position Ticket ... + ulong GetMaxInProfitPosition( + string symbol = "", // Specified Symbol + ENUM_POSITION_TYPE type = NULL // Specified Type + ) + { + // + ulong result = -1; + + // + double profit = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + + // + string positionSymbol = mPositionInfo.Symbol(); + + // + double positionProfit = mPositionInfo.Profit(); + double positionAbsProfit = MathAbs(positionProfit); + if (positionProfit <= 0) + { + continue; + } + + // + ENUM_POSITION_TYPE positionType = mPositionInfo.PositionType(); + + // + if ( + type == NULL && + StringLen(symbol) <= 0) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + + // + continue; + } + else if ( + type != NULL && + StringLen(symbol) > 0) + { + // + if (type == positionType && + symbol == positionSymbol) + { + // + if (type == POSITION_TYPE_BUY) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + else + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + + // + continue; + } + } + else if (StringLen(symbol) > 0) + { + // + if (positionSymbol == symbol) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + + // + continue; + } + } + else if (type != NULL) + { + // + if (type == positionType) + { + // + if (type == POSITION_TYPE_BUY) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + else + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + + // + continue; + } + } + } + + // + return result; + } + + // + // Retrieve Max In DrawDown Position Ticket ... + ulong GetMaxInDrawDownPosition( + string symbol = "", // Specified Symbol + ENUM_POSITION_TYPE type = NULL // Specified Type + ) + { + // + ulong result = -1; + + // + double profit = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + + // + string positionSymbol = mPositionInfo.Symbol(); + + // + double positionProfit = mPositionInfo.Profit(); + double positionAbsProfit = MathAbs(positionProfit); + if (positionProfit >= 0) + { + continue; + } + + // + ENUM_POSITION_TYPE positionType = mPositionInfo.PositionType(); + + // + if ( + type == NULL && + StringLen(symbol) <= 0) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + + // + continue; + } + else if ( + type != NULL && + StringLen(symbol) > 0) + { + // + if (type == positionType && + symbol == positionSymbol) + { + // + if (type == POSITION_TYPE_BUY) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + else + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + + // + continue; + } + } + else if (StringLen(symbol) > 0) + { + // + if (positionSymbol == symbol) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + + // + continue; + } + } + else if (type != NULL) + { + // + if (type == positionType) + { + // + if (type == POSITION_TYPE_BUY) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + else + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + + // + continue; + } + } + } + + // + return result; + } + + // + // Retrieve Specific Position's Profit ... + double GetPositionProfit( + const ulong ticket // Specified Position Ticket + ) + { + // + double result = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + if (positionTicket != ticket) + { + continue; + } + + // + result = mPositionInfo.Profit(); + break; + } + + // + return result; + } + + // + // Retrieve Specific Position's OpenDate ... + datetime GetPositionOpenDate( + const ulong ticket // Specified Position Ticket + ) + { + // + datetime result = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + if (positionTicket != ticket) + { + continue; + } + + // + result = mPositionInfo.Time(); + break; + } + + // + return result; + } + + // + // Retrieve Specific Position's Comment ... + string GetPositionComment( + const ulong ticket // Specified Position Ticket + ) + { + // + string result = ""; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + if (positionTicket != ticket) + { + continue; + } + + // + result = mPositionInfo.Comment(); + break; + } + + // + return result; + } + + // + // Retrieve All Open Positions Profit ... + double GetPositionsProfit( + string symbol = "", // Specified Symbol + ENUM_POSITION_TYPE type = NULL // Specified Type + ) + { + // + double result = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + + // + string positionSymbol = mPositionInfo.Symbol(); + + // + double positionProfit = mPositionInfo.Profit(); + + // + ENUM_POSITION_TYPE positionType = mPositionInfo.PositionType(); + + // + if ( + type == NULL && + StringLen(symbol) <= 0) + { + // + result += positionProfit; + + // + continue; + } + else if ( + type != NULL && + StringLen(symbol) > 0) + { + // + if (type == positionType && + symbol == positionSymbol) + { + // + if (type == POSITION_TYPE_BUY) + { + result += positionProfit; + } + else + { + result += positionProfit; + } + + // + continue; + } + } + else if (StringLen(symbol) > 0) + { + // + if (positionSymbol == symbol) + { + result += positionProfit; + + // + continue; + } + } + else if (type != NULL) + { + // + if (type == positionType) + { + // + if (type == POSITION_TYPE_BUY) + { + result += positionProfit; + } + else + { + result += positionProfit; + } + + // + continue; + } + } + } + + // + return result; + } + + // + // Find Oldes Position ... + ulong GetOldestPosition( + string symbol = "", // Specified Symbol + ENUM_POSITION_TYPE type = NULL // Specified Type + ) + { + // + ulong result = 0; + + // + int age = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + + // + string positionSymbol = mPositionInfo.Symbol(); + + // + double positionProfit = mPositionInfo.Profit(); + double positionAbsProfit = MathAbs(positionProfit); + if (positionProfit >= 0) + { + continue; + } + + // + ENUM_POSITION_TYPE positionType = mPositionInfo.PositionType(); + + // + string positionComment = mPositionInfo.Comment(); + ENUM_TIMEFRAMES positionPeriod = ExtractPositionPeriod(positionComment); + + // + // Calculate Position's Age ... + datetime positionOpenTime = mPositionInfo.Time(); + + // + // Retrieve Trade Open Bar Index based on Current Period ... + int positionOpenBarIndex = iBarShift( + positionSymbol, + positionPeriod, + positionOpenTime); + + // + // Calculate Trade Life ... + int positionAge = MathAbs(0 - positionOpenBarIndex); + + // + if ( + type == NULL && + StringLen(symbol) <= 0) + { + // + if (age < positionAge) + { + // + age = positionAge; + result = positionTicket; + } + + // + continue; + } + else if ( + type != NULL && + StringLen(symbol) > 0) + { + // + if (type == positionType && + symbol == positionSymbol) + { + // + if (type == POSITION_TYPE_BUY) + { + // + if (age < positionAge) + { + // + age = positionAge; + result = positionTicket; + } + } + else + { + // + if (age < positionAge) + { + // + age = positionAge; + result = positionTicket; + } + } + + // + continue; + } + } + else if (StringLen(symbol) > 0) + { + // + if (positionSymbol == symbol) + { + // + if (age < positionAge) + { + // + age = positionAge; + result = positionTicket; + } + + // + continue; + } + } + else if (type != NULL) + { + // + if (type == positionType) + { + // + if (type == POSITION_TYPE_BUY) + { + // + if (age < positionAge) + { + // + age = positionAge; + result = positionTicket; + } + } + else + { + // + if (age < positionAge) + { + // + age = positionAge; + result = positionTicket; + } + } + + // + continue; + } + } + } + + // + return result; + } + + // + // Force Open a Buy/Long Position ... + bool Buy( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // position volume + double price, // execution price + double sl = 0, // stop loss price + double tp = 0, // take profit price + string comment = "" // comment + ) + { + // + bool result = false; + + // + string mPeriodStr = GeneratePositionPeriodComment(period); + + // + comment += mPeriodStr; + + // + result = mTrader.Buy( + volume, + symbol, + price, + sl, + tp, + comment); + + // + return result; + } + + // + // Send BUY LIMIT order ... + bool BuyLimit( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // order volume + double price, // order price + double sl = 0.0, // stop loss price + double tp = 0.0, // take profit price + ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime + datetime expiration = 0, // order expiration time + string comment = "" // comment + ) + { + // + bool result = false; + + // + string mPeriodStr = GeneratePositionPeriodComment(period); + + // + comment += mPeriodStr; + + // + result = mTrader.BuyLimit( + volume, + price, + symbol, + sl, + tp, + typeTime, + expiration, + comment); + + // + return result; + } + + // + // Send BUY STOP order ... + bool BuyStop( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // order volume + double price, // order price + double sl = 0.0, // stop loss price + double tp = 0.0, // take profit price + ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime + datetime expiration = 0, // order expiration time + string comment = "" // comment + ) + { + // + bool result = false; + + // + string mPeriodStr = GeneratePositionPeriodComment(period); + + // + comment += mPeriodStr; + + // + result = mTrader.BuyStop( + volume, + price, + symbol, + sl, + tp, + typeTime, + expiration, + comment); + + // + return result; + } + + // + // Force Open a Sell/Short Position ... + bool Sell( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // position volume + double price, // execution price + double sl = 0, // stop loss price + double tp = 0, // take profit price + string comment = "" // comment + ) + { + // + bool result = false; + + // + string mPeriodStr = GeneratePositionPeriodComment(period); + + // + comment += mPeriodStr; + + // + result = mTrader.Sell( + volume, + symbol, + price, + sl, + tp, + comment); + + // + return result; + } + + // + // Send SELL LIMIT order ... + bool SellLimit( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // order volume + double price, // order price + double sl = 0.0, // stop loss price + double tp = 0.0, // take profit price + ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime + datetime expiration = 0, // order expiration time + string comment = "" // comment + ) + { + // + bool result = false; + + // + string mPeriodStr = GeneratePositionPeriodComment(period); + + // + comment += mPeriodStr; + + // + result = mTrader.SellLimit( + volume, + price, + symbol, + sl, + tp, + typeTime, + expiration, + comment); + + // + return result; + } + + // + // Send SELL STOP order ... + bool SellStop( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // order volume + double price, // order price + double sl = 0.0, // stop loss price + double tp = 0.0, // take profit price + ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime + datetime expiration = 0, // order expiration time + string comment = "" // comment + ) + { + // + bool result = false; + + // + string mPeriodStr = GeneratePositionPeriodComment(period); + + // + comment += mPeriodStr; + + // + result = mTrader.SellStop( + volume, + price, + symbol, + sl, + tp, + typeTime, + expiration, + comment); + + // + return result; + } + + // + // Modify Position ... + bool Modify( + const ulong ticket, // position ticket + double sl = 0, // stop loss price + double tp = 0, // take profit + string comment = "" // comment + ) + { + // + bool result = false; + + // + // Validate Args ... + if (tp <= 0 && sl <= 0) + { + result = false; + return result; + } + + // + // Use Position Comment when there isn't new One ... + if (StringLen(comment) == 0) + { + comment = GetPositionComment(ticket); + } + + // + result = mTrader.PositionModify( + ticket, + sl, + tp, + comment); + + // + return result; + } + + // + // Close Position By Ticket ... + bool Close( + ulong ticket, // Position Ticket + string comment = "" // Close Position By Specific Comment + ) + { + // + bool result = false; + + // + // Try to Select Position ... + if (!mPositionInfo.SelectByTicket(ticket)) + { + return result; + } + + // + // Close Position By Specific Comment ... + result = mTrader.PositionClose( + ticket, + mSlippage, + comment); + + // + return result; + } + + // + // Close All Positions ... + void CloseAllPositions( + string comment = "" // Close Position By Specific Comment + ) + { + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + Close( + positionTicket, + comment); + } + } + + // + // Close Partial By Ticket ... + bool ClosePartial( + ulong ticket, // Position Ticket + double volume, // Volume Size for Partial Closing + string comment = "" // Close Position By Specific Comment + ) + { + // + bool result = false; + + // + if (!mPositionInfo.SelectByTicket(ticket)) + { + return result; + } + + // + result = mTrader.PositionClosePartial( + ticket, + volume, + mSlippage, + comment); + + // + return result; + } + + // + // Find Position Open Bar Index ... + int GetPositionOpenBarIndex( + const ulong ticket // position ticket + ) + { + // + int result = -1; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + if (positionTicket != ticket) + { + continue; + } + + // + string symbol = mPositionInfo.Symbol(); + datetime openAt = mPositionInfo.Time(); + string comment = mPositionInfo.Comment(); + ENUM_TIMEFRAMES period = ExtractPositionPeriod(comment); + + // + result = iBarShift( + symbol, + period, + openAt); + } + + // + return result; + } + + // + bool GetPosition( + XPosition &position, // Holds result ... + ulong ticket // Required Position Ticket ... + ) + { + // + bool result = false; + + // + XPosition positions[]; + GetPositions(positions); + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + result = iPosition.ticket == ticket; + if (!result) + { + continue; + } + + // + position = iPosition; + break; + } + + // + return result; + } + + // + // Retrieve Positions as an Array ... + void GetPositions( + XPosition &result[] // Hold Result ... + ) + { + // + Clean(result); + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong magic = mPositionInfo.Magic(); + ulong ticket = mPositionInfo.Ticket(); + string symbol = mPositionInfo.Symbol(); + datetime openAt = mPositionInfo.Time(); + double swap = mPositionInfo.Swap(); + double sl = mPositionInfo.StopLoss(); + double tp = mPositionInfo.TakeProfit(); + double profit = mPositionInfo.Profit(); + double volume = mPositionInfo.Volume(); + string comment = mPositionInfo.Comment(); + double entry = mPositionInfo.PriceOpen(); + double price = mPositionInfo.PriceCurrent(); + double commission = mPositionInfo.Commission(); + ENUM_POSITION_TYPE type = mPositionInfo.PositionType(); + ENUM_TIMEFRAMES period = ExtractPositionPeriod(comment); + + // + XPosition iPosition = {}; + + // + iPosition.tp = tp; + iPosition.sl = sl; + iPosition.swap = swap; + iPosition.type = type; + iPosition.magic = magic; + iPosition.entry = entry; + iPosition.price = price; + iPosition.ticket = ticket; + iPosition.symbol = symbol; + iPosition.period = period; + iPosition.volume = volume; + iPosition.openAt = openAt; + iPosition.profit = profit; + iPosition.comment = comment; + iPosition.commission = commission; + + // + Add( + iPosition, + result); + } + } + + // + void GetPositions( + XPosition &result[], // Hold Result ... + string symbol, // Trading Symbol ... + ENUM_TIMEFRAMES period // Trading Period ... + ) + { + // + Clean(result); + + // + bool hasPeriod = period != NULL; + bool hasSymbol = symbol != NULL && StringLen(symbol) > 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return; + } + + // + XPosition allPositions[]; + GetPositions(allPositions); + + // + if (!hasPeriod && !hasSymbol) + { + // + Copy( + allPositions, + result); + + // + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = allPositions[i]; + + // + if (hasSymbol && + symbol != iPosition.symbol) + { + continue; + } + + // + ENUM_TIMEFRAMES positionPeriod = ExtractPositionPeriod(iPosition.comment); + if (hasPeriod && + period != positionPeriod) + { + continue; + } + + // + Add( + iPosition, + result); + } + } + + // + // Execute a Signal ... + bool ExecuteSignal( + XSignal &signal, // Signal ... + string comment = "", // Position Comment ... + ENUM_ORDER_TYPE_TIME lifetime = ORDER_TIME_GTC, // Order LifeTime ... + datetime expiration = 0 // order expiration time + ) + { + // + bool result = false; + + // + double currentEntry = GetEntry( + signal.symbol, + signal.type); + bool isLong = IsLong(signal.type); + + // + ResetLastError(); + + // + if (signal.mode == X_ORDER_MODE_MARKET) + { + // + // Execute MArket Orders ... + if (isLong) + { + // + result = Buy( + signal.symbol, + signal.period, + signal.volume, + signal.entry, + signal.sl, + signal.tp, + comment); + } + else + { + // + result = Sell( + signal.symbol, + signal.period, + signal.volume, + signal.entry, + signal.sl, + signal.tp, + comment); + } + } + else if (signal.mode == X_ORDER_MODE_LIMIT) + { + // + // Execute Limit Orders ... + + // + // Check Conditions ... + + // + // Check Price ... + result = isLong + ? signal.entry < currentEntry + : signal.entry > currentEntry; + if (!result) + { + return result; + } + + // + // Check Expiration Date ... + result = (lifetime == ORDER_TIME_SPECIFIED || lifetime == ORDER_TIME_SPECIFIED_DAY) + ? expiration > 0 + : true; + if (!result) + { + return result; + } + + // + if (isLong) + { + // + result = BuyLimit( + signal.symbol, + signal.period, + signal.volume, + signal.entry, + signal.sl, + signal.tp, + lifetime, + expiration, + comment); + } + else + { + // + result = SellLimit( + signal.symbol, + signal.period, + signal.volume, + signal.entry, + signal.sl, + signal.tp, + lifetime, + expiration, + comment); + } + } + else if (signal.mode == X_ORDER_MODE_STOP) + { + // + // Execute Stop Orders ... + + // + // Check Conditions ... + + // + // Check Price ... + result = isLong + ? signal.entry > currentEntry + : signal.entry < currentEntry; + if (!result) + { + return result; + } + + // + // Check Expiration Date ... + result = (lifetime == ORDER_TIME_SPECIFIED || lifetime == ORDER_TIME_SPECIFIED_DAY) + ? expiration > 0 + : true; + if (!result) + { + return result; + } + + // + if (isLong) + { + // + result = BuyStop( + signal.symbol, + signal.period, + signal.volume, + signal.entry, + signal.sl, + signal.tp, + lifetime, + expiration, + comment); + } + else + { + // + result = SellStop( + signal.symbol, + signal.period, + signal.volume, + signal.entry, + signal.sl, + signal.tp, + lifetime, + expiration, + comment); + } + } + + // + if (!result) + { + LogMessage("Error: " + (string)GetLastError() + ", " + GetErrorDescription(GetLastError())); + } + else + { + // + // Retrieve Last Position Ticket ... + ulong ticket = GetLastOpenPositionTicket(); + + // + // Check Position have Support Signals or not ... + int supportsCount = ArraySize(signal.supports); + if (supportsCount > 0) + { + // + int executed = 0; + for (int i = 0; i < supportsCount; i++) + { + // + XSignal iSupport = signal.supports[i]; + + // + int supIndex = i + 1; + string iComment = GenerateSupportSignalComment( + ticket, + supIndex); + + // + bool isExecuted = ExecuteSignal( + iSupport, + iComment); + if (isExecuted) + { + executed++; + } + } + + // + result = executed == supportsCount; + } + } + + // + return result; + } + + // + // Execute a Collection of Signals ... + int ExecuteSignals( + const XSignal &signals[], // an Array of Signals ... + string comment = "", // Position Comment ... + ENUM_ORDER_TYPE_TIME lifetime = ORDER_TIME_GTC, // Order LifeTime ... + datetime expiration = 0 // order expiration time + ) + { + // + int result = 0; + + // + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + if (StringLen(comment) == 0) + { + comment = GenerateProvidersString(iSignal); + } + + // + bool isExecuted = ExecuteSignal( + iSignal, + comment, + lifetime, + expiration); + + // + if (isExecuted) + { + result++; + } + } + + // + return result; + } + + // + // Retrieve in Profit Positions ... + void GetInProfitPositions( + XPosition &result[] // Hold Result ... + ) + { + // + Clean(result); + + // + XPosition allPositions[]; + GetPositions(allPositions); + int positionsCount = ArraySize(allPositions); + if (positionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = allPositions[i]; + + // + if (iPosition.profit > 0) + { + Add( + iPosition, + result); + } + } + } + + // + // Retrieve in Drawdown Positions ... + void GetInDrawdownPositions( + XPosition &result[] // Hold Result ... + ) + { + // + Clean(result); + + // + XPosition allPositions[]; + GetPositions(allPositions); + int positionsCount = ArraySize(allPositions); + if (positionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = allPositions[i]; + + // + if (iPosition.profit < 0) + { + Add( + iPosition, + result); + } + } + } + + // + // Close a Collection Of Positions ... + int ClosePositions( + XPosition &positions[], // Positions to Close ... + string comment = "" // Specified Comment ... + ) + { + // + int result = 0; + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + bool isClosed = Close( + iPosition.ticket, + comment); + if (isClosed) + { + result++; + } + } + + // + return result; + } + + // + // Retrieve All Orders ... + void GetOrders( + XOrder &result[], // Holdes Result .... + string symbol, // Trading Symbol ... + ENUM_TIMEFRAMES period, // Trading TimeFrame ... + ENUM_ORDER_STATE state = NULL // Order State ... + ) + { + // + Clean(result); + + // + int ordersCount = OrdersTotal(); + if (ordersCount <= 0) + { + return; + } + + // + // Since Orders may be so more than positions ... + // start Orders Collectiong Loops reverse ... + for (int i = ordersCount - 1; i >= 0; i--) + { + // + if (!mOrderInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mOrderInfo.Magic() != mMagicNumber) + { + continue; + } + + // + // Reading Order Info ... + long magic = mOrderInfo.Magic(); + double sl = mOrderInfo.StopLoss(); + ulong ticket = mOrderInfo.Ticket(); + double tp = mOrderInfo.TakeProfit(); + string oSymbol = mOrderInfo.Symbol(); + string comment = mOrderInfo.Comment(); + long pocitionID = mOrderInfo.PositionId(); + double openPrice = mOrderInfo.PriceOpen(); + datetime setupAt = mOrderInfo.TimeSetup(); + datetime executedAt = mOrderInfo.TimeDone(); + ENUM_ORDER_STATE oState = mOrderInfo.State(); + ENUM_ORDER_TYPE type = mOrderInfo.OrderType(); + double currentPrice = mOrderInfo.PriceCurrent(); + datetime expiredAt = mOrderInfo.TimeExpiration(); + double initialVolume = mOrderInfo.VolumeInitial(); + double currentVolume = mOrderInfo.VolumeCurrent(); + double stopLimitPrice = mOrderInfo.PriceStopLimit(); + ENUM_ORDER_TYPE_TIME lifetime = mOrderInfo.TypeTime(); + ENUM_ORDER_TYPE_FILLING filling = mOrderInfo.TypeFilling(); + + // + if (StringLen(symbol) > 0 && symbol != oSymbol) + { + continue; + } + + // + ENUM_TIMEFRAMES oPeriod = ExtractPositionPeriod(comment); + if (period != NULL && period != oPeriod) + { + continue; + } + + // + if (state != NULL && oState != state) + { + continue; + } + + // + // Now Create an instance of XOrder struct and fill it by + // retrieved data, and add it to results ... + XOrder iOrder = {}; + + // + iOrder.sl = sl; + iOrder.tp = tp; + iOrder.type = type; + iOrder.magic = magic; + iOrder.state = oState; + iOrder.ticket = ticket; + iOrder.smybol = oSymbol; + iOrder.period = oPeriod; + iOrder.setupAt = setupAt; + iOrder.comment = comment; + iOrder.filling = filling; + iOrder.lifetime = lifetime; + iOrder.expiredAt = expiredAt; + iOrder.openPrice = openPrice; + iOrder.pocitionID = pocitionID; + iOrder.executedAt = executedAt; + iOrder.currentPrice = currentPrice; + iOrder.initialVolume = initialVolume; + iOrder.currentVolume = currentVolume; + iOrder.stopLimitPrice = stopLimitPrice; + + // + Add( + iOrder, + result); + } + } + + // + int CountOrders() + { + return OrdersTotal(); + } + + // + // Cancel Specific Order ... + bool CancelOrder(ulong ticket) + { + return mTrader.OrderDelete(ticket); + } + + // + // Cancel Specific Orders ... + bool CancelOrders( + XOrder &orders[]) + { + // + bool result = false; + + // + int ordersCount = ArraySize(orders); + if (ordersCount <= 0) + { + return result; + } + + // + for (int i = 0; i < ordersCount; i++) + { + // + XOrder iOrder = orders[i]; + + // + bool isDeleted = mTrader.OrderDelete(iOrder.ticket); + if (isDeleted && !result) + { + result = isDeleted; + } + } + + // + return result; + } + + // + // Retrieve All Deals ... + void GetDeals(XDeal &result[]) + { + // + Clean(result); + + // + int dealsCount = HistoryDealsTotal(); + if (dealsCount <= 0) + { + return; + } + + // + for (int i = dealsCount - 1; i >= 0; i--) + { + // + if (!mDealInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mDealInfo.Magic() != mMagicNumber) + { + continue; + } + + // + // Reading Order Info ... + double swap = mDealInfo.Swap(); + ulong magic = mDealInfo.Magic(); + ulong order = mDealInfo.Order(); + ulong ticket = mDealInfo.Ticket(); + datetime time = mDealInfo.Time(); + double price = mDealInfo.Price(); + string symbol = mDealInfo.Symbol(); + double profit = mDealInfo.Profit(); + double volume = mDealInfo.Volume(); + string comment = mDealInfo.Comment(); + ulong positionId = mDealInfo.PositionId(); + ENUM_DEAL_ENTRY entry = mDealInfo.Entry(); + double commission = mDealInfo.Commission(); + ENUM_DEAL_TYPE type = mDealInfo.DealType(); + ENUM_DEAL_REASON reason = (ENUM_DEAL_REASON)HistoryDealGetInteger( + ticket, + DEAL_REASON); + + // + XDeal iDeal = {}; + + // + iDeal.swap = swap; + iDeal.time = time; + iDeal.type = type; + iDeal.magic = magic; + iDeal.entry = entry; + iDeal.order = order; + iDeal.price = price; + iDeal.ticket = ticket; + iDeal.symbol = symbol; + iDeal.profit = profit; + iDeal.volume = volume; + iDeal.reason = reason; + iDeal.comment = comment; + iDeal.positionId = positionId; + iDeal.commission = commission; + + // + Add( + iDeal, + result); + } + } + + // + // Generate String Representation Of Position's Time Frame ... + string GeneratePositionPeriodComment(ENUM_TIMEFRAMES period) + { + // + string result = mPeriodPrefix + "(" + ToString(period) + ")"; + + // + return result; + } + + // + // Extract Position Time Frame From it's Comment ... + ENUM_TIMEFRAMES ExtractPositionPeriod(string comment) + { + // + ENUM_TIMEFRAMES result = _Period; + + // + if (StringLen(comment) <= 0) + { + return result; + } + + // + string periodStr = ExtractString( + comment, + mPeriodPrefix + "(", + ")"); + if (StringLen(periodStr) <= 0) + { + return result; + } + + // + result = ToPeriod(periodStr); + + // + return result; + } + + // + // Retrieve Last Open Position Ticket ... + ulong GetLastOpenPositionTicket() + { + // + ulong result = 0; + + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + result = PositionGetTicket(PositionsTotal() - 1); + + // + return result; + } + + // + // Retrieve Last Placed Order Ticket ... + ulong GetLastPlacedOrderTicket() + { + // + ulong result = 0; + + int ordersCount = OrdersTotal(); + if (ordersCount <= 0) + { + return result; + } + + // + if (mOrderInfo.SelectByIndex(ordersCount - 1)) + { + result = mOrderInfo.Ticket(); + } + + // + return result; + } + + // + // SUPPORT Signals ... + + // + // Retrieve a Position if Exists + // by all of it's Supported Positon/Order (s) ... + bool GetPositionPack( + ulong ticket, // Sepcified Position's Ticket + XPositionPack &pack // Hold Result ... + ) + { + // + bool result = false; + + // + int positionsCount = CountPositions(); + int ordersCount = CountOrders(); + if (ordersCount <= 0 && positionsCount <= 0) + { + return result; + } + + // + XPosition position; + result = GetPosition( + position, + ticket); + if (!result) + { + return result; + } + + // + XOrder supportOrders[]; + XPosition supportPositions[]; + + // + XOrder orders[]; + GetOrders( + orders, + position.symbol, + position.period, + ORDER_STATE_PLACED); + ordersCount = ArraySize(orders); + + // + // Select Orders ... + if (ordersCount > 0) + { + // + for (int i = 0; i < ordersCount; i++) + { + // + XOrder iOrder = orders[i]; + + // + string params[]; + bool hasSupport = ExtractSupportParams( + iOrder.comment, + params); + if (hasSupport) + { + // + ulong parentTicket = ExtractParentTicket(iOrder.comment); + if (parentTicket == ticket) + { + // + Add( + iOrder, + supportOrders); + } + } + } + } + + // + XPosition positions[]; + GetPositions( + positions, + position.symbol, + position.period); + positionsCount = ArraySize(positions); + + // + // Select Positions ... + if (positionsCount > 0) + { + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + string params[]; + bool hasSupport = ExtractSupportParams( + iPosition.comment, + params); + if (hasSupport) + { + // + ulong parentTicket = ExtractParentTicket(iPosition.comment); + if (parentTicket == ticket) + { + // + Add( + iPosition, + supportPositions); + } + } + } + } + + // + int supportOrdersCount = ArraySize(supportOrders); + int supportPositionsCount = ArraySize(supportPositions); + + // + pack.ticket = ticket; + pack.position = position; + + // + Copy(supportOrders, + pack.supportOrders); + Copy(supportPositions, + pack.supportPositions); + + // + pack.supportOrdersCount = supportOrdersCount; + pack.supportPositionsCount = supportPositionsCount; + + // + result = true; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... + + // + // EVENTS Handlers Notifiers ... + + // + // STATE ... + void NotifyTradeStateChangeEvent(const XOnTradeHandlerState &state) + { + // + int count = ArraySize(mTradeStateChangedEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnTradeStateChanged iHandler = mTradeStateChangedEventHandlers[i]; + iHandler(state); + } + } + + // + // DEALS ... + void NotifyDealsChangeEvent(int changes) + { + // + int count = ArraySize(mDealsChangedEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnDealsChanged iHandler = mDealsChangedEventHandlers[i]; + iHandler(changes); + } + } + + // + // ORDERS ... + void NotifyOrdersChangeEvent(int changes) + { + // + int count = ArraySize(mOrdersChangedEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnOrdersChanged iHandler = mOrdersChangedEventHandlers[i]; + iHandler(changes); + } + } + + // + // POSITIONS ... + void NotifyPositionsChangeEvent(int changes) + { + // + int count = ArraySize(mPositionsChangedEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnPositionsChanged iHandler = mPositionsChangedEventHandlers[i]; + iHandler(changes); + } + } + + // + // TPSL ... + + // + void NotifyStopLossEvent(const XDeal &deal) + { + // + int count = ArraySize(mStopLossEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnStopLoss iHandler = mStopLossEventHandlers[i]; + iHandler(deal); + } + } + + // + void NotifyTakeProfitEvent(const XDeal &deal) + { + // + int count = ArraySize(mTakeProfitEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnTakeProfit iHandler = mTakeProfitEventHandlers[i]; + iHandler(deal); + } + } + +private: + // + // using deviation, it must be in Point ... + int mSlippage; + + // + // using magic number ... + ulong mMagicNumber; + + // + // using CTrade instance ... + XSCTradeBase mTrader; + + // + // Deals Info ... + CDealInfo mDealInfo; + + // + // Order Info ... + COrderInfo mOrderInfo; + + // + // using PositionInfo instance ... + CPositionInfo mPositionInfo; + + // + // ADDITIONAL Data ... + + // + string mPeriodPrefix; + + // + // START Trade Processing ... + // + + // + int mDaysForRead; + + // + // set the limits of the trade history on the global scope ... + + // + // // start date for trade history in cache ... + datetime mStartDate; + + // + // end date for trade history in cache ... + datetime mEndDate; + + // + // global OnTrade counters ... + + // + // number of active orders ... + int mOrdersCount; + + // + // number of open positions ... + int mPositionsCount; + + // + // number of deals in the trade history cache ... + int mDealsCount; + + // + // number of orders in the trade history cache ... + int mHistoryOrdersCount; + + // + // flag of counter relevance ... + bool mScanStarted; + + // + // Check Statrt Date In Trade History ... + void CheckStartDateInTradeHistory() + { + // + // initial interval, if we were to start working right now .. + datetime currStart = TimeCurrent() - (mDaysForRead * PeriodSeconds(PERIOD_D1)); + + // + // make sure that the start limit of the trade history has not gone + // more than 1 day over the intended date ... + if (currStart - mStartDate > PeriodSeconds(PERIOD_D1)) + { + // + // correct the start date of history to be loaded in the cache ... + mStartDate = currStart; + + // + // now reload the trade history for the updated interval ... + HistorySelect(mStartDate, mEndDate); + + // + // correct the deal and order counters in history for further comparison + mHistoryOrdersCount = HistoryOrdersTotal(); + mDealsCount = HistoryDealsTotal(); + } + } + + // + // Process On Trade Context ... + void ProcessOnTradeContext( + XOnTradeHandlerState &result // Hold's Result + ) + { + // + mEndDate = TimeCurrent(); + + // + ResetLastError(); + + // + // download trading history from the specified interval to the program cache ... + bool selected = HistorySelect(mStartDate, mEndDate); + if (!selected) + { + return; + } + + // + // get the current values ... + int currOrders = OrdersTotal(); + int currPositions = PositionsTotal(); + int currDeals = HistoryDealsTotal(); + int currHistoryOrders = HistoryOrdersTotal(); + + // + // Orders ... + // check if the number of active orders has been changed ... + if (currOrders != mOrdersCount) + { + // + // number of active orders has been changed ... + result.hasNewOrder = true; + result.newOrders = currOrders - mOrdersCount; + + // + // update the value ... + mOrdersCount = currOrders; + } + + // + // Positions ... + // changes in the number of open positions ... + if (currPositions != mPositionsCount) + { + // + // number of open positions has been changed ... + result.hasNewPosition = true; + result.newPositions = currPositions - mPositionsCount; + + // + // update the value ... + mPositionsCount = currPositions; + } + + // + // Deals ... + // changes in the number of deals in the trade history cache ... + if (currDeals != mDealsCount) + { + // + // number of deals in the trade history cache has been changed ... + result.hasNewDeal = true; + result.newDeals = currDeals - mDealsCount; + + // + // update the value ... + mDealsCount = currDeals; + } + + // + // History Orders ... + // changes in the number of history orders in the trade history cache ... + if (currHistoryOrders != mHistoryOrdersCount) + { + // + // number of history orders in the trade history cache has been changed ... + result.hasNewHistoryOrder = true; + result.newHistoryOrders = currHistoryOrders - mHistoryOrdersCount; + + // + // update the value ... + mHistoryOrdersCount = currHistoryOrders; + } + + // + // checking if it is necessary to change the limits of the trade history to be requested in cache ... + CheckStartDateInTradeHistory(); + } + + // + // Reset On Trade Scanner Context ... + void ResetOnTradeContext() + { + // + mEndDate = TimeCurrent(); + mStartDate = mEndDate - (mDaysForRead * PeriodSeconds(PERIOD_D1)); + } + + // + // Initial Context Of Trade Scanner ... + void InitOnTradeContext() + { + // + ResetLastError(); + + // + mOrdersCount = OrdersTotal(); + mPositionsCount = PositionsTotal(); + + // + // load history ... + bool selected = HistorySelect(mStartDate, mEndDate); + if (!selected) + { + return; + } + + // + // get the current value ... + mDealsCount = HistoryDealsTotal(); + mHistoryOrdersCount = HistoryOrdersTotal(); + + // + mScanStarted = true; + } + + // + // Deals Changed Event Handlers ... + TOnDealsChanged mDealsChangedEventHandlers[]; + + // + // Orders Changed Event Handlers ... + TOnOrdersChanged mOrdersChangedEventHandlers[]; + + // + // Positions Changed Event Handlers ... + TOnPositionsChanged mPositionsChangedEventHandlers[]; + + // + // Trade State Changed Event Handlers ... + TOnTradeStateChanged mTradeStateChangedEventHandlers[]; + + // + // TPSL ... + TOnStopLoss mStopLossEventHandlers[]; + TOnTakeProfit mTakeProfitEventHandlers[]; + + // + // END Trade Processing ... + // +}; + +// +// START Usefull Functions ... +// + +// +// Add Specific XPosition to Specified Array ... +void Add( + XDeal &item, + XDeal &buffer[]) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + XOrder &item, + XOrder &buffer[]) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + XPosition &item, + XPosition &buffer[]) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} + +// +// Clear All Items Inside Array ... +void Clean(XDeal &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void Clean(XOrder &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void Clean(XPosition &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} + +// +// Generate Identifier Tag ... +string GenerateTag(XSignal &info) +{ + // + string result = ""; + + // + result = info.symbol + "," + ToString(info.period); + + // + return result; +} + +// +// Convert Position to Signal ... +XSignal ToSignalInfo( + XPosition &position) +{ + // + XSignal result; + + // + result.tp = position.tp; + result.sl = position.sl; + result.type = position.type; + result.entry = position.entry; + result.symbol = position.symbol; + result.period = position.period; + result.volume = position.volume; + + // + return result; +} + +// +// AGE Calculations ... +// + +// +// Retrieve a Position Age ... +int GetAge( + XPosition &position, // Selected Position ... + ENUM_TIMEFRAMES period = NULL // Dest Time Frame ... +) +{ + // + int result = -1; + + // + if (period == NULL) + { + period = _Period; + } + + // + result = iBarShift( + position.symbol, + period, + position.openAt); + + // + return result; +} + +// +// Retrieve an Order Age ... +int GetAge( + XOrder &order, // Selected Order ... + ENUM_TIMEFRAMES period = NULL // Dest Time Frame ... +) +{ + // + int result = -1; + + // + if (period == NULL) + { + period = _Period; + } + + // + result = iBarShift( + order.smybol, + period, + order.setupAt); + + // + return result; +} + +// +// Retrieve a Deal Age ... +int GetAge( + XDeal &deal, // Selected Deal ... + ENUM_TIMEFRAMES period = NULL // Dest Time Frame ... +) +{ + // + int result = -1; + + // + if (period == NULL) + { + period = _Period; + } + + // + result = iBarShift( + deal.symbol, + period, + deal.time); + + // + return result; +} + +// +// OLDEST Detection ... + +// +// Get Oldest Deal ... +int GetOldest( + XDeal &item, // Hold Result ... + XDeal &items[] // Source Array ... +) +{ + // + int result = 0; + + // + int itemsCount = ArraySize(items); + if (itemsCount <= 0) + { + return result; + } + + // + int tmpAge = 0; + XDeal tmpItem; + for (int i = 0; i < itemsCount; i++) + { + // + XDeal iItem = items[i]; + + // + int iAge = GetAge(iItem); + if (iAge > 0 && + (tmpAge == 0 || tmpAge < iAge)) + { + // + tmpAge = iAge; + tmpItem = iItem; + } + } + + // + if (tmpAge > 0) + { + // + result = tmpAge; + item = tmpItem; + } + + // + return result; +} + +// +// Get Oldest Order ... +int GetOldest( + XOrder &item, // Hold Result ... + XOrder &items[] // Source Array ... +) +{ + // + int result = 0; + + // + int itemsCount = ArraySize(items); + if (itemsCount <= 0) + { + return result; + } + + // + int tmpAge = 0; + XOrder tmpItem; + for (int i = 0; i < itemsCount; i++) + { + // + XOrder iItem = items[i]; + + // + int iAge = GetAge(iItem); + if (iAge > 0 && + (tmpAge == 0 || tmpAge < iAge)) + { + // + tmpAge = iAge; + tmpItem = iItem; + } + } + + // + if (tmpAge > 0) + { + // + result = tmpAge; + item = tmpItem; + } + + // + return result; +} + +// +// Get Oldes Position ... +int GetOldest( + XPosition &item, // Hold Result ... + XPosition &items[] // Source Array ... +) +{ + // + int result = 0; + + // + int itemsCount = ArraySize(items); + if (itemsCount <= 0) + { + return result; + } + + // + int tmpAge = 0; + XPosition tmpItem; + for (int i = 0; i < itemsCount; i++) + { + // + XPosition iItem = items[i]; + + // + int iAge = GetAge(iItem); + if (iAge > 0 && + (tmpAge == 0 || tmpAge < iAge)) + { + // + tmpAge = iAge; + tmpItem = iItem; + } + } + + // + if (tmpAge > 0) + { + // + result = tmpAge; + item = tmpItem; + } + + // + return result; +} + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Experts/x-saherelm.xea.ex5 b/MQLTestWorkspace/X121/Old/Experts/x-saherelm.xea.ex5 new file mode 100644 index 0000000..5ff7473 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Experts/x-saherelm.xea.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Experts/x-saherelm.xea.mq5 b/MQLTestWorkspace/X121/Old/Experts/x-saherelm.xea.mq5 new file mode 100644 index 0000000..1d8522b --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Experts/x-saherelm.xea.mq5 @@ -0,0 +1,378 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Expert Advisor +// ---------------------------------------- +// Name: X121EA +// Description: this is an expert controller +// advisors which provides a mechanism for use them ... +// +// +// 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 X121EA" +#property strict + +// +// START Definitions ... +// + +// +#define ShortName "X121EA" + +// +// END Definitions ... +// + +// +// START Inputs ... +// + +// +// EA ... +input group "Common"; +input bool xEAEnable = true; // Enable EA +input int xEASlippage = 10; // Slippgae +input ulong xEAMagicNumber = 1604056; // Magic Number + +// +// Providers ... +input group "Providers"; +input bool xEAUseCurrentConfig = true; // Use Only Current Config +input string xEAProvidersConfiguration = ""; // Providers Configuration +input string xEADefaultSignalProviders = "X786,X92,X110,X121,X128"; // Default Allowed Signal Providers + +// +// Signals ... +input group "Signals"; +input bool xEAEnableLongs = true; // Enable Long Trades +input bool xEAEnableShorts = true; // Enable Short Trades + +// +// Risk Management ... +input group "Risk Management"; +input int xEAMaxOpenPositions = 15; // Max Allowed Open Trades +input double xEAMinRiskAmountPerTrade = 0.001; // Min Risk Amount Per Trade +input double xEAMaxAllowedDrawDownFactor = 0.001; // Max Allowed Drawdown Factor + +// +// Alerts ... +input group "Alerts"; +input bool xEAEnableAlerts = true; // Enable Events Alert +input bool xEAEnableHourlyAlerts = false; // Send Alert on each new Hour +input bool xEAEnableDailyAlerts = false; // Send Alert on each new Day +input bool xEAEnableWeeklyAlerts = false; // Send Alert on each new Week +input bool xEAEnableMonthlyAlerts = false; // Send Alert on each new Month + +// +// END Inputs ... +// + +// +// START Including Providers ... +// + +// +// Logger Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Classes/x-saherelm.x121.xea.class.mq5" + +// +// END Including Providers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +XSCX121EA *mX121EA; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + logTag = ShortName; + drawPrefix = logTag; + alertPrefix = logTag; + + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + bool isInit = InitEAInstance(); + if (!isInit) + { + return INIT_FAILED; + } + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // De Initialize XEA Providers ... + delete mX121EA; +} + +// +// On Tick Handler ... +void OnTick() +{ + // + // Prevent Going Forward if user Disable it ... + if (xEAEnable) + { + mX121EA.OnTick(); + } +} + +// +// Handle Trade Events ... +void OnTrade() +{ + mX121EA.OnTrade(); +} + +// +// Handle Signal Event ... +void OnSignalConditionsRecieved(X121MarketConditions &info) +{ +} + +// +// Handle StopLoss Event ... +void OnStopLossTriggered(const XDeal &deal) +{ +} + +// +// Handle TakeProfit Event ... +void OnTakeProfitTriggered(const XDeal &deal) +{ +} + +// +// Handle Deals Changed Event ... +void OnDealsChangedHandler(int count) +{ +} + +// +// Handle Order Changed Event ... +void OnOrdersChangedHandler(int count) +{ +} + +// +// Handle Position Changed Event ... +void OnPositionsChangedHandler(int count) +{ +} + +// +// Handle Trade State Changed ... +void OnTradeStateChangedHandler(const XOnTradeHandlerState &state) +{ +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + // Validate Args ... + result = + // + xEASlippage > 0 && + xEAMagicNumber > 0 && + xEAMinRiskAmountPerTrade > 0 && + StringLen(xEADefaultSignalProviders) > 0 + // + // TODO: add new validations here ... + // + ; + + // + // Validate Providers ... + if (result) + { + // + string providers[]; + SplitContent( + providers, + xEADefaultSignalProviders); + + // + int providersCount = ArraySize(providers); + if (providersCount <= 0) + { + // + result = false; + return result; + } + + // + string allProviders[]; + GetAllProviders(allProviders); + + // + bool hasError = false; + for (int i = 0; i < providersCount; i++) + { + // + string iProvider = providers[i]; + if (!Contains(iProvider, allProviders)) + { + // + hasError = true; + break; + } + } + + // + if (hasError) + { + // + result = false; + return result; + } + } + + // + // Logging State ... + string message = "Validation of (" + logTag + ") Inputs " + (result ? "Succeeded" : "Failed") + " ..."; + LogMessage(message); + + // + return result; +} + +// +// Initialize X121EA Class Instances ... +bool InitEAInstance() +{ + // + bool result = false; + + // + X121SignalProvider providers[]; + + // + // Validatie Providers Configuration ... + if (xEAUseCurrentConfig) + { + // + // Here we Ignore xEAProvidersConfiguration ... + // Have to Create a Default Provider Structure and Attached it to X121EA Instance ... + X121SignalProvider provider; + + // + provider.symbol = _Symbol; + provider.period = _Period; + provider.riskAmount = xEAMinRiskAmountPerTrade; + + // + string signalProviders[]; + SplitContent( + signalProviders, + xEADefaultSignalProviders); + + // + Copy( + signalProviders, + provider.providers); + + // + // Now add Default Provider to Providers Array ... + Add( + provider, + providers); + } + else + { + // + // TODO: Here we must Implement all mechanism to Extract Provider Configurations and + // Add them one by one to XEA Instance ... + } + + // + mX121EA = new XSCX121EA( + _Symbol, + _Period, + xEAMagicNumber, + xEASlippage, + OnStopLossTriggered, + OnTakeProfitTriggered, + OnDealsChangedHandler, + OnOrdersChangedHandler, + OnPositionsChangedHandler, + OnTradeStateChangedHandler, + OnSignalConditionsRecieved); + + // + mX121EA.EnableLongs(xEAEnableLongs); + mX121EA.EnableShorts(xEAEnableShorts); + mX121EA.MaxAllowedPositions(xEAMaxOpenPositions); + mX121EA.MaxAllowedDrawDownFactor(xEAMaxAllowedDrawDownFactor); + + // + // Attach Providers to EA Instance ... + int providersCount = ArraySize(providers); + int addedProviders = mX121EA.AddProviders(providers); + result = addedProviders == providersCount; + + // + return result; +} +// +// END Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xama.helper.class.ex5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xama.helper.class.ex5 new file mode 100644 index 0000000..a4afc54 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xama.helper.class.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xama.helper.class.mq5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xama.helper.class.mq5 new file mode 100644 index 0000000..ca80be4 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xama.helper.class.mq5 @@ -0,0 +1,446 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXAMAHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// Inputs ... +struct XAMAInputs +{ + // + // Makret ... + int length; // Length + int fastEMA; // Fast EMA Length + int slowEMA; // Slow EMA Length + int maShift; // Shift + ENUM_APPLIED_PRICE appliedTo; // Applied To + + // + // Presentation ... + bool showLine; // Show Line +}; + +// +// Index of Lines ... +enum ENUM_XAMA_BUFFERS +{ + // + // Main Requirements ... + XAMA_LINE = 0, + XAMA_STATE_LINE = 1, +}; + +// +// XAMA Indicator States ... +enum ENUM_XAMA_STATES +{ + X_XAMA_BULLISH = 0, + X_XAMA_BEARISH = 2, + X_XAMA_NEUTURAL = 1, +}; + +// +// Retrieve Info Model ... +struct XAMAInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double value; + + // + double values[]; + double states[]; + + // + // State ... + ENUM_XAMA_STATES state; + + // + // Conditions ... + + // + // Detect Trend is Bullish or not ... + bool isBullish; + + // + // Detect Trend is Switched to Bullish Or not ... + bool isSwitchedBullish; + + // + // Detect Trend is Bearish or not ... + bool isBearish; + + // + // Detect Trend is Switched to Bearish Or not ... + bool isSwitchedBearish; + + // + // Detect Trend is Neutural or not ... + bool isNeutural; + + // + // Detect Trend is Switched to Neutural Or not ... + bool isSwitchedNeutural; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXAMAHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double valueBuffer[]; + double stateBuffer[]; + + // + // Constructor ... + void XSCXAMAHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXAMAHelper() + { + } + + // + // START Properties ... + // + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XAMA" + GetTagPrefix(); + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = mLength; + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Args ... + result = + // + (mLength >= 2) + // + ; + if (!result) + { + return false; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xama", + // + // Inputs ... + // + // Makret ... + "", + // + // Length ... + mLength, + // + // Fast EMA Length ... + mFastEMA, + // + // Slow EMA Length ... + mSlowEMA, + // + // Shift ... + mMaShift, + // + // Applied To ... + mAppliedTo, + // + // Presentation ... + "", + // + // Show Line ... + mShowLine + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XAMAInputs GetConfig() + { + // + XAMAInputs result; + + // + result.length = mLength; + result.fastEMA = mFastEMA; + result.slowEMA = mSlowEMA; + result.maShift = mMaShift; + result.appliedTo = mAppliedTo; + result.showLine = mShowLine; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XAMAInputs &config) + { + // + bool result = false; + + // + mLength = config.length; + mFastEMA = config.fastEMA; + mSlowEMA = config.slowEMA; + mMaShift = config.maShift; + mAppliedTo = config.appliedTo; + mShowLine = config.showLine; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + // + // VALUE ... + ArraySetAsSeries(valueBuffer, true); + CopyBuffer( + mHandler, + XAMA_LINE, + barIndex, + mLoopbackBars, + valueBuffer); + + // + // STATE ... + ArraySetAsSeries(stateBuffer, true); + CopyBuffer( + mHandler, + XAMA_STATE_LINE, + barIndex, + mLoopbackBars, + stateBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XAMAInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XAMAInfo result; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + result.value = valueBuffer[barIndex]; + + // + Copy( + valueBuffer, + result.values); + + // + Copy( + stateBuffer, + result.states); + + // + ENUM_XAMA_STATES state = (ENUM_XAMA_STATES)stateBuffer[barIndex]; + ENUM_XAMA_STATES prevState = (ENUM_XAMA_STATES)stateBuffer[barIndex + 1]; + result.state = state; + + // + result.isBullish = state == X_XAMA_BULLISH; + result.isBearish = state == X_XAMA_BEARISH; + result.isNeutural = state == X_XAMA_NEUTURAL; + + // + result.isSwitchedBullish = + state == X_XAMA_BULLISH && prevState != X_XAMA_BULLISH; + result.isSwitchedBearish = + state == X_XAMA_BEARISH && prevState != X_XAMA_BEARISH; + result.isSwitchedNeutural = + state == X_XAMA_NEUTURAL && prevState != X_XAMA_NEUTURAL; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Market ... + // + // Length ... + int mLength; + // + // Fast EMA Length ... + int mFastEMA; + // + // Slow EMA Length ... + int mSlowEMA; + // + // Shift ... + int mMaShift; + // + // Applied To ... + ENUM_APPLIED_PRICE mAppliedTo; + // + // Presentation ... + // + // Show Line ... + bool mShowLine; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xcc.helper.class.ex5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xcc.helper.class.ex5 new file mode 100644 index 0000000..5023f40 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xcc.helper.class.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xcc.helper.class.mq5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xcc.helper.class.mq5 new file mode 100644 index 0000000..414a604 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xcc.helper.class.mq5 @@ -0,0 +1,293 @@ +/////////////////////////////////////////////////////// +// +// 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 + +// +// START Definitions ... +// + +// +struct XCCInputs +{ + // + // Chart Style ... + color upColor; // Up Color + color downColor; // Down Color + color lineColor; // Line mode and Doji candlestick Color + color bearishColor; // Bullish Color + color bullishColor; // Bearish Color + color volumesColor; // Volumes Color + + // + // Presentation ... + bool showCandles; // Show Candles +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXCCHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Constructor ... + void XSCXCCHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXCCHelper() + { + } + + // + // START Properties ... + // + + // + // Show Candles ... + bool ShowCandles( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowCandles == show) + { + return true; + } + + // + mShowCandles = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XCC" + GetTagPrefix(); + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) {} + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = 2; + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xcc", + // + // Inputs ... + // + // Chart Style ... + "", + // + // Up Color ... + mUpColor, + // + // Down Color ... + mDownColor, + // + // Line mode and Doji candlestick Color ... + mLineColor, + // + // Bullish Color ... + mBearishColor, + // + // Bearish Color ... + mBullishColor, + // + // Volumes Color ... + mVolumesColor, + // + // Presentation ... + "", + // + // Show Candles ... + mShowCandles + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XCCInputs GetConfig() + { + // + XCCInputs result; + + // + result.upColor = mUpColor; + result.downColor = mDownColor; + result.lineColor = mLineColor; + result.bearishColor = mBearishColor; + result.bullishColor = mBullishColor; + result.volumesColor = mVolumesColor; + result.showCandles = mShowCandles; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XCCInputs &config) + { + // + bool result = false; + + // + mUpColor = config.upColor; + mDownColor = config.downColor; + mLineColor = config.lineColor; + mBearishColor = config.bearishColor; + mBullishColor = config.bullishColor; + mVolumesColor = config.volumesColor; + mShowCandles = config.showCandles; + + // + result = Init(); + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Chart Style ... + // + // Up Color ... + color mUpColor; + // + // Down Color ... + color mDownColor; + // + // Line mode and Doji candlestick Color ... + color mLineColor; + // + // Bullish Color ... + color mBearishColor; + // + // Bearish Color ... + color mBullishColor; + // + // Volumes Color ... + color mVolumesColor; + + // + // Presentation ... + // + // Show Candles ... + bool mShowCandles; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xche.helper.class.ex5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xche.helper.class.ex5 new file mode 100644 index 0000000..ede8c26 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xche.helper.class.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xche.helper.class.mq5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xche.helper.class.mq5 new file mode 100644 index 0000000..1e917ab --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xche.helper.class.mq5 @@ -0,0 +1,612 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXCHEHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// Inputs ... +struct XCHEInputs +{ + // + // Market ... + int length; // Length + int loopback; // Loopback + double multiplier1; // 1st Multiplier + double multiplier2; // 2nd Multiplier + + // + // Calculation ... + ENUM_APPLIED_PRICE upAppliedTo; // Up Zone Applied to + ENUM_APPLIED_PRICE downAppliedTo; // Down Zone Applied to + + // + // Presentation ... + bool showLongExit1Line; // Show 1st Long Exit + bool showShortExit1Line; // Show 1st Short Exit + bool showLongExit2Line; // Show 2st Long Exit + bool showShortExit2Line; // Show 2st Short Exit +}; + +// +// Index of Lines ... +enum ENUM_XCHE_BUFFERS +{ + // + // Main Requirements ... + XCHE_1ST_LONG_EXIT_LINE = 0, + XCHE_1ST_SHORT_EXIT_LINE = 1, + XCHE_2ND_LONG_EXIT_LINE = 2, + XCHE_2ND_SHORT_EXIT_LINE = 3, +}; + +// +// Retrieve Info Model ... +struct XCHEInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double longExit1; + double longExit2; + double shortExit1; + double shortExit2; + + // + double le1[]; + double le2[]; + + // + double se1[]; + double se2[]; + + // + // Conditions ... + // + bool isLongExit1Start; + bool isShortExit1Start; + + // + bool isLongExit2Start; + bool isShortExit2Start; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXCHEHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double longExit1Buffer[]; + double shortExit1Buffer[]; + double longExit2Buffer[]; + double shortExit2Buffer[]; + + // + // Constructor ... + void XSCXCHEHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXCHEHelper() + { + } + + // + // START Properties ... + // + + // + // Show 1st Long Exit ... + bool ShowLongExit1Line( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowLongExit1Line == show) + { + return true; + } + + // + mShowLongExit1Line = show; + result = Init(); + + // + return result; + } + + // + // Show 1st Short Exit ... + bool ShowShortExit1Line( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowShortExit1Line == show) + { + return true; + } + + // + mShowShortExit1Line = show; + result = Init(); + + // + return result; + } + + // + // Show 2st Long Exit ... + bool ShowLongExit2Line( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowLongExit2Line == show) + { + return true; + } + + // + mShowLongExit2Line = show; + result = Init(); + + // + return result; + } + + // + // Show 2st Short Exit ... + bool ShowShortExit2Line( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowShortExit1Line == show) + { + return true; + } + + // + mShowShortExit1Line = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XCHE" + GetTagPrefix(); + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = MathMax(mLength, mLoopback); + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Inputs ... + // + // + result = + mLength >= 9 && + mLoopback >= 0; + if (!result) + { + return result; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xche", + // + // Inputs ... + // + // Market ... + "", + // + // Length ... + mLength, + // + // Loopback ... + mLoopback, + // + // 1st Multiplier ... + mMultiplier1, + // + // 2nd Multiplier ... + mMultiplier2, + // + // Calculation ... + "", + // + // Up Zone Applied to ... + mUpAppliedTo, + // + // Down Zone Applied to ... + mDownAppliedTo, + // + // Presentation ... + "", + // + // Show 1st Long Exit ... + mShowLongExit1Line, + // + // Show 1st Short Exit ... + mShowShortExit1Line, + // + // Show 2st Long Exit ... + mShowLongExit2Line, + // + // Show 2st Short Exit ... + mShowShortExit2Line + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XCHEInputs GetConfig() + { + // + XCHEInputs result; + + // + result.length = mLength; + result.loopback = mLoopback; + result.multiplier1 = mMultiplier1; + result.multiplier2 = mMultiplier2; + result.upAppliedTo = mUpAppliedTo; + result.downAppliedTo = mDownAppliedTo; + result.showLongExit1Line = mShowLongExit1Line; + result.showShortExit1Line = mShowShortExit1Line; + result.showLongExit2Line = mShowLongExit2Line; + result.showShortExit2Line = mShowShortExit2Line; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XCHEInputs &config) + { + // + bool result = false; + + // + mLength = config.length; + mLoopback = config.loopback; + mMultiplier1 = config.multiplier1; + mMultiplier2 = config.multiplier2; + mUpAppliedTo = config.upAppliedTo; + mDownAppliedTo = config.downAppliedTo; + mShowLongExit1Line = config.showLongExit1Line; + mShowShortExit1Line = config.showShortExit1Line; + mShowLongExit2Line = config.showLongExit2Line; + mShowShortExit2Line = config.showShortExit2Line; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + // + // LEVEL 1 .. + + // + // LONG Exit ... + ArraySetAsSeries(longExit1Buffer, true); + CopyBuffer( + mHandler, + XCHE_1ST_LONG_EXIT_LINE, + barIndex, + mLoopbackBars, + longExit1Buffer); + + // + // SHORT Exit ... + ArraySetAsSeries(shortExit1Buffer, true); + CopyBuffer( + mHandler, + XCHE_1ST_SHORT_EXIT_LINE, + barIndex, + mLoopbackBars, + shortExit1Buffer); + + // + // LEVEL 2 .. + + // + // LONG Exit ... + ArraySetAsSeries(longExit2Buffer, true); + CopyBuffer( + mHandler, + XCHE_2ND_LONG_EXIT_LINE, + barIndex, + mLoopbackBars, + longExit2Buffer); + + // + // SHORT Exit ... + ArraySetAsSeries(shortExit2Buffer, true); + CopyBuffer( + mHandler, + XCHE_2ND_SHORT_EXIT_LINE, + barIndex, + mLoopbackBars, + shortExit2Buffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XCHEInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XCHEInfo result; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + double longExit1 = longExit1Buffer[barIndex]; + double longExit1Prev = longExit1Buffer[barIndex + 1]; + double shortExit1 = shortExit1Buffer[barIndex]; + double shortExit1Prev = shortExit1Buffer[barIndex + 1]; + + // + double longExit2 = longExit2Buffer[barIndex]; + double longExit2Prev = longExit2Buffer[barIndex + 1]; + double shortExit2 = shortExit2Buffer[barIndex]; + double shortExit2Prev = shortExit2Buffer[barIndex + 1]; + + // + Copy( + longExit1Buffer, + result.le1); + Copy( + longExit2Buffer, + result.le2); + + // + Copy( + shortExit1Buffer, + result.se1); + Copy( + shortExit2Buffer, + result.se2); + + // + result.longExit1 = longExit1; + result.shortExit1 = shortExit1; + result.longExit2 = longExit2; + result.shortExit2 = shortExit2; + + // + result.isLongExit1Start = + longExit1 != EMPTY_VALUE && + longExit1Prev == EMPTY_VALUE; + + // + result.isShortExit1Start = + shortExit1 != EMPTY_VALUE && + shortExit1Prev == EMPTY_VALUE; + + // + result.isLongExit2Start = + longExit2 != EMPTY_VALUE && + longExit2Prev == EMPTY_VALUE; + + // + result.isShortExit2Start = + shortExit2 != EMPTY_VALUE && + shortExit2Prev == EMPTY_VALUE; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Market ... + // + // Length ... + int mLength; + // + // Loopback ... + int mLoopback; + // + // 1st Multiplier ... + double mMultiplier1; + // + // 2nd Multiplier ... + double mMultiplier2; + // + // Calculation ... + // + // Up Zone Applied to ... + ENUM_APPLIED_PRICE mUpAppliedTo; + // + // Down Zone Applied to ... + ENUM_APPLIED_PRICE mDownAppliedTo; + // + // Presentation ... + // + // Show 1st Long Exit ... + bool mShowLongExit1Line; + // + // Show 1st Short Exit ... + bool mShowShortExit1Line; + // + // Show 2st Long Exit ... + bool mShowLongExit2Line; + // + // Show 2st Short Exit ... + bool mShowShortExit2Line; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xct.helper.class.ex5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xct.helper.class.ex5 new file mode 100644 index 0000000..628a31d Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xct.helper.class.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xct.helper.class.mq5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xct.helper.class.mq5 new file mode 100644 index 0000000..c448ef7 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xct.helper.class.mq5 @@ -0,0 +1,248 @@ +/////////////////////////////////////////////////////// +// +// 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 + +// +// START Definitions ... +// + +// +struct XCTInputs +{ + // + color clr; + ENUM_BASE_CORNER corner; + + // + // Presentation ... + bool showCandleTime; // Show Candle Time +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXCTHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Constructor ... + void XSCXCTHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXCTHelper() + { + } + + // + // START Properties ... + // + + // + // Show Candles ... + bool ShowCandleTime( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowCandleTime == show) + { + return true; + } + + // + mShowCandleTime = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XCT" + GetTagPrefix(); + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = 1; + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xct", + // + // Inputs ... + mClr, + mCorner, + // + // Presentation ... + "", + mShowCandleTime + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XCTInputs GetConfig() + { + // + XCTInputs result; + + // + result.clr = mClr; + result.corner = mCorner; + result.showCandleTime = mShowCandleTime; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XCTInputs &config) + { + // + bool result = false; + + // + mClr = config.clr; + mCorner = config.corner; + mShowCandleTime = config.showCandleTime; + + // + result = Init(); + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + + // + // Text Color ... + color mClr; + // + // Text Position ... + ENUM_BASE_CORNER mCorner; + + // + // Presentation ... + // + // Show Candles ... + bool mShowCandleTime; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xdema.helper.class.ex5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xdema.helper.class.ex5 new file mode 100644 index 0000000..bd77ef2 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xdema.helper.class.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xdema.helper.class.mq5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xdema.helper.class.mq5 new file mode 100644 index 0000000..2806bc2 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xdema.helper.class.mq5 @@ -0,0 +1,470 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXDEMAHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// Inputs ... +struct XDEMAInputs +{ + // + // Makret ... + int length; // Length + int shift; // Shift + + // + // Presentation ... + bool showDema; // Show Dema + bool showEMA; // Show EMA + bool showEMAOfEMA; // Show EMA of EMA +}; + +// +// Index of Lines ... +enum ENUM_XDEMA_BUFFERS +{ + // + // Main Requirements ... + XDEMA_LINE = 0, + XDEMA_EMA_LINE = 2, + XDEMA_EMA_OF_EMA_LINE = 4, +}; + +// +// Retrieve Info Model ... +struct XDEMAInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double dema; + double ema; + double emaOfEma; + + // + double demas[]; + double emas[]; + double emaOfEMAs[]; + + // + // Conditions ... +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXDEMAHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double demaBuffer[]; + double emaBuffer[]; + double emaOfEMABuffer[]; + + // + // Constructor ... + void XSCXDEMAHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXDEMAHelper() + { + } + + // + // START Properties ... + // + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XDEMA" + GetTagPrefix(); + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = mLength; + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Args ... + result = + // + (mLength >= 2 && + mShift >= 0) + // + ; + if (!result) + { + return false; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xdema", + // + // Inputs ... + // + // Makret ... + "", + // + // Length ... + mLength, + // + // Shift ... + mShift, + // + // Presentation ... + "", + // + // Show Dema ... + mShowDema, + // + // Show EMA ... + mShowEMA, + // + // Show EMA of EMA ... + mShowEMAOfEMA + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XDEMAInputs GetConfig() + { + // + XDEMAInputs result; + + // + result.length = mLength; + result.shift = mShift; + result.showDema = mShowDema; + result.showEMA = mShowEMA; + result.showEMAOfEMA = mShowEMAOfEMA; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XDEMAInputs &config) + { + // + bool result = false; + + // + mLength = config.length; + mShift = config.shift; + mShowDema = config.showDema; + mShowEMA = config.showEMA; + mShowEMAOfEMA = config.showEMAOfEMA; + + // + result = Init(); + + // + return result; + } + + // + // Show Dema ... + bool ShowDema( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowDema == show) + { + return true; + } + + // + mShowDema = show; + result = Init(); + + // + return result; + } + + // + // Show EMA ... + bool ShowEMA( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowEMA == show) + { + return true; + } + + // + mShowEMA = show; + result = Init(); + + // + return result; + } + + // + // Show EMA of EMA ... + bool ShowEMAOfEMA( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowEMAOfEMA == show) + { + return true; + } + + // + mShowEMAOfEMA = show; + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + // + // DEMA ... + ArraySetAsSeries(demaBuffer, true); + CopyBuffer( + mHandler, + XDEMA_LINE, + barIndex, + mLoopbackBars, + demaBuffer); + + // + // EMA ... + ArraySetAsSeries(emaBuffer, true); + CopyBuffer( + mHandler, + XDEMA_EMA_LINE, + barIndex, + mLoopbackBars, + emaBuffer); + + // + // EMAOFEMA ... + ArraySetAsSeries(emaOfEMABuffer, true); + CopyBuffer( + mHandler, + XDEMA_EMA_OF_EMA_LINE, + barIndex, + mLoopbackBars, + emaOfEMABuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XDEMAInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XDEMAInfo result; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + result.ema = emaBuffer[barIndex]; + result.dema = demaBuffer[barIndex]; + result.emaOfEma = emaOfEMABuffer[barIndex]; + + // + Copy( + emaBuffer, + result.demas); + Copy( + demaBuffer, + result.emas); + Copy( + emaOfEMABuffer, + result.emaOfEMAs); + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Market ... + // + // Length ... + int mLength; + // + // Shift ... + int mShift; + // + // Presentation ... + // + // Show Dema ... + bool mShowDema; + // + // Show EMA ... + bool mShowEMA; + // + // Show EMA of EMA ... + bool mShowEMAOfEMA; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xfbb.helper.class.ex5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xfbb.helper.class.ex5 new file mode 100644 index 0000000..8e9751e Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xfbb.helper.class.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xfbb.helper.class.mq5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xfbb.helper.class.mq5 new file mode 100644 index 0000000..17bc30a --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xfbb.helper.class.mq5 @@ -0,0 +1,733 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXFBBHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// Inputs ... +struct XFBBInputs +{ + // + // Market ... + // + // Length ... + int length; + // + // Multiplier ... + double multiplier; + // + // Applied To ... + ENUM_APPLIED_PRICE appliedTo; + + // + // Presentation ... + // + // Show Base ... + bool showBase; + // + // Show Band ... + bool showBand; + // + // Show Golden Area ... + bool showGoldenArea; + // + // Show Other Levels ... + bool showOthers; +}; + +// +// Index of Lines ... +enum ENUM_XFBB_BUFFERS +{ + // + // Main Requirements ... + XFBB_BASE_LINE = 0, + XFBB_BASE_STATE_LINE = 1, + XFBB_UP_BAND_LINE = 13, + XFBB_DOWN_BAND_LINE = 24, + // + XFBB_UP_1_LINE = 2, + XFBB_UP_2_LINE = 4, + XFBB_UP_3_LINE = 6, + XFBB_UP_4_LINE = 8, + XFBB_UP_5_LINE = 10, + // + XFBB_DOWN_1_LINE = 14, + XFBB_DOWN_2_LINE = 16, + XFBB_DOWN_3_LINE = 18, + XFBB_DOWN_4_LINE = 20, + XFBB_DOWN_5_LINE = 22, +}; + +// +// Retrieve Info Model ... +struct XFBBInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double base; + double baseState; + + // + double upBand; + double downBand; + + // + double up1; + double up2; + double up3; + double up4; + double up5; + + // + double down1; + double down2; + double down3; + double down4; + double down5; + + // + double bases[]; + double baseStates[]; + double upBands[]; + double downBands[]; + double up1s[]; + double up2s[]; + double up3s[]; + double up4s[]; + double up5s[]; + double down1s[]; + double down2s[]; + double down3s[]; + double down4s[]; + double down5s[]; + + // + // Conditions ... +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXFBBHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double baseBuffer[]; + double baseStateBuffer[]; + double upBandBuffer[]; + double downBandBuffer[]; + double up1Buffer[]; + double up2Buffer[]; + double up3Buffer[]; + double up4Buffer[]; + double up5Buffer[]; + double down1Buffer[]; + double down2Buffer[]; + double down3Buffer[]; + double down4Buffer[]; + double down5Buffer[]; + + // + // Constructor ... + void XSCXFBBHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXFBBHelper() + { + } + + // + // START Properties ... + // + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XFBB" + GetTagPrefix(); + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = mLength; + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Args ... + result = + // + (mLength >= 2 && + mMultiplier >= 0) + // + ; + if (!result) + { + return false; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xfbb", + // + // Inputs ... + // + // Market ... + "", + // + // Length ... + mLength, + // + // Multiplier ... + mMultiplier, + // + // Applied To ... + mApliedTo, + // + // Presentation ... + "", + // + // Show Base ... + mShowBase, + // + // Show Band ... + mShowBand, + // + // Show Golden Area ... + mShowGoldenArea, + // + // Show Other Levels ... + mShowOthers + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XFBBInputs GetConfig() + { + // + XFBBInputs result; + + // + result.length = mLength; + result.multiplier = mMultiplier; + result.appliedTo = mApliedTo; + result.showBase = mShowBase; + result.showBand = mShowBand; + result.showGoldenArea = mShowGoldenArea; + result.showOthers = mShowOthers; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XFBBInputs &config) + { + // + bool result = false; + + // + mLength = config.length; + mMultiplier = config.multiplier; + mApliedTo = config.appliedTo; + mShowBase = config.showBase; + mShowBand = config.showBand; + mShowGoldenArea = config.showGoldenArea; + mShowOthers = config.showOthers; + + // + result = Init(); + + // + return result; + } + + // + // Show Base ... + bool ShowBase( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowBase == show) + { + return true; + } + + // + mShowBase = show; + result = Init(); + + // + return result; + } + + // + // Show Band ... + bool ShowBand( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowBand == show) + { + return true; + } + + // + mShowBand = show; + result = Init(); + + // + return result; + } + + // + // Show Golden Area ... + bool ShowGoldenArea( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowGoldenArea == show) + { + return true; + } + + // + mShowGoldenArea = show; + result = Init(); + + // + return result; + } + + // + // Show Other Levels ... + bool ShowOthers( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowOthers == show) + { + return true; + } + + // + mShowOthers = show; + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + // + // BASE ... + ArraySetAsSeries(baseBuffer, true); + CopyBuffer( + mHandler, + XFBB_BASE_LINE, + barIndex, + mLoopbackBars, + baseBuffer); + + // + // BASE STATE ... + ArraySetAsSeries(baseStateBuffer, true); + CopyBuffer( + mHandler, + XFBB_BASE_STATE_LINE, + barIndex, + mLoopbackBars, + baseStateBuffer); + + // + // UPBAND ... + ArraySetAsSeries(upBandBuffer, true); + CopyBuffer( + mHandler, + XFBB_UP_BAND_LINE, + barIndex, + mLoopbackBars, + upBandBuffer); + + // + // DOWNBAND ... + ArraySetAsSeries(downBandBuffer, true); + CopyBuffer( + mHandler, + XFBB_DOWN_BAND_LINE, + barIndex, + mLoopbackBars, + downBandBuffer); + + // + // UP 1 ... + ArraySetAsSeries(up1Buffer, true); + CopyBuffer( + mHandler, + XFBB_UP_1_LINE, + barIndex, + mLoopbackBars, + up1Buffer); + + // + // UP 2 ... + ArraySetAsSeries(up2Buffer, true); + CopyBuffer( + mHandler, + XFBB_UP_2_LINE, + barIndex, + mLoopbackBars, + up2Buffer); + + // + // UP 3 ... + ArraySetAsSeries(up3Buffer, true); + CopyBuffer( + mHandler, + XFBB_UP_3_LINE, + barIndex, + mLoopbackBars, + up3Buffer); + + // + // UP 4 ... + ArraySetAsSeries(up4Buffer, true); + CopyBuffer( + mHandler, + XFBB_UP_4_LINE, + barIndex, + mLoopbackBars, + up4Buffer); + + // + // UP 5 ... + ArraySetAsSeries(up5Buffer, true); + CopyBuffer( + mHandler, + XFBB_UP_5_LINE, + barIndex, + mLoopbackBars, + up5Buffer); + + // + // DOWN 1 ... + ArraySetAsSeries(down1Buffer, true); + CopyBuffer( + mHandler, + XFBB_DOWN_1_LINE, + barIndex, + mLoopbackBars, + down1Buffer); + + // + // DOWN 2 ... + ArraySetAsSeries(down2Buffer, true); + CopyBuffer( + mHandler, + XFBB_DOWN_2_LINE, + barIndex, + mLoopbackBars, + down2Buffer); + + // + // DOWN 3 ... + ArraySetAsSeries(down3Buffer, true); + CopyBuffer( + mHandler, + XFBB_DOWN_3_LINE, + barIndex, + mLoopbackBars, + down3Buffer); + + // + // DOWN 4 ... + ArraySetAsSeries(down4Buffer, true); + CopyBuffer( + mHandler, + XFBB_DOWN_4_LINE, + barIndex, + mLoopbackBars, + down4Buffer); + + // + // DOWN 5 ... + ArraySetAsSeries(down5Buffer, true); + CopyBuffer( + mHandler, + XFBB_DOWN_5_LINE, + barIndex, + mLoopbackBars, + down5Buffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XFBBInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XFBBInfo result; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + // values ... + result.base = baseBuffer[barIndex]; + result.baseState = baseStateBuffer[barIndex]; + result.upBand = upBandBuffer[barIndex]; + result.downBand = downBandBuffer[barIndex]; + result.up1 = up1Buffer[barIndex]; + result.up2 = up2Buffer[barIndex]; + result.up3 = up3Buffer[barIndex]; + result.up4 = up4Buffer[barIndex]; + result.up5 = up5Buffer[barIndex]; + result.down1 = down1Buffer[barIndex]; + result.down2 = down2Buffer[barIndex]; + result.down3 = down3Buffer[barIndex]; + result.down4 = down4Buffer[barIndex]; + result.down5 = down5Buffer[barIndex]; + + // + Copy( + baseBuffer, + result.bases); + Copy( + baseStateBuffer, + result.baseStates); + Copy( + upBandBuffer, + result.upBands); + Copy( + downBandBuffer, + result.downBands); + Copy( + up1Buffer, + result.up1s); + Copy( + up2Buffer, + result.up2s); + Copy( + up3Buffer, + result.up3s); + Copy( + up4Buffer, + result.up4s); + Copy( + up5Buffer, + result.up5s); + Copy( + down1Buffer, + result.down1s); + Copy( + down2Buffer, + result.down2s); + Copy( + down3Buffer, + result.down3s); + Copy( + down4Buffer, + result.down4s); + Copy( + down5Buffer, + result.down5s); + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Market ... + // + // Length ... + int mLength; + // + // Multiplier ... + double mMultiplier; + // + // Applied To ... + ENUM_APPLIED_PRICE mApliedTo; + + // + // Presentation ... + // + // Show Base ... + bool mShowBase; + // + // Show Band ... + bool mShowBand; + // + // Show Golden Area ... + bool mShowGoldenArea; + // + // Show Other Levels ... + bool mShowOthers; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xhk.helper.class.ex5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xhk.helper.class.ex5 new file mode 100644 index 0000000..5fccd57 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xhk.helper.class.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xhk.helper.class.mq5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xhk.helper.class.mq5 new file mode 100644 index 0000000..eeef329 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xhk.helper.class.mq5 @@ -0,0 +1,441 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXHKHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// Inputs ... +struct XHKInputs +{ + // + // Presentation ... + bool drawCandles; // Draw Hiken Ashi Candle + bool drawCandleLines; // Show HikenAshi Lines +}; + +// +// Index of Lines ... +enum ENUM_XHK_BUFFERS +{ + // + // Main Requirements ... + XHK_OPEN_LINE = 0, + XHK_HIGH_LINE = 1, + XHK_LOW_LINE = 2, + XHK_CLOSE_LINE = 3, +}; + +// +// Retrieve Info Model ... +struct XHKInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double open; + double high; + double low; + double close; + + // + double opens[]; + double highs[]; + double lows[]; + double closes[]; + + // + // Conditions ... + + // + // Detect Candle is Bullish or not ... + bool isBullish; + + // + // Detect Candle is Bearish or not ... + bool isBearish; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXHKHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double openBuffer[]; + double highBuffer[]; + double lowBuffer[]; + double closeBuffer[]; + + // + // Constructor ... + void XSCXHKHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + // + // Indicator Properties ... + // + // Presentation ... + // + // Draw Hiken Ashi Candle ... + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXHKHelper() + { + } + + // + // START Properties ... + // + + // + // Draw Candles ... + bool DrawCandles( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mDrawCandles == show) + { + return true; + } + + // + mDrawCandles = show; + result = Init(); + + // + return result; + } + + // + // Show HikenAshi Lines ... + bool DrawCandleLines( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mDrawCandleLines == show) + { + return true; + } + + // + mDrawCandleLines = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XHK" + GetTagPrefix(); + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = 2; + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xhk", + // + // Inputs ... + // + // Presentation ... + "", + // + // Draw Hiken Ashi Candle ... + mDrawCandles, + // + // Show HikenAshi Lines ... + mDrawCandleLines + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XHKInputs GetConfig() + { + // + XHKInputs result; + + // + result.drawCandles = mDrawCandles; + result.drawCandleLines = mDrawCandleLines; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XHKInputs &config) + { + // + bool result = false; + + // + mDrawCandles = config.drawCandles; + mDrawCandleLines = config.drawCandleLines; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + // + // OPEN ... + ArraySetAsSeries(openBuffer, true); + CopyBuffer( + mHandler, + XHK_OPEN_LINE, + barIndex, + mLoopbackBars, + openBuffer); + + // + // HIGH ... + ArraySetAsSeries(highBuffer, true); + CopyBuffer( + mHandler, + XHK_HIGH_LINE, + barIndex, + mLoopbackBars, + highBuffer); + + // + // LOW ... + ArraySetAsSeries(lowBuffer, true); + CopyBuffer( + mHandler, + XHK_LOW_LINE, + barIndex, + mLoopbackBars, + lowBuffer); + + // + // CLOSE ... + ArraySetAsSeries(closeBuffer, true); + CopyBuffer( + mHandler, + XHK_CLOSE_LINE, + barIndex, + mLoopbackBars, + closeBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XHKInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XHKInfo result; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + double open = openBuffer[barIndex]; + double high = highBuffer[barIndex]; + double low = lowBuffer[barIndex]; + double close = closeBuffer[barIndex]; + + // + result.open = open; + result.high = high; + result.low = low; + result.close = close; + + // + Copy( + openBuffer, + result.opens); + Copy( + highBuffer, + result.highs); + Copy( + lowBuffer, + result.lows); + Copy( + closeBuffer, + result.closes); + + // + result.isBullish = open < close; + result.isBearish = open >= close; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Presentation ... + // + // Draw Hiken Ashi Candle ... + bool mDrawCandles; + // + // Show HikenAshi Lines ... + bool mDrawCandleLines; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xhull.helper.class.ex5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xhull.helper.class.ex5 new file mode 100644 index 0000000..7d0b879 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xhull.helper.class.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xhull.helper.class.mq5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xhull.helper.class.mq5 new file mode 100644 index 0000000..fa73e73 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xhull.helper.class.mq5 @@ -0,0 +1,544 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXHULLHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// Inputs ... +struct XHULLInputs +{ + // + // Market ... + int length; // Length + double divisor; // Divisor (Speed) + + // + // Calculation ... + ENUM_APPLIED_PRICE upAppliedTo; // Up Zone Applied to + ENUM_APPLIED_PRICE downAppliedTo; // Down Zone Applied to + + // + // Presentation ... + bool showUpZone; // Show Up Zone + bool showDownZone; // Show Down Zone +}; + +// +// Index of Lines ... +enum ENUM_XHULL_BUFFERS +{ + // + // Main Requirements ... + XHULL_UP_ZONE_LINE = 0, + XHULL_UP_ZONE_STATE_LINE = 1, + XHULL_DOWN_ZONE_LINE = 2, + XHULL_DOWN_ZONE_STATE_LINE = 3, +}; + +// +// Hull States ... +enum XHULL_ZONE_STATES +{ + XHULL_STATE_NEUTURAL = 0, + XHULL_STATE_BULLISH = 1, + XHULL_STATE_BEARISH = 2 +}; + +// +// Retrieve Info Model ... +struct XHULLInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double up; + XHULL_ZONE_STATES upState; + double down; + XHULL_ZONE_STATES downState; + + // + double ups[]; + double upStates[]; + double downs[]; + double downStates[]; + + // + // Conditions ... + + // + bool isUpBullish; + bool isUpNeutural; + bool isUpBearish; + + // + bool isUpSwitchedToBullish; + bool isUpSwitchedToBearish; + bool isUpSwitchedToNeutural; + + // + bool isDownBullish; + bool isDownBearish; + bool isDownNeutural; + + // + bool isDownSwitchedToBullish; + bool isDownSwitchedToBearish; + bool isDownSwitchedToNeutural; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXHULLHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double upBuffer[]; + double upStateBuffer[]; + double downBuffer[]; + double downStateBuffer[]; + + // + // Constructor ... + void XSCXHULLHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXHULLHelper() + { + } + + // + // START Properties ... + // + + // + // Show Up Zone ... + bool ShowUpZone( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowUpZone == show) + { + return true; + } + + // + mShowUpZone = show; + result = Init(); + + // + return result; + } + + // + // Show Down Zone ... + bool ShowDownZone( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowDownZone == show) + { + return true; + } + + // + mShowDownZone = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XHULL" + GetTagPrefix(); + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + // + result = mLength; + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Inputs ... + // + result = + mLength >= 9 && + mDivisor >= 0.5; + if (!result) + { + return result; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xhull", + // + // Inputs ... + // + // Market ... + "", + // + // Length ... + mLength, + // + // Divisor (Speed) ... + mDivisor, + // + // Calculation ... + "", + // + // Up Zone Applied to ... + mUpAppliedTo, + // + // Down Zone Applied to ... + mDownAppliedTo, + // + // Presentation ... + "", + // + // Show Up Zone ... + mShowUpZone, + // + // Show Down Zone ... + mShowDownZone + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XHULLInputs GetConfig() + { + // + XHULLInputs result; + + // + result.length = mLength; + result.divisor = mDivisor; + result.upAppliedTo = mUpAppliedTo; + result.downAppliedTo = mDownAppliedTo; + result.showUpZone = mShowUpZone; + result.showDownZone = mShowDownZone; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XHULLInputs &config) + { + // + bool result = false; + + // + mLength = config.length; + mDivisor = config.divisor; + mUpAppliedTo = config.upAppliedTo; + mDownAppliedTo = config.downAppliedTo; + mShowUpZone = config.showUpZone; + mShowDownZone = config.showDownZone; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + // + // UP ... + ArraySetAsSeries(upBuffer, true); + CopyBuffer( + mHandler, + XHULL_UP_ZONE_LINE, + barIndex, + mLoopbackBars, + upBuffer); + + // + // UP State ... + ArraySetAsSeries(upStateBuffer, true); + CopyBuffer( + mHandler, + XHULL_UP_ZONE_STATE_LINE, + barIndex, + mLoopbackBars, + upStateBuffer); + + // + // DOWN ... + ArraySetAsSeries(downBuffer, true); + CopyBuffer( + mHandler, + XHULL_DOWN_ZONE_LINE, + barIndex, + mLoopbackBars, + downBuffer); + + // + // DOWN State ... + ArraySetAsSeries(downStateBuffer, true); + CopyBuffer( + mHandler, + XHULL_DOWN_ZONE_STATE_LINE, + barIndex, + mLoopbackBars, + downStateBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XHULLInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XHULLInfo result; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + double up = upBuffer[barIndex]; + XHULL_ZONE_STATES upState = (XHULL_ZONE_STATES)upStateBuffer[barIndex]; + XHULL_ZONE_STATES upStatePrev = (XHULL_ZONE_STATES)upStateBuffer[barIndex + 1]; + + // + double down = downBuffer[barIndex]; + XHULL_ZONE_STATES downState = (XHULL_ZONE_STATES)downStateBuffer[barIndex]; + XHULL_ZONE_STATES downStatePrev = (XHULL_ZONE_STATES)downStateBuffer[barIndex + 1]; + + // + result.up = up; + result.upState = upState; + result.down = down; + result.downState = downState; + + // + Copy( + upBuffer, + result.ups); + Copy( + upStateBuffer, + result.upStates); + Copy( + downBuffer, + result.downs); + Copy( + downStateBuffer, + result.downStates); + + // + result.isUpBullish = upState = XHULL_STATE_BULLISH; + result.isUpBearish = upState = XHULL_STATE_BEARISH; + result.isUpNeutural = upState = XHULL_STATE_NEUTURAL; + + // + result.isUpSwitchedToBullish = upState == XHULL_STATE_BULLISH && + upStatePrev != XHULL_STATE_BULLISH; + result.isUpSwitchedToBearish = upState == XHULL_STATE_BEARISH && + upStatePrev != XHULL_STATE_BEARISH; + result.isUpSwitchedToNeutural = upState == XHULL_STATE_NEUTURAL && + upStatePrev != XHULL_STATE_NEUTURAL; + + // + result.isDownBullish = downState = XHULL_STATE_BULLISH; + result.isDownBearish = downState = XHULL_STATE_BEARISH; + result.isDownNeutural = downState = XHULL_STATE_NEUTURAL; + + // + result.isDownSwitchedToBullish = downState == XHULL_STATE_BULLISH && + downStatePrev != XHULL_STATE_BULLISH; + result.isDownSwitchedToBearish = downState == XHULL_STATE_BEARISH && + downStatePrev != XHULL_STATE_BEARISH; + result.isDownSwitchedToNeutural = downState == XHULL_STATE_NEUTURAL && + downStatePrev != XHULL_STATE_NEUTURAL; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Market ... + // + // Length ... + int mLength; + // + // Divisor (Speed) ... + double mDivisor; + // + // Calculation ... + // + // Up Zone Applied to ... + ENUM_APPLIED_PRICE mUpAppliedTo; + // + // Down Zone Applied to ... + ENUM_APPLIED_PRICE mDownAppliedTo; + // + // Presentation ... + // + // Show Up Zone ... + bool mShowUpZone; + // + // Show Down Zone ... + bool mShowDownZone; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xich.helper.class.ex5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xich.helper.class.ex5 new file mode 100644 index 0000000..e79b639 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xich.helper.class.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xich.helper.class.mq5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xich.helper.class.mq5 new file mode 100644 index 0000000..e348836 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xich.helper.class.mq5 @@ -0,0 +1,1083 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXICHHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// Ichimoku Lines Calculator Mode ... +enum ENUM_X_ICHIMOKU_CALCULATION_MODE +{ + // + X_XICH_HH_LL_MODE = 1, // Highest High and Lowest Low + X_XICH_HO_LC_MODE = 2, // Highest Open and Lowest Close +}; + +// +// Inputs ... +struct XICHInputs +{ + // + // TENKANSEN ... + // Tenkan Sen ... + int tenkanSenLength; // Length + ENUM_X_ICHIMOKU_CALCULATION_MODE tenkanSenMode; // Calculation Mode + + // + // KIJUNSEN ... + // Kijun Sen ... + int kijunSenLength; // Length + ENUM_X_ICHIMOKU_CALCULATION_MODE kijunSenMode; // Calculation Mode + + // + // SENKOUSPANB ... + // Senkou Span B ... + int senkouSpanBLength; // Length + ENUM_X_ICHIMOKU_CALCULATION_MODE senkouSpanBMode; // Calculation Mode + + // + // CHIKOUSPAN ... + // Chikou Span ... + ENUM_APPLIED_PRICE chikuoSpanAppliedTo; // Price Type + + // + // Presentation ... + bool showTenkanSen; // Show Tenkan Sen + bool showKijunSen; // Show Kijun Sen + bool showKijunSenPlus; // Show Kijun Sen + + bool showKijunSenNegative; // Show Kijun Sen - + bool showChikouSpan; // Show Chikou Span + bool showSenkouSpanA; // Show Senkou Span A + bool showSenkouSpanB; // Show Senkou Span B + bool showKumo; // Show Kumo + bool shiftKumo; // Shift Kumo to Future +}; + +// +// Index of Lines ... +enum ENUM_XICH_BUFFERS +{ + // + // Main Requirements ... + XICH_TEANKANSEN_LINE = 0, + XICH_KIJUNSEN_LINE = 1, + XICH_CHIKOUSPAN_LINE = 4, + XICH_SENKOUSPANA_LINE = 5, + XICH_SENKOUSPANB_LINE = 6, + // + XICH_D_TENK_LINE = 9, + XICH_D_KIJ_LINE = 10, + XICH_D_CHIK_LINE = 11, + XICH_D_SSA_LINE = 12, + XICH_D_SSB_LINE = 13 +}; + +// +// Retrieve Info Model ... +struct XICHInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double tenkanSen; + double kijunSen; + double chikouSpan; + double senkouSpanA; + double senkouSpanB; + double senkouSpanAFuture; + double senkouSpanBFuture; + + // + double dKij; + double dSSA; + double dSSB; + double dTenk; + double dChik; + + // + double dKijs[]; + double dSSAs[]; + double dSSBs[]; + double dTenks[]; + double dChiks[]; + + // + // Conditions ... + + // + bool isTenkanSenOverKijunSen; + bool isTenkanSenUnderKijunSen; + bool isTenkanSenCrossedOverKijunSen; + bool isTenkanSenCrossedUnderKijunSen; + + // + bool isKumoBullish; + bool isKumoBearish; + bool isFutureKumoBullish; + bool isFutureKumoBearish; + bool isKumoSwitchedToBullish; + bool isKumoSwitchedToBearish; + bool isFutureKumoSwitchedToBullish; + bool isFutureKumoSwitchedToBearish; + + // + bool isTenkanSenOverSenkouSpanA; + bool isTenkanSenUnderSenkouSpanA; + bool isTenkanSenOverFutureSenkouSpanA; + bool isTenkanSenUnderFutureSenkouSpanA; + bool isTenkanSenCrossedOverSenkouSpanA; + bool isTenkanSenCrossedUnderSenkouSpanA; + bool isTenkanSenCrossedOverFutureSenkouSpanA; + bool isTenkanSenCrossedUnderFutureSenkouSpanA; + + // + bool isTenkanSenOverSenkouSpanB; + bool isTenkanSenUnderSenkouSpanB; + bool isTenkanSenOverFutureSenkouSpanB; + bool isTenkanSenUnderFutureSenkouSpanB; + bool isTenkanSenCrossedOverSenkouSpanB; + bool isTenkanSenCrossedUnderSenkouSpanB; + bool isTenkanSenCrossedOverFutureSenkouSpanB; + bool isTenkanSenCrossedUnderFutureSenkouSpanB; + + // + bool isKijunSenOverSenkouSpanA; + bool isKijunSenUnderSenkouSpanA; + bool isKijunSenOverFutureSenkouSpanA; + bool isKijunSenUnderFutureSenkouSpanA; + bool isKijunSenCrossedOverSenkouSpanA; + bool isKijunSenCrossedUnderSenkouSpanA; + bool isKijunSenCrossedOverFutureSenkouSpanA; + bool isKijunSenCrossedUnderFutureSenkouSpanA; + + // + bool isKijunSenOverSenkouSpanB; + bool isKijunSenUnderSenkouSpanB; + bool isKijunSenOverFutureSenkouSpanB; + bool isKijunSenUnderFutureSenkouSpanB; + bool isKijunSenCrossedOverSenkouSpanB; + bool isKijunSenCrossedUnderSenkouSpanB; + bool isKijunSenCrossedOverFutureSenkouSpanB; + bool isKijunSenCrossedUnderFutureSenkouSpanB; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXICHHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double tenkanSenBuffer[]; + double kijunSenBuffer[]; + double chikouSpanBuffer[]; + double senkouSpanABuffer[]; + double senkouSpanBBuffer[]; + + // + double dTenkanBuffer[]; + double dKijunBuffer[]; + double dChikouBuffer[]; + double dSSABuffer[]; + double dSSBBuffer[]; + + // + // Constructor ... + void XSCXICHHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXICHHelper() + { + } + + // + // START Properties ... + // + + // + // Show Tenkan Sen ... + bool ShowTenkanSen( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowTenkanSen == show) + { + return true; + } + + // + mShowTenkanSen = show; + result = Init(); + + // + return result; + } + + // + // Show Kijun Sen ... + bool ShowKijunSen( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowKijunSen == show) + { + return true; + } + + // + mShowKijunSen = show; + result = Init(); + + // + return result; + } + + // + // Show Chikou Span ... + bool ShowChikouSpan( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowChikouSpan == show) + { + return true; + } + + // + mShowChikouSpan = show; + result = Init(); + + // + return result; + } + + // + // Show Senkou Span A ... + bool ShowSenkouSpanA( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowSenkouSpanA == show) + { + return true; + } + + // + mShowSenkouSpanA = show; + result = Init(); + + // + return result; + } + + // + // Show Senkou Span B ... + bool ShowSenkouSpanB( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowSenkouSpanB == show) + { + return true; + } + + // + mShowSenkouSpanB = show; + result = Init(); + + // + return result; + } + + // + // Show Kumo ... + bool ShowKumo( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowKumo == show) + { + return true; + } + + // + mShowKumo = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XICH" + GetTagPrefix(); + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + // + result = MathMax(result, mTenkanSenLength); + result = MathMax(result, mKijunSenLength); + result = MathMax(result, mSenkouSpanBLength); + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Inputs ... + // + result = + (mTenkanSenLength > 2 && + mKijunSenLength > mTenkanSenLength && + mSenkouSpanBLength > mKijunSenLength); + if (!result) + { + return result; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xich", + // + // Inputs ... + // + // TENKANSEN ... + "", + // + // Length ... + mTenkanSenLength, + // + // Calculation Mode ... + mTenkanSenMode, + // + // KIJUNSEN ... + "", + // + // Length ... + mKijunSenLength, + // + // Calculation Mode ... + mKijunSenMode, + // + // SENKOUSPANA ... + "", + // + // Length ... + mSenkouSpanBLength, + // + // Calculation Mode ... + mSenkouSpanBMode, + // + // CHIKOUSPAN ... + "", + // + // Price Type ... + mChikuoSpanAppliedTo, + // + // PRESENTATION ... + "", + // + // Show Tenkan Sen ... + mShowTenkanSen, + // + // Show Kijun Sen ... + mShowKijunSen, + // + // Show Kijun Sen + ... + mShowKijunSenPlus, + // + // Show Kijun Sen - ... + mShowKijunSenNegative, + // + // Show Chikou Span ... + mShowChikouSpan, + // + // Show Senkou Span A ... + mShowSenkouSpanA, + // + // Show Senkou Span B ... + mShowSenkouSpanB, + // + // Show Kumo ... + mShowKumo, + // + // Shift Kumo to Future ... + mShiftKumo + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XICHInputs GetConfig() + { + // + XICHInputs result; + + // + result.tenkanSenLength = mTenkanSenLength; + result.tenkanSenMode = mTenkanSenMode; + result.kijunSenLength = mKijunSenLength; + result.kijunSenMode = mKijunSenMode; + result.senkouSpanBLength = mSenkouSpanBLength; + result.senkouSpanBMode = mSenkouSpanBMode; + result.chikuoSpanAppliedTo = mChikuoSpanAppliedTo; + result.showTenkanSen = mShowTenkanSen; + result.showKijunSen = mShowKijunSen; + result.showKijunSenPlus = mShowKijunSenPlus; + result.showKijunSenNegative = mShowKijunSenNegative; + result.showChikouSpan = mShowChikouSpan; + result.showSenkouSpanA = mShowSenkouSpanA; + result.showSenkouSpanB = mShowSenkouSpanB; + result.showKumo = mShowKumo; + result.shiftKumo = mShiftKumo; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XICHInputs &config) + { + // + bool result = false; + + // + mTenkanSenLength = config.tenkanSenLength; + mTenkanSenMode = config.tenkanSenMode; + mKijunSenLength = config.kijunSenLength; + mKijunSenMode = config.kijunSenMode; + mSenkouSpanBLength = config.senkouSpanBLength; + mSenkouSpanBMode = config.senkouSpanBMode; + mChikuoSpanAppliedTo = config.chikuoSpanAppliedTo; + mShowTenkanSen = config.showTenkanSen; + mShowKijunSen = config.showKijunSen; + mShowKijunSenPlus = config.showKijunSenPlus; + mShowKijunSenNegative = config.showKijunSenNegative; + mShowChikouSpan = config.showChikouSpan; + mShowSenkouSpanA = config.showSenkouSpanA; + mShowSenkouSpanB = config.showSenkouSpanB; + mShowKumo = config.showKumo; + mShiftKumo = config.shiftKumo; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + // + // Since Ichimoku Has Some Issues ... + mLoopbackBars = 52; + + // + // TENKANSEN ... + ArraySetAsSeries(tenkanSenBuffer, true); + CopyBuffer( + mHandler, + XICH_TEANKANSEN_LINE, + barIndex, + mLoopbackBars, + tenkanSenBuffer); + + // + // KIJUNSEN ... + ArraySetAsSeries(kijunSenBuffer, true); + CopyBuffer( + mHandler, + XICH_KIJUNSEN_LINE, + barIndex, + mLoopbackBars, + kijunSenBuffer); + + // + // CHIKOUSPAN ... + ArraySetAsSeries(chikouSpanBuffer, true); + CopyBuffer( + mHandler, + XICH_CHIKOUSPAN_LINE, + barIndex + mKijunSenLength + 1, + mLoopbackBars, + chikouSpanBuffer); + + // + // SENKOUSPANA ... + ArraySetAsSeries(senkouSpanABuffer, true); + CopyBuffer( + mHandler, + XICH_SENKOUSPANA_LINE, + -1 * (barIndex + mKijunSenLength), + mLoopbackBars, + senkouSpanABuffer); + + // + // SENKOUSPANB ... + ArraySetAsSeries(senkouSpanBBuffer, true); + CopyBuffer( + mHandler, + XICH_SENKOUSPANB_LINE, + -1 * (barIndex + mKijunSenLength), + mLoopbackBars, + senkouSpanBBuffer); + + // + // DATA Buffers ... + + // + // D Tenkan ... + ArraySetAsSeries(dTenkanBuffer, true); + CopyBuffer( + mHandler, + XICH_D_TENK_LINE, + barIndex, + mLoopbackBars, + dTenkanBuffer); + + // + // D Kijun ... + ArraySetAsSeries(dKijunBuffer, true); + CopyBuffer( + mHandler, + XICH_D_KIJ_LINE, + barIndex, + mLoopbackBars, + dKijunBuffer); + + // + // D Chikou ... + ArraySetAsSeries(dChikouBuffer, true); + CopyBuffer( + mHandler, + XICH_D_CHIK_LINE, + barIndex, + mLoopbackBars, + dChikouBuffer); + + // + // D SSA ... + ArraySetAsSeries(dSSABuffer, true); + CopyBuffer( + mHandler, + XICH_D_SSA_LINE, + barIndex, + mLoopbackBars, + dSSABuffer); + + // + // D SSB ... + ArraySetAsSeries(dSSBBuffer, true); + CopyBuffer( + mHandler, + XICH_D_SSB_LINE, + barIndex, + mLoopbackBars, + dSSBBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XICHInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XICHInfo result; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + double dTenk = dTenkanBuffer[barIndex]; + double dTenkPrev = dTenkanBuffer[barIndex + 1]; + + // + double dKij = dKijunBuffer[barIndex]; + double dKijrev = dKijunBuffer[barIndex + 1]; + + // + double dChik = dChikouBuffer[barIndex]; + double dChikPrev = dChikouBuffer[barIndex + 1]; + + // + double dSSA = dSSABuffer[barIndex]; + double dSSAPrev = dSSABuffer[barIndex + 1]; + + // + double dSSB = dSSBBuffer[barIndex]; + double dSSBPrev = dSSBBuffer[barIndex + 1]; + + // + Copy( + dKijunBuffer, + result.dKijs); + Copy( + dSSABuffer, + result.dSSAs); + Copy( + dSSBBuffer, + result.dSSBs); + Copy( + dTenkanBuffer, + result.dTenks); + Copy( + dChikouBuffer, + result.dChiks); + + // + result.dTenk = dTenk; + result.dKij = dKij; + result.dChik = dChik; + result.dSSA = dSSA; + result.dSSB = dSSB; + + // + double tenkanSen = tenkanSenBuffer[barIndex]; + double tenkanSenPrev = tenkanSenBuffer[barIndex + 1]; + + // + double kijunSen = kijunSenBuffer[barIndex]; + double kijunSenPrev = kijunSenBuffer[barIndex + 1]; + + // + double chikouSpan = chikouSpanBuffer[barIndex + mKijunSenLength]; + double chikouSpanPrev = chikouSpanBuffer[barIndex + mKijunSenLength + 1]; + + // + double senkouSpanA = senkouSpanABuffer[barIndex + mKijunSenLength]; + double senkouSpanAPrev = senkouSpanABuffer[barIndex + mKijunSenLength + 1]; + + // + double senkouSpanB = senkouSpanBBuffer[barIndex + mKijunSenLength]; + double senkouSpanBPrev = senkouSpanBBuffer[barIndex + mKijunSenLength + 1]; + + // + double senkouSpanAFuture = senkouSpanABuffer[barIndex]; + double senkouSpanAFuturePrev = senkouSpanABuffer[barIndex + 1]; + + // + double senkouSpanBFuture = senkouSpanBBuffer[barIndex]; + double senkouSpanBFuturePrev = senkouSpanBBuffer[barIndex + 1]; + + // + bool isTenkanSenOverKijunSen = + tenkanSen > kijunSen; + bool isTenkanSenUnderKijunSen = + tenkanSen < kijunSen; + bool isTenkanSenCrossedOverKijunSen = + tenkanSen > kijunSen && + tenkanSenPrev <= kijunSenPrev; + bool isTenkanSenCrossedUnderKijunSen = + tenkanSen < kijunSen && + tenkanSenPrev >= kijunSenPrev; + + // + bool isKumoBullish = + senkouSpanA > senkouSpanB; + bool isKumoBearish = + senkouSpanA < senkouSpanB; + bool isFutureKumoBullish = + senkouSpanAFuture > senkouSpanBFuture; + bool isFutureKumoBearish = + senkouSpanAFuture < senkouSpanBFuture; + bool isKumoSwitchedToBullish = + senkouSpanA > senkouSpanB && + senkouSpanAPrev <= senkouSpanBPrev; + bool isKumoSwitchedToBearish = + senkouSpanA < senkouSpanB && + senkouSpanAPrev >= senkouSpanBPrev; + bool isFutureKumoSwitchedToBullish = + senkouSpanAFuture > senkouSpanBFuture && + senkouSpanAFuturePrev <= senkouSpanBFuturePrev; + bool isFutureKumoSwitchedToBearish = + senkouSpanAFuture < senkouSpanBFuture && + senkouSpanAFuturePrev >= senkouSpanBFuturePrev; + + // + bool isTenkanSenOverSenkouSpanA = + tenkanSen > senkouSpanA; + bool isTenkanSenUnderSenkouSpanA = + tenkanSen < senkouSpanA; + bool isTenkanSenOverFutureSenkouSpanA = + tenkanSen > senkouSpanAFuture; + bool isTenkanSenUnderFutureSenkouSpanA = + tenkanSen < senkouSpanAFuture; + bool isTenkanSenCrossedOverSenkouSpanA = + tenkanSen > senkouSpanA && + tenkanSenPrev <= senkouSpanAPrev; + bool isTenkanSenCrossedUnderSenkouSpanA = + tenkanSen < senkouSpanA && + tenkanSenPrev >= senkouSpanAPrev; + bool isTenkanSenCrossedOverFutureSenkouSpanA = + tenkanSen > senkouSpanAFuture && + tenkanSenPrev <= senkouSpanAFuturePrev; + bool isTenkanSenCrossedUnderFutureSenkouSpanA = + tenkanSen < senkouSpanAFuture && + tenkanSenPrev >= senkouSpanAFuturePrev; + + // + bool isTenkanSenOverSenkouSpanB = + tenkanSen > senkouSpanB; + bool isTenkanSenUnderSenkouSpanB = + tenkanSen < senkouSpanB; + bool isTenkanSenOverFutureSenkouSpanB = + tenkanSen > senkouSpanBFuture; + bool isTenkanSenUnderFutureSenkouSpanB = + tenkanSen < senkouSpanBFuture; + bool isTenkanSenCrossedOverSenkouSpanB = + tenkanSen > senkouSpanB && + tenkanSenPrev <= senkouSpanBPrev; + bool isTenkanSenCrossedUnderSenkouSpanB = + tenkanSen < senkouSpanB && + tenkanSenPrev >= senkouSpanBPrev; + bool isTenkanSenCrossedOverFutureSenkouSpanB = + tenkanSen > senkouSpanBFuture && + tenkanSenPrev <= senkouSpanBFuturePrev; + bool isTenkanSenCrossedUnderFutureSenkouSpanB = + tenkanSen < senkouSpanBFuture && + tenkanSenPrev >= senkouSpanBFuturePrev; + + // + bool isKijunSenOverSenkouSpanA = + kijunSen > senkouSpanA; + bool isKijunSenUnderSenkouSpanA = + kijunSen < senkouSpanA; + bool isKijunSenOverFutureSenkouSpanA = + kijunSen > senkouSpanAFuture; + bool isKijunSenUnderFutureSenkouSpanA = + kijunSen < senkouSpanAFuture; + bool isKijunSenCrossedOverSenkouSpanA = + kijunSen > senkouSpanA && + kijunSenPrev <= senkouSpanAPrev; + bool isKijunSenCrossedUnderSenkouSpanA = + kijunSen < senkouSpanA && + kijunSenPrev >= senkouSpanAPrev; + bool isKijunSenCrossedOverFutureSenkouSpanA = + kijunSen > senkouSpanAFuture && + kijunSenPrev <= senkouSpanAFuturePrev; + bool isKijunSenCrossedUnderFutureSenkouSpanA = + kijunSen < senkouSpanAFuture && + kijunSenPrev >= senkouSpanAFuturePrev; + + // + bool isKijunSenOverSenkouSpanB = + kijunSen > senkouSpanB; + bool isKijunSenUnderSenkouSpanB = + kijunSen < senkouSpanB; + bool isKijunSenOverFutureSenkouSpanB = + kijunSen > senkouSpanBFuture; + bool isKijunSenUnderFutureSenkouSpanB = + kijunSen < senkouSpanBFuture; + bool isKijunSenCrossedOverSenkouSpanB = + kijunSen > senkouSpanB && + kijunSenPrev <= senkouSpanB; + bool isKijunSenCrossedUnderSenkouSpanB = + kijunSen < senkouSpanB && + kijunSenPrev >= senkouSpanB; + bool isKijunSenCrossedOverFutureSenkouSpanB = + kijunSen > senkouSpanBFuture && + kijunSenPrev <= senkouSpanBFuturePrev; + bool isKijunSenCrossedUnderFutureSenkouSpanB = + kijunSen < senkouSpanBFuture && + kijunSenPrev >= senkouSpanBFuturePrev; + + // + result.tenkanSen = tenkanSen; + result.kijunSen = kijunSen; + result.chikouSpan = chikouSpan; + result.senkouSpanA = senkouSpanA; + result.senkouSpanB = senkouSpanB; + result.senkouSpanAFuture = senkouSpanAFuture; + result.senkouSpanBFuture = senkouSpanBFuture; + + // + result.isTenkanSenOverKijunSen = isTenkanSenOverKijunSen; + result.isTenkanSenUnderKijunSen = isTenkanSenUnderKijunSen; + result.isTenkanSenCrossedOverKijunSen = isTenkanSenCrossedOverKijunSen; + result.isTenkanSenCrossedUnderKijunSen = isTenkanSenCrossedUnderKijunSen; + + // + result.isKumoBullish = isKumoBullish; + result.isKumoBearish = isKumoBearish; + result.isFutureKumoBullish = isFutureKumoBullish; + result.isFutureKumoBearish = isFutureKumoBearish; + result.isKumoSwitchedToBullish = isKumoSwitchedToBullish; + result.isKumoSwitchedToBearish = isKumoSwitchedToBearish; + result.isFutureKumoSwitchedToBullish = isFutureKumoSwitchedToBullish; + result.isFutureKumoSwitchedToBearish = isFutureKumoSwitchedToBearish; + + // + result.isTenkanSenOverSenkouSpanA = isTenkanSenOverSenkouSpanA; + result.isTenkanSenUnderSenkouSpanA = isTenkanSenUnderSenkouSpanA; + result.isTenkanSenOverFutureSenkouSpanA = isTenkanSenOverFutureSenkouSpanA; + result.isTenkanSenUnderFutureSenkouSpanA = isTenkanSenUnderFutureSenkouSpanA; + result.isTenkanSenCrossedOverSenkouSpanA = isTenkanSenCrossedOverSenkouSpanA; + result.isTenkanSenCrossedUnderSenkouSpanA = isTenkanSenCrossedUnderSenkouSpanA; + result.isTenkanSenCrossedOverFutureSenkouSpanA = isTenkanSenCrossedOverFutureSenkouSpanA; + result.isTenkanSenCrossedUnderFutureSenkouSpanA = isTenkanSenCrossedUnderFutureSenkouSpanA; + + // + result.isTenkanSenOverSenkouSpanB = isTenkanSenOverSenkouSpanB; + result.isTenkanSenUnderSenkouSpanB = isTenkanSenUnderSenkouSpanB; + result.isTenkanSenOverFutureSenkouSpanB = isTenkanSenOverFutureSenkouSpanB; + result.isTenkanSenUnderFutureSenkouSpanB = isTenkanSenUnderFutureSenkouSpanB; + result.isTenkanSenCrossedOverSenkouSpanB = isTenkanSenCrossedOverSenkouSpanB; + result.isTenkanSenCrossedUnderSenkouSpanB = isTenkanSenCrossedUnderSenkouSpanB; + result.isTenkanSenCrossedOverFutureSenkouSpanB = isTenkanSenCrossedOverFutureSenkouSpanB; + result.isTenkanSenCrossedUnderFutureSenkouSpanB = isTenkanSenCrossedUnderFutureSenkouSpanB; + + // + result.isKijunSenOverSenkouSpanA = isKijunSenOverSenkouSpanA; + result.isKijunSenUnderSenkouSpanA = isKijunSenUnderSenkouSpanA; + result.isKijunSenOverFutureSenkouSpanA = isKijunSenOverFutureSenkouSpanA; + result.isKijunSenUnderFutureSenkouSpanA = isKijunSenUnderFutureSenkouSpanA; + result.isKijunSenCrossedOverSenkouSpanA = isKijunSenCrossedOverSenkouSpanA; + result.isKijunSenCrossedUnderSenkouSpanA = isKijunSenCrossedUnderSenkouSpanA; + result.isKijunSenCrossedOverFutureSenkouSpanA = isKijunSenCrossedOverFutureSenkouSpanA; + result.isKijunSenCrossedUnderFutureSenkouSpanA = isKijunSenCrossedUnderFutureSenkouSpanA; + + // + result.isKijunSenOverSenkouSpanB = isKijunSenOverSenkouSpanB; + result.isKijunSenUnderSenkouSpanB = isKijunSenUnderSenkouSpanB; + result.isKijunSenOverFutureSenkouSpanB = isKijunSenOverFutureSenkouSpanB; + result.isKijunSenUnderFutureSenkouSpanB = isKijunSenUnderFutureSenkouSpanB; + result.isKijunSenCrossedOverSenkouSpanB = isKijunSenCrossedOverSenkouSpanB; + result.isKijunSenCrossedUnderSenkouSpanB = isKijunSenCrossedUnderSenkouSpanB; + result.isKijunSenCrossedOverFutureSenkouSpanB = isKijunSenCrossedOverFutureSenkouSpanB; + result.isKijunSenCrossedUnderFutureSenkouSpanB = isKijunSenCrossedUnderFutureSenkouSpanB; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // TENKANSEN ... + // + // Length ... + int mTenkanSenLength; + // + // Calculation Mode ... + ENUM_X_ICHIMOKU_CALCULATION_MODE mTenkanSenMode; + // + // KIJUNSEN ... + // + // Length ... + int mKijunSenLength; + // + // Calculation Mode ... + ENUM_X_ICHIMOKU_CALCULATION_MODE mKijunSenMode; + // + // SENKOUSPANB ... + // + // Length ... + int mSenkouSpanBLength; + // + // Calculation Mode ... + ENUM_X_ICHIMOKU_CALCULATION_MODE mSenkouSpanBMode; + // + // CHIKOUSPAN ... + // + // Price Type ... + ENUM_APPLIED_PRICE mChikuoSpanAppliedTo; + // + // Presentation ... + // + // Show Tenkan Sen ... + bool mShowTenkanSen; + // + // Show Kijun Sen ... + bool mShowKijunSen; + // + // Show Kijun Sen + ... + bool mShowKijunSenPlus; + // + // Show Kijun Sen - ... + bool mShowKijunSenNegative; + // + // Show Chikou Span ... + bool mShowChikouSpan; + // + // Show Senkou Span A ... + bool mShowSenkouSpanA; + // + // Show Senkou Span B ... + bool mShowSenkouSpanB; + // + // Show Kumo ... + bool mShowKumo; + // + // Shift Kumo to Future ... + bool mShiftKumo; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xman.helper.class.ex5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xman.helper.class.ex5 new file mode 100644 index 0000000..ff91aef Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xman.helper.class.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xman.helper.class.mq5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xman.helper.class.mq5 new file mode 100644 index 0000000..d20082c --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xman.helper.class.mq5 @@ -0,0 +1,3062 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXMANHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// All Extractable Buffers ... +enum ENUM_XMAN_BUFFERS +{ + // + // Peaks and Vales ... + XMAN_PEAKS_LINE = 0, // Peaks + XMAN_PEAKS_STATE_LINE = 65, // New Peak + XMAN_VALES_LINE = 1, // Vales + XMAN_VALES_STATE_LINE = 66, // New Vales + // + // Fibonacci Retracement ... + XMAN_FIB_L1_LINE = 6, // Fibo Level 1 + XMAN_FIB_L2_LINE = 8, // Fibo Level 2 + XMAN_FIB_L3_LINE = 10, // Fibo Level 3 + // + // Period Cycles ... + // + // Short Cycle ... + XMAN_SC_HH_LINE = 12, // High + XMAN_SC_HH_STATE_LINE = 67, // High State + XMAN_SC_LL_LINE = 14, // Low + XMAN_SC_LL_STATE_LINE = 68, // Low State + // + // Medium ... + XMAN_MC_HH_LINE = 16, // High + XMAN_MC_HH_STATE_LINE = 69, // High State + XMAN_MC_LL_LINE = 18, // Low + XMAN_MC_LL_STATE_LINE = 70, // Low State + // + // Long ... + XMAN_LC_HH_LINE = 20, // High + XMAN_LC_HH_STATE_LINE = 71, // High State + XMAN_LC_LL_LINE = 22, // Low + XMAN_LC_LL_STATE_LINE = 72, // Low State + // + // Hind ... + XMAN_HC_HH_LINE = 24, // High + XMAN_HC_HH_STATE_LINE = 73, // High State + XMAN_HC_LL_LINE = 26, // Low + XMAN_HC_LL_STATE_LINE = 74, // Low State + // + // XSTR ... + XMAN_TREND_LINE = 30, // Trend Value + XMAN_TREND_STATE_LINE = 75, // Trend Direction + // + // XMRB ... + // + // RIBBON 1 _ HIGH ... + XMAN_RB1_LINE = 32, // Value + XMAN_RB1_STATE_LINE = 76, // State + // + // RIBBON 2 _ OPEN ... + XMAN_RB2_LINE = 34, // Value + XMAN_RB2_STATE_LINE = 77, // State + // + // RIBBON 3 _ CLOSE ... + XMAN_RB3_LINE = 36, // Value + XMAN_RB3_STATE_LINE = 78, // State + // + // RIBBON 4 _ MEDIAN ... + XMAN_RB4_LINE = 38, // Value + XMAN_RB4_STATE_LINE = 79, // State + // + // RIBBON 5 _ TYPICAL ... + XMAN_RB5_LINE = 40, // Value + XMAN_RB5_STATE_LINE = 80, // State + // + // RIBBON 6 _ LOW ... + XMAN_RB6_LINE = 42, // Value + XMAN_RB6_STATE_LINE = 81, // State + // + // XSSLC ... + XMAN_SSLC_UP_LINE = 44, // Up + XMAN_SSLC_DOWN_LINE = 82, // Down + // + // XHULL ... + XMAN_HULL_UP_LINE = 48, // Up + XMAN_HULL_UP_STATE_LINE = 82, // Up State + XMAN_HULL_DOWN_LINE = 50, // Down + XMAN_HULL_DOWN_STATE_LINE = 83, // Down State + // + // XHK ... + XMAN_HK_OPEN_LINE = 52, // Open + XMAN_HK_HIGH_LINE = 53, // High + XMAN_HK_LOW_LINE = 54, // Low + XMAN_HK_CLOSE_LINE = 55, // Close + XMAN_HK_STATE_LINE = 84, // State +}; + +// +// Define States On XMAN ... +enum ENUM_XMAN_STATES +{ + XMAN_STATE_BULLISH = 2, + XMAN_STATE_STRONG_BULLISH = 8, + XMAN_STATE_BEARISH = 3, + XMAN_STATE_STRONG_BEARISH = 9, + XMAN_STATE_NEUTURAL = 1, + XMAN_STATE_STRONG_NEUTURAL = 7, +}; + +// +// XPERIOD Calculation Method ... +// USED For Multiple Time Frames ... +enum ENUM_X_PERIOD_METHOD +{ + // + X_PERIOD_NOTHING, // Nothing + X_PERIOD_AUTO, // Auto Select + X_PERIOD_MANUALLY // Manually +}; + +// +enum ENUM_X_MA_METHOD +{ + X_MA_NOTHING, // Nothing + X_MA_SMA, // Simple + X_MA_EMA, // Expotential + X_MA_SMMA, // Smoothed Simple + X_MA_LWMA, // Linear Weighted + X_MA_AMA // Adaptive +}; + +// +// Model all required info as a Model for Instancing Helper Class ... +struct XMANInputs +{ + // + // Candle Timer ... + color candleTimerColor; // Text Color + ENUM_BASE_CORNER candleTimerCorner; // Text Position + + // + // Chart Style ... + color upColor; // Up Color + color downColor; // Down Color + color lineColor; // Line mode and Doji candlestick Color + color bearishColor; // Bullish Color + color bullishColor; // Bearish Color + color volumesColor; // Volumes Color + + // + // Market Cycles ... + + // + // Level 1 ... + ENUM_X_PERIOD_METHOD l1Method; // How to Find Period + ENUM_TIMEFRAMES l1Period; // Time Period + + // + // Level 2 ... + ENUM_X_PERIOD_METHOD l2Method; // How to Find Period + ENUM_TIMEFRAMES l2Period; // Time Period + + // + // Level 3 ... + ENUM_X_PERIOD_METHOD l3Method; // How to Find Period + ENUM_TIMEFRAMES l3Period; // Time Period + + // + // Level 4 ... + ENUM_X_PERIOD_METHOD l4Method; // How to Find Period + ENUM_TIMEFRAMES l4Period; // Time Period + + // + // Fibonacci ... + double fiboLevel1; // Fibio 1st Level + double fiboLevel2; // Fibio 2st Level + double fiboLevel3; // Fibio 3rd Level + + // + // Boundary Detection Modes ... + ENUM_SERIESMODE hhMode; // Highest High Calculation Method + ENUM_SERIESMODE llMode; // Lowest Low Calculation Method + + // + // Trend Detection + double trendMultiplier; // Multiplier + ENUM_APPLIED_PRICE trendPriceAppliedTo; // Applied To + + // + // Ribbon Detection ... + ENUM_X_MA_METHOD ribbonMode; // How to Calculate + + // + // Hull Trend Detection ... + double hullDivisor; // Divisor (Speed) + ENUM_APPLIED_PRICE hullUpAppliedTo; // Up Zone Applied to + ENUM_APPLIED_PRICE hullDownAppliedTo; // Down Zone Applied to + + // + // SSL Channel Detection ... + ENUM_X_MA_METHOD sslcMode; // How to Calculate + ENUM_APPLIED_PRICE sslcUpAppliedTo; // Up Applied To + ENUM_APPLIED_PRICE sslcDownAppliedTo; // Down Applied To + + // + // Presentation ... + bool showCandleTimer; // Show Candle Time + bool showCandles; // Show Candles + bool showHKCandles; // Draw Hiken Ashi Candle + bool showPeaksAndVales; // Show Peaks and Vales + bool showTrends; // Show Trends + bool fillTrends; // Fill Trends + bool showLevels; // Show Levels + bool showConsolidations; // Show Consolidations + bool showRibbons; // Show Ribbons + bool showHull; // Show Hull + bool showSSLChannel; // Show SSL Channel + bool showFibo1Levels; // Show Fibo 1st Level + bool showFibo2Levels; // Show Fibo 2nd Level + bool showFibo3Levels; // Show Fibo 3rd Level +}; + +// +// Model all Extractable Info as a Model for Market Analyzing ... +struct XMANInfo +{ + // + // COMMONS ... + + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // SPECIALS ... + + // + // Buffers ... + + // + // Peaks and Vales ... + double peaks[]; + double peaksStates[]; + double vales[]; + double valesStates[]; + + // + // Fibonacci ... + double fibLevel1s[]; + double fibLevel2s[]; + double fibLevel3s[]; + + // + // Cycles ... + + // + // Short ... + double sHHs[]; + double sHHStates[]; + double sLLs[]; + double sLLStates[]; + + // + // Medium ... + double mHHs[]; + double mHHStates[]; + double mLLs[]; + double mLLStates[]; + + // + // Long ... + double lHHs[]; + double lHHStates[]; + double lLLs[]; + double lLLStates[]; + + // + // Hind ... + double hHHs[]; + double hHHStates[]; + double hLLs[]; + double hLLStates[]; + + // + // Trends ... + double trends[]; + double trendStates[]; + + // + // Ribbons ... + + // + // 1 _ High ... + double ribbon1s[]; + double ribbon1States[]; + + // + // 2 _ Open ... + double ribbon2s[]; + double ribbon2States[]; + + // + // 3 _ Close ... + double ribbon3s[]; + double ribbon3States[]; + + // + // 4 _ Median ... + double ribbon4s[]; + double ribbon4States[]; + + // + // 5 _ Typical ... + double ribbon5s[]; + double ribbon5States[]; + + // + // 6 _ Low ... + double ribbon6s[]; + double ribbon6States[]; + + // + // SSL Channel ... + double sslUps[]; + double sslDowns[]; + + // + // Hull Trend ... + double hullUps[]; + double hullUpStates[]; + double hullDowns[]; + double hullDownStates[]; + + // + // Hiken Ashi ... + double hkOpens[]; + double hkHighs[]; + double hkLows[]; + double hkCloses[]; + double hkStates[]; + + // + // Conditions ... + + // + // Peaks and Vales ... + bool isNewPeak; + bool isNewVale; + + // + // Trend ... + bool isTrendBullish; + bool isTrendSwitchedToBullish; + bool isTrendBearish; + bool isTrendSwitchedToBearish; + bool isTrendNeutural; + bool isTrendSwitchedToNeutural; + + // + // SSL Channel ... + bool isSSLBullish; + bool isSSLSwitchedToBullish; + bool isSSLBearish; + bool isSSLSwitchedBearish; + bool isSSLNeutural; + bool isSSLSwitchedNeutural; + + // + // Hull Trend ... + + // + bool isHullBullish; + bool isHullUpBullish; + bool isHullDownBullish; + bool isHullSwitchedToBullish; + + // + bool isHullBearish; + bool isHullUpBearish; + bool isHullDownBearish; + bool isHullSwitchedToBearish; + + // + bool isHullNeutural; + bool isHullUpNeutural; + bool isHullDownNeutural; + bool isHullSwitchedToNeutural; + + // + // HK ... + bool isHKBullish; + bool isHKBearish; + + // + // Market Cycles ... + + // + // Short ... + + // + bool isSCBullish; + bool isSCHBullish; + bool isSCLBullish; + bool isSCSwitchedToBullish; + bool isSCHSwitchedToBullish; + bool isSCLSwitchedToBullish; + + // + bool isSCBearish; + bool isSCHBearish; + bool isSCLBearish; + bool isSCSwitchedToBearish; + bool isSCHSwitchedToBearish; + bool isSCLSwitchedToBearish; + + // + bool isSCNeutural; + bool isSCHNeutural; + bool isSCLNeutural; + bool isSCSwitchedToNeutural; + bool isSCHSwitchedToNeutural; + bool isSCLSwitchedToNeutural; + + // + // Medium ... + + // + bool isMCBullish; + bool isMCHBullish; + bool isMCLBullish; + bool isMCSwitchedToBullish; + bool isMCHSwitchedToBullish; + bool isMCLSwitchedToBullish; + + // + bool isMCBearish; + bool isMCHBearish; + bool isMCLBearish; + bool isMCSwitchedToBearish; + bool isMCHSwitchedToBearish; + bool isMCLSwitchedToBearish; + + // + bool isMCNeutural; + bool isMCHNeutural; + bool isMCLNeutural; + bool isMCSwitchedToNeutural; + bool isMCHSwitchedToNeutural; + bool isMCLSwitchedToNeutural; + + // + // Long ... + + // + bool isLCBullish; + bool isLCHBullish; + bool isLCLBullish; + bool isLCSwitchedToBullish; + bool isLCHSwitchedToBullish; + bool isLCLSwitchedToBullish; + + // + bool isLCBearish; + bool isLCHBearish; + bool isLCLBearish; + bool isLCSwitchedToBearish; + bool isLCHSwitchedToBearish; + bool isLCLSwitchedToBearish; + + // + bool isLCNeutural; + bool isLCHNeutural; + bool isLCLNeutural; + bool isLCSwitchedToNeutural; + bool isLCHSwitchedToNeutural; + bool isLCLSwitchedToNeutural; + + // + // Hind ... + + // + bool isHCBullish; + bool isHCHBullish; + bool isHCLBullish; + bool isHCSwitchedToBullish; + bool isHCHSwitchedToBullish; + bool isHCLSwitchedToBullish; + + // + bool isHCBearish; + bool isHCHBearish; + bool isHCLBearish; + bool isHCSwitchedToBearish; + bool isHCHSwitchedToBearish; + bool isHCLSwitchedToBearish; + + // + bool isHCNeutural; + bool isHCHNeutural; + bool isHCLNeutural; + bool isHCSwitchedToNeutural; + bool isHCHSwitchedToNeutural; + bool isHCLSwitchedToNeutural; + + // + // Ribbons ... + + // + // R1 ... + + // + bool isRibbon1Bullish; + bool isRibbon2Bullish; + bool isRibbon3Bullish; + bool isRibbon4Bullish; + bool isRibbon5Bullish; + bool isRibbon6Bullish; + + // + bool isRibbon1Bearish; + bool isRibbon2Bearish; + bool isRibbon3Bearish; + bool isRibbon4Bearish; + bool isRibbon5Bearish; + bool isRibbon6Bearish; + + // + bool isRibbon1Neutural; + bool isRibbon2Neutural; + bool isRibbon3Neutural; + bool isRibbon4Neutural; + bool isRibbon5Neutural; + bool isRibbon6Neutural; + + // + bool isRibbonBullish; + bool isRibbonSwitchedToBullish; + + // + bool isRibbonBearish; + bool isRibbonSwitchedToBearish; + + // + bool isRibbonNeutural; + bool isRibbonSwitchedToNeutural; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +class XSCXMANHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Peaks and Vales ... + double peaksBuffer[]; + double peaksStateBuffer[]; + double valesBuffer[]; + double valesStateBuffer[]; + + // + // Fibonacci ... + double fibLevel1Buffer[]; + double fibLevel2Buffer[]; + double fibLevel3Buffer[]; + + // + // Cycles ... + + // + // Short ... + double sHHBuffer[]; + double sHHStateBuffer[]; + double sLLBuffer[]; + double sLLStateBuffer[]; + + // + // Medium ... + double mHHBuffer[]; + double mHHStateBuffer[]; + double mLLBuffer[]; + double mLLStateBuffer[]; + + // + // Long ... + double lHHBuffer[]; + double lHHStateBuffer[]; + double lLLBuffer[]; + double lLLStateBuffer[]; + + // + // Hind ... + double hHHBuffer[]; + double hHHStateBuffer[]; + double hLLBuffer[]; + double hLLStateBuffer[]; + + // + // Trends ... + double trendBuffer[]; + double trendStateBuffer[]; + + // + // Ribbons ... + + // + // 1 _ High ... + double ribbon1Buffer[]; + double ribbon1StateBuffer[]; + + // + // 2 _ Open ... + double ribbon2Buffer[]; + double ribbon2StateBuffer[]; + + // + // 3 _ Close ... + double ribbon3Buffer[]; + double ribbon3StateBuffer[]; + + // + // 4 _ Median ... + double ribbon4Buffer[]; + double ribbon4StateBuffer[]; + + // + // 5 _ Typical ... + double ribbon5Buffer[]; + double ribbon5StateBuffer[]; + + // + // 6 _ Low ... + double ribbon6Buffer[]; + double ribbon6StateBuffer[]; + + // + // SSL Channel ... + double sslUpBuffer[]; + double sslDownBuffer[]; + + // + // Hull Trend ... + double hullUpBuffer[]; + double hullUpStateBuffer[]; + double hullDownBuffer[]; + double hullDownStateBuffer[]; + + // + // Hiken Ashi ... + double hkOpenBuffer[]; + double hkHighBuffer[]; + double hkLowBuffer[]; + double hkCloseBuffer[]; + double hkStateBuffer[]; + + // + // Constructor ... + void XSCXMANHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXMANHelper() + { + } + + // + // START Properties ... + // + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XMAN" + GetTagPrefix(); + } + + // + virtual int GetMaxLength() + { + // + int result = 1; + + // + result = 1; + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Args ... + result = + // + // L1 ... + // Short Cycle ... + ( + // + mL1Method == X_PERIOD_AUTO + ? mL1Period == NULL + : mL1Period != NULL && mL1Method != X_PERIOD_NOTHING + // + ) + // + && + // + // L2 ... + // Medium Cycle ... + ( + // + mL2Method == X_PERIOD_AUTO + ? mL2Period == NULL + : mL2Period != NULL && mL2Method != X_PERIOD_NOTHING + // + ) + // + && + // + // L3 ... + // Long Cycle ... + ( + // + mL3Method == X_PERIOD_AUTO + ? mL3Period == NULL + : mL3Period != NULL && mL3Method != X_PERIOD_NOTHING + // + ) + // + && + // + // L4 ... + // Hind Cycle ... + ( + // + mL4Method == X_PERIOD_AUTO + ? mL4Period == NULL + : mL4Period != NULL && mL4Method != X_PERIOD_NOTHING + // + ) + // + && + // + // Validate Ribbon ... + ( + // + mRibbonMode != X_MA_NOTHING + // + ) + // + ; + if (!result) + { + return false; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xman", + // + // Inputs ... + // + // Candle Timer ... + "", + // + mCandleTimerColor, // Text Color + mCandleTimerCorner, // Text Position + // + // Chart Style ... + "", + // + mUpColor, // Up Color + mDownColor, // Down Color + mLineColor, // Line mode and Doji candlestick Color + mBearishColor, // Bullish Color + mBullishColor, // Bearish Color + mVolumesColor, // Volumes Color + // + // Market Cycles ... + "", + // + // Level 1 ... + "", + // + mL1Method, // How to Find Period + mL1Period, // Time Period + // + // Level 2 ... + "", + // + mL2Method, // How to Find Period + mL2Period, // Time Period + // + // Level 3 ... + "", + // + mL3Method, // How to Find Period + mL3Period, // Time Period + // + // Level 4 ... + "", + // + mL4Method, // How to Find Period + mL4Period, // Time Period + // + // Fibonacci ... + "", + // + mFiboLevel1, // Fibio 1st Level + mFiboLevel2, // Fibio 2st Level + mFiboLevel3, // Fibio 3rd Level + // + // Boundary Detection Modes ... + "", + // + mHHMode, // Highest High Calculation Method + mLLMode, // Lowest Low Calculation Method + // + // Trend Detection + "", + // + mTrendMultiplier, // Multiplier + mTrendPriceAppliedTo, // Applied To + // + // Ribbon Detection ... + "", + // + mRibbonMode, // How to Calculate + // + // Hull Trend Detection ... + "", + // + mHullDivisor, // Divisor (Speed) + mHullUpAppliedTo, // Up Zone Applied to + mHullDownAppliedTo, // Down Zone Applied to + // + // SSL Channel Detection ... + "", + // + mSslcMode, // How to Calculate + mSslcUpAppliedTo, // Up Applied To + mSslcDownAppliedTo, // Down Applied To + // + // Presentation ... + "", + // + mShowCandleTimer, // Show Candle Timer + mShowCandles, // Show Candles + mShowHKCandles, // Draw Hiken Ashi Candle + mShowPeaksAndVales, // Show Peaks and Vales + mShowTrends, // Show Trends + mSillTrends, // Fill Trends + mShowLevels, // Show Levels + mShowConsolidations, // Show Consolidations + mShowRibbons, // Show Ribbons + mShowHull, // Show Hull + mShowSSLChannel, // Show SSL Channel + mShowFibo1Levels, // Show Fibo 1st Level + mShowFibo2Levels, // Show Fibo 2nd Level + mShowFibo3Levels // Show Fibo 3rd Level + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XMANInputs GetConfig() + { + // + XMANInputs result; + + // + result.candleTimerColor = mCandleTimerColor; + result.candleTimerCorner = mCandleTimerCorner; + result.upColor = mUpColor; + result.downColor = mDownColor; + result.lineColor = mLineColor; + result.bearishColor = mBearishColor; + result.bullishColor = mBullishColor; + result.volumesColor = mVolumesColor; + result.l1Method = mL1Method; + result.l1Period = mL1Period; + result.l2Method = mL2Method; + result.l2Period = mL2Period; + result.l3Method = mL3Method; + result.l3Period = mL3Period; + result.l4Method = mL4Method; + result.l4Period = mL4Period; + result.fiboLevel1 = mFiboLevel1; + result.fiboLevel2 = mFiboLevel2; + result.fiboLevel3 = mFiboLevel3; + result.hhMode = mHHMode; + result.llMode = mLLMode; + result.trendMultiplier = mTrendMultiplier; + result.trendPriceAppliedTo = mTrendPriceAppliedTo; + result.ribbonMode = mRibbonMode; + result.hullDivisor = mHullDivisor; + result.hullUpAppliedTo = mHullUpAppliedTo; + result.hullDownAppliedTo = mHullDownAppliedTo; + result.sslcMode = mSslcMode; + result.sslcUpAppliedTo = mSslcUpAppliedTo; + result.sslcDownAppliedTo = mSslcDownAppliedTo; + result.showCandleTimer = mShowCandleTimer; + result.showCandles = mShowCandles; + result.showHKCandles = mShowHKCandles; + result.showPeaksAndVales = mShowPeaksAndVales; + result.showTrends = mShowTrends; + result.fillTrends = mSillTrends; + result.showLevels = mShowLevels; + result.showConsolidations = mShowConsolidations; + result.showRibbons = mShowRibbons; + result.showHull = mShowHull; + result.showSSLChannel = mShowSSLChannel; + result.showFibo1Levels = mShowFibo1Levels; + result.showFibo2Levels = mShowFibo2Levels; + result.showFibo3Levels = mShowFibo3Levels; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XMANInputs &config) + { + // + bool result = false; + + // + mCandleTimerColor = config.candleTimerColor; + mCandleTimerCorner = config.candleTimerCorner; + mUpColor = config.upColor; + mDownColor = config.downColor; + mLineColor = config.lineColor; + mBearishColor = config.bearishColor; + mBullishColor = config.bullishColor; + mVolumesColor = config.volumesColor; + mL1Method = config.l1Method; + mL1Period = config.l1Period; + mL2Method = config.l2Method; + mL2Period = config.l2Period; + mL3Method = config.l3Method; + mL3Period = config.l3Period; + mL4Method = config.l4Method; + mL4Period = config.l4Period; + mFiboLevel1 = config.fiboLevel1; + mFiboLevel2 = config.fiboLevel2; + mFiboLevel3 = config.fiboLevel3; + mHHMode = config.hhMode; + mLLMode = config.llMode; + mTrendMultiplier = config.trendMultiplier; + mTrendPriceAppliedTo = config.trendPriceAppliedTo; + mRibbonMode = config.ribbonMode; + mHullDivisor = config.hullDivisor; + mHullUpAppliedTo = config.hullUpAppliedTo; + mHullDownAppliedTo = config.hullDownAppliedTo; + mSslcMode = config.sslcMode; + mSslcUpAppliedTo = config.sslcUpAppliedTo; + mSslcDownAppliedTo = config.sslcDownAppliedTo; + mShowCandleTimer = config.showCandleTimer; + mShowCandles = config.showCandles; + mShowHKCandles = config.showHKCandles; + mShowPeaksAndVales = config.showPeaksAndVales; + mShowTrends = config.showTrends; + mSillTrends = config.fillTrends; + mShowLevels = config.showLevels; + mShowConsolidations = config.showConsolidations; + mShowRibbons = config.showRibbons; + mShowHull = config.showHull; + mShowSSLChannel = config.showSSLChannel; + mShowFibo1Levels = config.showFibo1Levels; + mShowFibo2Levels = config.showFibo2Levels; + mShowFibo3Levels = config.showFibo3Levels; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + // + // Peaks ... + ArraySetAsSeries(peaksBuffer, true); + CopyBuffer( + mHandler, + XMAN_PEAKS_LINE, + barIndex, + mLoopbackBars, + peaksBuffer); + + // + // Peaks State ... + ArraySetAsSeries(peaksStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_PEAKS_STATE_LINE, + barIndex, + mLoopbackBars, + peaksStateBuffer); + + // + // Vales ... + ArraySetAsSeries(valesBuffer, true); + CopyBuffer( + mHandler, + XMAN_VALES_LINE, + barIndex, + mLoopbackBars, + valesBuffer); + + // + // Vales State ... + ArraySetAsSeries(valesStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_VALES_STATE_LINE, + barIndex, + mLoopbackBars, + valesStateBuffer); + + // + // Fibo 1 ... + ArraySetAsSeries(fibLevel1Buffer, true); + CopyBuffer( + mHandler, + XMAN_FIB_L1_LINE, + barIndex, + mLoopbackBars, + fibLevel1Buffer); + + // + // Fibo 2 ... + ArraySetAsSeries(fibLevel2Buffer, true); + CopyBuffer( + mHandler, + XMAN_FIB_L2_LINE, + barIndex, + mLoopbackBars, + fibLevel2Buffer); + + // + // Fibo 3 ... + ArraySetAsSeries(fibLevel3Buffer, true); + CopyBuffer( + mHandler, + XMAN_FIB_L3_LINE, + barIndex, + mLoopbackBars, + fibLevel3Buffer); + + // + // Cycles ... + + // + // Short ... + + // + // High ... + ArraySetAsSeries(sHHBuffer, true); + CopyBuffer( + mHandler, + XMAN_SC_HH_LINE, + barIndex, + mLoopbackBars, + sHHBuffer); + + // + // High State ... + ArraySetAsSeries(sHHStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_SC_HH_STATE_LINE, + barIndex, + mLoopbackBars, + sHHStateBuffer); + + // + // High ... + ArraySetAsSeries(sLLBuffer, true); + CopyBuffer( + mHandler, + XMAN_SC_LL_LINE, + barIndex, + mLoopbackBars, + sLLBuffer); + + // + // High State ... + ArraySetAsSeries(sLLStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_SC_LL_STATE_LINE, + barIndex, + mLoopbackBars, + sLLStateBuffer); + + // + // Medium ... + + // + // High ... + ArraySetAsSeries(mHHBuffer, true); + CopyBuffer( + mHandler, + XMAN_MC_HH_LINE, + barIndex, + mLoopbackBars, + mHHBuffer); + + // + // High State ... + ArraySetAsSeries(mHHStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_MC_HH_STATE_LINE, + barIndex, + mLoopbackBars, + mHHStateBuffer); + + // + // High ... + ArraySetAsSeries(mLLBuffer, true); + CopyBuffer( + mHandler, + XMAN_MC_LL_LINE, + barIndex, + mLoopbackBars, + mLLBuffer); + + // + // High State ... + ArraySetAsSeries(mLLStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_MC_LL_STATE_LINE, + barIndex, + mLoopbackBars, + mLLStateBuffer); + + // + // Long ... + + // + // High ... + ArraySetAsSeries(lHHBuffer, true); + CopyBuffer( + mHandler, + XMAN_LC_HH_LINE, + barIndex, + mLoopbackBars, + lHHBuffer); + + // + // High State ... + ArraySetAsSeries(lHHStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_LC_HH_STATE_LINE, + barIndex, + mLoopbackBars, + lHHStateBuffer); + + // + // High ... + ArraySetAsSeries(lLLBuffer, true); + CopyBuffer( + mHandler, + XMAN_LC_LL_LINE, + barIndex, + mLoopbackBars, + lLLBuffer); + + // + // High State ... + ArraySetAsSeries(lLLStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_LC_LL_STATE_LINE, + barIndex, + mLoopbackBars, + lLLStateBuffer); + + // + // Hind ... + + // + // High ... + ArraySetAsSeries(hHHBuffer, true); + CopyBuffer( + mHandler, + XMAN_HC_HH_LINE, + barIndex, + mLoopbackBars, + hHHBuffer); + + // + // High State ... + ArraySetAsSeries(hHHStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_HC_HH_STATE_LINE, + barIndex, + mLoopbackBars, + hHHStateBuffer); + + // + // High ... + ArraySetAsSeries(hLLBuffer, true); + CopyBuffer( + mHandler, + XMAN_HC_LL_LINE, + barIndex, + mLoopbackBars, + hLLBuffer); + + // + // High State ... + ArraySetAsSeries(hLLStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_HC_LL_STATE_LINE, + barIndex, + mLoopbackBars, + hLLStateBuffer); + + // + // Trend ... + + // + // Trend ... + ArraySetAsSeries(trendBuffer, true); + CopyBuffer( + mHandler, + XMAN_TREND_LINE, + barIndex, + mLoopbackBars, + trendBuffer); + + // + // Trend State ... + ArraySetAsSeries(trendStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_TREND_STATE_LINE, + barIndex, + mLoopbackBars, + trendStateBuffer); + + // + // Ribbons ... + + // + // 1 ... + + // + // R1 ... + ArraySetAsSeries(ribbon1Buffer, true); + CopyBuffer( + mHandler, + XMAN_RB1_LINE, + barIndex, + mLoopbackBars, + ribbon1Buffer); + + // + // R1 State ... + ArraySetAsSeries(ribbon1StateBuffer, true); + CopyBuffer( + mHandler, + XMAN_RB1_STATE_LINE, + barIndex, + mLoopbackBars, + ribbon1StateBuffer); + + // + // 2 ... + + // + // R2 ... + ArraySetAsSeries(ribbon2Buffer, true); + CopyBuffer( + mHandler, + XMAN_RB2_LINE, + barIndex, + mLoopbackBars, + ribbon2Buffer); + + // + // R2 State ... + ArraySetAsSeries(ribbon2StateBuffer, true); + CopyBuffer( + mHandler, + XMAN_RB2_STATE_LINE, + barIndex, + mLoopbackBars, + ribbon2StateBuffer); + + // + // 3 ... + + // + // R3 ... + ArraySetAsSeries(ribbon3Buffer, true); + CopyBuffer( + mHandler, + XMAN_RB3_LINE, + barIndex, + mLoopbackBars, + ribbon3Buffer); + + // + // R3 State ... + ArraySetAsSeries(ribbon3StateBuffer, true); + CopyBuffer( + mHandler, + XMAN_RB3_STATE_LINE, + barIndex, + mLoopbackBars, + ribbon3StateBuffer); + + // + // 4 ... + + // + // R4 ... + ArraySetAsSeries(ribbon4Buffer, true); + CopyBuffer( + mHandler, + XMAN_RB4_LINE, + barIndex, + mLoopbackBars, + ribbon4Buffer); + + // + // R4 State ... + ArraySetAsSeries(ribbon4StateBuffer, true); + CopyBuffer( + mHandler, + XMAN_RB4_STATE_LINE, + barIndex, + mLoopbackBars, + ribbon4StateBuffer); + + // + // 5 ... + + // + // R5 ... + ArraySetAsSeries(ribbon5Buffer, true); + CopyBuffer( + mHandler, + XMAN_RB5_LINE, + barIndex, + mLoopbackBars, + ribbon5Buffer); + + // + // R5 State ... + ArraySetAsSeries(ribbon5StateBuffer, true); + CopyBuffer( + mHandler, + XMAN_RB5_STATE_LINE, + barIndex, + mLoopbackBars, + ribbon5StateBuffer); + + // + // 6 ... + + // + // R6 ... + ArraySetAsSeries(ribbon6Buffer, true); + CopyBuffer( + mHandler, + XMAN_RB6_LINE, + barIndex, + mLoopbackBars, + ribbon6Buffer); + + // + // R6 State ... + ArraySetAsSeries(ribbon6StateBuffer, true); + CopyBuffer( + mHandler, + XMAN_RB6_STATE_LINE, + barIndex, + mLoopbackBars, + ribbon6StateBuffer); + + // + // SSL Channel ... + + // + // UP ... + ArraySetAsSeries(sslUpBuffer, true); + CopyBuffer( + mHandler, + XMAN_SSLC_UP_LINE, + barIndex, + mLoopbackBars, + sslUpBuffer); + + // + // DOWN ... + ArraySetAsSeries(sslDownBuffer, true); + CopyBuffer( + mHandler, + XMAN_SSLC_DOWN_LINE, + barIndex, + mLoopbackBars, + sslDownBuffer); + + // + // HULL Trend ... + + // + // UP ... + ArraySetAsSeries(hullUpBuffer, true); + CopyBuffer( + mHandler, + XMAN_HULL_UP_LINE, + barIndex, + mLoopbackBars, + hullUpBuffer); + + // + // UP State ... + ArraySetAsSeries(hullUpStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_HULL_UP_STATE_LINE, + barIndex, + mLoopbackBars, + hullUpStateBuffer); + + // + // DOWN ... + ArraySetAsSeries(hullDownBuffer, true); + CopyBuffer( + mHandler, + XMAN_HULL_DOWN_LINE, + barIndex, + mLoopbackBars, + hullDownBuffer); + + // + // DOWN State ... + ArraySetAsSeries(hullDownStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_HULL_DOWN_STATE_LINE, + barIndex, + mLoopbackBars, + hullDownStateBuffer); + + // + // Hiken Ashi ... + + // + // Open ... + ArraySetAsSeries(hkOpenBuffer, true); + CopyBuffer( + mHandler, + XMAN_HK_OPEN_LINE, + barIndex, + mLoopbackBars, + hkOpenBuffer); + + // + // High ... + ArraySetAsSeries(hkHighBuffer, true); + CopyBuffer( + mHandler, + XMAN_HK_HIGH_LINE, + barIndex, + mLoopbackBars, + hkHighBuffer); + + // + // Low ... + ArraySetAsSeries(hkLowBuffer, true); + CopyBuffer( + mHandler, + XMAN_HK_LOW_LINE, + barIndex, + mLoopbackBars, + hkLowBuffer); + + // + // Close ... + ArraySetAsSeries(hkCloseBuffer, true); + CopyBuffer( + mHandler, + XMAN_HK_CLOSE_LINE, + barIndex, + mLoopbackBars, + hkCloseBuffer); + + // + // Close ... + ArraySetAsSeries(hkStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_HK_STATE_LINE, + barIndex, + mLoopbackBars, + hkStateBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XMANInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XMANInfo result; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + // Buffers ... + + // + Copy(peaksBuffer, + result.peaks); + Copy(peaksStateBuffer, + result.peaksStates); + Copy(valesBuffer, + result.vales); + Copy(valesStateBuffer, + result.valesStates); + + // + Copy(fibLevel1Buffer, + result.fibLevel1s); + Copy(fibLevel2Buffer, + result.fibLevel2s); + Copy(fibLevel3Buffer, + result.fibLevel3s); + + // + Copy(sHHBuffer, + result.sHHs); + Copy(sHHStateBuffer, + result.sHHStates); + Copy(sLLBuffer, + result.sLLs); + Copy(sLLStateBuffer, + result.sLLStates); + + // + Copy(mHHBuffer, + result.mHHs); + Copy(mHHStateBuffer, + result.mHHStates); + Copy(mLLBuffer, + result.mLLs); + Copy(mLLStateBuffer, + result.mLLStates); + + // + Copy(lHHBuffer, + result.lHHs); + Copy(lHHStateBuffer, + result.lHHStates); + Copy(lLLBuffer, + result.lLLs); + Copy(lLLStateBuffer, + result.lLLStates); + + // + Copy(hHHBuffer, + result.hHHs); + Copy(hHHStateBuffer, + result.hHHStates); + Copy(hLLBuffer, + result.hLLs); + Copy(hLLStateBuffer, + result.hLLStates); + + // + Copy(trendBuffer, + result.trends); + Copy(trendStateBuffer, + result.trendStates); + + // + Copy(ribbon1Buffer, + result.ribbon1s); + Copy(ribbon1StateBuffer, + result.ribbon1States); + + // + Copy(ribbon2Buffer, + result.ribbon2s); + Copy(ribbon2StateBuffer, + result.ribbon2States); + + // + Copy(ribbon3Buffer, + result.ribbon3s); + Copy(ribbon3StateBuffer, + result.ribbon3States); + + // + Copy(ribbon4Buffer, + result.ribbon4s); + Copy(ribbon4StateBuffer, + result.ribbon4States); + + // + Copy(ribbon5Buffer, + result.ribbon5s); + Copy(ribbon5StateBuffer, + result.ribbon5States); + + // + Copy(ribbon6Buffer, + result.ribbon6s); + Copy(ribbon6StateBuffer, + result.ribbon6States); + + // + Copy(sslUpBuffer, + result.sslUps); + Copy(sslDownBuffer, + result.sslDowns); + + // + Copy(hullUpBuffer, + result.hullUps); + Copy(hullUpStateBuffer, + result.hullUpStates); + Copy(hullDownBuffer, + result.hullDowns); + Copy(hullDownStateBuffer, + result.hullDownStates); + + // + Copy(hkOpenBuffer, + result.hkOpens); + Copy(hkHighBuffer, + result.hkHighs); + Copy(hkLowBuffer, + result.hkLows); + Copy(hkCloseBuffer, + result.hkCloses); + Copy(hkStateBuffer, + result.hkStates); + + // + // Conditions ... + bool isNewPeak = + // + peaksStateBuffer[barIndex] != EMPTY_VALUE + // + ; + bool isNewVale = + // + valesStateBuffer[barIndex] != EMPTY_VALUE + // + ; + + // + // XSTR ... + + // + // Reading Temp ... + ENUM_XMAN_STATES trendState = (ENUM_XMAN_STATES)trendStateBuffer[barIndex]; + ENUM_XMAN_STATES trendStatePrev = (ENUM_XMAN_STATES)trendStateBuffer[barIndex + 1]; + + // + bool isTrendBullish = + // + trendState == XMAN_STATE_BULLISH + // + ; + + // + bool isTrendPrevBullish = + // + trendStatePrev == XMAN_STATE_BULLISH + // + ; + + // + bool isTrendSwitchedToBullish = + // + isTrendBullish && + !isTrendPrevBullish + // + ; + + // + bool isTrendBearish = + // + trendState == XMAN_STATE_BEARISH + // + ; + + // + bool isTrendPrevBearish = + // + trendStatePrev == XMAN_STATE_BEARISH + // + ; + + // + bool isTrendSwitchedToBearish = + // + isTrendBearish && + !isTrendPrevBearish + // + ; + + // + bool isTrendNeutural = + // + !isTrendBullish && + !isTrendBearish + // + ; + + // + bool isTrendPrevNeutural = + // + !isTrendPrevBullish && + !isTrendPrevBearish + // + ; + + // + bool isTrendSwitchedToNeutural = + // + isTrendNeutural && + !isTrendPrevNeutural + // + ; + + // + // XSSLC ... + + // + bool isSSLBullish = + // + sslUpBuffer[barIndex] > sslDownBuffer[barIndex] + // + ; + + // + bool isSSLPrevBullish = + // + sslUpBuffer[barIndex + 1] > sslDownBuffer[barIndex + 1] + // + ; + + // + bool isSSLSwitchedToBullish = + // + isSSLBullish && + !isSSLPrevBullish + // + ; + + // + bool isSSLBearish = + // + sslUpBuffer[barIndex] < sslDownBuffer[barIndex] + // + ; + + // + bool isSSLPrevBearish = + // + sslUpBuffer[barIndex + 1] < sslDownBuffer[barIndex + 1] + // + ; + + // + bool isSSLSwitchedBearish = + // + isSSLBearish && + !isSSLPrevBearish + // + ; + + // + bool isSSLNeutural = + // + !isSSLBullish && + !isSSLBearish + // + ; + + // + bool isSSLPrevNeutural = + // + !isSSLPrevBullish && + !isSSLPrevBearish + // + ; + + // + bool isSSLSwitchedNeutural = + // + isSSLNeutural && + !isSSLPrevNeutural + // + ; + + // + // XHULL ... + + // + bool isHullUpBullish = + // + hullUpStateBuffer[barIndex] == XMAN_STATE_BULLISH + // + ; + + // + bool isHullUpPrevBullish = + // + hullUpStateBuffer[barIndex + 1] == XMAN_STATE_BULLISH + // + ; + + // + bool isHullDownBullish = + // + hullDownStateBuffer[barIndex] == XMAN_STATE_BULLISH + // + ; + + // + bool isHullDownPrevBullish = + // + hullDownStateBuffer[barIndex + 1] == XMAN_STATE_BULLISH + // + ; + + // + bool isHullBullish = + // + isHullUpBullish && + isHullDownBullish + // + ; + + // + bool isHullPrevBullish = + // + isHullUpPrevBullish && + isHullDownPrevBullish + // + ; + + // + bool isHullSwitchedToBullish = + // + isHullBullish && + !isHullPrevBullish + // + ; + + // + bool isHullUpBearish = + // + hullUpStateBuffer[barIndex] == XMAN_STATE_BEARISH + // + ; + + // + bool isHullUpPrevBearish = + // + hullUpStateBuffer[barIndex + 1] == XMAN_STATE_BEARISH + // + ; + + // + bool isHullDownBearish = + // + hullDownStateBuffer[barIndex] == XMAN_STATE_BEARISH + // + ; + + // + bool isHullDownPrevBearish = + // + hullDownStateBuffer[barIndex + 1] == XMAN_STATE_BEARISH + // + ; + + // + bool isHullBearish = + // + isHullUpBearish && + isHullDownBearish + // + ; + + // + bool isHullPrevBearish = + // + isHullUpPrevBearish && + isHullDownPrevBearish + // + ; + + // + bool isHullSwitchedToBearish = + // + isHullBearish && + !isHullPrevBearish + // + ; + + // + bool isHullUpNeutural = + // + !isHullUpBullish && + !isHullUpBearish + // + ; + + // + bool isHullUpPrevNeutural = + // + !isHullUpPrevBullish && + !isHullUpPrevBearish + // + ; + + // + bool isHullDownNeutural = + // + !isHullDownBullish && + !isHullDownBearish + // + ; + + // + bool isHullDownPrevNeutural = + // + !isHullDownPrevBullish && + !isHullDownPrevBearish + // + ; + + // + bool isHullNeutural = + // + isHullUpNeutural && + isHullDownNeutural + // + ; + + // + bool isHullPrevNeutural = + // + isHullUpPrevNeutural && + isHullDownPrevNeutural + // + ; + + // + bool isHullSwitchedToNeutural = + // + isHullNeutural && + !isHullPrevNeutural + // + ; + + // + // XHK ... + + // + // Hiken Ashi ... + bool isHKBullish = + // + hkStateBuffer[barIndex] == XMAN_STATE_BULLISH + // + ; + bool isHKBearish = + // + hkStateBuffer[barIndex] == XMAN_STATE_BEARISH + // + ; + + // + // Cycles ... + + // + // Level 1 ... + + // + ENUM_XMAN_STATES scHState = (ENUM_XMAN_STATES)sHHStateBuffer[barIndex]; + ENUM_XMAN_STATES scHStatePrev = (ENUM_XMAN_STATES)sHHStateBuffer[barIndex + 1]; + ENUM_XMAN_STATES scLState = (ENUM_XMAN_STATES)sLLStateBuffer[barIndex]; + ENUM_XMAN_STATES scLStatePrev = (ENUM_XMAN_STATES)sLLStateBuffer[barIndex + 1]; + + // + // Bullish ... + + // + bool isSCHBullish = scHState == XMAN_STATE_BULLISH; + bool isSCHPrevBullish = scHStatePrev == XMAN_STATE_BULLISH; + + // + bool isSCLBullish = scLState == XMAN_STATE_BULLISH; + bool isSCLPrevBullish = scLStatePrev == XMAN_STATE_BULLISH; + + // + bool isSCBullish = + isSCHBullish && + isSCLBullish; + + // + bool isSCPrevBullish = + isSCHPrevBullish && + isSCLPrevBullish; + + // + bool isSCHSwitchedToBullish = + isSCHBullish && + !isSCHPrevBullish; + + // + bool isSCLSwitchedToBullish = + isSCLBullish && + !isSCLPrevBullish; + + // + bool isSCSwitchedToBullish = + isSCBullish && + !isSCPrevBullish; + + // + // Bearish ... + + // + bool isSCHBearish = scHState == XMAN_STATE_BEARISH; + bool isSCHPrevBearish = scHStatePrev == XMAN_STATE_BEARISH; + + // + bool isSCLBearish = scLState == XMAN_STATE_BEARISH; + bool isSCLPrevBearish = scLStatePrev == XMAN_STATE_BEARISH; + + // + bool isSCBearish = + isSCHBearish && + isSCLBearish; + + // + bool isSCPrevBearish = + isSCHPrevBearish && + isSCLPrevBearish; + + // + bool isSCHSwitchedToBearish = + isSCHBearish && + !isSCHPrevBearish; + + // + bool isSCLSwitchedToBearish = + isSCLBearish && + !isSCLPrevBearish; + + // + bool isSCSwitchedToBearish = + isSCBearish && + !isSCPrevBearish; + + // + // Neutural ... + + // + bool isSCHNeutural = + !isSCHBullish && + !isSCHBearish; + + // + bool isSCHPrevNeutural = + !isSCHPrevBullish && + !isSCHPrevBearish; + + // + bool isSCLNeutural = + !isSCLBullish && + !isSCLBearish; + + // + bool isSCLPrevNeutural = + !isSCLPrevBullish && + !isSCLPrevBearish; + + // + bool isSCNeutural = + isSCHNeutural && + isSCLNeutural; + + // + bool isSCPrevNeutural = + isSCHPrevNeutural && + isSCLPrevNeutural; + + // + bool isSCHSwitchedToNeutural = + isSCHNeutural && + !isSCHPrevNeutural; + + // + bool isSCLSwitchedToNeutural = + isSCLNeutural && + !isSCLPrevNeutural; + + // + bool isSCSwitchedToNeutural = + isSCNeutural && + !isSCPrevNeutural; + + // + // Level 2 ... + + // + ENUM_XMAN_STATES mcHState = (ENUM_XMAN_STATES)mHHStateBuffer[barIndex]; + ENUM_XMAN_STATES mcHStatePrev = (ENUM_XMAN_STATES)mHHStateBuffer[barIndex + 1]; + ENUM_XMAN_STATES mcLState = (ENUM_XMAN_STATES)mLLStateBuffer[barIndex]; + ENUM_XMAN_STATES mcLStatePrev = (ENUM_XMAN_STATES)mLLStateBuffer[barIndex + 1]; + + // + // Bullish ... + + // + bool isMCHBullish = mcHState == XMAN_STATE_BULLISH; + bool isMCHPrevBullish = mcHStatePrev == XMAN_STATE_BULLISH; + + // + bool isMCLBullish = mcLState == XMAN_STATE_BULLISH; + bool isMCLPrevBullish = mcLStatePrev == XMAN_STATE_BULLISH; + + // + bool isMCBullish = + isMCHBullish && + isMCLBullish; + + // + bool isMCPrevBullish = + isMCHPrevBullish && + isMCLPrevBullish; + + // + bool isMCHSwitchedToBullish = + isMCHBullish && + !isMCHPrevBullish; + + // + bool isMCLSwitchedToBullish = + isMCLBullish && + !isMCLPrevBullish; + + // + bool isMCSwitchedToBullish = + isMCBullish && + !isMCPrevBullish; + + // + // Bearish ... + + // + bool isMCHBearish = mcHState == XMAN_STATE_BEARISH; + bool isMCHPrevBearish = mcHStatePrev == XMAN_STATE_BEARISH; + + // + bool isMCLBearish = mcLState == XMAN_STATE_BEARISH; + bool isMCLPrevBearish = mcLStatePrev == XMAN_STATE_BEARISH; + + // + bool isMCBearish = + isMCHBearish && + isMCLBearish; + + // + bool isMCPrevBearish = + isMCHPrevBearish && + isMCLPrevBearish; + + // + bool isMCHSwitchedToBearish = + isMCHBearish && + !isMCHPrevBearish; + + // + bool isMCLSwitchedToBearish = + isMCLBearish && + !isMCLPrevBearish; + + // + bool isMCSwitchedToBearish = + isMCBearish && + !isMCPrevBearish; + + // + // Neutural ... + + // + bool isMCHNeutural = + !isMCHBullish && + !isMCHBearish; + + // + bool isMCHPrevNeutural = + !isMCHPrevBullish && + !isMCHPrevBearish; + + // + bool isMCLNeutural = + !isMCLBullish && + !isMCLBearish; + + // + bool isMCLPrevNeutural = + !isMCLPrevBullish && + !isMCLPrevBearish; + + // + bool isMCNeutural = + isMCHNeutural && + isMCLNeutural; + + // + bool isMCPrevNeutural = + isMCHPrevNeutural && + isMCLPrevNeutural; + + // + bool isMCHSwitchedToNeutural = + isMCHNeutural && + !isMCHPrevNeutural; + + // + bool isMCLSwitchedToNeutural = + isMCLNeutural && + !isMCLPrevNeutural; + + // + bool isMCSwitchedToNeutural = + isMCNeutural && + !isMCPrevNeutural; + + // + // Level 3 ... + + // + ENUM_XMAN_STATES lcHState = (ENUM_XMAN_STATES)lHHStateBuffer[barIndex]; + ENUM_XMAN_STATES lcHStatePrev = (ENUM_XMAN_STATES)lHHStateBuffer[barIndex + 1]; + ENUM_XMAN_STATES lcLState = (ENUM_XMAN_STATES)lLLStateBuffer[barIndex]; + ENUM_XMAN_STATES lcLStatePrev = (ENUM_XMAN_STATES)lLLStateBuffer[barIndex + 1]; + + // + // Bullish ... + + // + bool isLCHBullish = lcHState == XMAN_STATE_BULLISH; + bool isLCHPrevBullish = lcHStatePrev == XMAN_STATE_BULLISH; + + // + bool isLCLBullish = lcLState == XMAN_STATE_BULLISH; + bool isLCLPrevBullish = lcLStatePrev == XMAN_STATE_BULLISH; + + // + bool isLCBullish = + isLCHBullish && + isLCLBullish; + + // + bool isLCPrevBullish = + isLCHPrevBullish && + isLCLPrevBullish; + + // + bool isLCHSwitchedToBullish = + isLCHBullish && + !isLCHPrevBullish; + + // + bool isLCLSwitchedToBullish = + isLCLBullish && + !isLCLPrevBullish; + + // + bool isLCSwitchedToBullish = + isLCBullish && + !isLCPrevBullish; + + // + // Bearish ... + + // + bool isLCHBearish = lcHState == XMAN_STATE_BEARISH; + bool isLCHPrevBearish = lcHStatePrev == XMAN_STATE_BEARISH; + + // + bool isLCLBearish = lcLState == XMAN_STATE_BEARISH; + bool isLCLPrevBearish = lcLStatePrev == XMAN_STATE_BEARISH; + + // + bool isLCBearish = + isLCHBearish && + isLCLBearish; + + // + bool isLCPrevBearish = + isLCHPrevBearish && + isLCLPrevBearish; + + // + bool isLCHSwitchedToBearish = + isLCHBearish && + !isLCHPrevBearish; + + // + bool isLCLSwitchedToBearish = + isLCLBearish && + !isLCLPrevBearish; + + // + bool isLCSwitchedToBearish = + isLCBearish && + !isLCPrevBearish; + + // + // Neutural ... + + // + bool isLCHNeutural = + !isLCHBullish && + !isLCHBearish; + + // + bool isLCHPrevNeutural = + !isLCHPrevBullish && + !isLCHPrevBearish; + + // + bool isLCLNeutural = + !isLCLBullish && + !isLCLBearish; + + // + bool isLCLPrevNeutural = + !isLCLPrevBullish && + !isLCLPrevBearish; + + // + bool isLCNeutural = + isLCHNeutural && + isLCLNeutural; + + // + bool isLCPrevNeutural = + isLCHPrevNeutural && + isLCLPrevNeutural; + + // + bool isLCHSwitchedToNeutural = + isLCHNeutural && + !isLCHPrevNeutural; + + // + bool isLCLSwitchedToNeutural = + isLCLNeutural && + !isLCLPrevNeutural; + + // + bool isLCSwitchedToNeutural = + isLCNeutural && + !isLCPrevNeutural; + + // + // Level 4 ... + + // + ENUM_XMAN_STATES hcHState = (ENUM_XMAN_STATES)hHHStateBuffer[barIndex]; + ENUM_XMAN_STATES hcHStatePrev = (ENUM_XMAN_STATES)hHHStateBuffer[barIndex + 1]; + ENUM_XMAN_STATES hcLState = (ENUM_XMAN_STATES)hLLStateBuffer[barIndex]; + ENUM_XMAN_STATES hcLStatePrev = (ENUM_XMAN_STATES)hLLStateBuffer[barIndex + 1]; + + // + // Bullish ... + + // + bool isHCHBullish = hcHState == XMAN_STATE_BULLISH; + bool isHCHPrevBullish = hcHStatePrev == XMAN_STATE_BULLISH; + + // + bool isHCLBullish = hcLState == XMAN_STATE_BULLISH; + bool isHCLPrevBullish = hcLStatePrev == XMAN_STATE_BULLISH; + + // + bool isHCBullish = + isHCHBullish && + isHCLBullish; + + // + bool isHCPrevBullish = + isHCHPrevBullish && + isHCLPrevBullish; + + // + bool isHCHSwitchedToBullish = + isHCHBullish && + !isHCHPrevBullish; + + // + bool isHCLSwitchedToBullish = + isHCLBullish && + !isHCLPrevBullish; + + // + bool isHCSwitchedToBullish = + isHCBullish && + !isHCPrevBullish; + + // + // Bearish ... + + // + bool isHCHBearish = hcHState == XMAN_STATE_BEARISH; + bool isHCHPrevBearish = hcHStatePrev == XMAN_STATE_BEARISH; + + // + bool isHCLBearish = hcLState == XMAN_STATE_BEARISH; + bool isHCLPrevBearish = hcLStatePrev == XMAN_STATE_BEARISH; + + // + bool isHCBearish = + isHCHBearish && + isHCLBearish; + + // + bool isHCPrevBearish = + isHCHPrevBearish && + isHCLPrevBearish; + + // + bool isHCHSwitchedToBearish = + isHCHBearish && + !isHCHPrevBearish; + + // + bool isHCLSwitchedToBearish = + isHCLBearish && + !isHCLPrevBearish; + + // + bool isHCSwitchedToBearish = + isHCBearish && + !isHCPrevBearish; + + // + // Neutural ... + + // + bool isHCHNeutural = + !isHCHBullish && + !isHCHBearish; + + // + bool isHCHPrevNeutural = + !isHCHPrevBullish && + !isHCHPrevBearish; + + // + bool isHCLNeutural = + !isHCLBullish && + !isHCLBearish; + + // + bool isHCLPrevNeutural = + !isHCLPrevBullish && + !isHCLPrevBearish; + + // + bool isHCNeutural = + isHCHNeutural && + isHCLNeutural; + + // + bool isHCPrevNeutural = + isHCHPrevNeutural && + isHCLPrevNeutural; + + // + bool isHCHSwitchedToNeutural = + isHCHNeutural && + !isHCHPrevNeutural; + + // + bool isHCLSwitchedToNeutural = + isHCLNeutural && + !isHCLPrevNeutural; + + // + bool isHCSwitchedToNeutural = + isHCNeutural && + !isHCPrevNeutural; + + // + // Ribbons ... + + // + // R1 ... + ENUM_XMAN_STATES r1State = (ENUM_XMAN_STATES)ribbon1StateBuffer[barIndex]; + ENUM_XMAN_STATES r1StatePrev = (ENUM_XMAN_STATES)ribbon1StateBuffer[barIndex + 1]; + + // + // R2 ... + ENUM_XMAN_STATES r2State = (ENUM_XMAN_STATES)ribbon2StateBuffer[barIndex]; + ENUM_XMAN_STATES r2StatePrev = (ENUM_XMAN_STATES)ribbon2StateBuffer[barIndex + 1]; + + // + // R3 ... + ENUM_XMAN_STATES r3State = (ENUM_XMAN_STATES)ribbon3StateBuffer[barIndex]; + ENUM_XMAN_STATES r3StatePrev = (ENUM_XMAN_STATES)ribbon3StateBuffer[barIndex + 1]; + + // + // R4 ... + ENUM_XMAN_STATES r4State = (ENUM_XMAN_STATES)ribbon4StateBuffer[barIndex]; + ENUM_XMAN_STATES r4StatePrev = (ENUM_XMAN_STATES)ribbon4StateBuffer[barIndex + 1]; + + // + // R5 ... + ENUM_XMAN_STATES r5State = (ENUM_XMAN_STATES)ribbon5StateBuffer[barIndex]; + ENUM_XMAN_STATES r5StatePrev = (ENUM_XMAN_STATES)ribbon5StateBuffer[barIndex + 1]; + + // + // R6 ... + ENUM_XMAN_STATES r6State = (ENUM_XMAN_STATES)ribbon6StateBuffer[barIndex]; + ENUM_XMAN_STATES r6StatePrev = (ENUM_XMAN_STATES)ribbon6StateBuffer[barIndex + 1]; + + // + // Bullish ... + + // + bool isRibbon1Bullish = r1State == XMAN_STATE_BULLISH; + bool isRibbon2Bullish = r2State == XMAN_STATE_BULLISH; + bool isRibbon3Bullish = r3State == XMAN_STATE_BULLISH; + bool isRibbon4Bullish = r4State == XMAN_STATE_BULLISH; + bool isRibbon5Bullish = r5State == XMAN_STATE_BULLISH; + bool isRibbon6Bullish = r6State == XMAN_STATE_BULLISH; + + // + bool isRibbon1PrevBullish = r1StatePrev == XMAN_STATE_BULLISH; + bool isRibbon2PrevBullish = r2StatePrev == XMAN_STATE_BULLISH; + bool isRibbon3PrevBullish = r3StatePrev == XMAN_STATE_BULLISH; + bool isRibbon4PrevBullish = r4StatePrev == XMAN_STATE_BULLISH; + bool isRibbon5PrevBullish = r5StatePrev == XMAN_STATE_BULLISH; + bool isRibbon6PrevBullish = r6StatePrev == XMAN_STATE_BULLISH; + + // + // Bearish ... + + // + bool isRibbon1Bearish = r1State == XMAN_STATE_BEARISH; + bool isRibbon2Bearish = r2State == XMAN_STATE_BEARISH; + bool isRibbon3Bearish = r3State == XMAN_STATE_BEARISH; + bool isRibbon4Bearish = r4State == XMAN_STATE_BEARISH; + bool isRibbon5Bearish = r5State == XMAN_STATE_BEARISH; + bool isRibbon6Bearish = r6State == XMAN_STATE_BEARISH; + + // + bool isRibbon1PrevBearish = r1StatePrev == XMAN_STATE_BEARISH; + bool isRibbon2PrevBearish = r2StatePrev == XMAN_STATE_BEARISH; + bool isRibbon3PrevBearish = r3StatePrev == XMAN_STATE_BEARISH; + bool isRibbon4PrevBearish = r4StatePrev == XMAN_STATE_BEARISH; + bool isRibbon5PrevBearish = r5StatePrev == XMAN_STATE_BEARISH; + bool isRibbon6PrevBearish = r6StatePrev == XMAN_STATE_BEARISH; + + // + // Neutural ... + + // + bool isRibbon1Neutural = + !isRibbon1Bullish && + !isRibbon1Bearish; + + // + bool isRibbon2Neutural = + !isRibbon2Bullish && + !isRibbon2Bearish; + + // + bool isRibbon3Neutural = + !isRibbon3Bullish && + !isRibbon3Bearish; + + // + bool isRibbon4Neutural = + !isRibbon4Bullish && + !isRibbon4Bearish; + + // + bool isRibbon5Neutural = + !isRibbon5Bullish && + !isRibbon5Bearish; + + // + bool isRibbon6Neutural = + !isRibbon6Bullish && + !isRibbon6Bearish; + + // + bool isRibbon1PrevNeutural = + !isRibbon1PrevBullish && + !isRibbon1PrevBearish; + + // + bool isRibbon2PrevNeutural = + !isRibbon2PrevBullish && + !isRibbon2PrevBearish; + + // + bool isRibbon3PrevNeutural = + !isRibbon3PrevBullish && + !isRibbon3PrevBearish; + + // + bool isRibbon4PrevNeutural = + !isRibbon4PrevBullish && + !isRibbon4PrevBearish; + + // + bool isRibbon5PrevNeutural = + !isRibbon5PrevBullish && + !isRibbon5PrevBearish; + + // + bool isRibbon6PrevNeutural = + !isRibbon6PrevBullish && + !isRibbon6PrevBearish; + + // + // All Ribbons ... + + // + bool isRibbonBullish = + isRibbon1Bullish && + isRibbon2Bullish && + isRibbon3Bullish && + isRibbon4Bullish && + isRibbon5Bullish && + isRibbon6Bullish; + // + bool isRibbonPrevBullish = + isRibbon1PrevBullish && + isRibbon2PrevBullish && + isRibbon3PrevBullish && + isRibbon4PrevBullish && + isRibbon5PrevBullish && + isRibbon6PrevBullish; + + // + bool isRibbonSwitchedToBullish = + isRibbonBullish && + !isRibbonPrevBullish; + + // + bool isRibbonBearish = + isRibbon1Bearish && + isRibbon2Bearish && + isRibbon3Bearish && + isRibbon4Bearish && + isRibbon5Bearish && + isRibbon6Bearish; + + // + bool isRibbonPrevBearish = + isRibbon1PrevBearish && + isRibbon2PrevBearish && + isRibbon3PrevBearish && + isRibbon4PrevBearish && + isRibbon5PrevBearish && + isRibbon6PrevBearish; + + // + bool isRibbonSwitchedToBearish = + isRibbonBearish && + !isRibbonPrevBearish; + + // + bool isRibbonNeutural = + isRibbon1Neutural && + isRibbon2Neutural && + isRibbon3Neutural && + isRibbon4Neutural && + isRibbon5Neutural && + isRibbon6Neutural; + + // + bool isRibbonPrevNeutural = + isRibbon1PrevNeutural && + isRibbon2PrevNeutural && + isRibbon3PrevNeutural && + isRibbon4PrevNeutural && + isRibbon5PrevNeutural && + isRibbon6PrevNeutural; + + // + bool isRibbonSwitchedToNeutural = + isRibbonNeutural && + !isRibbonPrevNeutural; + + // + result.isNewPeak = isNewPeak; + result.isNewVale = isNewVale; + result.isTrendBullish = isTrendBullish; + result.isTrendSwitchedToBullish = isTrendSwitchedToBullish; + result.isTrendBearish = isTrendBearish; + result.isTrendSwitchedToBearish = isTrendSwitchedToBearish; + result.isTrendNeutural = isTrendNeutural; + result.isTrendSwitchedToNeutural = isTrendSwitchedToNeutural; + result.isSSLBullish = isSSLBullish; + result.isSSLSwitchedToBullish = isSSLSwitchedToBullish; + result.isSSLBearish = isSSLBearish; + result.isSSLSwitchedBearish = isSSLSwitchedBearish; + result.isSSLNeutural = isSSLNeutural; + result.isSSLSwitchedNeutural = isSSLSwitchedNeutural; + result.isHullBullish = isHullBullish; + result.isHullUpBullish = isHullUpBullish; + result.isHullDownBullish = isHullDownBullish; + result.isHullSwitchedToBullish = isHullSwitchedToBullish; + result.isHullBearish = isHullBearish; + result.isHullUpBearish = isHullUpBearish; + result.isHullDownBearish = isHullDownBearish; + result.isHullSwitchedToBearish = isHullSwitchedToBearish; + result.isHullNeutural = isHullNeutural; + result.isHullUpNeutural = isHullUpNeutural; + result.isHullDownNeutural = isHullDownNeutural; + result.isHullSwitchedToNeutural = isHullSwitchedToNeutural; + result.isHKBullish = isHKBullish; + result.isHKBearish = isHKBearish; + result.isSCBullish = isSCBullish; + result.isSCHBullish = isSCHBullish; + result.isSCLBullish = isSCLBullish; + result.isSCSwitchedToBullish = isSCSwitchedToBullish; + result.isSCHSwitchedToBullish = isSCHSwitchedToBullish; + result.isSCLSwitchedToBullish = isSCLSwitchedToBullish; + result.isSCBearish = isSCBearish; + result.isSCHBearish = isSCHBearish; + result.isSCLBearish = isSCLBearish; + result.isSCSwitchedToBearish = isSCSwitchedToBearish; + result.isSCHSwitchedToBearish = isSCHSwitchedToBearish; + result.isSCLSwitchedToBearish = isSCLSwitchedToBearish; + result.isSCNeutural = isSCNeutural; + result.isSCHNeutural = isSCHNeutural; + result.isSCLNeutural = isSCLNeutural; + result.isSCSwitchedToNeutural = isSCSwitchedToNeutural; + result.isSCHSwitchedToNeutural = isSCHSwitchedToNeutural; + result.isSCLSwitchedToNeutural = isSCLSwitchedToNeutural; + result.isMCBullish = isMCBullish; + result.isMCHBullish = isMCHBullish; + result.isMCLBullish = isMCLBullish; + result.isMCSwitchedToBullish = isMCSwitchedToBullish; + result.isMCHSwitchedToBullish = isMCHSwitchedToBullish; + result.isMCLSwitchedToBullish = isMCLSwitchedToBullish; + result.isMCBearish = isMCBearish; + result.isMCHBearish = isMCHBearish; + result.isMCLBearish = isMCLBearish; + result.isMCSwitchedToBearish = isMCSwitchedToBearish; + result.isMCHSwitchedToBearish = isMCHSwitchedToBearish; + result.isMCLSwitchedToBearish = isMCLSwitchedToBearish; + result.isMCNeutural = isMCNeutural; + result.isMCHNeutural = isMCHNeutural; + result.isMCLNeutural = isMCLNeutural; + result.isMCSwitchedToNeutural = isMCSwitchedToNeutural; + result.isMCHSwitchedToNeutural = isMCHSwitchedToNeutural; + result.isMCLSwitchedToNeutural = isMCLSwitchedToNeutural; + result.isLCBullish = isLCBullish; + result.isLCHBullish = isLCHBullish; + result.isLCLBullish = isLCLBullish; + result.isLCSwitchedToBullish = isLCSwitchedToBullish; + result.isLCHSwitchedToBullish = isLCHSwitchedToBullish; + result.isLCLSwitchedToBullish = isLCLSwitchedToBullish; + result.isLCBearish = isLCBearish; + result.isLCHBearish = isLCHBearish; + result.isLCLBearish = isLCLBearish; + result.isLCSwitchedToBearish = isLCSwitchedToBearish; + result.isLCHSwitchedToBearish = isLCHSwitchedToBearish; + result.isLCLSwitchedToBearish = isLCLSwitchedToBearish; + result.isLCNeutural = isLCNeutural; + result.isLCHNeutural = isLCHNeutural; + result.isLCLNeutural = isLCLNeutural; + result.isLCSwitchedToNeutural = isLCSwitchedToNeutural; + result.isLCHSwitchedToNeutural = isLCHSwitchedToNeutural; + result.isLCLSwitchedToNeutural = isLCLSwitchedToNeutural; + result.isHCBullish = isHCBullish; + result.isHCHBullish = isHCHBullish; + result.isHCLBullish = isHCLBullish; + result.isHCSwitchedToBullish = isHCSwitchedToBullish; + result.isHCHSwitchedToBullish = isHCHSwitchedToBullish; + result.isHCLSwitchedToBullish = isHCLSwitchedToBullish; + result.isHCBearish = isHCBearish; + result.isHCHBearish = isHCHBearish; + result.isHCLBearish = isHCLBearish; + result.isHCSwitchedToBearish = isHCSwitchedToBearish; + result.isHCHSwitchedToBearish = isHCHSwitchedToBearish; + result.isHCLSwitchedToBearish = isHCLSwitchedToBearish; + result.isHCNeutural = isHCNeutural; + result.isHCHNeutural = isHCHNeutural; + result.isHCLNeutural = isHCLNeutural; + result.isHCSwitchedToNeutural = isHCSwitchedToNeutural; + result.isHCHSwitchedToNeutural = isHCHSwitchedToNeutural; + result.isHCLSwitchedToNeutural = isHCLSwitchedToNeutural; + result.isRibbon1Bullish = isRibbon1Bullish; + result.isRibbon2Bullish = isRibbon2Bullish; + result.isRibbon3Bullish = isRibbon3Bullish; + result.isRibbon4Bullish = isRibbon4Bullish; + result.isRibbon5Bullish = isRibbon5Bullish; + result.isRibbon6Bullish = isRibbon6Bullish; + result.isRibbon1Bearish = isRibbon1Bearish; + result.isRibbon2Bearish = isRibbon2Bearish; + result.isRibbon3Bearish = isRibbon3Bearish; + result.isRibbon4Bearish = isRibbon4Bearish; + result.isRibbon5Bearish = isRibbon5Bearish; + result.isRibbon6Bearish = isRibbon6Bearish; + result.isRibbon1Neutural = isRibbon1Neutural; + result.isRibbon2Neutural = isRibbon2Neutural; + result.isRibbon3Neutural = isRibbon3Neutural; + result.isRibbon4Neutural = isRibbon4Neutural; + result.isRibbon5Neutural = isRibbon5Neutural; + result.isRibbon6Neutural = isRibbon6Neutural; + result.isRibbonBullish = isRibbonBullish; + result.isRibbonSwitchedToBullish = isRibbonSwitchedToBullish; + result.isRibbonBearish = isRibbonBearish; + result.isRibbonSwitchedToBearish = isRibbonSwitchedToBearish; + result.isRibbonNeutural = isRibbonNeutural; + result.isRibbonSwitchedToNeutural = isRibbonSwitchedToNeutural; + + // + return result; + } + + // + // Protcted ... +protected: + // + // Private ... +private: + // + // Inputs ... + + // + // Candle Timer ... + color mCandleTimerColor; // Text Color + ENUM_BASE_CORNER mCandleTimerCorner; // Text Position + + // + // Chart Style ... + color mUpColor; // Up Color + color mDownColor; // Down Color + color mLineColor; // Line mode and Doji candlestick Color + color mBearishColor; // Bullish Color + color mBullishColor; // Bearish Color + color mVolumesColor; // Volumes Color + + // + // Market Cycles ... + + // + // Level 1 ... + ENUM_X_PERIOD_METHOD mL1Method; // How to Find Period + ENUM_TIMEFRAMES mL1Period; // Time Period + + // + // Level 2 ... + ENUM_X_PERIOD_METHOD mL2Method; // How to Find Period + ENUM_TIMEFRAMES mL2Period; // Time Period + + // + // Level 3 ... + ENUM_X_PERIOD_METHOD mL3Method; // How to Find Period + ENUM_TIMEFRAMES mL3Period; // Time Period + + // + // Level 4 ... + ENUM_X_PERIOD_METHOD mL4Method; // How to Find Period + ENUM_TIMEFRAMES mL4Period; // Time Period + + // + // Fibonacci ... + double mFiboLevel1; // Fibio 1st Level + double mFiboLevel2; // Fibio 2st Level + double mFiboLevel3; // Fibio 3rd Level + + // + // Boundary Detection Modes ... + ENUM_SERIESMODE mHHMode; // Highest High Calculation Method + ENUM_SERIESMODE mLLMode; // Lowest Low Calculation Method + + // + // Trend Detection + double mTrendMultiplier; // Multiplier + ENUM_APPLIED_PRICE mTrendPriceAppliedTo; // Applied To + + // + // Ribbon Detection ... + ENUM_X_MA_METHOD mRibbonMode; // How to Calculate + + // + // Hull Trend Detection ... + double mHullDivisor; // Divisor (Speed) + ENUM_APPLIED_PRICE mHullUpAppliedTo; // Up Zone Applied to + ENUM_APPLIED_PRICE mHullDownAppliedTo; // Down Zone Applied to + + // + // SSL Channel Detection ... + ENUM_X_MA_METHOD mSslcMode; // How to Calculate + ENUM_APPLIED_PRICE mSslcUpAppliedTo; // Up Applied To + ENUM_APPLIED_PRICE mSslcDownAppliedTo; // Down Applied To + + // + // Presentation ... + bool mShowCandleTimer; // Show Candle Time + bool mShowCandles; // Show Candles + bool mShowHKCandles; // Draw Hiken Ashi Candle + bool mShowPeaksAndVales; // Show Peaks and Vales + bool mShowTrends; // Show Trends + bool mSillTrends; // Fill Trends + bool mShowLevels; // Show Levels + bool mShowConsolidations; // Show Consolidations + bool mShowRibbons; // Show Ribbons + bool mShowHull; // Show Hull + bool mShowSSLChannel; // Show SSL Channel + bool mShowFibo1Levels; // Show Fibo 1st Level + bool mShowFibo2Levels; // Show Fibo 2nd Level + bool mShowFibo3Levels; // Show Fibo 3rd Level +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xmrb.helper.class.ex5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xmrb.helper.class.ex5 new file mode 100644 index 0000000..a5adbac Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xmrb.helper.class.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xmrb.helper.class.mq5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xmrb.helper.class.mq5 new file mode 100644 index 0000000..5680e05 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xmrb.helper.class.mq5 @@ -0,0 +1,895 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXMRBHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// Inputs ... +struct XMRBInputs +{ + // + // Ribbon 1 ... + int fast1Length; // Fast + int slow1Length; // Slow + + // + // Ribbon 2 ... + int fast2Length; // Fast + int slow2Length; // Slow + + // + // Ribbon 3 ... + int fast3Length; // Fast + int slow3Length; // Slow + + // + // Ribbon 4 ... + int fast4Length; // Fast + int slow4Length; // Slow + + // + // Ribbon 5 ... + int fast5Length; // Fast + int slow5Length; // Slow + + // + // Calculation ... + ENUM_MA_METHOD ribbonMode; // Mode + ENUM_APPLIED_PRICE ribbonAppliedTo; // Applied To + + // + // Presentation ... + bool showFastMa; // Show Fast + bool showSlowMa; // Show Slow + bool showRibbon; // Show Ribbon +}; + +// +// Index of Lines ... +enum ENUM_XMRB_BUFFERS +{ + // + // Main Requirements ... + XMRB_FAST_LINE = 0, + XMRB_SLOW_LINE = 1, + // + // RIBBON 1 ... + XMRB_R1_FAST_LINE = 2, + XMRB_R1_SLOW_LINE = 3, + // + // RIBBON 2 ... + XMRB_R2_FAST_LINE = 4, + XMRB_R2_SLOW_LINE = 5, + // + // RIBBON 3 ... + XMRB_R3_FAST_LINE = 6, + XMRB_R3_SLOW_LINE = 7, + // + // RIBBON 4 ... + XMRB_R4_FAST_LINE = 8, + XMRB_R4_SLOW_LINE = 9, + // + // RIBBON 5 ... + XMRB_R5_FAST_LINE = 10, + XMRB_R5_SLOW_LINE = 11, +}; + +// +// Retrieve Info Model ... +struct XMRBInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double fast; + double slow; + double fastR1; + double slowR1; + double fastR2; + double slowR2; + double fastR3; + double slowR3; + double fastR4; + double slowR4; + double fastR5; + double slowR5; + + // + double fasts[]; + double slows[]; + double fastR1s[]; + double slowR1s[]; + double fastR2s[]; + double slowR2s[]; + double fastR3s[]; + double slowR3s[]; + double fastR4s[]; + double slowR4s[]; + double fastR5s[]; + double slowR5s[]; + + // + // Conditions ... + + // + bool isFastOverSlow; + bool isFastCrossedOverSlow; + bool isFastUnderSlow; + bool isFastCrossedUnderSlow; + + // + bool isR1FastOverSlow; + bool isR1FastCrossedOverSlow; + bool isR1FastUnderSlow; + bool isR1FastCrossedUnderSlow; + + // + bool isR2FastOverSlow; + bool isR2FastCrossedOverSlow; + bool isR2FastUnderSlow; + bool isR2FastCrossedUnderSlow; + + // + bool isR3FastOverSlow; + bool isR3FastCrossedOverSlow; + bool isR3FastUnderSlow; + bool isR3FastCrossedUnderSlow; + + // + bool isR4FastOverSlow; + bool isR4FastCrossedOverSlow; + bool isR4FastUnderSlow; + bool isR4FastCrossedUnderSlow; + + // + bool isR5FastOverSlow; + bool isR5FastCrossedOverSlow; + bool isR5FastUnderSlow; + bool isR5FastCrossedUnderSlow; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXMRBHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double fastBuffer[]; + double slowBuffer[]; + double fastR1Buffer[]; + double slowR1Buffer[]; + double fastR2Buffer[]; + double slowR2Buffer[]; + double fastR3Buffer[]; + double slowR3Buffer[]; + double fastR4Buffer[]; + double slowR4Buffer[]; + double fastR5Buffer[]; + double slowR5Buffer[]; + + // + // Constructor ... + void XSCXMRBHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXMRBHelper() + { + } + + // + // START Properties ... + // + + // + // Show Fast ... + bool ShowFast( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowFastMa == show) + { + return true; + } + + // + mShowFastMa = show; + result = Init(); + + // + return result; + } + + // + // Show Slow ... + bool ShowSlow( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowSlowMa == show) + { + return true; + } + + // + mShowSlowMa = show; + result = Init(); + + // + return result; + } + + // + // Show Ribbon ... + bool ShowRibbon( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowRibbon == show) + { + return true; + } + + // + mShowRibbon = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XMRB" + GetTagPrefix(); + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = MathMax(mFast1Length, mFast2Length); + result = MathMax(result, mFast3Length); + result = MathMax(result, mFast4Length); + result = MathMax(result, mFast5Length); + + // + result = MathMax(result, mSlow1Length); + result = MathMax(result, mSlow2Length); + result = MathMax(result, mSlow3Length); + result = MathMax(result, mSlow4Length); + result = MathMax(result, mSlow5Length); + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Inputs ... + result = + // + (mFast1Length > 2 && + mFast2Length > mFast1Length && + mFast3Length > mFast2Length && + mFast4Length > mFast3Length && + mFast5Length > mFast4Length && + mSlow1Length > mFast1Length && + mSlow2Length > mFast2Length && + mSlow3Length > mFast3Length && + mSlow4Length > mFast4Length && + mSlow5Length > mFast5Length && + mSlow2Length > mSlow1Length && + mSlow3Length > mSlow2Length && + mSlow4Length > mSlow3Length && + mSlow5Length > mSlow4Length + // + ) + // + ; + if (!result) + { + return result; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xmrb", + // + // Inputs ... + // + // Ribbon 1 ... + "", + mFast1Length, + mSlow1Length, + // + // Ribbon 2 ... + "", + mFast2Length, + mSlow2Length, + // + // Ribbon 3 ... + "", + mFast3Length, + mSlow3Length, + // + // Ribbon 4 ... + "", + mFast4Length, + mSlow4Length, + // + // Ribbon 5 ... + "", + mFast5Length, + mSlow5Length, + // + // Calculation ... + "", + // + // Mode ... + mRibbonMode, + // + // Applied To ... + mRibbonAppliedTo, + // + // Presentation ... + "", + // + // Show Fast ... + mShowFastMa, + // + // Show Slow ... + mShowSlowMa, + // + // Show Ribbon ... + mShowRibbon + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XMRBInputs GetConfig() + { + // + XMRBInputs result; + + // + result.fast1Length = mFast1Length; + result.slow1Length = mSlow1Length; + result.fast2Length = mFast2Length; + result.slow2Length = mSlow2Length; + result.fast3Length = mFast3Length; + result.slow3Length = mSlow3Length; + result.fast4Length = mFast4Length; + result.slow4Length = mSlow4Length; + result.fast5Length = mFast5Length; + result.slow5Length = mSlow5Length; + result.ribbonMode = mRibbonMode; + result.ribbonAppliedTo = mRibbonAppliedTo; + result.showFastMa = mShowFastMa; + result.showSlowMa = mShowSlowMa; + result.showRibbon = mShowRibbon; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XMRBInputs &config) + { + // + bool result = false; + + // + mFast1Length = config.fast1Length; + mSlow1Length = config.slow1Length; + mFast2Length = config.fast2Length; + mSlow2Length = config.slow2Length; + mFast3Length = config.fast3Length; + mSlow3Length = config.slow3Length; + mFast4Length = config.fast4Length; + mSlow4Length = config.slow4Length; + mFast5Length = config.fast5Length; + mSlow5Length = config.slow5Length; + mRibbonMode = config.ribbonMode; + mRibbonAppliedTo = config.ribbonAppliedTo; + mShowFastMa = config.showFastMa; + mShowSlowMa = config.showSlowMa; + mShowRibbon = config.showRibbon; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + // + // FAST ... + ArraySetAsSeries(fastBuffer, true); + CopyBuffer( + mHandler, + XMRB_FAST_LINE, + barIndex, + mLoopbackBars, + fastBuffer); + + // + // SLOW ... + ArraySetAsSeries(slowBuffer, true); + CopyBuffer( + mHandler, + XMRB_SLOW_LINE, + barIndex, + mLoopbackBars, + slowBuffer); + + // + // RIBBON 1 ... + + // + // FAST ... + ArraySetAsSeries(fastR1Buffer, true); + CopyBuffer( + mHandler, + XMRB_R1_FAST_LINE, + barIndex, + mLoopbackBars, + fastR1Buffer); + + // + // SLOW ... + ArraySetAsSeries(slowR1Buffer, true); + CopyBuffer( + mHandler, + XMRB_R1_SLOW_LINE, + barIndex, + mLoopbackBars, + slowR1Buffer); + + // + // RIBBON 2 ... + + // + // FAST ... + ArraySetAsSeries(fastR2Buffer, true); + CopyBuffer( + mHandler, + XMRB_R2_FAST_LINE, + barIndex, + mLoopbackBars, + fastR2Buffer); + + // + // SLOW ... + ArraySetAsSeries(slowR2Buffer, true); + CopyBuffer( + mHandler, + XMRB_R2_SLOW_LINE, + barIndex, + mLoopbackBars, + slowR2Buffer); + + // + // RIBBON 3 ... + + // + // FAST ... + ArraySetAsSeries(fastR3Buffer, true); + CopyBuffer( + mHandler, + XMRB_R3_FAST_LINE, + barIndex, + mLoopbackBars, + fastR3Buffer); + + // + // SLOW ... + ArraySetAsSeries(slowR3Buffer, true); + CopyBuffer( + mHandler, + XMRB_R3_SLOW_LINE, + barIndex, + mLoopbackBars, + slowR3Buffer); + + // + // RIBBON 4 ... + + // + // FAST ... + ArraySetAsSeries(fastR4Buffer, true); + CopyBuffer( + mHandler, + XMRB_R4_FAST_LINE, + barIndex, + mLoopbackBars, + fastR4Buffer); + + // + // SLOW ... + ArraySetAsSeries(slowR4Buffer, true); + CopyBuffer( + mHandler, + XMRB_R4_SLOW_LINE, + barIndex, + mLoopbackBars, + slowR4Buffer); + + // + // RIBBON 5 ... + + // + // FAST ... + ArraySetAsSeries(fastR5Buffer, true); + CopyBuffer( + mHandler, + XMRB_R5_FAST_LINE, + barIndex, + mLoopbackBars, + fastR5Buffer); + + // + // SLOW ... + ArraySetAsSeries(slowR5Buffer, true); + CopyBuffer( + mHandler, + XMRB_R5_SLOW_LINE, + barIndex, + mLoopbackBars, + slowR5Buffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XMRBInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XMRBInfo result; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + double fast = fastBuffer[barIndex]; + double fastPrev = fastBuffer[barIndex + 1]; + double slow = slowBuffer[barIndex]; + double slowPrev = slowBuffer[barIndex + 1]; + double fastR1 = fastR1Buffer[barIndex]; + double fastR1Prev = fastR1Buffer[barIndex + 1]; + double slowR1 = slowR1Buffer[barIndex]; + double slowR1Prev = slowR1Buffer[barIndex + 1]; + double fastR2 = fastR2Buffer[barIndex]; + double fastR2Prev = fastR2Buffer[barIndex + 1]; + double slowR2 = slowR2Buffer[barIndex]; + double slowR2Prev = slowR2Buffer[barIndex + 1]; + double fastR3 = fastR3Buffer[barIndex]; + double fastR3Prev = fastR3Buffer[barIndex + 1]; + double slowR3 = slowR3Buffer[barIndex]; + double slowR3Prev = slowR3Buffer[barIndex + 1]; + double fastR4 = fastR4Buffer[barIndex]; + double fastR4Prev = fastR4Buffer[barIndex + 1]; + double slowR4 = slowR4Buffer[barIndex]; + double slowR4Prev = slowR4Buffer[barIndex + 1]; + double fastR5 = fastR5Buffer[barIndex]; + double fastR5Prev = fastR5Buffer[barIndex + 1]; + double slowR5 = slowR5Buffer[barIndex]; + double slowR5Prev = slowR5Buffer[barIndex + 1]; + + // + Copy( + fastBuffer, + result.fasts); + Copy( + slowBuffer, + result.slows); + Copy( + fastR1Buffer, + result.fastR1s); + Copy( + slowR1Buffer, + result.slowR1s); + Copy( + fastR2Buffer, + result.fastR2s); + Copy( + slowR2Buffer, + result.slowR2s); + Copy( + fastR3Buffer, + result.fastR3s); + Copy( + slowR3Buffer, + result.slowR3s); + Copy( + fastR4Buffer, + result.fastR4s); + Copy( + slowR4Buffer, + result.slowR4s); + Copy( + fastR5Buffer, + result.fastR5s); + Copy( + slowR5Buffer, + result.slowR5s); + + // + result.fast = fast; + result.slow = slow; + result.fastR1 = fastR1; + result.slowR1 = slowR1; + result.fastR2 = fastR2; + result.slowR2 = slowR2; + result.fastR3 = fastR3; + result.slowR3 = slowR3; + result.fastR4 = fastR4; + result.slowR4 = slowR4; + result.fastR5 = fastR5; + result.slowR5 = slowR5; + + // + result.isFastOverSlow = + fast > slow; + result.isFastCrossedOverSlow = + fast > slow && fastPrev <= slowPrev; + result.isFastUnderSlow = + fast < slow; + result.isFastCrossedUnderSlow = + fast < slow && fastPrev >= slowPrev; + + // + result.isR1FastOverSlow = + fastR1 > slowR1; + result.isR1FastCrossedOverSlow = + fastR1 > slowR1 && fastR1Prev <= slowR1Prev; + result.isR1FastUnderSlow = + fastR1 < slowR1; + result.isR1FastCrossedUnderSlow = + fastR1 < slowR1 && fastR1Prev >= slowR1Prev; + + // + result.isR2FastOverSlow = + fastR2 > slowR2; + result.isR2FastCrossedOverSlow = + fastR2 > slowR2 && fastR2Prev <= slowR2Prev; + result.isR2FastUnderSlow = + fastR2 < slowR2; + result.isR2FastCrossedUnderSlow = + fastR2 < slowR2 && fastR2Prev >= slowR2Prev; + + // + result.isR3FastOverSlow = + fastR3 > slowR3; + result.isR3FastCrossedOverSlow = + fastR3 > slowR3 && fastR3Prev <= slowR3Prev; + result.isR3FastUnderSlow = + fastR3 < slowR3; + result.isR3FastCrossedUnderSlow = + fastR3 < slowR3 && fastR3Prev >= slowR3Prev; + + // + result.isR4FastOverSlow = + fastR4 > slowR4; + result.isR4FastCrossedOverSlow = + fastR4 > slowR4 && fastR4Prev <= slowR4Prev; + result.isR4FastUnderSlow = + fastR4 < slowR4; + result.isR4FastCrossedUnderSlow = + fastR4 < slowR4 && fastR4Prev >= slowR4Prev; + + // + result.isR5FastOverSlow = + fastR5 > slowR5; + result.isR5FastCrossedOverSlow = + fastR5 > slowR5 && fastR5Prev <= slowR5Prev; + result.isR5FastUnderSlow = + fastR5 < slowR5; + result.isR5FastCrossedUnderSlow = + fastR5 < slowR5 && fastR5Prev >= slowR5Prev; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Market ... + // + // Ribbon 1 ... + int mFast1Length; + int mSlow1Length; + // + // Ribbon 2 ... + int mFast2Length; + int mSlow2Length; + // + // Ribbon 3 ... + int mFast3Length; + int mSlow3Length; + // + // Ribbon 4 ... + int mFast4Length; + int mSlow4Length; + // + // Ribbon 5 ... + int mFast5Length; + int mSlow5Length; + // + // Calculation ... + // + // Mode ... + ENUM_MA_METHOD mRibbonMode; + // + // Applied To ... + ENUM_APPLIED_PRICE mRibbonAppliedTo; + // + // Presentation ... + // + // Show Fast ... + bool mShowFastMa; + // + // Show Slow ... + bool mShowSlowMa; + // + // Show Ribbon ... + bool mShowRibbon; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xosc.helper.class.ex5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xosc.helper.class.ex5 new file mode 100644 index 0000000..e907e1a Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xosc.helper.class.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xosc.helper.class.mq5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xosc.helper.class.mq5 new file mode 100644 index 0000000..161fb25 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xosc.helper.class.mq5 @@ -0,0 +1,830 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXOSCHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// Inputs ... +struct XOSCInputs +{ + // + // ATR ... + int atrLength; + + // + // RVI ... + int rviLength; + + // + // BULLPOWER ... + int bullpLength; + + // + // BEARPOWER ... + int bearpLength; + + // + // VOLUME ... + ENUM_APPLIED_VOLUME volumeAppliedTo; + + // + // RSI ... + int rsiLength; + ENUM_APPLIED_PRICE rsiAppliedTo; + + // + // CCI ... + int cciLength; + ENUM_APPLIED_PRICE cciAppliedTo; + + // + // MOMENTUM ... + int momentumLength; + ENUM_APPLIED_PRICE momentumAppliedTo; + + // + // SAR ... + double sarStep; + double sarMaximum; + + // + // MACD ... + int macdFastLength; + int macdSlowLength; + int macdSignaLength; + ENUM_APPLIED_PRICE macdAppliedTo; + + // + // STOCHASTIC ... + int stochKLength; + int stochDLength; + int stochSlowing; + ENUM_MA_METHOD stochMaMethod; + ENUM_STO_PRICE stochMode; + + // + // STANDARDDEVIATION ... + int stddevLength; + int stddevShift; + ENUM_MA_METHOD stddevMethod; + ENUM_APPLIED_PRICE stddevAppliedTo; +}; + +// +// Index of Lines ... +enum ENUM_XOSC_BUFFERS +{ + // + // Main Requirements ... + XOSC_ATR_LINE = 0, + XOSC_RVI_MAIN_LINE = 1, + XOSC_RVI_SIGNAL_LINE = 2, + XOSC_BULLP_LINE = 3, + XOSC_BEARP_LINE = 4, + XOSC_VOLUME_LINE = 5, + XOSC_RSI_LINE = 6, + XOSC_CCI_LINE = 7, + XOSC_MOMENTUM_LINE = 8, + XOSC_SAR_LINE = 9, + XOSC_MACD_MAIN_LINE = 10, + XOSC_MACD_SIGNAL_LINE = 11, + XOSC_STOCH_MAIN_LINE = 12, + XOSC_STOCH_SIGNAL_LINE = 13, + XOSC_STDDEV_LINE = 14, +}; + +// +// Retrieve Info Model ... +struct XOSCInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double atr; + double rviMain; + double rviSignal; + double bullPower; + double bearPower; + double volume; + double rsi; + double cci; + double momentum; + double sar; + double macdMain; + double macdSignal; + double stochMain; + double stochSignal; + double stddev; + + // + double atrs[]; + double rviMains[]; + double rviSignals[]; + double bullPs[]; + double bearPs[]; + double volumes[]; + double rsis[]; + double ccis[]; + double momentums[]; + double sars[]; + double macdMains[]; + double macdSignals[]; + double stochMains[]; + double stochSignals[]; + double stddevs[]; + + // + // Conditions ... + // TODO: Implement it Later ... +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXOSCHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double atrBuffer[]; + double rviMainBuffer[]; + double rviSignalBuffer[]; + double bullPBuffer[]; + double bearPBuffer[]; + double volumeBuffer[]; + double rsiBuffer[]; + double cciBuffer[]; + double momentumBuffer[]; + double sarBuffer[]; + double macdMainBuffer[]; + double macdSignalBuffer[]; + double stochMainBuffer[]; + double stochSignalBuffer[]; + double stddevBuffer[]; + + // + // Constructor ... + void XSCXOSCHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXOSCHelper() + { + } + + // + // START Properties ... + // + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XOSC" + GetTagPrefix(); + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = MathMax(mAtrLength, mRviLength); + result = MathMax(result, mBullpLength); + result = MathMax(result, mBearpLength); + result = MathMax(result, mRsiLength); + result = MathMax(result, mCciLength); + result = MathMax(result, mMomentumLength); + result = MathMax(result, mMacdFastLength); + result = MathMax(result, mMacdSlowLength); + result = MathMax(result, mMacdSignaLength); + result = MathMax(result, mStochKLength); + result = MathMax(result, mStochDLength); + result = MathMax(result, mStochSlowing); + result = MathMax(result, mStddevLength); + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Args ... + result = + // + mAtrLength >= 2 && + mRviLength >= 2 && + mBullpLength >= 2 && + mBearpLength >= 2 && + mRsiLength >= 2 && + mCciLength >= 2 && + mMomentumLength >= 2 && + mSarStep > 0 && + mSarStep < mSarMaximum && + mMacdFastLength >= 2 && + mMacdSlowLength > mMacdFastLength && + mMacdSignaLength >= 2 && + mStochKLength >= 2 && + mStochDLength >= 2 && + mStochSlowing >= 2 && + mStddevLength >= 2 && + mStddevShift >= 0 + // + ; + if (!result) + { + return false; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xosc", + // + // Inputs ... + // + // ATR ... + "", + mAtrLength, + // + // RVI ... + "", + mRviLength, + // + // BULLPOWER ... + "", + mBullpLength, + // + // BEARPOWER ... + "", + mBearpLength, + // + // VOLUME ... + "", + mVolumeAppliedTo, + // + // RSI ... + "", + mRsiLength, + mRsiAppliedTo, + // + // CCI ... + "", + mCciLength, + mCciAppliedTo, + // + // STANDARDDEVIATION ... + "", + mStddevLength, + mStddevShift, + mStddevMethod, + mStddevAppliedTo, + // + // MOMENTUM ... + "", + mMomentumLength, + mMomentumAppliedTo, + // + // SAR ... + "", + mSarStep, + mSarMaximum, + // + // MACD ... + "", + mMacdFastLength, + mMacdSlowLength, + mMacdSignaLength, + mMacdAppliedTo, + // + // STOCHASTIC ... + "", + mStochKLength, + mStochDLength, + mStochSlowing, + mStochMaMethod, + mStochMode + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XOSCInputs GetConfig() + { + // + XOSCInputs result; + + // + result.atrLength = mAtrLength; + result.rviLength = mRviLength; + result.bullpLength = mBullpLength; + result.bearpLength = mBearpLength; + result.volumeAppliedTo = mVolumeAppliedTo; + result.rsiLength = mRsiLength; + result.rsiAppliedTo = mRsiAppliedTo; + result.cciLength = mCciLength; + result.cciAppliedTo = mCciAppliedTo; + result.momentumLength = mMomentumLength; + result.momentumAppliedTo = mMomentumAppliedTo; + result.sarStep = mSarStep; + result.sarMaximum = mSarMaximum; + result.macdFastLength = mMacdFastLength; + result.macdSlowLength = mMacdSlowLength; + result.macdSignaLength = mMacdSignaLength; + result.macdAppliedTo = mMacdAppliedTo; + result.stochKLength = mStochKLength; + result.stochDLength = mStochDLength; + result.stochSlowing = mStochSlowing; + result.stochMaMethod = mStochMaMethod; + result.stochMode = mStochMode; + result.stddevLength = mStddevLength; + result.stddevShift = mStddevShift; + result.stddevMethod = mStddevMethod; + result.stddevAppliedTo = mStddevAppliedTo; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XOSCInputs &config) + { + // + bool result = false; + + // + mAtrLength = config.atrLength; + mRviLength = config.rviLength; + mBullpLength = config.bullpLength; + mBearpLength = config.bearpLength; + mVolumeAppliedTo = config.volumeAppliedTo; + mRsiLength = config.rsiLength; + mRsiAppliedTo = config.rsiAppliedTo; + mCciLength = config.cciLength; + mCciAppliedTo = config.cciAppliedTo; + mMomentumLength = config.momentumLength; + mMomentumAppliedTo = config.momentumAppliedTo; + mSarStep = config.sarStep; + mSarMaximum = config.sarMaximum; + mMacdFastLength = config.macdFastLength; + mMacdSlowLength = config.macdSlowLength; + mMacdSignaLength = config.macdSignaLength; + mMacdAppliedTo = config.macdAppliedTo; + mStochKLength = config.stochKLength; + mStochDLength = config.stochDLength; + mStochSlowing = config.stochSlowing; + mStochMaMethod = config.stochMaMethod; + mStochMode = config.stochMode; + mStddevLength = config.stddevLength; + mStddevShift = config.stddevShift; + mStddevMethod = config.stddevMethod; + mStddevAppliedTo = config.stddevAppliedTo; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + // + // ATR ... + ArraySetAsSeries(atrBuffer, true); + CopyBuffer( + mHandler, + XOSC_ATR_LINE, + barIndex, + mLoopbackBars, + atrBuffer); + + // + // RVI ... + + // + // MAIN ... + ArraySetAsSeries(rviMainBuffer, true); + CopyBuffer( + mHandler, + XOSC_RVI_MAIN_LINE, + barIndex, + mLoopbackBars, + rviMainBuffer); + + // + // SIGNAL ... + ArraySetAsSeries(rviSignalBuffer, true); + CopyBuffer( + mHandler, + XOSC_RVI_SIGNAL_LINE, + barIndex, + mLoopbackBars, + rviSignalBuffer); + + // + // BULLPOWER ... + ArraySetAsSeries(bullPBuffer, true); + CopyBuffer( + mHandler, + XOSC_BULLP_LINE, + barIndex, + mLoopbackBars, + bullPBuffer); + + // + // BEARPOWER ... + ArraySetAsSeries(bearPBuffer, true); + CopyBuffer( + mHandler, + XOSC_BEARP_LINE, + barIndex, + mLoopbackBars, + bearPBuffer); + + // + // VOLUME ... + ArraySetAsSeries(volumeBuffer, true); + CopyBuffer( + mHandler, + XOSC_BEARP_LINE, + barIndex, + mLoopbackBars, + volumeBuffer); + + // + // RSI ... + ArraySetAsSeries(rsiBuffer, true); + CopyBuffer( + mHandler, + XOSC_VOLUME_LINE, + barIndex, + mLoopbackBars, + rsiBuffer); + + // + // CCI ... + ArraySetAsSeries(cciBuffer, true); + CopyBuffer( + mHandler, + XOSC_CCI_LINE, + barIndex, + mLoopbackBars, + cciBuffer); + + // + // MOMENTUM ... + ArraySetAsSeries(momentumBuffer, true); + CopyBuffer( + mHandler, + XOSC_MOMENTUM_LINE, + barIndex, + mLoopbackBars, + momentumBuffer); + + // + // SAR ... + ArraySetAsSeries(sarBuffer, true); + CopyBuffer( + mHandler, + XOSC_SAR_LINE, + barIndex, + mLoopbackBars, + sarBuffer); + + // + // MACD ... + + // + // MAIN ... + ArraySetAsSeries(macdMainBuffer, true); + CopyBuffer( + mHandler, + XOSC_MACD_MAIN_LINE, + barIndex, + mLoopbackBars, + macdMainBuffer); + + // + // SIGNAL ... + ArraySetAsSeries(macdSignalBuffer, true); + CopyBuffer( + mHandler, + XOSC_MACD_SIGNAL_LINE, + barIndex, + mLoopbackBars, + macdSignalBuffer); + + // + // STOCHASTIC ... + + // + // MAIN ... + ArraySetAsSeries(stochMainBuffer, true); + CopyBuffer( + mHandler, + XOSC_STOCH_MAIN_LINE, + barIndex, + mLoopbackBars, + stochMainBuffer); + + // + // SIGNAL ... + ArraySetAsSeries(stochSignalBuffer, true); + CopyBuffer( + mHandler, + XOSC_STOCH_SIGNAL_LINE, + barIndex, + mLoopbackBars, + stochSignalBuffer); + + // + // STANDARDDEVIATION ... + ArraySetAsSeries(stddevBuffer, true); + CopyBuffer( + mHandler, + XOSC_STDDEV_LINE, + barIndex, + mLoopbackBars, + stddevBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XOSCInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XOSCInfo result; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + result.atr = atrBuffer[barIndex]; + result.rviMain = rviMainBuffer[barIndex]; + result.rviSignal = rviSignalBuffer[barIndex]; + result.bullPower = bullPBuffer[barIndex]; + result.bearPower = bearPBuffer[barIndex]; + result.volume = volumeBuffer[barIndex]; + result.rsi = rsiBuffer[barIndex]; + result.cci = cciBuffer[barIndex]; + result.momentum = momentumBuffer[barIndex]; + result.sar = sarBuffer[barIndex]; + result.macdMain = macdMainBuffer[barIndex]; + result.macdSignal = macdMainBuffer[barIndex]; + result.stochMain = stochMainBuffer[barIndex]; + result.stochSignal = stochSignalBuffer[barIndex]; + result.stddev = stddevBuffer[barIndex]; + + // + Copy( + atrBuffer, + result.atrs); + Copy( + rviMainBuffer, + result.rviMains); + Copy( + rviSignalBuffer, + result.rviSignals); + Copy( + bullPBuffer, + result.bullPs); + Copy( + bearPBuffer, + result.bearPs); + Copy( + volumeBuffer, + result.volumes); + Copy( + rsiBuffer, + result.rsis); + Copy( + cciBuffer, + result.ccis); + Copy( + momentumBuffer, + result.momentums); + Copy( + sarBuffer, + result.sars); + Copy( + macdMainBuffer, + result.macdMains); + Copy( + macdSignalBuffer, + result.macdSignals); + Copy( + stochMainBuffer, + result.stochMains); + Copy( + stochSignalBuffer, + result.stochSignals); + Copy( + stddevBuffer, + result.stddevs); + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // ATR ... + int mAtrLength; + + // + // RVI ... + int mRviLength; + + // + // BULLPOWER ... + int mBullpLength; + + // + // BEARPOWER ... + int mBearpLength; + + // + // VOLUME ... + ENUM_APPLIED_VOLUME mVolumeAppliedTo; + + // + // RSI ... + int mRsiLength; + ENUM_APPLIED_PRICE mRsiAppliedTo; + + // + // CCI ... + int mCciLength; + ENUM_APPLIED_PRICE mCciAppliedTo; + + // + // MOMENTUM ... + int mMomentumLength; + ENUM_APPLIED_PRICE mMomentumAppliedTo; + + // + // SAR ... + double mSarStep; + double mSarMaximum; + + // + // MACD ... + int mMacdFastLength; + int mMacdSlowLength; + int mMacdSignaLength; + ENUM_APPLIED_PRICE mMacdAppliedTo; + + // + // STOCHASTIC ... + int mStochKLength; + int mStochDLength; + int mStochSlowing; + ENUM_MA_METHOD mStochMaMethod; + ENUM_STO_PRICE mStochMode; + + // + // STANDARDDEVIATION ... + int mStddevLength; + int mStddevShift; + ENUM_MA_METHOD mStddevMethod; + ENUM_APPLIED_PRICE mStddevAppliedTo; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xpv.helper.class.ex5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xpv.helper.class.ex5 new file mode 100644 index 0000000..7083942 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xpv.helper.class.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xpv.helper.class.mq5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xpv.helper.class.mq5 new file mode 100644 index 0000000..9e4914f --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xpv.helper.class.mq5 @@ -0,0 +1,946 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXPVHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// Inputs ... +struct XPVInputs +{ + // + // Makret Cycles ... + int shortLength; // Short Length + int mediumLength; // Medium Length + int longLength; // Long Length + int hindLength; // Hind Length + double fiboLevel1; // Fibio 1st Level + double fiboLevel2; // Fibio 2st Level + double fiboLevel3; // Fibio 3rd Level + + // + // Detection Modes ... + ENUM_SERIESMODE hhMode; // Highest High Calculation Method + ENUM_SERIESMODE llMode; // Lowest Low Calculation Method + + // + // Presentation ... + bool showPeaksAndVales; // Show Peaks and Vales + bool showLevels; // Show Levels + bool showFibo1Levels; // Show Fibo 1st Level + bool showFibo2Levels; // Show Fibo 2nd Level + bool showFibo3Levels; // Show Fibo 3rd Level +}; + +// +// Index of Lines ... +enum ENUM_XPV_BUFFERS +{ + // + // Main Requirements ... + XPV_PEAKS_LINE = 0, + XPV_VALES_LINE = 1, + // + XPV_RESISTANCE_LINE = 2, + XPV_RESISTANCE_STATE_LINE = 3, + // + XPV_SUPPORT_LINE = 4, + XPV_SUPPORT_STATE_LINE = 5, + // + XPV_FL1_LINE = 6, + XPV_FL2_LINE = 8, + XPV_FL3_LINE = 10, + // + // SHORT ... + XPV_SHORT_HIGH_LINE = 12, + XPV_SHORT_LOW_LINE = 13, + // + // MEDIUM ... + XPV_MEDIUM_HIGH_LINE = 14, + XPV_MEDIUM_LOW_LINE = 15, + // + // LONG ... + XPV_LONG_HIGH_LINE = 16, + XPV_LONG_LOW_LINE = 17, + // + // HIND ... + XPV_HIND_HIGH_LINE = 18, + XPV_HIND_LOW_LINE = 19, +}; + +// +// Retrieve Info Model ... +struct XPVInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double peak; + double vale; + double fl1; + double fl2; + double fl3; + + // + double r; + double rState; + double s; + double sSate; + + // + // SHORT ... + double sl; + double sh; + + // + // MEDIUM ... + double ml; + double mh; + + // + // LONG ... + double ll; + double lh; + + // + // HIND ... + double hl; + double hh; + + // + double peakss[]; + double valess[]; + double fl1s[]; + double fl2s[]; + double fl3s[]; + double rs[]; + double rStates[]; + double ss[]; + double sStates[]; + double sls[]; + double shs[]; + double mls[]; + double mhs[]; + double lls[]; + double lhs[]; + double hls[]; + double hhs[]; + + // + // Conditions ... + + // + // Determines New Peaks Happens ... + bool isNewPeak; + + // + // Determines New Vales Happens ... + bool isNewVale; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXPVHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double peaksBuffer[]; + double valesBuffer[]; + double fl1Buffer[]; + double fl2Buffer[]; + double fl3Buffer[]; + + // + // Support and Resistance ... + double rBuffer[]; + double rStateBuffer[]; + + // + double sBuffer[]; + double sStateBuffer[]; + + // + // SHORT ... + double slBuffer[]; + double shBuffer[]; + + // + // MEDIUM ... + double mlBuffer[]; + double mhBuffer[]; + + // + // LONG ... + double llBuffer[]; + double lhBuffer[]; + + // + // HIND ... + double hlBuffer[]; + double hhBuffer[]; + + // + // Constructor ... + void XSCXPVHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXPVHelper() + { + } + + // + // START Properties ... + // + + // + // Show Levels ... + bool ShowLevels( + bool show // Show or Hide Levels + ) + { + // + bool result = false; + + // + if (mShowLevels == show) + { + return true; + } + + // + mShowLevels = show; + result = Init(); + + // + return result; + } + + // + // Show Peaks and Vales ... + bool ShowPeaksAnVales( + bool show // Show or Hide Levels + ) + { + // + bool result = false; + + // + if (mShowPeaksAndVales == show) + { + return true; + } + + // + mShowPeaksAndVales = show; + result = Init(); + + // + return result; + } + + // + // Show Fibo 1st Level ... + bool ShowFibo1Levels( + bool show // Show or Hide Levels + ) + { + // + bool result = false; + + // + if (mShowFibo1Levels == show) + { + return true; + } + + // + mShowFibo1Levels = show; + result = Init(); + + // + return result; + } + + // + // Show Fibo 2nd Level ... + bool ShowFibo2Levels( + bool show // Show or Hide Levels + ) + { + // + bool result = false; + + // + if (mShowFibo2Levels == show) + { + return true; + } + + // + mShowFibo2Levels = show; + result = Init(); + + // + return result; + } + + // + // Show Fibo 3rd Level ... + bool ShowFibo3Levels( + bool show // Show or Hide Levels + ) + { + // + bool result = false; + + // + if (mShowFibo3Levels == show) + { + return true; + } + + // + mShowFibo3Levels = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XPV" + GetTagPrefix(); + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = MathMax(mShortLength, mMediumLength); + result = MathMax(result, mLongLength); + result = MathMax(result, mHindLength); + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Args ... + result = + // + (mShortLength > 2 && + mMediumLength > mShortLength && + mLongLength > mMediumLength && + mHindLength > mLongLength) + // + ; + if (!result) + { + return false; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xpv", + // + // Inputs ... + // + // Market ... + "", + // + // Short Length ... + mShortLength, + // + // Medium Length + mMediumLength, + // + // Long Length ... + mLongLength, + // + // Hind Length ... + mHindLength, + // + // Fibio 1st Level ... + mFiboLevel1, + // + // Fibio 2st Level ... + mFiboLevel2, + // + // Fibio 3rd Level ... + mFiboLevel3, + // + // Detection Mode ... + "", + // + // Highest High Calculation Method ... + mHHMode, + // + // Lowest Low Calculation Method ... + mLLMode, + // + // Presentations ... + "", + // + // Show Peaks and Vales ... + mShowPeaksAndVales, + // + // Show Levels ... + mShowLevels, + // + // Show Fibo 1st Level ... + mShowFibo1Levels, + // + // Show Fibo 2nd Level ... + mShowFibo2Levels, + // + // Show Fibo 3rd Level ... + mShowFibo3Levels + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XPVInputs GetConfig() + { + // + XPVInputs result; + + // + result.shortLength = mShortLength; + result.mediumLength = mMediumLength; + result.longLength = mLongLength; + result.hindLength = mHindLength; + result.fiboLevel1 = mFiboLevel1; + result.fiboLevel2 = mFiboLevel2; + result.fiboLevel3 = mFiboLevel3; + result.hhMode = mHHMode; + result.llMode = mLLMode; + result.showPeaksAndVales = mShowPeaksAndVales; + result.showLevels = mShowLevels; + result.showFibo1Levels = mShowFibo1Levels; + result.showFibo2Levels = mShowFibo2Levels; + result.showFibo3Levels = mShowFibo3Levels; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XPVInputs &config) + { + // + bool result = false; + + // + mShortLength = config.shortLength; + mMediumLength = config.mediumLength; + mLongLength = config.longLength; + mHindLength = config.hindLength; + mFiboLevel1 = config.fiboLevel1; + mFiboLevel2 = config.fiboLevel2; + mFiboLevel3 = config.fiboLevel3; + mHHMode = config.hhMode; + mLLMode = config.llMode; + mShowPeaksAndVales = config.showPeaksAndVales; + mShowLevels = config.showLevels; + mShowFibo1Levels = config.showFibo1Levels; + mShowFibo2Levels = config.showFibo2Levels; + mShowFibo3Levels = config.showFibo3Levels; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + // + // PEAKS ... + ArraySetAsSeries(peaksBuffer, true); + CopyBuffer( + mHandler, + XPV_PEAKS_LINE, + barIndex, + mLoopbackBars, + peaksBuffer); + + // + // VALES ... + ArraySetAsSeries(valesBuffer, true); + CopyBuffer( + mHandler, + XPV_VALES_LINE, + barIndex, + mLoopbackBars, + valesBuffer); + + // + // FIBBO LEVELS ... + + // + // LEVEL 1 ... + ArraySetAsSeries(fl1Buffer, true); + CopyBuffer( + mHandler, + XPV_FL1_LINE, + barIndex, + mLoopbackBars, + fl1Buffer); + + // + // LEVEL 2 ... + ArraySetAsSeries(fl2Buffer, true); + CopyBuffer( + mHandler, + XPV_FL2_LINE, + barIndex, + mLoopbackBars, + fl2Buffer); + + // + // LEVEL 3 ... + ArraySetAsSeries(fl3Buffer, true); + CopyBuffer( + mHandler, + XPV_FL3_LINE, + barIndex, + mLoopbackBars, + fl3Buffer); + + // + // Support and Resistance ... + + // + // Resistance ... + ArraySetAsSeries(rBuffer, true); + ArraySetAsSeries(rStateBuffer, true); + CopyBuffer( + mHandler, + XPV_RESISTANCE_LINE, + barIndex, + mLoopbackBars, + rBuffer); + CopyBuffer( + mHandler, + XPV_RESISTANCE_STATE_LINE, + barIndex, + mLoopbackBars, + rStateBuffer); + + // + // Support ... + ArraySetAsSeries(sBuffer, true); + ArraySetAsSeries(sStateBuffer, true); + CopyBuffer( + mHandler, + XPV_SUPPORT_LINE, + barIndex, + mLoopbackBars, + sBuffer); + CopyBuffer( + mHandler, + XPV_SUPPORT_STATE_LINE, + barIndex, + mLoopbackBars, + sStateBuffer); + + // + // CYCLES ... + + // + // SHORT ... + + // + // HIGH ... + ArraySetAsSeries(shBuffer, true); + CopyBuffer( + mHandler, + XPV_SHORT_HIGH_LINE, + barIndex, + mLoopbackBars, + shBuffer); + + // + // LOW ... + ArraySetAsSeries(slBuffer, true); + CopyBuffer( + mHandler, + XPV_SHORT_LOW_LINE, + barIndex, + mLoopbackBars, + slBuffer); + + // + // MEDIUM ... + + // + // HIGH ... + ArraySetAsSeries(mhBuffer, true); + CopyBuffer( + mHandler, + XPV_MEDIUM_HIGH_LINE, + barIndex, + mLoopbackBars, + mhBuffer); + + // + // LOW ... + ArraySetAsSeries(mlBuffer, true); + CopyBuffer( + mHandler, + XPV_MEDIUM_LOW_LINE, + barIndex, + mLoopbackBars, + mlBuffer); + + // + // LONG ... + + // + // HIGH ... + ArraySetAsSeries(lhBuffer, true); + CopyBuffer( + mHandler, + XPV_LONG_HIGH_LINE, + barIndex, + mLoopbackBars, + lhBuffer); + + // + // LOW ... + ArraySetAsSeries(llBuffer, true); + CopyBuffer( + mHandler, + XPV_LONG_LOW_LINE, + barIndex, + mLoopbackBars, + llBuffer); + + // + // HIND ... + + // + // HIGH ... + ArraySetAsSeries(hhBuffer, true); + CopyBuffer( + mHandler, + XPV_HIND_HIGH_LINE, + barIndex, + mLoopbackBars, + hhBuffer); + + // + // LOW ... + ArraySetAsSeries(hlBuffer, true); + CopyBuffer( + mHandler, + XPV_HIND_LOW_LINE, + barIndex, + mLoopbackBars, + hlBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XPVInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XPVInfo result; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + result.peak = peaksBuffer[barIndex]; + result.vale = valesBuffer[barIndex]; + result.fl1 = fl1Buffer[barIndex]; + result.fl2 = fl2Buffer[barIndex]; + result.fl3 = fl3Buffer[barIndex]; + + // + result.r = rBuffer[barIndex]; + result.rState = rStateBuffer[barIndex]; + result.s = sBuffer[barIndex]; + result.sSate = sStateBuffer[barIndex]; + + // + // SHORT ... + result.sl = slBuffer[barIndex]; + result.sh = shBuffer[barIndex]; + + // + // MEDIUM ... + result.ml = mlBuffer[barIndex]; + result.mh = mhBuffer[barIndex]; + + // + // LONG ... + result.ll = llBuffer[barIndex]; + result.lh = lhBuffer[barIndex]; + + // + // HIND ... + result.hl = hlBuffer[barIndex]; + result.hh = hhBuffer[barIndex]; + + // + Copy( + peaksBuffer, + result.peakss); + Copy( + valesBuffer, + result.valess); + Copy( + fl1Buffer, + result.fl1s); + Copy( + fl2Buffer, + result.fl2s); + Copy( + fl3Buffer, + result.fl3s); + Copy( + rBuffer, + result.rs); + Copy( + rStateBuffer, + result.rStates); + Copy( + sBuffer, + result.ss); + Copy( + sStateBuffer, + result.sStates); + Copy( + slBuffer, + result.sls); + Copy( + shBuffer, + result.shs); + Copy( + mlBuffer, + result.mls); + Copy( + mhBuffer, + result.mhs); + Copy( + llBuffer, + result.lls); + Copy( + lhBuffer, + result.lhs); + Copy( + hlBuffer, + result.hls); + Copy( + hhBuffer, + result.hhs); + + // + result.isNewPeak = + peaksBuffer[barIndex] != peaksBuffer[barIndex + 1]; + result.isNewVale = + valesBuffer[barIndex] != valesBuffer[barIndex + 1]; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Market ... + // + // Short Length ... + int mShortLength; + // + // Medium Length + int mMediumLength; + // + // Long Length ... + int mLongLength; + // + // Hind Length ... + int mHindLength; + // + // Fibio 1st Level ... + double mFiboLevel1; + // + // Fibio 2st Level ... + double mFiboLevel2; + // + // Fibio 3rd Level ... + double mFiboLevel3; + // + // Detection Mode ... + // + // Highest High Calculation Method ... + ENUM_SERIESMODE mHHMode; + // + // Lowest Low Calculation Method ... + ENUM_SERIESMODE mLLMode; + // + // Presentations ... + // + // Show Peaks and Vales ... + bool mShowPeaksAndVales; + // + // Show Levels ... + bool mShowLevels; + // + // Show Fibo 1st Level ... + bool mShowFibo1Levels; + // + // Show Fibo 2nd Level ... + bool mShowFibo2Levels; + // + // Show Fibo 3rd Level ... + bool mShowFibo3Levels; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xsslc.helper.class.ex5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xsslc.helper.class.ex5 new file mode 100644 index 0000000..1a86e32 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xsslc.helper.class.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xsslc.helper.class.mq5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xsslc.helper.class.mq5 new file mode 100644 index 0000000..7fd81db --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xsslc.helper.class.mq5 @@ -0,0 +1,481 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXSSLCHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// Inputs ... +struct XSSLCInputs +{ + // + // Market ... + int length; // Length + + // + // Calculation ... + ENUM_MA_METHOD method; // Method + ENUM_APPLIED_PRICE upAppliedTo; // Up Applied To + ENUM_APPLIED_PRICE downAppliedTo; // Down Applied To + + // + // Presentation ... + bool showUp; // Show Up + bool showDown; // Show Down +}; + +// +// Index of Lines ... +enum ENUM_XSSLC_BUFFERS +{ + // + // Main Requirements ... + XSSLC_UP_LINE = 0, + XSSLC_DOWN_LINE = 1, +}; + +// +// Retrieve Info Model ... +struct XSSLCInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double up; + double down; + + // + double ups[]; + double downs[]; + + // + // Conditions ... + + // + // Detect Trend is Bullish or not ... + bool isBullish; + + // + // Detect Trend is Switched to Bullish Or not ... + bool isSwitchedBullish; + + // + // Detect Trend is Bearish or not ... + bool isBearish; + + // + // Detect Trend is Switched to Bearish Or not ... + bool isSwitchedBearish; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXSSLCHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double upBuffer[]; + double downBuffer[]; + + // + // Constructor ... + void XSCXSSLCHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXSSLCHelper() + { + } + + // + // START Properties ... + // + + // + // Show Up ... + bool ShowUp( + bool show // Show or Hide Line + ) + { + // + bool result = false; + + // + if (mShowUp == show) + { + return true; + } + + // + mShowUp = show; + result = Init(); + + // + return result; + } + + // + // Show Down ... + bool ShowDown( + bool show // Show or Hide Line + ) + { + // + bool result = false; + + // + if (mShowDown == show) + { + return true; + } + + // + mShowDown = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XSSLC" + GetTagPrefix(); + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = mLength; + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Args ... + result = + // + (mLength >= 2) + // + ; + if (!result) + { + return false; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xsslc", + // + // Inputs ... + // + // Market ... + "", + // + // Length ... + mLength, + // + // Calculation ... + "", + // + // Method ... + mMethod, + // + // Up Applied To ... + mUpAppliedTo, + // + // Down Applied To ... + mDownAppliedTo, + // + // Presentation ... + "", + // + // Show Up ... + mShowUp, + // + // Show Down ... + mShowDown + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XSSLCInputs GetConfig() + { + // + XSSLCInputs result; + + // + result.length = mLength; + result.method = mMethod; + result.upAppliedTo = mUpAppliedTo; + result.downAppliedTo = mDownAppliedTo; + result.showUp = mShowUp; + result.showDown = mShowDown; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XSSLCInputs &config) + { + // + bool result = false; + + // + mLength = config.length; + mMethod = config.method; + mUpAppliedTo = config.upAppliedTo; + mDownAppliedTo = config.downAppliedTo; + mShowUp = config.showUp; + mShowDown = config.showDown; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + // + // UP ... + ArraySetAsSeries(upBuffer, true); + CopyBuffer( + mHandler, + XSSLC_UP_LINE, + barIndex, + mLoopbackBars, + upBuffer); + + // + // DOWN ... + ArraySetAsSeries(downBuffer, true); + CopyBuffer( + mHandler, + XSSLC_DOWN_LINE, + barIndex, + mLoopbackBars, + downBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XSSLCInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XSSLCInfo result; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + double up = upBuffer[barIndex]; + double upPrev = upBuffer[barIndex + 1]; + double down = downBuffer[barIndex]; + double downPrev = downBuffer[barIndex + 1]; + + // + Copy( + upBuffer, + result.ups + ); + Copy( + downBuffer, + result.downs + ); + + // + result.up = up; + result.down = down; + + // + result.isBullish = up > down; + result.isBearish = up < down; + + // + result.isSwitchedBullish = + up > down && + upPrev <= downPrev; + result.isSwitchedBearish = + up < down && + upPrev >= downPrev; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Market ... + // + // Length ... + int mLength; + // + // Calculation ... + // + // Method ... + ENUM_MA_METHOD mMethod; + // + // Up Applied To ... + ENUM_APPLIED_PRICE mUpAppliedTo; + // + // Down Applied To ... + ENUM_APPLIED_PRICE mDownAppliedTo; + // + // Presentation ... + // + // Show Up ... + bool mShowUp; + // + // Show Down ... + bool mShowDown; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xstr.helper.class.ex5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xstr.helper.class.ex5 new file mode 100644 index 0000000..6283736 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xstr.helper.class.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xstr.helper.class.mq5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xstr.helper.class.mq5 new file mode 100644 index 0000000..72b7f90 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xstr.helper.class.mq5 @@ -0,0 +1,473 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXSTRHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// Inputs ... +struct XSTRInputs +{ + // + // Market ... + // + // Length ... + int atrLength; + // + // Multiplier ... + double atrMultiplier; + // + // Applied To ... + ENUM_APPLIED_PRICE atrAppliedTo; + + // + // Presentation ... + // + // Show Trends ... + bool showTrends; + // + // Fill Trends ... + bool fillTrends; +}; + +// +// Index of Lines ... +enum ENUM_XSTR_BUFFERS +{ + // + // Main Requirements ... + XSTR_LINE = 2, + XSTR_TREND_LINE = 5 +}; + +// +// Trend State ... +enum ENUM_XSTR_TREND +{ + XSTR_BULLISH = 1, + XSTR_BEARISH = -1 +}; + +// +// Retrieve Info Model ... +struct XSTRInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double main; + ENUM_XSTR_TREND trend; + + // + double mains[]; + double trends[]; + + // + // Conditions ... + bool isTrendBullish; + bool isTrendBearish; + bool isTrendSwitchedToBullish; + bool isTrendSwitchedToBearish; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXSTRHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double mainBuffer[]; + double trendBuffer[]; + + // + // Constructor ... + void XSCXSTRHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXSTRHelper() + { + } + + // + // START Properties ... + // + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XSTR" + GetTagPrefix(); + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = mAtrLength; + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Args ... + result = + // + (mAtrLength >= 2 && + mAtrMultiplier >= 0) + // + ; + if (!result) + { + return false; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xstr", + // + // Inputs ... + // + // Makret ... + "", + // + // Length ... + mAtrLength, + // + // Multiplier ... + mAtrMultiplier, + // + // Applied To ... + mAtrAppliedTo, + // + // Presentation ... + "", + // + // Show Trends ... + mShowTrends, + // + // Fill Trends ... + mFillTrends); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XSTRInputs GetConfig() + { + // + XSTRInputs result; + + // + result.atrLength = mAtrLength; + result.atrMultiplier = mAtrMultiplier; + result.atrAppliedTo = mAtrAppliedTo; + result.showTrends = mShowTrends; + result.fillTrends = mFillTrends; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XSTRInputs &config) + { + // + bool result = false; + + // + mAtrLength = config.atrLength; + mAtrMultiplier = config.atrMultiplier; + mAtrAppliedTo = config.atrAppliedTo; + mShowTrends = config.showTrends; + mFillTrends = config.fillTrends; + + // + result = Init(); + + // + return result; + } + + // + // Show Trends ... + bool ShowTrends( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowTrends == show) + { + return true; + } + + // + mShowTrends = show; + result = Init(); + + // + return result; + } + + // + // Fill Trends ... + bool FillTrends( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mFillTrends == show) + { + return true; + } + + // + mFillTrends = show; + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + // + // MAIN ... + ArraySetAsSeries(mainBuffer, true); + CopyBuffer( + mHandler, + XSTR_LINE, + barIndex, + mLoopbackBars, + mainBuffer); + + // + // TREND ... + ArraySetAsSeries(trendBuffer, true); + CopyBuffer( + mHandler, + XSTR_TREND_LINE, + barIndex, + mLoopbackBars, + trendBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XSTRInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XSTRInfo result; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + double main = mainBuffer[barIndex]; + ENUM_XSTR_TREND trend = (ENUM_XSTR_TREND)trendBuffer[barIndex]; + ENUM_XSTR_TREND trendPrev = (ENUM_XSTR_TREND)trendBuffer[barIndex + 1]; + + // + Copy( + mainBuffer, + result.mains); + Copy( + trendBuffer, + result.trends); + + // + result.main = main; + result.trend = trend; + + // + result.isTrendBullish = + trend == XSTR_BULLISH; + + // + result.isTrendBearish = + trend == XSTR_BEARISH; + + // + result.isTrendSwitchedToBullish = + trend == XSTR_BULLISH && + trendPrev != XSTR_BULLISH; + + // + result.isTrendSwitchedToBearish = + trend == XSTR_BEARISH && + trendPrev != XSTR_BEARISH; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Market ... + // + // Length ... + int mAtrLength; + // + // Multiplier ... + double mAtrMultiplier; + // + // Applied To ... + ENUM_APPLIED_PRICE mAtrAppliedTo; + + // + // Presentation ... + // + // Show Trends ... + bool mShowTrends; + // + // Fill Trends ... + bool mFillTrends; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xtm.helper.class.ex5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xtm.helper.class.ex5 new file mode 100644 index 0000000..c2f511b Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xtm.helper.class.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xtm.helper.class.mq5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xtm.helper.class.mq5 new file mode 100644 index 0000000..3587529 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xtm.helper.class.mq5 @@ -0,0 +1,445 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXTMHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// Inputs ... +struct XTMInputs +{ + // + // Makret ... + int length; // Length + int shift; // Shift + + // + // Calculations ... + ENUM_MA_METHOD method; // Method + ENUM_APPLIED_PRICE appliedTo; // Applied To + + // + // Presentation ... + bool showLine; // Show Line +}; + +// +// Index of Lines ... +enum ENUM_XTM_BUFFERS +{ + // + // Main Requirements ... + XTM_LINE = 0, + XTM_STATE_LINE = 1, +}; + +// +// XTM Indicator States ... +enum ENUM_XTM_STATES +{ + X_XTM_BULLISH = 0, + X_XTM_BEARISH = 2, + X_XTM_NEUTURAL = 1, +}; + +// +// Retrieve Info Model ... +struct XTMInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double value; + + // + // State ... + ENUM_XTM_STATES state; + + // + double values[]; + double states[]; + + // + // Conditions ... + + // + // Detect Trend is Bullish or not ... + bool isBullish; + + // + // Detect Trend is Switched to Bullish Or not ... + bool isSwitchedBullish; + + // + // Detect Trend is Bearish or not ... + bool isBearish; + + // + // Detect Trend is Switched to Bearish Or not ... + bool isSwitchedBearish; + + // + // Detect Trend is Neutural or not ... + bool isNeutural; + + // + // Detect Trend is Switched to Neutural Or not ... + bool isSwitchedNeutural; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXTMHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double valueBuffer[]; + double stateBuffer[]; + + // + // Constructor ... + void XSCXTMHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXTMHelper() + { + } + + // + // START Properties ... + // + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XTM" + GetTagPrefix(); + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = mLength; + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Args ... + result = + // + (mLength >= 2) + // + ; + if (!result) + { + return false; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xtm", + // + // Inputs ... + // + // Makret ... + "", + // + // Length ... + mLength, + // + // Shift ... + mShift, + // + // Calculations ... + "", + // + // Method ... + mMethod, + // + // Applied To ... + mAppliedTo, + // + // Presentation ... + "", + // + // Show Line ... + mShowLine + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XTMInputs GetConfig() + { + // + XTMInputs result; + + // + result.length = mLength; + result.shift = mShift; + result.method = mMethod; + result.appliedTo = mAppliedTo; + result.showLine = mShowLine; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XTMInputs &config) + { + // + bool result = false; + + // + mLength = config.length; + mShift = config.shift; + mMethod = config.method; + mAppliedTo = config.appliedTo; + mShowLine = config.showLine; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + // + // VALUE ... + ArraySetAsSeries(valueBuffer, true); + CopyBuffer( + mHandler, + XTM_LINE, + barIndex, + mLoopbackBars, + valueBuffer); + + // + // STATE ... + ArraySetAsSeries(stateBuffer, true); + CopyBuffer( + mHandler, + XTM_STATE_LINE, + barIndex, + mLoopbackBars, + stateBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XTMInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XTMInfo result; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + result.value = valueBuffer[barIndex]; + + // + ENUM_XTM_STATES state = (ENUM_XTM_STATES)stateBuffer[barIndex]; + ENUM_XTM_STATES prevState = (ENUM_XTM_STATES)stateBuffer[barIndex + 1]; + result.state = state; + + // + Copy( + valueBuffer, + result.values); + Copy( + stateBuffer, + result.states); + + // + result.isBullish = state == X_XTM_BULLISH; + result.isBearish = state == X_XTM_BEARISH; + result.isNeutural = state == X_XTM_NEUTURAL; + + // + result.isSwitchedBullish = + state == X_XTM_BULLISH && prevState != X_XTM_BULLISH; + result.isSwitchedBearish = + state == X_XTM_BEARISH && prevState != X_XTM_BEARISH; + result.isSwitchedNeutural = + state == X_XTM_NEUTURAL && prevState != X_XTM_NEUTURAL; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Makret ... + // + // Length ... + int mLength; + // + // Shift ... + int mShift; + + // + // Calculations ... + // + // Method ... + ENUM_MA_METHOD mMethod; + // + // Applied To ... + ENUM_APPLIED_PRICE mAppliedTo; + + // + // Presentation ... + // + // Show Line ... + bool mShowLine; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xtrnd.helper.class.ex5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xtrnd.helper.class.ex5 new file mode 100644 index 0000000..106ae03 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xtrnd.helper.class.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xtrnd.helper.class.mq5 b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xtrnd.helper.class.mq5 new file mode 100644 index 0000000..2a97e2d --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Helpers/x-saherelm.x121.xtrnd.helper.class.mq5 @@ -0,0 +1,1235 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXTRNDHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// XPERIOD Calculation Method ... +// USED For Multiple Time Frames ... +enum ENUM_X_PERIOD_METHOD +{ + // + X_PERIOD_NOTHING, + // + X_PERIOD_AUTO, + // + X_PERIOD_MANUALLY +}; + +// +// Inputs ... +struct XTRNDInputs +{ + // + // Makret ... + int cycleLength; // Cycle Length to Check + int numberOfVerifications; // Number of Verifications + + // + // Calculation ... + ENUM_SERIESMODE hhMode; // Detect Up + ENUM_SERIESMODE llMode; // Detect Low + + // + // Cycles ... + + // + // Level 1 ... + ENUM_X_PERIOD_METHOD l1Method; // How to Find Period + ENUM_TIMEFRAMES l1Period; // Time Period + + // + // Level 2 ... + ENUM_X_PERIOD_METHOD l2Method; // How to Find Period + ENUM_TIMEFRAMES l2Period; // Time Period + + // + // Level 3 ... + ENUM_X_PERIOD_METHOD l3Method; // How to Find Period + ENUM_TIMEFRAMES l3Period; // Time Period + + // + // Presentation ... + bool showConsolidations; // Show Consolidations + bool showTrend; // Show Trend + bool showL1Trend; // Show Cycle 1 Trend + bool showL2Trend; // Show Cycle 2 Trend + bool showL3Trend; // Show Cycle 3 Trend +}; + +// +// Index of Lines ... +enum ENUM_XTRND_BUFFERS +{ + // + // Main Requirements ... + XTRND_UP_LINE = 0, + XTRND_UP_STATE_LINE = 16, + XTRND_DOWN_LINE = 2, + XTRND_DOWN_STATE_LINE = 17, + // + // LEVEL 1 ... + XTRND_L1_UP_LINE = 4, + XTRND_L1_UP_STATE_LINE = 18, + XTRND_L1_DOWN_LINE = 6, + XTRND_L1_DOWN_STATE_LINE = 19, + // + // LEVEL 2 ... + XTRND_L2_UP_LINE = 8, + XTRND_L2_UP_STATE_LINE = 20, + XTRND_L2_DOWN_LINE = 10, + XTRND_L2_DOWN_STATE_LINE = 21, + // + // LEVEL 3 ... + XTRND_L3_UP_LINE = 12, + XTRND_L3_UP_STATE_LINE = 22, + XTRND_L3_DOWN_LINE = 14, + XTRND_L3_DOWN_STATE_LINE = 23, +}; + +// +enum ENUM_XTRND_STATES +{ + XTRND_STATE_BULLISH = 1, + XTRND_STATE_BEARISH = 2, + XTRND_STATE_CONSOLIDATION = 0, +}; + +// +// Retrieve Info Model ... +struct XTRNDInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double hh; + ENUM_XTRND_STATES hhState; + double ll; + double llState; + double l1hh; + ENUM_XTRND_STATES l1hhState; + double l1ll; + ENUM_XTRND_STATES l1llState; + double l2hh; + ENUM_XTRND_STATES l2hhState; + double l2ll; + ENUM_XTRND_STATES l2llState; + double l3hh; + ENUM_XTRND_STATES l3hhState; + double l3ll; + ENUM_XTRND_STATES l3llState; + + // + double hhs[]; + double hhStates[]; + double lls[]; + double llStates[]; + double l1hhs[]; + double l1hhStates[]; + double l1lls[]; + double l1llStates[]; + double l2hhs[]; + double l2hhStates[]; + double l2lls[]; + double l2llStates[]; + double l3hhs[]; + double l3hhStates[]; + double l3lls[]; + double l3llStates[]; + + // + // Conditions ... + // + bool isTrendBullish; + bool isTrendSwitchedToBullish; + bool isTrendBearish; + bool isTrendSwitchedToBearish; + bool isTrendConsolidation; + bool isTrendSwitchedToConsolidation; + + // + bool isTrendUpBullish; + bool isTrendUpBearish; + bool isTrendDownBullish; + bool isTrendDownBearish; + + // + bool isL1TrendBullish; + bool isL1TrendSwitchedToBullish; + bool isL1TrendBearish; + bool isL1TrendSwitchedToBearish; + bool isL1TrendConsolidation; + bool isL1TrendSwitchedToConsolidation; + + // + bool isL1TrendUpBullish; + bool isL1TrendUpBearish; + bool isL1TrendDownBullish; + bool isL1TrendDownBearish; + + // + bool isL2TrendBullish; + bool isL2TrendSwitchedToBullish; + bool isL2TrendBearish; + bool isL2TrendSwitchedToBearish; + bool isL2TrendConsolidation; + bool isL2TrendSwitchedToConsolidation; + + // + bool isL2TrendUpBullish; + bool isL2TrendUpBearish; + bool isL2TrendDownBullish; + bool isL2TrendDownBearish; + + // + bool isL3TrendBullish; + bool isL3TrendSwitchedToBullish; + bool isL3TrendBearish; + bool isL3TrendSwitchedToBearish; + bool isL3TrendConsolidation; + bool isL3TrendSwitchedToConsolidation; + + // + bool isL3TrendUpBullish; + bool isL3TrendUpBearish; + bool isL3TrendDownBullish; + bool isL3TrendDownBearish; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXTRNDHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double hhBuffer[]; + double hhStateBuffer[]; + double llBuffer[]; + double llStateBuffer[]; + double l1hhBuffer[]; + double l1hhStateBuffer[]; + double l1llBuffer[]; + double l1llStateBuffer[]; + double l2hhBuffer[]; + double l2hhStateBuffer[]; + double l2llBuffer[]; + double l2llStateBuffer[]; + double l3hhBuffer[]; + double l3hhStateBuffer[]; + double l3llBuffer[]; + double l3llStateBuffer[]; + + // + // Constructor ... + void XSCXTRNDHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXTRNDHelper() + { + } + + // + // START Properties ... + // + + // + // Show Trend ... + bool ShowTrend( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowTrend == show) + { + return true; + } + + // + mShowTrend = show; + result = Init(); + + // + return result; + } + + // + // Show Cycle 1 Trend ... + bool ShowL1Trends( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowL1Trends == show) + { + return true; + } + + // + mShowL1Trends = show; + result = Init(); + + // + return result; + } + + // + // Show Cycle 2 Trend ... + bool ShowL2Trends( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowL2Trends == show) + { + return true; + } + + // + mShowL2Trends = show; + result = Init(); + + // + return result; + } + + // + // Show Cycle 3 Trend ... + bool ShowL3Trends( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowL3Trends == show) + { + return true; + } + + // + mShowL3Trends = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XTRND" + GetTagPrefix(); + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = MathMax( + mCycleLength, + mNumberOfVerifications); + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Inputs ... + // + // + result = + // + (mCycleLength > 0 && + mNumberOfVerifications > 0) + // + ; + if (!result) + { + return result; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xtrnd", + // + // Inputs ... + // + // Market ... + "", + // + // Cycle Length to Check ... + mCycleLength, + // + // Number of Verifications ... + mNumberOfVerifications, + // + // Calculations ... + "", + // + // Detect Up ... + mHHMode, + // + // Detect Low ... + mLLMode, + // + // Cycles ... + "", + // + // LEVEL 1 ... + "", + // + // How to Find Period ... + mLLMethod, + // + // Time Period ... + mL1Period, + // + // LEVEL 2 ... + "", + // + // How to Find Period ... + mL2Method, + // + // Time Period ... + mL2Period, + // + // LEVEL 3 ... + "", + // + // How to Find Period ... + mL3Method, + // + // Time Period ... + mL3Period, + // + // Presentation ... + "", + // + // Show Consolidations ... + mShowConsolidations, + // + // Show Trend ... + mShowTrend, + // + // Show Cycle 1 Trend ... + mShowL1Trends, + // + // Show Cycle 2 Trend ... + mShowL2Trends, + // + // Show Cycle 3 Trend ... + mShowL3Trends + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XTRNDInputs GetConfig() + { + // + XTRNDInputs result; + + // + result.cycleLength = mCycleLength; + result.numberOfVerifications = mNumberOfVerifications; + result.hhMode = mHHMode; + result.llMode = mLLMode; + result.l1Method = mLLMethod; + result.l1Period = mL1Period; + result.l2Method = mL2Method; + result.l2Period = mL2Period; + result.l3Method = mL3Method; + result.l3Period = mL3Period; + result.showConsolidations = mShowConsolidations; + result.showTrend = mShowTrend; + result.showL1Trend = mShowL1Trends; + result.showL2Trend = mShowL2Trends; + result.showL3Trend = mShowL3Trends; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XTRNDInputs &config) + { + // + bool result = false; + + // + mCycleLength = config.cycleLength; + mNumberOfVerifications = config.numberOfVerifications; + mHHMode = config.hhMode; + mLLMode = config.llMode; + mLLMethod = config.l1Method; + mL1Period = config.l1Period; + mL2Method = config.l2Method; + mL2Period = config.l2Period; + mL3Method = config.l3Method; + mL3Period = config.l3Period; + mShowConsolidations = config.showConsolidations; + mShowTrend = config.showTrend; + mShowL1Trends = config.showL1Trend; + mShowL2Trends = config.showL2Trend; + mShowL3Trends = config.showL3Trend; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + // + // HH ... + ArraySetAsSeries(hhBuffer, true); + CopyBuffer( + mHandler, + XTRND_UP_LINE, + barIndex, + mLoopbackBars, + hhBuffer); + + // + // HH State ... + ArraySetAsSeries(hhStateBuffer, true); + CopyBuffer( + mHandler, + XTRND_UP_STATE_LINE, + barIndex, + mLoopbackBars, + hhStateBuffer); + + // + // LL ... + ArraySetAsSeries(llBuffer, true); + CopyBuffer( + mHandler, + XTRND_DOWN_LINE, + barIndex, + mLoopbackBars, + llBuffer); + + // + // LL State ... + ArraySetAsSeries(llStateBuffer, true); + CopyBuffer( + mHandler, + XTRND_DOWN_STATE_LINE, + barIndex, + mLoopbackBars, + llStateBuffer); + + // + // CYCLES ... + + // + // LEVEL 1 ... + + // + // HH ... + ArraySetAsSeries(l1hhBuffer, true); + CopyBuffer( + mHandler, + XTRND_L1_UP_LINE, + barIndex, + mLoopbackBars, + l1hhBuffer); + + // + // HH State ... + ArraySetAsSeries(l1hhStateBuffer, true); + CopyBuffer( + mHandler, + XTRND_L1_UP_STATE_LINE, + barIndex, + mLoopbackBars, + l1hhStateBuffer); + + // + // LL ... + ArraySetAsSeries(l1llBuffer, true); + CopyBuffer( + mHandler, + XTRND_L1_DOWN_LINE, + barIndex, + mLoopbackBars, + l1llBuffer); + + // + // LL State ... + ArraySetAsSeries(l1llStateBuffer, true); + CopyBuffer( + mHandler, + XTRND_L1_DOWN_STATE_LINE, + barIndex, + mLoopbackBars, + l1llStateBuffer); + + // + // LEVEL 2 ... + + // + // HH ... + ArraySetAsSeries(l2hhBuffer, true); + CopyBuffer( + mHandler, + XTRND_L2_UP_LINE, + barIndex, + mLoopbackBars, + l2hhBuffer); + + // + // HH State ... + ArraySetAsSeries(l2hhStateBuffer, true); + CopyBuffer( + mHandler, + XTRND_L2_UP_STATE_LINE, + barIndex, + mLoopbackBars, + l2hhStateBuffer); + + // + // LL ... + ArraySetAsSeries(l2llBuffer, true); + CopyBuffer( + mHandler, + XTRND_L2_DOWN_LINE, + barIndex, + mLoopbackBars, + l2llBuffer); + + // + // LL State ... + ArraySetAsSeries(l2llStateBuffer, true); + CopyBuffer( + mHandler, + XTRND_L2_DOWN_STATE_LINE, + barIndex, + mLoopbackBars, + l2llStateBuffer); + + // + // LEVEL 3 ... + + // + // HH ... + ArraySetAsSeries(l3hhBuffer, true); + CopyBuffer( + mHandler, + XTRND_L3_UP_LINE, + barIndex, + mLoopbackBars, + l3hhBuffer); + + // + // HH State ... + ArraySetAsSeries(l3hhStateBuffer, true); + CopyBuffer( + mHandler, + XTRND_L3_UP_STATE_LINE, + barIndex, + mLoopbackBars, + l3hhStateBuffer); + + // + // LL ... + ArraySetAsSeries(l3llBuffer, true); + CopyBuffer( + mHandler, + XTRND_L3_DOWN_LINE, + barIndex, + mLoopbackBars, + l3llBuffer); + + // + // LL State ... + ArraySetAsSeries(l3llStateBuffer, true); + CopyBuffer( + mHandler, + XTRND_L3_DOWN_STATE_LINE, + barIndex, + mLoopbackBars, + l3llStateBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XTRNDInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XTRNDInfo result; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + double hh = hhBuffer[barIndex]; + ENUM_XTRND_STATES hhState = (ENUM_XTRND_STATES)hhStateBuffer[barIndex]; + ENUM_XTRND_STATES hhStatePrev = (ENUM_XTRND_STATES)hhStateBuffer[barIndex + 1]; + + // + double ll = llBuffer[barIndex]; + ENUM_XTRND_STATES llState = (ENUM_XTRND_STATES)llStateBuffer[barIndex]; + ENUM_XTRND_STATES llStatePrev = (ENUM_XTRND_STATES)llStateBuffer[barIndex + 1]; + + // + double l1hh = l1hhBuffer[barIndex]; + ENUM_XTRND_STATES l1hhState = (ENUM_XTRND_STATES)l1hhStateBuffer[barIndex]; + ENUM_XTRND_STATES l1hhStatePrev = (ENUM_XTRND_STATES)l1hhStateBuffer[barIndex + 1]; + + // + double l1ll = l1llBuffer[barIndex]; + ENUM_XTRND_STATES l1llState = (ENUM_XTRND_STATES)l1llStateBuffer[barIndex]; + ENUM_XTRND_STATES l1llStatePrev = (ENUM_XTRND_STATES)l1llStateBuffer[barIndex + 1]; + + // + double l2hh = l2hhBuffer[barIndex]; + ENUM_XTRND_STATES l2hhState = (ENUM_XTRND_STATES)l2hhStateBuffer[barIndex]; + ENUM_XTRND_STATES l2hhStatePrev = (ENUM_XTRND_STATES)l2hhStateBuffer[barIndex + 1]; + + // + double l2ll = l2llBuffer[barIndex]; + ENUM_XTRND_STATES l2llState = (ENUM_XTRND_STATES)l2llStateBuffer[barIndex]; + ENUM_XTRND_STATES l2llStatePrev = (ENUM_XTRND_STATES)l2llStateBuffer[barIndex + 1]; + + // + double l3hh = l3hhBuffer[barIndex]; + ENUM_XTRND_STATES l3hhState = (ENUM_XTRND_STATES)l3hhStateBuffer[barIndex]; + ENUM_XTRND_STATES l3hhStatePrev = (ENUM_XTRND_STATES)l3hhStateBuffer[barIndex + 1]; + + // + double l3ll = l3llBuffer[barIndex]; + ENUM_XTRND_STATES l3llState = (ENUM_XTRND_STATES)l3llStateBuffer[barIndex]; + ENUM_XTRND_STATES l3llStatePrev = (ENUM_XTRND_STATES)l3llStateBuffer[barIndex + 1]; + + // + Copy( + hhBuffer, + result.hhs); + Copy( + hhStateBuffer, + result.hhStates); + Copy( + llBuffer, + result.lls); + Copy( + llStateBuffer, + result.llStates); + Copy( + l1hhBuffer, + result.l1hhs); + Copy( + l1hhStateBuffer, + result.l1hhStates); + Copy( + l1llBuffer, + result.l1lls); + Copy( + l1llStateBuffer, + result.l1llStates); + Copy( + l2hhBuffer, + result.l2hhs); + Copy( + l2hhStateBuffer, + result.l2hhStates); + Copy( + l2llBuffer, + result.l2lls); + Copy( + l2llStateBuffer, + result.l2llStates); + Copy( + l3hhBuffer, + result.l3hhs); + Copy( + l3hhStateBuffer, + result.l3hhStates); + Copy( + l3llBuffer, + result.l3lls); + Copy( + l3llStateBuffer, + result.l3llStates); + + // + bool isTrendBullish = + hhState == XTRND_STATE_BULLISH && + llState == XTRND_STATE_BULLISH; + bool isPrevTrendBullish = + hhStatePrev == XTRND_STATE_BULLISH && + llStatePrev == XTRND_STATE_BULLISH; + bool isTrendBearish = + hhState == XTRND_STATE_BEARISH && + llState == XTRND_STATE_BEARISH; + bool isPrevTrendBearish = + hhStatePrev == XTRND_STATE_BEARISH && + llStatePrev == XTRND_STATE_BEARISH; + bool isTrendConsolidation = + hhState == XTRND_STATE_CONSOLIDATION && + llState == XTRND_STATE_CONSOLIDATION; + bool isPrevTrendConsolidation = + hhStatePrev == XTRND_STATE_CONSOLIDATION && + llStatePrev == XTRND_STATE_CONSOLIDATION; + + // + bool isTrendUpBullish = + hhState == XTRND_STATE_BULLISH; + bool isTrendUpBearish = + hhState == XTRND_STATE_BEARISH; + bool isTrendDownBullish = + llState == XTRND_STATE_BULLISH; + bool isTrendDownBearish = + llState == XTRND_STATE_BEARISH; + + // + bool isTrendSwitchedToBullish = + isTrendBullish && + !isPrevTrendBullish; + bool isTrendSwitchedToBearish = + isTrendBearish && + !isPrevTrendBearish; + bool isTrendSwitchedToConsolidation = + isTrendConsolidation && + !isPrevTrendConsolidation; + + // + bool isL1TrendBullish = + l1hhState == XTRND_STATE_BULLISH && + l1llState == XTRND_STATE_BULLISH; + bool isL1PrevTrendBullish = + l1hhStatePrev == XTRND_STATE_BULLISH && + l1llStatePrev == XTRND_STATE_BULLISH; + bool isL1TrendBearish = + l1hhState == XTRND_STATE_BEARISH && + l1llState == XTRND_STATE_BEARISH; + bool isL1PrevTrendBearish = + l1hhStatePrev == XTRND_STATE_BEARISH && + l1llStatePrev == XTRND_STATE_BEARISH; + bool isL1TrendConsolidation = + l1hhState == XTRND_STATE_CONSOLIDATION && + l1llState == XTRND_STATE_CONSOLIDATION; + bool isL1PrevTrendConsolidation = + l1hhStatePrev == XTRND_STATE_CONSOLIDATION && + l1llStatePrev == XTRND_STATE_CONSOLIDATION; + + // + bool isL1TrendUpBullish = + l1hhState == XTRND_STATE_BULLISH; + bool isL1TrendUpBearish = + l1hhState == XTRND_STATE_BEARISH; + bool isL1TrendDownBullish = + l1llState == XTRND_STATE_BULLISH; + bool isL1TrendDownBearish = + l1llState == XTRND_STATE_BEARISH; + + // + bool isL1TrendSwitchedToBullish = + isL1TrendBullish && + !isL1PrevTrendBullish; + bool isL1TrendSwitchedToBearish = + isL1TrendBearish && + !isL1PrevTrendBearish; + bool isL1TrendSwitchedToConsolidation = + isL1TrendConsolidation && + !isL1PrevTrendConsolidation; + + // + bool isL2TrendBullish = + l2hhState == XTRND_STATE_BULLISH && + l2llState == XTRND_STATE_BULLISH; + bool isL2PrevTrendBullish = + l2hhStatePrev == XTRND_STATE_BULLISH && + l2llStatePrev == XTRND_STATE_BULLISH; + bool isL2TrendBearish = + l2hhState == XTRND_STATE_BEARISH && + l2llState == XTRND_STATE_BEARISH; + bool isL2PrevTrendBearish = + l2hhStatePrev == XTRND_STATE_BEARISH && + l2llStatePrev == XTRND_STATE_BEARISH; + bool isL2TrendConsolidation = + l2hhState == XTRND_STATE_CONSOLIDATION && + l2llState == XTRND_STATE_CONSOLIDATION; + bool isL2PrevTrendConsolidation = + l2hhStatePrev == XTRND_STATE_CONSOLIDATION && + l2llStatePrev == XTRND_STATE_CONSOLIDATION; + + // + bool isL2TrendUpBullish = + l2hhState == XTRND_STATE_BULLISH; + bool isL2TrendUpBearish = + l2hhState == XTRND_STATE_BEARISH; + bool isL2TrendDownBullish = + l2llState == XTRND_STATE_BULLISH; + bool isL2TrendDownBearish = + l2llState == XTRND_STATE_BEARISH; + + // + bool isL2TrendSwitchedToBullish = + isL2TrendBullish && + !isL2PrevTrendBullish; + bool isL2TrendSwitchedToBearish = + isL2TrendBearish && + !isL2PrevTrendBearish; + bool isL2TrendSwitchedToConsolidation = + isL2TrendConsolidation && + !isL2PrevTrendConsolidation; + + // + bool isL3TrendBullish = + l3hhState == XTRND_STATE_BULLISH && + l3llState == XTRND_STATE_BULLISH; + bool isL3PrevTrendBullish = + l3hhStatePrev == XTRND_STATE_BULLISH && + l3llStatePrev == XTRND_STATE_BULLISH; + bool isL3TrendBearish = + l3hhState == XTRND_STATE_BEARISH && + l3llState == XTRND_STATE_BEARISH; + bool isL3PrevTrendBearish = + l3hhStatePrev == XTRND_STATE_BEARISH && + l3llStatePrev == XTRND_STATE_BEARISH; + bool isL3TrendConsolidation = + l3hhState == XTRND_STATE_CONSOLIDATION && + l3llState == XTRND_STATE_CONSOLIDATION; + bool isL3PrevTrendConsolidation = + l3hhStatePrev == XTRND_STATE_CONSOLIDATION && + l3llStatePrev == XTRND_STATE_CONSOLIDATION; + + // + bool isL3TrendUpBullish = + l3hhState == XTRND_STATE_BULLISH; + bool isL3TrendUpBearish = + l3hhState == XTRND_STATE_BEARISH; + bool isL3TrendDownBullish = + l3llState == XTRND_STATE_BULLISH; + bool isL3TrendDownBearish = + l3llState == XTRND_STATE_BEARISH; + + // + bool isL3TrendSwitchedToBullish = + isL3TrendBullish && + !isL3PrevTrendBullish; + bool isL3TrendSwitchedToBearish = + isL3TrendBearish && + !isL3PrevTrendBearish; + bool isL3TrendSwitchedToConsolidation = + isL3TrendConsolidation && + !isL3PrevTrendConsolidation; + + // + result.hh = hh; + result.hhState = hhState; + result.ll = ll; + result.llState = llState; + result.l1hh = l1hh; + result.l1hhState = l1hhState; + result.l1ll = l1ll; + result.l1llState = l1llState; + result.l2hh = l2hh; + result.l2hhState = l2hhState; + result.l2ll = l2ll; + result.l2llState = l2llState; + result.l3hh = l3hh; + result.l3hhState = l3hhState; + result.l3ll = l3ll; + result.l3llState = l3llState; + + // + // LEVEL 0 ... + + // + result.isTrendBullish = isTrendBullish; + result.isTrendBearish = isTrendBearish; + result.isTrendConsolidation = isTrendConsolidation; + + // + result.isTrendUpBullish = isTrendUpBullish; + result.isTrendUpBearish = isTrendUpBearish; + result.isTrendDownBullish = isTrendDownBullish; + result.isTrendDownBearish = isTrendDownBearish; + + // + result.isTrendSwitchedToBullish = isTrendSwitchedToBullish; + result.isTrendSwitchedToBearish = isTrendSwitchedToBearish; + result.isTrendSwitchedToConsolidation = isTrendSwitchedToConsolidation; + + // + // LEVEL 1 ... + + // + result.isL1TrendBullish = isL1TrendBullish; + result.isL1TrendBearish = isL1TrendBearish; + result.isL1TrendConsolidation = isL1TrendConsolidation; + + // + result.isL1TrendUpBullish = isL1TrendUpBullish; + result.isL1TrendUpBearish = isL1TrendUpBearish; + result.isL1TrendDownBullish = isL1TrendDownBullish; + result.isL1TrendDownBearish = isL1TrendDownBearish; + + // + result.isL1TrendSwitchedToBullish = isL1TrendSwitchedToBullish; + result.isL1TrendSwitchedToBearish = isL1TrendSwitchedToBearish; + result.isL1TrendSwitchedToConsolidation = isL1TrendSwitchedToConsolidation; + + // + // LEVEL 2 ... + + // + result.isL2TrendBullish = isL2TrendBullish; + result.isL2TrendBearish = isL2TrendBearish; + result.isL2TrendConsolidation = isL2TrendConsolidation; + + // + result.isL2TrendUpBullish = isL2TrendUpBullish; + result.isL2TrendUpBearish = isL2TrendUpBearish; + result.isL2TrendDownBullish = isL2TrendDownBullish; + result.isL2TrendDownBearish = isL2TrendDownBearish; + + // + result.isL2TrendSwitchedToBullish = isL2TrendSwitchedToBullish; + result.isL2TrendSwitchedToBearish = isL2TrendSwitchedToBearish; + result.isL2TrendSwitchedToConsolidation = isL2TrendSwitchedToConsolidation; + + // + // LEVEL 3 ... + + // + result.isL3TrendBullish = isL3TrendBullish; + result.isL3TrendBearish = isL3TrendBearish; + result.isL3TrendConsolidation = isL3TrendConsolidation; + + // + result.isL3TrendUpBullish = isL3TrendUpBullish; + result.isL3TrendUpBearish = isL3TrendUpBearish; + result.isL3TrendDownBullish = isL3TrendDownBullish; + result.isL3TrendDownBearish = isL3TrendDownBearish; + + // + result.isL3TrendSwitchedToBullish = isL3TrendSwitchedToBullish; + result.isL3TrendSwitchedToBearish = isL3TrendSwitchedToBearish; + result.isL3TrendSwitchedToConsolidation = isL3TrendSwitchedToConsolidation; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Market ... + // + // Cycle Length to Check ... + int mCycleLength; + // + // Number of Verifications ... + int mNumberOfVerifications; + // + // Calculations ... + // + // Detect Up ... + ENUM_SERIESMODE mHHMode; + // + // Detect Low ... + ENUM_SERIESMODE mLLMode; + // + // Cycles ... + // + // LEVEL 1 ... + // + // How to Find Period ... + ENUM_X_PERIOD_METHOD mLLMethod; + // + // Time Period ... + ENUM_TIMEFRAMES mL1Period; + // + // LEVEL 2 ... + // + // How to Find Period ... + ENUM_X_PERIOD_METHOD mL2Method; + // + // Time Period ... + ENUM_TIMEFRAMES mL2Period; + // + // LEVEL 3 ... + // + // How to Find Period ... + ENUM_X_PERIOD_METHOD mL3Method; + // + // Time Period ... + ENUM_TIMEFRAMES mL3Period; + // + // Presentation ... + // + // Show Consolidations ... + bool mShowConsolidations; + // + // Show Trend ... + bool mShowTrend; + // + // Show Cycle 1 Trend ... + bool mShowL1Trends; + // + // Show Cycle 2 Trend ... + bool mShowL2Trends; + // + // Show Cycle 3 Trend ... + bool mShowL3Trends; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Indicators/Market/WH Fair Value Gap MT5.ex5 b/MQLTestWorkspace/X121/Old/Indicators/Market/WH Fair Value Gap MT5.ex5 new file mode 100644 index 0000000..97a3517 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Indicators/Market/WH Fair Value Gap MT5.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xama.ex5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xama.ex5 new file mode 100644 index 0000000..5378723 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xama.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xama.mq5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xama.mq5 new file mode 100644 index 0000000..4856cbb --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xama.mq5 @@ -0,0 +1,350 @@ +////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: X121_XAMA +// 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 X121_XAMA Indicator" +#property strict + +// +// START Constants ... +// +#define ShortName "X121_XAMA" + +// +// XAMA Indicator States ... +enum ENUM_X_XAMA_STATES +{ + X_XAMA_BULLISH = 0, + X_XAMA_BEARISH = 2, + X_XAMA_NEUTURAL = 1, +}; +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Makret"; +input int length = 52; // Length +input int fastEMA = 2; // Fast EMA Length +input int slowEMA = 30; // Slow EMA Length +input int maShift = 0; // Shift +input ENUM_APPLIED_PRICE appliedTo = PRICE_LOW; // Applied To + +// +input group "Presentation"; +input bool showLine = true; // Show Line + +// +// END Inputs ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 3 +#property indicator_plots 1 + +// +// maBuffer ... +#define maBufferIndex 0 +#define maColorBufferIndex 1 + +double maBuffer[]; +double maColorBuffer[]; + +#property indicator_label1 "X121_XAMA" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrLime, clrGray, clrRed +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int maHandler = INVALID_HANDLE; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Initializing MA Handler ... + maHandler = iAMA( + _Symbol, + _Period, + length, + fastEMA, + slowEMA, + maShift, + appliedTo); + if (maHandler == INVALID_HANDLE) + { + // + string message = "Error Initializing Ma Handler ..."; + Print(message); + + // + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + IndicatorRelease(maHandler); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // Check Calculated Bars ... + int maCalculatedBars = BarsCalculated(maHandler); + if (maCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedMas = CopyBuffer(maHandler, 0, 0, limit, maBuffer); + if (copiedMas <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + // Do Buffers Calculation ... + CalculateBuffers(i); + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 2) + { + result = true; + } + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = length; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + ENUM_DRAW_TYPE drawType = showLine ? DRAW_COLOR_LINE : DRAW_NONE; + + // + // Ma Buffer ... + ArraySetAsSeries(maBuffer, true); + SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_DATA); + PlotIndexSetInteger(maBufferIndex, PLOT_DRAW_TYPE, drawType); + PlotIndexSetInteger(maBufferIndex, PLOT_SHOW_DATA, showLine); + + // + // Ma Color Buffer ... + ArraySetAsSeries(maColorBuffer, true); + SetIndexBuffer(maColorBufferIndex, maColorBuffer, INDICATOR_COLOR_INDEX); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers(int bar_index) +{ + // + // Requirements ... + XOHCL candle = GetCandle(bar_index); + + // + double maValue = maBuffer[bar_index]; + + // + double lineColorIndex = + maValue < candle.low ? 0 : maValue > candle.high ? 2 + : 1; + // + // Set Ma Buffer Color Index ... + maColorBuffer[bar_index] = lineColorIndex; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xcc.ex5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xcc.ex5 new file mode 100644 index 0000000..34b97ce Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xcc.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xcc.mq5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xcc.mq5 new file mode 100644 index 0000000..7389725 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xcc.mq5 @@ -0,0 +1,454 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Candle Styles +// --------------------------------------------------- +// Name: X121_CC +// 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 X121_CC Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_CC" + +// +// 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 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( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (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.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/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xche.ex5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xche.ex5 new file mode 100644 index 0000000..b76eaec Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xche.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xche.mq5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xche.mq5 new file mode 100644 index 0000000..59e850f --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xche.mq5 @@ -0,0 +1,631 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: X121_XCHE +// Description: Chandelier Exit Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121_XCHE Indicator" +#property strict + +// +// START Constants ... +// + +// +#define ShortName "X121_XCHE" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Market"; +input int length = 35; // Length +input int loopback = 26; // Loopback +input double multiplier1 = 3.0; // 1st Multiplier +input double multiplier2 = 3.5; // 2nd Multiplier + +// +input group "Calculation"; +input ENUM_APPLIED_PRICE upAppliedTo = PRICE_HIGH; // Up Zone Applied to +input ENUM_APPLIED_PRICE downAppliedTo = PRICE_LOW; // Down Zone Applied to + +// +input group "Presentation"; +input bool showLongExit1Line = true; // Show 1st Long Exit +input bool showShortExit1Line = true; // Show 1st Short Exit +input bool showLongExit2Line = true; // Show 2st Long Exit +input bool showShortExit2Line = true; // Show 2st Short Exit + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 8 +#property indicator_plots 8 + +// +// Long Exit 1 ... +#define longExit1BufferIndex 0 +double longExit1Buffer[]; + +// +#property indicator_label1 "X121_XCHE LE 1" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrLime +#property indicator_style1 STYLE_DOT + +// +// Short Exit 1 ... +#define shortExit1BufferIndex 1 +double shortExit1Buffer[]; + +// +#property indicator_label2 "X121_XCHE SE 1" +#property indicator_type2 DRAW_LINE +#property indicator_style2 STYLE_DOT +#property indicator_color2 clrRed + +// +// Long Exit 2 ... +#define longExit2BufferIndex 2 +double longExit2Buffer[]; + +// +#property indicator_label3 "X121_XCHE LE 2" +#property indicator_type3 DRAW_LINE +#property indicator_style2 STYLE_DOT +#property indicator_color3 clrAqua + +// +// Short Exit 2 ... +#define shortExit2BufferIndex 3 +double shortExit2Buffer[]; + +// +#property indicator_label4 "X121_XCHE SE 2" +#property indicator_type4 DRAW_LINE +#property indicator_style2 STYLE_DOT +#property indicator_color4 clrMagenta + +// +// START Arrows ... + +// +// Long Exit 1 Start ... +#define longExit1StartBufferIndex 4 +double longExit1StartBuffer[]; + +// +#property indicator_label5 "X121_XCHE LES 1" +#property indicator_type5 DRAW_ARROW +#property indicator_color5 clrLime + +// +// Short Exit 1 Start ... +#define shortExit1StartBufferIndex 5 +double shortExit1StartBuffer[]; + +// +#property indicator_label6 "X121_XCHE SES 1" +#property indicator_type6 DRAW_ARROW +#property indicator_color6 clrRed + +// +// Long Exit 2 Start ... +#define longExit2StartBufferIndex 6 +double longExit2StartBuffer[]; + +// +#property indicator_label7 "X121_XCHE LES 2" +#property indicator_type7 DRAW_ARROW +#property indicator_color7 clrAqua + +// +// Short Exit 2 Start ... +#define shortExit2StartBufferIndex 7 +double shortExit2StartBuffer[]; + +// +#property indicator_label8 "X121_XCHE SES 2" +#property indicator_type8 DRAW_ARROW +#property indicator_color8 clrMagenta + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +// Working Array ... +double work[][6]; +#define hi1Idx 0 +#define lo1Idx 1 +#define hi2Idx 2 +#define lo2Idx 3 +#define trend1Idx 4 +#define trend2Idx 5 + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart mPeriod is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + if (Bars(_Symbol, _Period) < rates_total) + { + return (prev_calculated); + } + + // + if (ArrayRange(work, 0) != rates_total) + { + ArrayResize(work, rates_total); + } + + // + // this counts Available Bars ... + int limit; + + // + limit = prev_calculated - 1; + if (limit < 0) + { + limit = 0; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + CalculateBuffers( + i, + prev_calculated, + rates_total, + // + open, + high, + low, + close); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + result = + length >= 9 && + loopback >= 0; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(length, loopback); + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + uint arrowCode = 159; + + // + // LEVEL 1 ... + + // + // Long Exit 1 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE longExit1DrawType = showLongExit1Line ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE longExit1StartDrawType = showLongExit1Line ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(longExit1BufferIndex, longExit1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(longExit1BufferIndex, PLOT_SHOW_DATA, showLongExit1Line); + PlotIndexSetInteger(longExit1BufferIndex, PLOT_DRAW_TYPE, longExit1DrawType); + + // + // Start Buffer ... + SetIndexBuffer(longExit1StartBufferIndex, longExit1StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(longExit1StartBufferIndex, PLOT_ARROW, arrowCode); + PlotIndexSetInteger(longExit1StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(longExit1StartBufferIndex, PLOT_DRAW_TYPE, longExit1StartDrawType); + + // + // Short Exit 1 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE shortExit1DrawType = showShortExit1Line ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE shortExit1StartDrawType = showShortExit1Line ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(shortExit1BufferIndex, shortExit1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(shortExit1BufferIndex, PLOT_SHOW_DATA, showShortExit1Line); + PlotIndexSetInteger(shortExit1BufferIndex, PLOT_DRAW_TYPE, shortExit1DrawType); + + // + // Start Buffer ... + SetIndexBuffer(shortExit1StartBufferIndex, shortExit1StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(shortExit1StartBufferIndex, PLOT_ARROW, arrowCode); + PlotIndexSetInteger(shortExit1StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(shortExit1StartBufferIndex, PLOT_DRAW_TYPE, shortExit1StartDrawType); + + // + // LEVEL 2 ... + + // + // Long Exit 2 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE longExit2DrawType = showLongExit2Line ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE longExit2StartDrawType = showLongExit2Line ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(longExit2BufferIndex, longExit2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(longExit2BufferIndex, PLOT_SHOW_DATA, showLongExit2Line); + PlotIndexSetInteger(longExit2BufferIndex, PLOT_DRAW_TYPE, longExit2DrawType); + + // + // Start Buffer ... + SetIndexBuffer(longExit2StartBufferIndex, longExit2StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(longExit2StartBufferIndex, PLOT_ARROW, arrowCode); + PlotIndexSetInteger(longExit2StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(longExit2StartBufferIndex, PLOT_DRAW_TYPE, longExit2StartDrawType); + + // + // Short Exit 2 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE shortExit2DrawType = showShortExit2Line ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE shortExit2StartDrawType = showShortExit2Line ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(shortExit2BufferIndex, shortExit2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(shortExit2BufferIndex, PLOT_SHOW_DATA, showShortExit2Line); + PlotIndexSetInteger(shortExit2BufferIndex, PLOT_DRAW_TYPE, shortExit2DrawType); + + // + // Start Buffer ... + SetIndexBuffer(shortExit2StartBufferIndex, shortExit2StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(shortExit2StartBufferIndex, PLOT_ARROW, arrowCode); + PlotIndexSetInteger(shortExit2StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(shortExit2StartBufferIndex, PLOT_DRAW_TYPE, shortExit2StartDrawType); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, // Selected Bar Index + int prevCalculated, // Previous Calculated + int ratesTotal, // Total Rates + const double &open[], // Rates Open ... + const double &high[], // Rates High ... + const double &low[], // Rates Low ... + const double &close[] // Rates Close ... +) +{ + // + // Cleanup Buffers ... + longExit1Buffer[bar_index] = longExit1StartBuffer[bar_index] = shortExit1Buffer[bar_index] = shortExit1StartBuffer[bar_index] = EMPTY_VALUE; + longExit2Buffer[bar_index] = longExit2StartBuffer[bar_index] = shortExit2Buffer[bar_index] = shortExit2StartBuffer[bar_index] = EMPTY_VALUE; + + // + int start = MathMax(bar_index - loopback, 0); + + // + // Calculate ATR Value ... + double atrValue = 0; + for (int k = 1; k <= length && (bar_index - k - 1) >= 0; k++) + { + // + atrValue += MathMax(high[bar_index - k], close[MathMax(bar_index - k - 1, 0)]) - + MathMin(low[bar_index - k], close[MathMax(bar_index - k - 1, 0)]); + } + atrValue /= (double)length; + + // + // Retrieve Highest High and Lowest Lows ... + double loopbackMax = high[ArrayMaximum(high, start, loopback)]; + double loopbackMin = low[ArrayMinimum(low, start, loopback)]; + + // + // Fill Multi Dimesional Working Array ... + work[bar_index][hi1Idx] = loopbackMax - multiplier1 * atrValue; + work[bar_index][lo1Idx] = loopbackMin + multiplier1 * atrValue; + work[bar_index][hi2Idx] = loopbackMax - multiplier2 * atrValue; + work[bar_index][lo2Idx] = loopbackMin + multiplier2 * atrValue; + work[bar_index][trend1Idx] = (bar_index > 0) ? work[bar_index - 1][trend1Idx] : 0; + work[bar_index][trend2Idx] = (bar_index > 0) ? work[bar_index - 1][trend2Idx] : 0; + + // + if (bar_index > 0) + { + // + // Calculate Trends ... + if (close[bar_index] > work[bar_index - 1][lo1Idx]) + { + work[bar_index][trend1Idx] = 1; + } + + // + if (close[bar_index] < work[bar_index - 1][hi1Idx]) + { + work[bar_index][trend1Idx] = -1; + } + + // + if (close[bar_index] > work[bar_index - 1][lo2Idx]) + { + work[bar_index][trend2Idx] = 1; + } + + // + if (close[bar_index] < work[bar_index - 1][hi2Idx]) + { + work[bar_index][trend2Idx] = -1; + } + + // + // Calculate Exit Values ... + + // + // Exit 1 ... + + // + // Long ... + if (multiplier1 > 0 && work[bar_index][trend1Idx] == 1) + { + // + if (work[bar_index][hi1Idx] < work[bar_index - 1][hi1Idx]) + { + work[bar_index][hi1Idx] = work[bar_index - 1][hi1Idx]; + } + + // + longExit1Buffer[bar_index] = work[bar_index][hi1Idx]; + + // + if (longExit1Buffer[bar_index - 1] == EMPTY_VALUE) + { + longExit1StartBuffer[bar_index] = longExit1Buffer[bar_index]; + } + } + + // + // Short ... + if (multiplier1 > 0 && work[bar_index][trend1Idx] == -1) + { + // + if (work[bar_index][lo1Idx] > work[bar_index - 1][lo1Idx]) + { + work[bar_index][lo1Idx] = work[bar_index - 1][lo1Idx]; + } + + // + shortExit1Buffer[bar_index] = work[bar_index][lo1Idx]; + + // + if (shortExit1Buffer[bar_index - 1] == EMPTY_VALUE) + { + shortExit1StartBuffer[bar_index] = shortExit1Buffer[bar_index]; + } + } + + // + // Exit 2 ... + + // + // Long ... + if (multiplier2 > 0 && work[bar_index][trend2Idx] == 1) + { + if (work[bar_index][hi2Idx] < work[bar_index - 1][hi2Idx]) + { + work[bar_index][hi2Idx] = work[bar_index - 1][hi2Idx]; + } + + // + longExit2Buffer[bar_index] = work[bar_index][hi2Idx]; + + // + if (longExit2Buffer[bar_index - 1] == EMPTY_VALUE) + { + longExit2StartBuffer[bar_index] = longExit2Buffer[bar_index]; + } + } + + // + // Short ... + if (multiplier2 > 0 && work[bar_index][trend2Idx] == -1) + { + // + if (work[bar_index][lo2Idx] > work[bar_index - 1][lo2Idx]) + { + work[bar_index][lo2Idx] = work[bar_index - 1][lo2Idx]; + } + + // + shortExit2Buffer[bar_index] = work[bar_index][lo2Idx]; + + // + if (shortExit2Buffer[bar_index - 1] == EMPTY_VALUE) + { + shortExit2StartBuffer[bar_index] = shortExit2Buffer[bar_index]; + } + } + } +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xcpv.ex5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xcpv.ex5 new file mode 100644 index 0000000..af56594 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xcpv.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xct.ex5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xct.ex5 new file mode 100644 index 0000000..17fb60b Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xct.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xct.mq5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xct.mq5 new file mode 100644 index 0000000..72f2a26 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xct.mq5 @@ -0,0 +1,264 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: X121_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 X121_XCT Indicator" +#property strict + +// +// START Constants ... +// + +// +#define ShortName "X121_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 + + // + // Delete Object ... + ObjectDelete(0, ShortName); + + // + Comment(""); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + ArraySetAsSeries(time, true); + + // + if (!showCandleTime) + { + return rates_total; + } + + // + XCandleRemains remainTime; + GetCandleRemainsTime( + remainTime, + _Symbol, + _Period, + 0); + + // + string msg = ToString( + remainTime, + "", + "", + "", + "", + "", + ":", + true); + + // + long mSpread = SymbolInfoInteger(Symbol(), SYMBOL_SPREAD); + + // + string _sp = ""; + if (mSpread < 10) + _sp = ".."; + else if (mSpread < 100) + _sp = "."; + + // + string objText = "Spread: " + IntegerToString(mSpread) + _sp + " Next Bar in: " + msg; + + // + ObjectSetInteger(0, ShortName, OBJPROP_COLOR, clr); + ObjectSetString(0, ShortName, OBJPROP_TEXT, objText); + ObjectSetInteger(0, ShortName, OBJPROP_FONTSIZE, 10); + ObjectSetString(0, 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/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xdema.ex5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xdema.ex5 new file mode 100644 index 0000000..92c507c Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xdema.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xdema.mq5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xdema.mq5 new file mode 100644 index 0000000..186778e --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xdema.mq5 @@ -0,0 +1,348 @@ +////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: X121_XDEMA +// Description: Super Trend Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121_XAMA Indicator" +#property strict + +// +// START Constants ... +// + +#define ShortName "X121_XDEMA" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +// Market ... +input group "Market"; +input int length = 200; // Length +input int shift = 0; // Shift + +// +// Presentation ... +input group "Presentation"; +input bool showDema = true; // Show Dema +input bool showEMA = false; // Show EMA +input bool showEMAOfEMA = false; // Show EMA of EMA + +// +// END Inputs ... +// + +// +// Includes Common Library ... +#include +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 6 +#property indicator_plots 6 + +// +#define demaBufferIndex 0 +double demaBuffer[]; + +// +#define demaColorBufferIndex 1 +double demaColorBuffer[]; + +// +#property indicator_label1 "X121_XDEMA DEMA" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrDodgerBlue, CLR_NONE +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +#define emaBufferIndex 2 +double emaBuffer[]; + +// +#define emaColorBufferIndex 3 +double emaColorBuffer[]; + +// +#property indicator_label2 "X121_XDEMA EMA" +#property indicator_type2 DRAW_COLOR_LINE +#property indicator_color2 clrBlue, CLR_NONE +#property indicator_style2 STYLE_DOT +#property indicator_width2 1 + +// +#define emaOfEMABufferIndex 4 +double emaOfEMABuffer[]; + +// +#define emaOfEMAColorBufferIndex 5 +double emaOfEMAColorBuffer[]; + +// +#property indicator_label3 "X121_XDEMA EMA of EMA" +#property indicator_type3 DRAW_COLOR_LINE +#property indicator_color3 clrOrange, CLR_NONE +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed +} + +// +// Do Calculations ... +int OnCalculate(const int rates_total, + const int prev_calculated, + const int begin, + const double &price[]) +{ + // + ArraySetAsSeries(price, true); + + // + // check for data ... + if (rates_total < 2 * length - 2) + { + return 0; + } + + // + int limit; + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // calculate EMA ... + ExponentialMAOnBuffer(rates_total, prev_calculated, 0, length, price, emaBuffer); + + // + // calculate EMA on EMA array ... + ExponentialMAOnBuffer(rates_total, prev_calculated, length - 1, length, emaBuffer, emaOfEMABuffer); + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + // calculate DEMA ... + demaBuffer[i] = 2 * emaBuffer[i] - emaOfEMABuffer[i]; + + // + double showColorIDX = 0; + double hideColorIDX = 1; + + // + demaColorBuffer[i] = hideColorIDX; + emaColorBuffer[i] = hideColorIDX; + emaOfEMAColorBuffer[i] = hideColorIDX; + + // + if (showDema) + { + demaColorBuffer[i] = showColorIDX; + } + + // + if (showEMA) + { + emaColorBuffer[i] = showColorIDX; + } + + // + if (showEMAOfEMA) + { + emaOfEMAColorBuffer[i] = showColorIDX; + } + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + (length > 2 && + shift >= 0) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Peaks and Vales ... + result = length; + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // DEMA ... + + // + // Buffer ... + ArraySetAsSeries(demaBuffer, true); + SetIndexBuffer(demaBufferIndex, demaBuffer, INDICATOR_DATA); + PlotIndexSetInteger(demaBufferIndex, PLOT_SHOW_DATA, showDema); + + // + // Color Buffer ... + ArraySetAsSeries(demaColorBuffer, true); + SetIndexBuffer(demaColorBufferIndex, demaColorBuffer, INDICATOR_COLOR_INDEX); + + // + // EMA ... + + // + // Buffer ... + ArraySetAsSeries(emaBuffer, true); + SetIndexBuffer(emaBufferIndex, emaBuffer, INDICATOR_DATA); + PlotIndexSetInteger(emaBufferIndex, PLOT_SHOW_DATA, showEMA); + + // + // Color Buffer ... + ArraySetAsSeries(emaColorBuffer, true); + SetIndexBuffer(emaColorBufferIndex, emaColorBuffer, INDICATOR_COLOR_INDEX); + + // + // EMA of EMA ... + + // + // Buffer ... + ArraySetAsSeries(emaOfEMABuffer, true); + SetIndexBuffer(emaOfEMABufferIndex, emaOfEMABuffer, INDICATOR_DATA); + PlotIndexSetInteger(emaOfEMABufferIndex, PLOT_SHOW_DATA, showEMAOfEMA); + + // + // Color Buffer ... + ArraySetAsSeries(emaOfEMAColorBuffer, true); + SetIndexBuffer(emaOfEMAColorBufferIndex, emaOfEMAColorBuffer, INDICATOR_COLOR_INDEX); +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xfbb.ex5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xfbb.ex5 new file mode 100644 index 0000000..fbfcc92 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xfbb.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xfbb.mq5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xfbb.mq5 new file mode 100644 index 0000000..90d3274 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xfbb.mq5 @@ -0,0 +1,768 @@ +////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// -------------------------------------- +// Name: X121_XFBB +// Description: Fibonacci Band ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121_XFBB Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_XFBB" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +// Market ... +input group "Market"; +input int length = 200; // Length +input double multiplier = 3.0; // Multiplier +input ENUM_APPLIED_PRICE appliedTo = PRICE_TYPICAL; // Applied To + +// +// Presentation ... +input group "Presentation"; +input bool showBase = true; // Show Base +input bool showBand = true; // Show Band +input bool showGoldenArea = true; // Show Golden Area +input bool showOthers = false; // Show Other Levels + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 28 +#property indicator_plots 26 + +// +// PLOTTED Buffers ... + +// +#define baseBufferIndex 0 +#define basePlotBufferIndex 0 +double baseBuffer[]; + +// +#property indicator_label1 "X121_XFBB Base" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 CLR_NONE, clrDarkGray, clrDeepPink, clrMediumSeaGreen +#property indicator_style1 STYLE_DOT + +#define baseColorBufferIndex 1 +double baseColorBuffer[]; + +// +#define upL1BufferIndex 2 +#define upL1PlotBufferIndex 1 +double upL1Buffer[]; + +// +#property indicator_label2 "X121_XFBB UF 1" +#property indicator_type2 DRAW_COLOR_LINE +#property indicator_color2 CLR_NONE, clrDarkGray +#property indicator_style2 STYLE_DOT + +#define upL1ColorBufferIndex 3 +double upL1ColorBuffer[]; + +// +#define upL2BufferIndex 4 +#define upL2PlotBufferIndex 2 +double upL2Buffer[]; + +#define upL2ColorBufferIndex 5 +double upL2ColorBuffer[]; + +// +#property indicator_label3 "X121_XFBB UF 2" +#property indicator_type3 DRAW_COLOR_LINE +#property indicator_color3 CLR_NONE, clrDarkGray +#property indicator_style3 STYLE_DOT + +// +#define upL3BufferIndex 6 +#define upL3PlotBufferIndex 3 +double upL3Buffer[]; + +#define upL3ColorBufferIndex 7 +double upL3ColorBuffer[]; + +// +#property indicator_label4 "X121_XFBB UF 3" +#property indicator_type4 DRAW_COLOR_LINE +#property indicator_color4 CLR_NONE, clrGold +#property indicator_style4 STYLE_DOT + +// +#define upL4BufferIndex 8 +#define upL4PlotBufferIndex 4 +double upL4Buffer[]; + +#define upL4ColorBufferIndex 9 +double upL4ColorBuffer[]; + +// +#property indicator_label5 "X121_XFBB UF 4" +#property indicator_type5 DRAW_COLOR_LINE +#property indicator_color5 CLR_NONE, clrGold +#property indicator_style5 STYLE_DOT + +// +#define upL5BufferIndex 10 +#define upL5PlotBufferIndex 5 +double upL5Buffer[]; + +#define upL5ColorBufferIndex 11 +double upL5ColorBuffer[]; + +// +#property indicator_label6 "X121_XFBB UF 5" +#property indicator_type6 DRAW_COLOR_LINE +#property indicator_color6 CLR_NONE, clrDarkGray +#property indicator_style6 STYLE_DOT + +// +#define upL6BufferIndex 12 +#define upL6PlotBufferIndex 6 +double upL6Buffer[]; + +#define upL6ColorBufferIndex 13 +double upL6ColorBuffer[]; + +// +#property indicator_label7 "X121_XFBB UF 6" +#property indicator_type7 DRAW_COLOR_LINE +#property indicator_color7 CLR_NONE, clrRed +#property indicator_style7 STYLE_DOT + +// +// DOWN ... + +// +#define downL1BufferIndex 14 +#define downL1PlotBufferIndex 7 +double downL1Buffer[]; + +#define downL1ColorBufferIndex 15 +double downL1ColorBuffer[]; + +// +#property indicator_label8 "X121_XFBB UD 1" +#property indicator_type8 DRAW_COLOR_LINE +#property indicator_color8 CLR_NONE, clrDarkGray +#property indicator_style8 STYLE_DOT + +// +#define downL2BufferIndex 16 +#define downL2PlotBufferIndex 8 +double downL2Buffer[]; + +#define downL2ColorBufferIndex 17 +double downL2ColorBuffer[]; + +// +#property indicator_label9 "X121_XFBB UD 2" +#property indicator_type9 DRAW_COLOR_LINE +#property indicator_color9 CLR_NONE, clrDarkGray +#property indicator_style9 STYLE_DOT + +// +#define downL3BufferIndex 18 +#define downL3PlotBufferIndex 9 +double downL3Buffer[]; + +#define downL3ColorBufferIndex 19 +double downL3ColorBuffer[]; + +// +#property indicator_label10 "X121_XFBB UD 3" +#property indicator_type10 DRAW_COLOR_LINE +#property indicator_color10 CLR_NONE, clrGold +#property indicator_style10 STYLE_DOT + +// +#define downL4BufferIndex 20 +#define downL4PlotBufferIndex 10 +double downL4Buffer[]; + +#define downL4ColorBufferIndex 21 +double downL4ColorBuffer[]; + +// +#property indicator_label11 "X121_XFBB UD 4" +#property indicator_type11 DRAW_COLOR_LINE +#property indicator_color11 CLR_NONE, clrGold +#property indicator_style11 STYLE_DOT + +// +#define downL5BufferIndex 22 +#define downL5PlotBufferIndex 11 +double downL5Buffer[]; + +#define downL5ColorBufferIndex 23 +double downL5ColorBuffer[]; + +// +#property indicator_label12 "X121_XFBB UD 5" +#property indicator_type12 DRAW_COLOR_LINE +#property indicator_color12 CLR_NONE, clrDarkGray +#property indicator_style12 STYLE_DOT + +// +#define downL6BufferIndex 24 +#define downL6PlotBufferIndex 12 +double downL6Buffer[]; + +#define downL6ColorBufferIndex 25 +double downL6ColorBuffer[]; + +// +#property indicator_label13 "X121_XFBB UD 6" +#property indicator_type13 DRAW_COLOR_LINE +#property indicator_color13 CLR_NONE, clrRed +#property indicator_style13 STYLE_DOT + +// +// DATA BUffers ... + +// +#define stdDevBufferIndex 26 +double stdDevBuffer[]; + +// +#define vwmaBufferIndex 27 +double vwmaBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int mSTDevHandler = INVALID_HANDLE; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Initialize Handlers ... + mSTDevHandler = iStdDev( + _Symbol, + _Period, + length, + 0, + MODE_SMA, + appliedTo); + if (mSTDevHandler == INVALID_HANDLE) + { + return INIT_FAILED; + } + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + + // + IndicatorRelease(mSTDevHandler); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + int i = (prev_calculated > 0 ? prev_calculated - 1 : 0); + for (i; i < rates_total && !IsStopped(); i++) + { + // + double price = GetAppliedPrice( + appliedTo, + open, + high, + low, + close, + i); + + // + double vwma = iVWMA(price, volume[i], length, i, rates_total); + vwmaBuffer[i] = vwma; + baseBuffer[i] = vwma; + + // + double baseColorIDX = (i > 0) + ? (vwmaBuffer[i] > vwmaBuffer[i - 1]) + ? 3 + : (vwmaBuffer[i] < vwmaBuffer[i - 1]) + ? 2 + : baseColorBuffer[i - 1] + : 1; + + // + if (showBase) + { + baseColorBuffer[i] = baseColorIDX; + } + else + { + baseColorBuffer[i] = 0; + } + } + + // + // this counts Available Bars ... + int limit; + + // + // Check Calculated Bars ... + // + int stdDevCalculatedBars = BarsCalculated(mSTDevHandler); + if (stdDevCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + // + int copiedSTDDevs = CopyBuffer(mSTDevHandler, 0, 0, limit, stdDevBuffer); + if (copiedSTDDevs <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i > 0 && !IsStopped(); i--) + { + CalculateBuffers(i); + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + (length >= 2 && + multiplier > 0) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(result, length); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // PLOTTED ... + + // + // BASE ... + // ArraySetAsSeries(baseBuffer, true); + // ArraySetAsSeries(baseColorBuffer, true); + SetIndexBuffer(baseBufferIndex, baseBuffer, INDICATOR_DATA); + PlotIndexSetInteger(basePlotBufferIndex, PLOT_SHOW_DATA, showBase); + SetIndexBuffer(baseColorBufferIndex, baseColorBuffer, INDICATOR_COLOR_INDEX); + + // + // UP 1 ... + // ArraySetAsSeries(upL1Buffer, true); + // ArraySetAsSeries(upL1ColorBuffer, true); + SetIndexBuffer(upL1BufferIndex, upL1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(upL1PlotBufferIndex, PLOT_SHOW_DATA, showOthers); + SetIndexBuffer(upL1ColorBufferIndex, upL1ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // UP 2 ... + // ArraySetAsSeries(upL2Buffer, true); + // ArraySetAsSeries(upL2ColorBuffer, true); + SetIndexBuffer(upL2BufferIndex, upL2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(upL2PlotBufferIndex, PLOT_SHOW_DATA, showOthers); + SetIndexBuffer(upL2ColorBufferIndex, upL2ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // UP 3 ... + // ArraySetAsSeries(upL3Buffer, true); + // ArraySetAsSeries(upL3ColorBuffer, true); + SetIndexBuffer(upL3BufferIndex, upL3Buffer, INDICATOR_DATA); + PlotIndexSetInteger(upL3PlotBufferIndex, PLOT_SHOW_DATA, showGoldenArea); + SetIndexBuffer(upL3ColorBufferIndex, upL3ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // UP 4 ... + // ArraySetAsSeries(upL4Buffer, true); + // ArraySetAsSeries(upL4ColorBuffer, true); + SetIndexBuffer(upL4BufferIndex, upL4Buffer, INDICATOR_DATA); + PlotIndexSetInteger(upL4PlotBufferIndex, PLOT_SHOW_DATA, showGoldenArea); + SetIndexBuffer(upL4ColorBufferIndex, upL4ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // UP 5 ... + // ArraySetAsSeries(upL5Buffer, true); + // ArraySetAsSeries(upL5ColorBuffer, true); + SetIndexBuffer(upL5BufferIndex, upL5Buffer, INDICATOR_DATA); + PlotIndexSetInteger(upL5PlotBufferIndex, PLOT_SHOW_DATA, showOthers); + SetIndexBuffer(upL5ColorBufferIndex, upL5ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // UP 6 ... + // ArraySetAsSeries(upL6Buffer, true); + // ArraySetAsSeries(upL6ColorBuffer, true); + SetIndexBuffer(upL6BufferIndex, upL6Buffer, INDICATOR_DATA); + PlotIndexSetInteger(upL6PlotBufferIndex, PLOT_SHOW_DATA, showBand); + SetIndexBuffer(upL6ColorBufferIndex, upL6ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // DOWN 1 ... + // ArraySetAsSeries(downL1Buffer, true); + // ArraySetAsSeries(downL1ColorBuffer, true); + SetIndexBuffer(downL1BufferIndex, downL1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(downL1PlotBufferIndex, PLOT_SHOW_DATA, showOthers); + SetIndexBuffer(downL1ColorBufferIndex, downL1ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // DOWN 2 ... + // ArraySetAsSeries(downL2Buffer, true); + // ArraySetAsSeries(downL2ColorBuffer, true); + SetIndexBuffer(downL2BufferIndex, downL2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(downL2PlotBufferIndex, PLOT_SHOW_DATA, showOthers); + SetIndexBuffer(downL2ColorBufferIndex, downL2ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // DOWN 3 ... + // ArraySetAsSeries(downL3Buffer, true); + // ArraySetAsSeries(downL3ColorBuffer, true); + SetIndexBuffer(downL3BufferIndex, downL3Buffer, INDICATOR_DATA); + PlotIndexSetInteger(downL3PlotBufferIndex, PLOT_SHOW_DATA, showGoldenArea); + SetIndexBuffer(downL3ColorBufferIndex, downL3ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // DOWN 4 ... + // ArraySetAsSeries(downL4Buffer, true); + // ArraySetAsSeries(downL4ColorBuffer, true); + SetIndexBuffer(downL4BufferIndex, downL4Buffer, INDICATOR_DATA); + PlotIndexSetInteger(downL4PlotBufferIndex, PLOT_SHOW_DATA, showGoldenArea); + SetIndexBuffer(downL4ColorBufferIndex, downL4ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // DOWN 5 ... + // ArraySetAsSeries(downL5Buffer, true); + // ArraySetAsSeries(downL5ColorBuffer, true); + SetIndexBuffer(downL5BufferIndex, downL5Buffer, INDICATOR_DATA); + PlotIndexSetInteger(downL5PlotBufferIndex, PLOT_SHOW_DATA, showOthers); + SetIndexBuffer(downL5ColorBufferIndex, downL5ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // DOWN 6 ... + // ArraySetAsSeries(downL6Buffer, true); + // ArraySetAsSeries(downL6ColorBuffer, true); + SetIndexBuffer(downL6BufferIndex, downL6Buffer, INDICATOR_DATA); + PlotIndexSetInteger(downL6PlotBufferIndex, PLOT_SHOW_DATA, showBand); + SetIndexBuffer(downL6ColorBufferIndex, downL6ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // DATA ... + + // + // ArraySetAsSeries(stdDevBuffer, true); + SetIndexBuffer(stdDevBufferIndex, stdDevBuffer, INDICATOR_CALCULATIONS); + + // + // ArraySetAsSeries(vwmaBuffer, true); + SetIndexBuffer(vwmaBufferIndex, vwmaBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + double stdDev = stdDevBuffer[bar_index]; + double dev = stdDev * multiplier; + + // + double base = baseBuffer[bar_index]; + + // + double fib1 = 0.236; + double fib2 = 0.382; + double fib3 = 0.5; + double fib4 = 0.618; + double fib5 = 0.764; + double fib6 = 1; + + // + double u1 = base + (fib1 * dev); + double u2 = base + (fib2 * dev); + double u3 = base + (fib3 * dev); + double u4 = base + (fib4 * dev); + double u5 = base + (fib5 * dev); + double u6 = base + (fib6 * dev); + + // + upL1Buffer[bar_index] = u1; + upL2Buffer[bar_index] = u2; + upL3Buffer[bar_index] = u3; + upL4Buffer[bar_index] = u4; + upL5Buffer[bar_index] = u5; + upL6Buffer[bar_index] = u6; + + // + double d1 = base - (fib1 * dev); + double d2 = base - (fib2 * dev); + double d3 = base - (fib3 * dev); + double d4 = base - (fib4 * dev); + double d5 = base - (fib5 * dev); + double d6 = base - (fib6 * dev); + + // + downL1Buffer[bar_index] = d1; + downL2Buffer[bar_index] = d2; + downL3Buffer[bar_index] = d3; + downL4Buffer[bar_index] = d4; + downL5Buffer[bar_index] = d5; + downL6Buffer[bar_index] = d6; + + // + // Setup Color IDX ... + + // + double hideColorIDX = 0; + double showColorIDX = 1; + + // + // SET Default Colors ... + + // + upL1ColorBuffer[bar_index] = hideColorIDX; + upL2ColorBuffer[bar_index] = hideColorIDX; + upL3ColorBuffer[bar_index] = hideColorIDX; + upL4ColorBuffer[bar_index] = hideColorIDX; + upL5ColorBuffer[bar_index] = hideColorIDX; + upL6ColorBuffer[bar_index] = hideColorIDX; + + // + downL1ColorBuffer[bar_index] = hideColorIDX; + downL2ColorBuffer[bar_index] = hideColorIDX; + downL3ColorBuffer[bar_index] = hideColorIDX; + downL4ColorBuffer[bar_index] = hideColorIDX; + downL5ColorBuffer[bar_index] = hideColorIDX; + downL6ColorBuffer[bar_index] = hideColorIDX; + + // + if (!showBase) + { + baseColorBuffer[bar_index] = hideColorIDX; + } + + // + if (showBand) + { + // + upL6ColorBuffer[bar_index] = showColorIDX; + downL6ColorBuffer[bar_index] = showColorIDX; + } + + // + if (showGoldenArea) + { + // + upL3ColorBuffer[bar_index] = showColorIDX; + upL4ColorBuffer[bar_index] = showColorIDX; + + // + downL3ColorBuffer[bar_index] = showColorIDX; + downL4ColorBuffer[bar_index] = showColorIDX; + } + + // + if (showOthers) + { + // + upL1ColorBuffer[bar_index] = showColorIDX; + upL2ColorBuffer[bar_index] = showColorIDX; + upL5ColorBuffer[bar_index] = showColorIDX; + + // + downL1ColorBuffer[bar_index] = showColorIDX; + downL2ColorBuffer[bar_index] = showColorIDX; + downL5ColorBuffer[bar_index] = showColorIDX; + } +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xhk.ex5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xhk.ex5 new file mode 100644 index 0000000..ec446ea Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xhk.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xhk.mq5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xhk.mq5 new file mode 100644 index 0000000..4d80fb3 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xhk.mq5 @@ -0,0 +1,486 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// -------------------------------------------- +// Name: X121_HK +// Description: Hiken Ashi ... +// Market Analysor ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121_XHK Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_XHK" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Presentation"; +input bool drawCandles = true; // Draw Hiken Ashi Candle +input bool drawCandleLines = false; // Show HikenAshi Lines + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 13 +#property indicator_plots 5 + +// +// PLOTTED Buffers ... + +// +// Open ... +#define openBufferIndex 0 +double openBuffer[]; + +// +// High ... +#define highBufferIndex 1 +double highBuffer[]; + +// +// Low ... +#define lowBufferIndex 2 +double lowBuffer[]; + +// +// Close ... +#define closeBufferIndex 3 +double closeBuffer[]; + +// +// Candle Color ... +#define candleColorBufferIndex 4 +double candleColorBuffer[]; + +// +#define candlesBufferIndex 0 + +// +#property indicator_label1 "X121_XHK Open;X121_XHK High;X121_XHK Low;X121_XHK Close" +#property indicator_type1 DRAW_COLOR_CANDLES +#property indicator_color1 clrAqua, clrMagenta, CLR_NONE + +// +#define openHKBufferIndex 5 +#define openHKColorBufferIndex 6 +double openHKBuffer[]; +double openHKColorBuffer[]; + +// +#define openHKBufferPlotIndex 1 +#property indicator_label2 "X121_XHK O" +#property indicator_type2 DRAW_COLOR_LINE +#property indicator_color2 clrAqua, clrMagenta, clrLightGray +#property indicator_style2 STYLE_DOT +#property indicator_width2 1 + +// +#define highHKBufferIndex 7 +#define highHKColorBufferIndex 8 +double highHKBuffer[]; +double highHKColorBuffer[]; + +// +#define highHKBufferPlotIndex 2 +#property indicator_label3 "X121_XHK H" +#property indicator_type3 DRAW_COLOR_LINE +#property indicator_color3 clrAqua, clrMagenta, clrLightGray +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +#define lowHKBufferIndex 9 +#define lowHKColorBufferIndex 10 +double lowHKBuffer[]; +double lowHKColorBuffer[]; + +// +#define lowHKBufferPlotIndex 3 +#property indicator_label4 "X121_XHK L" +#property indicator_type4 DRAW_COLOR_LINE +#property indicator_color4 clrAqua, clrMagenta, clrLightGray +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +#define closeHKBufferIndex 11 +#define closeHKColorBufferIndex 12 +double closeHKBuffer[]; +double closeHKColorBuffer[]; + +// +#define closeHKBufferPlotIndex 4 +#property indicator_label5 "X121_XHK C" +#property indicator_type5 DRAW_COLOR_LINE +#property indicator_color5 clrAqua, clrMagenta, clrLightGray +#property indicator_style5 STYLE_DOT +#property indicator_width5 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (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); + } + + // + 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() +{ + // + // Candles Color ... + ArraySetAsSeries(candleColorBuffer, true); + SetIndexBuffer(candleColorBufferIndex, candleColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on Candles Buffer ... + PlotIndexSetDouble(candlesBufferIndex, PLOT_EMPTY_VALUE, 0.0); + + // + PlotIndexSetInteger(candlesBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(candleColorBufferIndex, PLOT_SHOW_DATA, false); + + // + // Open ... + ArraySetAsSeries(openBuffer, true); + PlotIndexSetInteger(openBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(openBufferIndex, openBuffer, INDICATOR_DATA); + + // + // High ... + ArraySetAsSeries(highBuffer, true); + SetIndexBuffer(highBufferIndex, highBuffer, INDICATOR_DATA); + PlotIndexSetInteger(highBufferIndex, PLOT_SHOW_DATA, false); + + // + // Close ... + ArraySetAsSeries(closeBuffer, true); + SetIndexBuffer(closeBufferIndex, closeBuffer, INDICATOR_DATA); + PlotIndexSetInteger(closeBufferIndex, PLOT_SHOW_DATA, false); + + // + // Low ... + ArraySetAsSeries(lowBuffer, true); + SetIndexBuffer(lowBufferIndex, lowBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lowBufferIndex, PLOT_SHOW_DATA, false); + + // + // Open HK ... + ENUM_DRAW_TYPE openDrawType = drawCandleLines ? DRAW_COLOR_LINE : DRAW_NONE; + ArraySetAsSeries(openHKBuffer, true); + SetIndexBuffer(openHKBufferIndex, openHKBuffer, INDICATOR_DATA); + PlotIndexSetInteger(openHKBufferPlotIndex, PLOT_SHOW_DATA, drawCandleLines); + PlotIndexSetInteger(openHKBufferPlotIndex, PLOT_DRAW_TYPE, openDrawType); + + // + ArraySetAsSeries(openHKColorBuffer, true); + SetIndexBuffer(openHKColorBufferIndex, openHKColorBuffer, INDICATOR_COLOR_INDEX); + + // + // High HK ... + ENUM_DRAW_TYPE highDrawType = drawCandleLines ? DRAW_COLOR_LINE : DRAW_NONE; + ArraySetAsSeries(highHKBuffer, true); + SetIndexBuffer(highHKBufferIndex, highHKBuffer, INDICATOR_DATA); + PlotIndexSetInteger(highHKBufferPlotIndex, PLOT_SHOW_DATA, drawCandleLines); + PlotIndexSetInteger(highHKBufferPlotIndex, PLOT_DRAW_TYPE, highDrawType); + + // + ArraySetAsSeries(highHKColorBuffer, true); + SetIndexBuffer(highHKColorBufferIndex, highHKColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Low HK ... + ENUM_DRAW_TYPE lowDrawType = drawCandleLines ? DRAW_COLOR_LINE : DRAW_NONE; + ArraySetAsSeries(lowHKBuffer, true); + SetIndexBuffer(lowHKBufferIndex, lowHKBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lowHKBufferPlotIndex, PLOT_SHOW_DATA, drawCandleLines); + PlotIndexSetInteger(lowHKBufferPlotIndex, PLOT_DRAW_TYPE, lowDrawType); + + // + ArraySetAsSeries(lowHKColorBuffer, true); + SetIndexBuffer(lowHKColorBufferIndex, lowHKColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Close HK ... + ENUM_DRAW_TYPE closeDrawType = drawCandleLines ? DRAW_COLOR_LINE : DRAW_NONE; + ArraySetAsSeries(closeHKBuffer, true); + SetIndexBuffer(closeHKBufferIndex, closeHKBuffer, INDICATOR_DATA); + PlotIndexSetInteger(closeHKBufferPlotIndex, PLOT_SHOW_DATA, drawCandleLines); + PlotIndexSetInteger(closeHKBufferPlotIndex, PLOT_DRAW_TYPE, closeDrawType); + + // + ArraySetAsSeries(closeHKColorBuffer, true); + SetIndexBuffer(closeHKColorBufferIndex, closeHKColorBuffer, INDICATOR_COLOR_INDEX); +} + +// +// 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 + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[]) +{ + // + double mPrevHKOpenValue; + double mPrevHKCloseValue; + + // + if (ArraySize(open) <= bar_index + 1) + { + // + mPrevHKOpenValue = 0; + mPrevHKCloseValue = 0; + } + else + { + // + mPrevHKOpenValue = openBuffer[bar_index + 1]; + mPrevHKCloseValue = closeBuffer[bar_index + 1]; + } + + // + double mHKOpenValue = (mPrevHKOpenValue + mPrevHKCloseValue) / 2; + double mHKCloseValue = (open[bar_index] + high[bar_index] + close[bar_index] + low[bar_index]) / 4; + double mHKHighValue = MathMax(high[bar_index], MathMax(mHKOpenValue, mHKCloseValue)); + double mHKLowValue = MathMin(low[bar_index], MathMin(mHKOpenValue, mHKCloseValue)); + + // + openBuffer[bar_index] = mHKOpenValue; + highBuffer[bar_index] = mHKHighValue; + lowBuffer[bar_index] = mHKLowValue; + closeBuffer[bar_index] = mHKCloseValue; + + // + double candleColorValue = + mHKOpenValue < mHKCloseValue ? 0 : 1; + + // + candleColorBuffer[bar_index] = drawCandles ? candleColorValue : 2; + + // + openHKBuffer[bar_index] = mHKOpenValue; + openHKColorBuffer[bar_index] = candleColorValue; + + // + highHKBuffer[bar_index] = mHKHighValue; + highHKColorBuffer[bar_index] = candleColorValue; + + // + lowHKBuffer[bar_index] = mHKLowValue; + lowHKColorBuffer[bar_index] = candleColorValue; + + // + closeHKBuffer[bar_index] = mHKCloseValue; + closeHKColorBuffer[bar_index] = candleColorValue; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xhull.ex5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xhull.ex5 new file mode 100644 index 0000000..26519fc Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xhull.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xhull.mq5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xhull.mq5 new file mode 100644 index 0000000..dbfc3e1 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xhull.mq5 @@ -0,0 +1,602 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: X121_XHULL +// Description: Hull Trend Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121_XHULL Indicator" +#property strict + +// +// START Constants ... +// + +// +#define ShortName "X121_XHULL" + +// +struct XHullData +{ + // + double value; + double value3; + + // + double wsum1; + double wsum2; + double wsum3; + + // + double lsum1; + double lsum2; + double lsum3; +}; + +// +// END Constants ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START XSCHULL Class Definition ... +// + +// +// a Class For Hull Calculations ... +class XSCHull +{ + // +public: + // + // Constructor ... + XSCHull() : mFullPeriod(1), mHalfPeriod(1), mSqrtPeriod(1), mArraySize(-1) + { + // + // These are a way above to assign Private variables at Construct time ... + } + + // + // Deconstructor ... + ~XSCHull() + { + ArrayFree(mData); + } + + // + // Initial Hull ... + bool Init( + int mPeriod, + double mDivisor) + { + // + bool result = false; + + // + mFullPeriod = (int)(mPeriod > 1 ? mPeriod : 1); + mHalfPeriod = (int)(mFullPeriod > 1 ? mFullPeriod / (mDivisor > 1 ? mDivisor : 1) : 1); + mSqrtPeriod = (int)MathSqrt(mFullPeriod); + + // + mArraySize = -1; + mWeight1 = mWeight2 = mWeight3 = 1; + + // + result = true; + + // + return result; + } + + // + // CalCulate Specific Value ... + double Calculate( + double value, + int i, + int bars) + { + // + double result = 0; + + // + if (mArraySize < bars) + { + // + mArraySize = ArrayResize(mData, bars + 500); + if (mArraySize < bars) + return result; + } + + // + mData[i].value = value; + if (i > mFullPeriod) + { + // + mData[i].wsum1 = mData[i - 1].wsum1 + value * mHalfPeriod - mData[i - 1].lsum1; + mData[i].lsum1 = mData[i - 1].lsum1 + value - mData[i - mHalfPeriod].value; + mData[i].wsum2 = mData[i - 1].wsum2 + value * mFullPeriod - mData[i - 1].lsum2; + mData[i].lsum2 = mData[i - 1].lsum2 + value - mData[i - mFullPeriod].value; + } + else + { + // + mData[i].wsum1 = mData[i].wsum2 = + mData[i].lsum1 = mData[i].lsum2 = mWeight1 = mWeight2 = 0; + for (int k = 0, w1 = mHalfPeriod, w2 = mFullPeriod; w2 > 0 && i >= k; k++, w1--, w2--) + { + // + if (w1 > 0) + { + // + mData[i].wsum1 += mData[i - k].value * w1; + mData[i].lsum1 += mData[i - k].value; + mWeight1 += w1; + } + + // + mData[i].wsum2 += mData[i - k].value * w2; + mData[i].lsum2 += mData[i - k].value; + mWeight2 += w2; + } + } + + // + mData[i].value3 = 2.0 * mData[i].wsum1 / mWeight1 - mData[i].wsum2 / mWeight2; + + // + if (i > mSqrtPeriod) + { + // + mData[i].wsum3 = mData[i - 1].wsum3 + mData[i].value3 * mSqrtPeriod - mData[i - 1].lsum3; + mData[i].lsum3 = mData[i - 1].lsum3 + mData[i].value3 - mData[i - mSqrtPeriod].value3; + } + else + { + // + mData[i].wsum3 = + mData[i].lsum3 = mWeight3 = 0; + + // + for (int k = 0, w3 = mSqrtPeriod; w3 > 0 && i >= k; k++, w3--) + { + // + mData[i].wsum3 += mData[i - k].value3 * w3; + mData[i].lsum3 += mData[i - k].value3; + mWeight3 += w3; + } + } + + // + result = mData[i].wsum3 / mWeight3; + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + int mFullPeriod; + int mHalfPeriod; + int mSqrtPeriod; + int mArraySize; + double mWeight1; + double mWeight2; + double mWeight3; + + // + XHullData mData[]; +}; + +// +// END XSCHULL Class Definition ... +// + +// +// START Inputs ... +// + +// +input group "Market"; +input int length = 72; // Length +input double divisor = 2.0; // Divisor (Speed) + +// +input group "Calculation"; +input ENUM_APPLIED_PRICE upAppliedTo = PRICE_HIGH; // Up Zone Applied to +input ENUM_APPLIED_PRICE downAppliedTo = PRICE_LOW; // Down Zone Applied to + +// +input group "Presentation"; +input bool showUpZone = true; // Show Up Zone +input bool showDownZone = true; // Show Down Zone + +// +// END Inputs ... +// + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 4 +#property indicator_plots 4 + +// +// UP Zone ... + +// +#define upZoneBufferIndex 0 +#define upZoneColorBufferIndex 1 + +// +double upZoneBuffer[]; +double upZoneColorBuffer[]; + +// +#property indicator_label1 "X121_XHULL Up" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrLightGray, clrAqua, clrMagenta +#property indicator_width1 1 + +// +// DOWN Zone ... + +// +#define downZoneBufferIndex 2 +#define downZoneColorBufferIndex 3 + +// +double downZoneBuffer[]; +double downZoneColorBuffer[]; + +// +#property indicator_label2 "X121_XHULL Down" +#property indicator_type2 DRAW_COLOR_LINE +#property indicator_color2 clrLightGray, clrAqua, clrMagenta +#property indicator_width2 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +XSCHull *mUpZHull; +XSCHull *mDownZHull; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Make an Instance of Hull Class ... + + // + mUpZHull = new XSCHull(); + mUpZHull.Init( + length, + divisor); + + // + mDownZHull = new XSCHull(); + mDownZHull.Init( + length, + divisor); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart mPeriod is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + delete mUpZHull; + delete mDownZHull; +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // this counts Available Bars ... + int limit; + + // + limit = prev_calculated - 1; + if (limit < 0) + { + limit = 0; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + // + double upPrice = getPrice( + upAppliedTo, + open, high, low, close, i); + + // + double downPrice = getPrice( + downAppliedTo, + open, high, low, close, i); + + // + CalculateBuffers( + i, + rates_total, + upPrice, + downPrice); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + result = + length >= 9 && + divisor >= 0.5; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = length; + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // UP Zone ... + + // + // Draw Type ... + ENUM_DRAW_TYPE upZoneDrawType = showUpZone ? DRAW_COLOR_LINE : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(upZoneBufferIndex, upZoneBuffer, INDICATOR_DATA); + PlotIndexSetInteger(upZoneBufferIndex, PLOT_SHOW_DATA, showUpZone); + PlotIndexSetInteger(upZoneBufferIndex, PLOT_DRAW_TYPE, upZoneDrawType); + + // + // Color Buffer ... + SetIndexBuffer(upZoneColorBufferIndex, upZoneColorBuffer, INDICATOR_COLOR_INDEX); + + // + // DOWN Zone ... + + // + // Draw Type ... + ENUM_DRAW_TYPE downZoneDrawType = showDownZone ? DRAW_COLOR_LINE : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(downZoneBufferIndex, downZoneBuffer, INDICATOR_DATA); + PlotIndexSetInteger(downZoneBufferIndex - 1, PLOT_SHOW_DATA, showDownZone); + PlotIndexSetInteger(downZoneBufferIndex - 1, PLOT_DRAW_TYPE, downZoneDrawType); + + // + // Color Buffer ... + SetIndexBuffer(downZoneColorBufferIndex, downZoneColorBuffer, INDICATOR_COLOR_INDEX); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, // Selected Bar Index + int ratesTotal, // Total Rates + double upPrice, // Up Price ... + double downPrice // Down Price ... +) +{ + // + double upValue = mUpZHull.Calculate( + upPrice, + bar_index, + ratesTotal); + upZoneBuffer[bar_index] = upValue; + double upColorIDX = (bar_index > 0) + ? (upZoneBuffer[bar_index] > upZoneBuffer[bar_index - 1]) + ? 1 + : (upZoneBuffer[bar_index] < upZoneBuffer[bar_index - 1]) + ? 2 + : upZoneColorBuffer[bar_index - 1] + : 0; + upZoneColorBuffer[bar_index] = upColorIDX; + + // + double downValue = mDownZHull.Calculate( + downPrice, + bar_index, + ratesTotal); + downZoneBuffer[bar_index] = downValue; + double downColorIDX = (bar_index > 0) + ? (downZoneBuffer[bar_index] > downZoneBuffer[bar_index - 1]) + ? 1 + : (downZoneBuffer[bar_index] < downZoneBuffer[bar_index - 1]) + ? 2 + : downZoneColorBuffer[bar_index - 1] + : 0; + downZoneColorBuffer[bar_index] = downColorIDX; +} + +// +// END Functions ... +// + +// +// TEMPLATE Function ... + +template +double getPrice(ENUM_APPLIED_PRICE tprice, T &open[], T &high[], T &low[], T &close[], int i) +{ + switch (tprice) + { + case PRICE_CLOSE: + return (close[i]); + case PRICE_OPEN: + return (open[i]); + case PRICE_HIGH: + return (high[i]); + case PRICE_LOW: + return (low[i]); + case PRICE_MEDIAN: + return ((high[i] + low[i]) / 2.0); + case PRICE_TYPICAL: + return ((high[i] + low[i] + close[i]) / 3.0); + case PRICE_WEIGHTED: + return ((high[i] + low[i] + close[i] + close[i]) / 4.0); + } + return (0); +} diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xich.ex5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xich.ex5 new file mode 100644 index 0000000..1e8f4d3 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xich.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xich.mq5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xich.mq5 new file mode 100644 index 0000000..724aff6 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xich.mq5 @@ -0,0 +1,836 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------------- +// Name: X121_XICH +// Description: Ichimoku Kinko Hyo ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121_XICH Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_XICH" + +// +// Ichimoku Golden Numbers ... +enum ENUM_X_ICHIMOKU_GOLDEN_NUMBERS +{ + X_ICH_BASE = 9, + X_ICH_GOLDEN = 17, + X_ICH_CYCLE = 26, + X_ICH_PERIOD = 35, + X_ICH_STAR = 45, + X_ICH_MED = 52, + X_ICH_LONG = 63, + X_ICH_FULL = 72 +}; + +// +// Ichimoku Lines Calculator Mode ... +enum ENUM_X_ICHIMOKU_CALCULATION_MODE +{ + // + X_XICH_HH_LL_MODE = 1, // Highest High and Lowest Low + X_XICH_HO_LC_MODE = 2, // Highest Open and Lowest Close +}; + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +// ICHIMOKU Kinko Hyo ... + +// +// TENKANSEN ... +input group "Tenkan Sen"; +input int tenkanSenLength = 9; // Length +input ENUM_X_ICHIMOKU_CALCULATION_MODE tenkanSenMode = X_XICH_HH_LL_MODE; // Calculation Mode + +// +// KIJUNSEN ... +input group "Kijun Sen"; +input int kijunSenLength = 26; // Length +input ENUM_X_ICHIMOKU_CALCULATION_MODE kijunSenMode = X_XICH_HH_LL_MODE; // Calculation Mode + +// +// SENKOUSPANB ... +input group "Senkou Span B"; +input int senkouSpanBLength = 52; // Length +input ENUM_X_ICHIMOKU_CALCULATION_MODE senkouSpanBMode = X_XICH_HH_LL_MODE; // Calculation Mode + +// +// CHIKOUSPAN ... +input group "Chikou Span"; +input ENUM_APPLIED_PRICE chikuoSpanAppliedTo = PRICE_CLOSE; // Price Type + +// +input group "Presentation"; +input bool showTenkanSen = true; // Show Tenkan Sen +input bool showKijunSen = true; // Show Kijun Sen +input bool showKijunSenPlus = false; // Show Kijun Sen + +input bool showKijunSenNegative = false; // Show Kijun Sen - +input bool showChikouSpan = true; // Show Chikou Span +input bool showSenkouSpanA = true; // Show Senkou Span A +input bool showSenkouSpanB = true; // Show Senkou Span B +input bool showKumo = true; // Show Kumo +input bool shiftKumo = true; // Shift Kumo to Future + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 15 +#property indicator_plots 8 + +// +// PLOTTED Buffers ... + +// +// ICHIMOKU ... + +// +// TENKANSEN ... + +// +#define tenkanSenBufferIndex 0 +double tenkanSenBuffer[]; + +// +#property indicator_label1 "X121_XICH TK" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrBrown +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +// KIJUNSEN ... + +// +#define kijunSenBufferIndex 1 +double kijunSenBuffer[]; + +// +#property indicator_label2 "X121_XICH KJ" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrDodgerBlue +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +#define kijunSenPlusBufferIndex 2 +double kijunSenPlusBuffer[]; + +// +#property indicator_label3 "X121_XICH KJ+" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrMediumTurquoise +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +#define kijunSenNegativeBufferIndex 3 +double kijunSenNegativeBuffer[]; + +// +#property indicator_label4 "X121_XICH KJ-" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrDarkSeaGreen +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +// CHIKOUSPAN ... + +// +#define chikouSpanBufferIndex 4 +double chikouSpanBuffer[]; + +// +#property indicator_label5 "X121_XICH CS" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrDarkGreen +#property indicator_style5 STYLE_SOLID +#property indicator_width5 1 + +// +#define senkouABufferIndex 5 +double senkouABuffer[]; + +// +#property indicator_label6 "X121_XICH SSA" +#property indicator_type6 DRAW_LINE +#property indicator_color6 clrLightGray +#property indicator_style6 STYLE_DASHDOTDOT +#property indicator_width6 1 + +// +#define senkouBBufferIndex 6 +double senkouBBuffer[]; + +// +#property indicator_label7 "X121_XICH SSB" +#property indicator_type7 DRAW_LINE +#property indicator_color7 clrLightGray +#property indicator_style7 STYLE_DASHDOTDOT +#property indicator_width7 1 + +// +// KUMO ... + +// +// SENKOUSPANA ... + +// +#define senkouSpanABufferIndex 7 +double senkouSpanABuffer[]; + +// +// SENKOUSPANB ... + +// +#define senkouSpanBBufferIndex 8 +double senkouSpanBBuffer[]; + +// +// KUMOCLOUD ... + +// +#define kumoBufferIndex 7 + +// +#property indicator_label8 "X121_XICH Kumo" +#property indicator_type8 DRAW_FILLING +#property indicator_color8 clrAqua, clrMagenta +#property indicator_style8 STYLE_SOLID +#property indicator_width8 1 + +// +// DATA Buffers ... + +// +#define dTenkanBufferIndex 9 +double dTenkanBuffer[]; + +// +#define dKijunBufferIndex 10 +double dKijunBuffer[]; + +// +#define dChikouBufferIndex 11 +double dChikouBuffer[]; + +// +#define dSSABufferIndex 12 +double dSSABuffer[]; + +// +#define dSSBBufferIndex 13 +double dSSBBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; +int mHandler; + +// +ENUM_SERIESMODE mTenkanSenTopMode = NULL; +ENUM_SERIESMODE mTenkanSenBottomMode = NULL; + +// +ENUM_SERIESMODE mKijunSenTopMode = NULL; +ENUM_SERIESMODE mKijunSenBottomMode = NULL; + +// +ENUM_SERIESMODE mSenkouSpanBTopMode = NULL; +ENUM_SERIESMODE mSenkouSpanBBottomMode = NULL; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Init Handler ... + mHandler = iIchimoku( + _Symbol, + _Period, + tenkanSenLength, + kijunSenLength, + senkouSpanBLength); + if (mHandler == INVALID_HANDLE) + { + return INIT_FAILED; + } + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + IndicatorRelease(mHandler); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // Check Calculated Bars ... + int ichCalculatedBars = BarsCalculated(mHandler); + if (ichCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedTenkans = CopyBuffer(mHandler, TENKANSEN_LINE, 0, limit, dTenkanBuffer); + int copiedKijuns = CopyBuffer(mHandler, KIJUNSEN_LINE, 0, limit, dKijunBuffer); + int copiedChikous = CopyBuffer(mHandler, CHIKOUSPAN_LINE, 0, limit, dChikouBuffer); + int copiedSSAs = CopyBuffer(mHandler, SENKOUSPANA_LINE, 0, limit, dSSABuffer); + int copiedSSBs = CopyBuffer(mHandler, SENKOUSPANB_LINE, 0, limit, dSSBBuffer); + if ( + copiedSSAs < 0 || + copiedSSBs < 0 || + copiedKijuns < 0 || + copiedTenkans < 0 || + copiedChikous < 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateBuffers(i); + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + (tenkanSenLength > 2 && + kijunSenLength > tenkanSenLength && + senkouSpanBLength > kijunSenLength) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Ichimoku ... + result = MathMax(result, tenkanSenLength); + result = MathMax(result, kijunSenLength); + result = MathMax(result, senkouSpanBLength); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // ICHIMOKU ... + + // + // TENKANSEN ... + + // + ENUM_DRAW_TYPE tenkanSenDrawType = showTenkanSen ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(tenkanSenBuffer, true); + SetIndexBuffer(tenkanSenBufferIndex, tenkanSenBuffer, INDICATOR_DATA); + PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_SHOW_DATA, showTenkanSen); + PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_DRAW_TYPE, tenkanSenDrawType); + + // + // KIJUNSEN ... + + // + ENUM_DRAW_TYPE kijunSenDrawType = showKijunSen ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(kijunSenBuffer, true); + SetIndexBuffer(kijunSenBufferIndex, kijunSenBuffer, INDICATOR_DATA); + PlotIndexSetInteger(kijunSenBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(kijunSenBufferIndex, PLOT_SHOW_DATA, showKijunSen); + PlotIndexSetInteger(kijunSenBufferIndex, PLOT_DRAW_TYPE, kijunSenDrawType); + + // + // KIJUNSEN Plus ... + + // + ENUM_DRAW_TYPE kijunSenPlusDrawType = showKijunSenPlus ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(kijunSenPlusBuffer, true); + SetIndexBuffer(kijunSenPlusBufferIndex, kijunSenPlusBuffer, INDICATOR_DATA); + PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_SHIFT, kijunSenLength); + PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_DRAW_TYPE, kijunSenPlusDrawType); + + // + // KIJUNSEN Negative ... + + // + ENUM_DRAW_TYPE kijunSenNegativeDrawType = showKijunSenNegative ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(kijunSenNegativeBuffer, true); + SetIndexBuffer(kijunSenNegativeBufferIndex, kijunSenNegativeBuffer, INDICATOR_DATA); + PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_SHIFT, -kijunSenLength); + PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_DRAW_TYPE, kijunSenNegativeDrawType); + + // + // CHIKOUSPAN ... + + // + ENUM_DRAW_TYPE chikouSpanDrawType = showChikouSpan ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(chikouSpanBuffer, true); + SetIndexBuffer(chikouSpanBufferIndex, chikouSpanBuffer, INDICATOR_DATA); + PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_SHIFT, -kijunSenLength); + PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_SHOW_DATA, showChikouSpan); + PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_DRAW_TYPE, chikouSpanDrawType); + + // + // SENKOUSPAN A and B ... + int shiftSize = shiftKumo ? kijunSenLength : 0; + + // + // SENKOUSPANA ... + ENUM_DRAW_TYPE senkouSpanADrawType = showSenkouSpanA ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(senkouABuffer, true); + SetIndexBuffer(senkouABufferIndex, senkouABuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouABufferIndex, PLOT_SHIFT, shiftSize); + PlotIndexSetInteger(senkouABufferIndex, PLOT_SHOW_DATA, showSenkouSpanA); + PlotIndexSetInteger(senkouABufferIndex, PLOT_DRAW_TYPE, senkouSpanADrawType); + + // + // SENKOUSPANB ... + ENUM_DRAW_TYPE senkouSpanBDrawType = showSenkouSpanB ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(senkouBBuffer, true); + SetIndexBuffer(senkouBBufferIndex, senkouBBuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouBBufferIndex, PLOT_SHIFT, shiftSize); + PlotIndexSetInteger(senkouBBufferIndex, PLOT_SHOW_DATA, showSenkouSpanB); + PlotIndexSetInteger(senkouBBufferIndex, PLOT_DRAW_TYPE, senkouSpanBDrawType); + + // + // KUMO ... + + // + // SENKOUSPANA ... + ArraySetAsSeries(senkouSpanABuffer, true); + SetIndexBuffer(senkouSpanABufferIndex, senkouSpanABuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouSpanABufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // SENKOUSPANB ... + ArraySetAsSeries(senkouSpanBBuffer, true); + SetIndexBuffer(senkouSpanBBufferIndex, senkouSpanBBuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouSpanBBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // KUMO ... + + // + ENUM_DRAW_TYPE kumoDrawType = showKumo ? DRAW_FILLING : DRAW_NONE; + + // + PlotIndexSetInteger(kumoBufferIndex, PLOT_SHIFT, shiftSize); + PlotIndexSetInteger(kumoBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(kumoBufferIndex, PLOT_DRAW_TYPE, kumoDrawType); + + // + // DATA Buffers ... + + // + // D Tenkan ... + ArraySetAsSeries(dTenkanBuffer, true); + SetIndexBuffer(dTenkanBufferIndex, dTenkanBuffer, INDICATOR_CALCULATIONS); + + // + // D Kijun ... + ArraySetAsSeries(dKijunBuffer, true); + SetIndexBuffer(dKijunBufferIndex, dKijunBuffer, INDICATOR_CALCULATIONS); + + // + // D Chikou ... + ArraySetAsSeries(dChikouBuffer, true); + SetIndexBuffer(dChikouBufferIndex, dChikouBuffer, INDICATOR_CALCULATIONS); + + // + // D SSA ... + ArraySetAsSeries(dSSABuffer, true); + SetIndexBuffer(dSSABufferIndex, dSSABuffer, INDICATOR_CALCULATIONS); + + // + // D SSB ... + ArraySetAsSeries(dSSBBuffer, true); + SetIndexBuffer(dSSBBufferIndex, dSSBBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // ICHIMOKU ... + + // + double topValue; + double bottomValue; + + // + // TENKANSEN ... + + // + // Extract Tenkan Sen Top/Bottom Calculation Mode based on User Input ... + if (mTenkanSenTopMode == NULL || mTenkanSenBottomMode == NULL) + { + // + switch (tenkanSenMode) + { + // + case X_XICH_HH_LL_MODE: + // + mTenkanSenTopMode = MODE_HIGH; + mTenkanSenBottomMode = MODE_LOW; + break; + + // + case X_XICH_HO_LC_MODE: + // + mTenkanSenTopMode = MODE_OPEN; + mTenkanSenBottomMode = MODE_CLOSE; + break; + } + } + + // + // Calculate Top ... + topValue = GetHighestHigh( + _Symbol, + _Period, + mTenkanSenTopMode, + tenkanSenLength, + bar_index); + + // + // Calculate Bottom ... + bottomValue = GetLowestLow( + _Symbol, + _Period, + mTenkanSenBottomMode, + tenkanSenLength, + bar_index); + + // + double tenkanSenValue = (topValue + bottomValue) / 2; + tenkanSenBuffer[bar_index] = tenkanSenValue; + + // + // KIJUNSEN ... + + // + // Extract Kijun Sen Top/Bottom Calculation Mode based on User Input ... + if (mKijunSenTopMode == NULL || mKijunSenBottomMode == NULL) + { + // + switch (kijunSenMode) + { + // + case X_XICH_HH_LL_MODE: + // + mKijunSenTopMode = MODE_HIGH; + mKijunSenBottomMode = MODE_LOW; + break; + + // + case X_XICH_HO_LC_MODE: + // + mKijunSenTopMode = MODE_OPEN; + mKijunSenBottomMode = MODE_CLOSE; + break; + } + } + + // + // Calculate Top ... + topValue = GetHighestHigh( + _Symbol, + _Period, + mKijunSenTopMode, + kijunSenLength, + bar_index); + + // + // Calculate Bottom ... + bottomValue = GetLowestLow( + _Symbol, + _Period, + mKijunSenBottomMode, + kijunSenLength, + bar_index); + + // + double kijunSenValue = (topValue + bottomValue) / 2; + kijunSenBuffer[bar_index] = kijunSenValue; + + // + kijunSenPlusBuffer[bar_index] = kijunSenValue; + kijunSenNegativeBuffer[bar_index] = kijunSenValue; + + // + // CHIKOUSPAN ... + double chikouSpanValue = GetAppliedPrice( + bar_index, + chikuoSpanAppliedTo); + chikouSpanBuffer[bar_index] = chikouSpanValue; + + // + // KUMO ... + + // + // SENKOUSPANA ... + double senkouSpanAValue = (tenkanSenValue + kijunSenValue) / 2; + senkouABuffer[bar_index] = senkouSpanAValue; + senkouSpanABuffer[bar_index] = senkouSpanAValue; + + // + // SENKOUSPANB ... + + // + // Extract Senkou Span B Top/Bottom Calculation Mode based on User Input ... + if (mSenkouSpanBTopMode == NULL || mSenkouSpanBBottomMode == NULL) + { + // + switch (senkouSpanBMode) + { + // + case X_XICH_HH_LL_MODE: + // + mSenkouSpanBTopMode = MODE_HIGH; + mSenkouSpanBBottomMode = MODE_LOW; + break; + + // + case X_XICH_HO_LC_MODE: + // + mSenkouSpanBTopMode = MODE_OPEN; + mSenkouSpanBBottomMode = MODE_CLOSE; + break; + } + } + + // + // Calculate Top ... + topValue = GetHighestHigh( + _Symbol, + _Period, + mSenkouSpanBTopMode, + senkouSpanBLength, + bar_index); + + // + // Calculate Bottom ... + bottomValue = GetLowestLow( + _Symbol, + _Period, + mSenkouSpanBBottomMode, + senkouSpanBLength, + bar_index); + + // + double senkouSpanBValue = (topValue + bottomValue) / 2; + senkouBBuffer[bar_index] = senkouSpanBValue; + senkouSpanBBuffer[bar_index] = senkouSpanBValue; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xman.ex5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xman.ex5 new file mode 100644 index 0000000..5dc69f2 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xman.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xman.mq5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xman.mq5 new file mode 100644 index 0000000..5d87912 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xman.mq5 @@ -0,0 +1,4064 @@ +/////////////////////////////////////////////////////// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------- +// Name: X121_XMAN +// Description: Market Analyzer +// - Find Peaks and Vales +// - Find Trend +// - Find Market Direction +// - Detect Pivot Points and Swings +// +// Contains: +// ----------- +// - 4 Cycle of TimeFrames +// - Fibonacci Golden Zone +// - Trend Detection using True Range Averaging +// - Trend Detecting using Moving Averages Ribbon +// - Trend Detecting using SSL Channel +// - Trend Detecting using Hull Implementation +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121_XMAN Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_XMAN" + +// +// XPERIOD Calculation Method ... +// USED For Multiple Time Frames ... +enum ENUM_X_PERIOD_METHOD +{ + // + X_PERIOD_NOTHING, // Nothing + X_PERIOD_AUTO, // Auto Select + X_PERIOD_MANUALLY // Manually +}; + +// +enum ENUM_X_MA_METHOD +{ + X_MA_NOTHING, // Nothing + X_MA_SMA, // Simple + X_MA_EMA, // Expotential + X_MA_SMMA, // Smoothed Simple + X_MA_LWMA, // Linear Weighted + X_MA_AMA // Adaptive +}; + +// +struct XHullData +{ + // + double value; + double value3; + + // + double wsum1; + double wsum2; + double wsum3; + + // + double lsum1; + double lsum2; + double lsum3; +}; + +// +// Holds an SnapShot of Charts Configuration ... +struct XChartStyle +{ + // + // chart's ID ... + long chartId; + // + // chart's mode ... + ENUM_CHART_MODE mode; + // + // show bid line ... + bool showBidLine; + // + // show ask line ... + bool showAskLine; + // + // show grids on chart ... + bool showGrid; + // + // show volumes ... + bool showVolumes; + // + // Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders) ... + bool showTradeLevels; + // + // chart autoscroll ... + bool autoScroll; + // + // chart quick navigation state ... + bool quickNavigation; + // + // chart's foreground color ... + color foreGroundColor; + // + // chart's background color ... + color backGroundColor; + // + // Up Color ... + color upColor; + // + // Down Color ... + color downColor; + // + // Bullish color ... + color bullishColor; + // + // Bearish color ... + color bearishColor; + // + // grid color ... + color gridColor; + // + // bid line color ... + color bidLineColor; + // + // ask line color ... + color askLineColor; + // + // line mode and doji candlestick color ... + color lineColor; + // + // Color of stop order levels (Stop Loss and Take Profit) ... + color stopColor; + // + // volumes color ... + color volumesColor; +}; + +// +struct XMRBColorInfo +{ + double clr; + double state; +}; + +// +// a Class For Hull Calculations ... +class XSCHull +{ + // +public: + // + // Constructor ... + XSCHull() : mFullPeriod(1), mHalfPeriod(1), mSqrtPeriod(1), mArraySize(-1) + { + // + // These are a way above to assign Private variables at Construct time ... + } + + // + // Deconstructor ... + ~XSCHull() + { + ArrayFree(mData); + } + + // + // Initial Hull ... + bool Init( + int mPeriod, + double mDivisor) + { + // + bool result = false; + + // + mFullPeriod = (int)(mPeriod > 1 ? mPeriod : 1); + mHalfPeriod = (int)(mFullPeriod > 1 ? mFullPeriod / (mDivisor > 1 ? mDivisor : 1) : 1); + mSqrtPeriod = (int)MathSqrt(mFullPeriod); + + // + mArraySize = -1; + mWeight1 = mWeight2 = mWeight3 = 1; + + // + result = true; + + // + return result; + } + + // + // CalCulate Specific Value ... + double Calculate( + double value, + int i, + int bars) + { + // + double result = 0; + + // + if (mArraySize < bars) + { + // + mArraySize = ArrayResize(mData, bars + 500); + if (mArraySize < bars) + return result; + } + + // + mData[i].value = value; + if (i > mFullPeriod) + { + // + mData[i].wsum1 = mData[i - 1].wsum1 + value * mHalfPeriod - mData[i - 1].lsum1; + mData[i].lsum1 = mData[i - 1].lsum1 + value - mData[i - mHalfPeriod].value; + mData[i].wsum2 = mData[i - 1].wsum2 + value * mFullPeriod - mData[i - 1].lsum2; + mData[i].lsum2 = mData[i - 1].lsum2 + value - mData[i - mFullPeriod].value; + } + else + { + // + mData[i].wsum1 = mData[i].wsum2 = + mData[i].lsum1 = mData[i].lsum2 = mWeight1 = mWeight2 = 0; + for (int k = 0, w1 = mHalfPeriod, w2 = mFullPeriod; w2 > 0 && i >= k; k++, w1--, w2--) + { + // + if (w1 > 0) + { + // + mData[i].wsum1 += mData[i - k].value * w1; + mData[i].lsum1 += mData[i - k].value; + mWeight1 += w1; + } + + // + mData[i].wsum2 += mData[i - k].value * w2; + mData[i].lsum2 += mData[i - k].value; + mWeight2 += w2; + } + } + + // + mData[i].value3 = 2.0 * mData[i].wsum1 / mWeight1 - mData[i].wsum2 / mWeight2; + + // + if (i > mSqrtPeriod) + { + // + mData[i].wsum3 = mData[i - 1].wsum3 + mData[i].value3 * mSqrtPeriod - mData[i - 1].lsum3; + mData[i].lsum3 = mData[i - 1].lsum3 + mData[i].value3 - mData[i - mSqrtPeriod].value3; + } + else + { + // + mData[i].wsum3 = + mData[i].lsum3 = mWeight3 = 0; + + // + for (int k = 0, w3 = mSqrtPeriod; w3 > 0 && i >= k; k++, w3--) + { + // + mData[i].wsum3 += mData[i - k].value3 * w3; + mData[i].lsum3 += mData[i - k].value3; + mWeight3 += w3; + } + } + + // + result = mData[i].wsum3 / mWeight3; + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + int mFullPeriod; + int mHalfPeriod; + int mSqrtPeriod; + int mArraySize; + double mWeight1; + double mWeight2; + double mWeight3; + + // + XHullData mData[]; +}; + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Candles Timer"; +input color candleTimerColor = clrGold; // Text Color +input ENUM_BASE_CORNER candleTimerCorner = CORNER_RIGHT_UPPER; // Text Position + +// +input group "Chart Style"; +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 "Makret Cycles"; + +// +input group "Level 1"; +input ENUM_X_PERIOD_METHOD l1Method = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES l1Period = NULL; // Time Period + +// +input group "Level 2"; +input ENUM_X_PERIOD_METHOD l2Method = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES l2Period = NULL; // Time Period + +// +input group "Level 3"; +input ENUM_X_PERIOD_METHOD l3Method = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES l3Period = NULL; // Time Period + +// +input group "Level 4"; +input ENUM_X_PERIOD_METHOD l4Method = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES l4Period = NULL; // Time Period + +// +input group "Fibonacci"; +input double fiboLevel1 = 0.382; // Fibio 1st Level +input double fiboLevel2 = 0.5; // Fibio 2st Level +input double fiboLevel3 = 0.618; // Fibio 3rd Level + +// +input group "Boundary Detection Modes"; +input ENUM_SERIESMODE hhMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE llMode = MODE_LOW; // Lowest Low Calculation Method + +// +input group "Trend Detection"; +input double trendMultiplier = 3; // Multiplier +input ENUM_APPLIED_PRICE trendPriceAppliedTo = PRICE_MEDIAN; // Applied To + +// +input group "Ribbon Detection"; +input ENUM_X_MA_METHOD ribbonMode = X_MA_AMA; // How to Calculate + +// +input group "Hull Trend Detection"; +input double hullDivisor = 2.0; // Divisor (Speed) +input ENUM_APPLIED_PRICE hullUpAppliedTo = PRICE_HIGH; // Up Zone Applied to +input ENUM_APPLIED_PRICE hullDownAppliedTo = PRICE_LOW; // Down Zone Applied to + +// +input group "SSL Channel Detection"; +input ENUM_X_MA_METHOD sslcMode = X_MA_SMA; // How to Calculate +input ENUM_APPLIED_PRICE sslcUpAppliedTo = PRICE_HIGH; // Up Applied To +input ENUM_APPLIED_PRICE sslcDownAppliedTo = PRICE_LOW; // Down Applied To + +// +input group "Presentation"; +input bool showCandleTimer = true; // Show Candle Time +input bool showCandles = true; // Show Candles +input bool showHKCandles = false; // Draw Hiken Ashi Candle +input bool showPeaksAndVales = true; // Show Peaks and Vales +input bool showTrends = true; // Show Trends +input bool fillTrends = false; // Fill Trends +input bool showLevels = false; // Show Levels +input bool showConsolidations = false; // Show Consolidations +input bool showRibbons = false; // Show Ribbons +input bool showHull = false; // Show Hull +input bool showSSLChannel = false; // Show SSL Channel +input bool showFibo1Levels = false; // Show Fibo 1st Level +input bool showFibo2Levels = false; // Show Fibo 2nd Level +input bool showFibo3Levels = false; // Show Fibo 3rd Level +input bool showFiboTracker = false; // Show Fibonacci Tracker + +// +// 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 85 +#property indicator_plots 41 + +// +// PEKSANDVALES ... + +// +// PEAKS ... + +// +#define peaksBufferIndex 0 +double peaksBuffer[]; + +// +#property indicator_label1 "X121_XMAN PEAKS" +#property indicator_type1 DRAW_ARROW +#property indicator_color1 clrAqua +#property indicator_width1 1 + +// +// VALES ... + +// +#define valesBufferIndex 1 +double valesBuffer[]; + +// +#property indicator_label2 "X121_XMAN VALES" +#property indicator_type2 DRAW_ARROW +#property indicator_color2 clrMagenta +#property indicator_width2 1 + +// +#define rBufferIndex 2 +double rBuffer[]; + +// +#define rColorBufferIndex 3 +double rColorBuffer[]; + +// +#property indicator_label3 "X121_XMAN R" +#property indicator_type3 DRAW_COLOR_LINE +#property indicator_color3 CLR_NONE, clrAqua +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +#define sBufferIndex 4 +#define sBufferPlotIndex 3 +double sBuffer[]; + +// +#define sColorBufferIndex 5 +double sColorBuffer[]; + +// +#property indicator_label4 "X121_XMAN S" +#property indicator_type4 DRAW_COLOR_LINE +#property indicator_color4 CLR_NONE, clrMagenta +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +// FIBBO Level 1 ... + +// +#define fl1BufferIndex 6 +#define fl1BufferPlotIndex 4 +double fl1Buffer[]; + +// +#define fl1ColorBufferIndex 7 +double fl1ColorBuffer[]; + +// +#property indicator_label5 "X121_XMAN FL1" +#property indicator_type5 DRAW_COLOR_LINE +#property indicator_color5 CLR_NONE, clrGold +#property indicator_style5 STYLE_DASHDOTDOT +#property indicator_width5 1 + +// +// FIBBO Level 2 ... + +// +#define fl2BufferIndex 8 +#define fl2BufferPlotIndex 5 +double fl2Buffer[]; + +// +#define fl2ColorBufferIndex 9 +double fl2ColorBuffer[]; + +// +#property indicator_label6 "X121_XMAN FL2" +#property indicator_type6 DRAW_COLOR_LINE +#property indicator_color6 CLR_NONE, clrGold +#property indicator_style6 STYLE_DASHDOTDOT +#property indicator_width6 1 + +// +// FIBBO Level 3 ... + +// +#define fl3BufferIndex 10 +#define fl3BufferPlotIndex 6 +double fl3Buffer[]; + +// +#define fl3ColorBufferIndex 11 +double fl3ColorBuffer[]; + +// +#property indicator_label7 "X121_XMAN FL3" +#property indicator_type7 DRAW_COLOR_LINE +#property indicator_color7 CLR_NONE, clrGold +#property indicator_style7 STYLE_DASHDOTDOT +#property indicator_width7 1 + +// +// LEVELS ... + +// +#define sHHBufferIndex 12 +#define sHHBufferPlotIndex 7 +double sHHBuffer[]; + +// +#define sHHColorBufferIndex 13 +double sHHColorBuffer[]; + +// +#property indicator_label8 "X121_XMAN SHH" +#property indicator_type8 DRAW_COLOR_LINE +#property indicator_color8 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style8 STYLE_DOT +#property indicator_width8 1 + +#define sLLBufferIndex 14 +#define sLLBufferPlotIndex 8 +double sLLBuffer[]; + +// +#define sLLColorBufferIndex 15 +double sLLColorBuffer[]; + +// +#property indicator_label9 "X121_XMAN SLL" +#property indicator_type9 DRAW_COLOR_LINE +#property indicator_color9 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style9 STYLE_DOT +#property indicator_width9 1 + +// +#define mHHBufferIndex 16 +#define mHHBufferPlotIndex 9 +double mHHBuffer[]; + +// +#define mHHColorBufferIndex 17 +double mHHColorBuffer[]; + +// +#property indicator_label10 "X121_XMAN MHH" +#property indicator_type10 DRAW_COLOR_LINE +#property indicator_color10 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style10 STYLE_DOT +#property indicator_width10 1 + +// +#define mLLBufferIndex 18 +#define mLLBufferPlotIndex 10 +double mLLBuffer[]; + +// +#define mLLColorBufferIndex 19 +double mLLColorBuffer[]; + +// +#property indicator_label11 "X121_XMAN MLL" +#property indicator_type11 DRAW_COLOR_LINE +#property indicator_color11 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style11 STYLE_DOT +#property indicator_width11 1 + +// +#define lHHBufferIndex 20 +#define lHHBufferPlotIndex 11 +double lHHBuffer[]; + +// +#define lHHColorBufferIndex 21 +double lHHColorBuffer[]; + +// +#property indicator_label12 "X121_XMAN LHH" +#property indicator_type12 DRAW_COLOR_LINE +#property indicator_color12 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style12 STYLE_DOT +#property indicator_width12 1 + +// +#define lLLBufferIndex 22 +#define lLLBufferPlotIndex 12 +double lLLBuffer[]; + +// +#define lLLColorBufferIndex 23 +double lLLColorBuffer[]; + +// +#property indicator_label13 "X121_XMAN LLL" +#property indicator_type13 DRAW_COLOR_LINE +#property indicator_color13 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style13 STYLE_DOT +#property indicator_width13 1 + +// +#define hHHBufferIndex 24 +#define hHHBufferPlotIndex 13 +double hHHBuffer[]; + +// +#define hHHColorBufferIndex 25 +double hHHColorBuffer[]; + +// +#property indicator_label14 "X121_XMAN HHH" +#property indicator_type14 DRAW_COLOR_LINE +#property indicator_color14 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style14 STYLE_DOT +#property indicator_width14 1 + +// +#define hLLBufferIndex 26 +#define hLLBufferPlotIndex 14 +double hLLBuffer[]; + +// +#define hLLColorBufferIndex 27 +double hLLColorBuffer[]; + +// +#property indicator_label15 "X121_XMAN HLL" +#property indicator_type15 DRAW_COLOR_LINE +#property indicator_color15 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style15 STYLE_DOT +#property indicator_width15 1 + +// +// XSTR Buffers ... + +// +#define fillUpBufferIndex 28 +double fillUpBuffer[]; + +#define fillDownBufferIndex 29 +double fillDownBuffer[]; + +// +#define fillingBufferPlotIndex 15 + +// +#property indicator_label16 "X121_XMAN TRND Filling" +#property indicator_type16 DRAW_FILLING +#property indicator_color16 clrBisque, clrPaleGreen + +// +#define trendBufferIndex 30 +#define trendBufferPlotIndex 16 +double trendBuffer[]; + +// +#define trendColorBufferIndex 31 +double trendColorBuffer[]; + +// +#property indicator_label17 "X121_XMAN TRND" +#property indicator_type17 DRAW_COLOR_LINE +#property indicator_color17 CLR_NONE, clrGreen, clrDarkRed +#property indicator_style17 STYLE_DOT +#property indicator_width17 1 + +// +// XMRB ... + +// +// RIBBON 1 ... +// High ... + +// +#define ribbon1BufferIndex 32 +#define ribbon1BufferPlotIndex 17 +double ribbon1Buffer[]; + +// +#define ribbon1ColorBufferIndex 33 +double ribbon1ColorBuffer[]; + +// +#property indicator_label18 "X121_XMAN RB 1" +#property indicator_type18 DRAW_COLOR_LINE +#property indicator_color18 CLR_NONE, clrGray, clrGreen, clrDarkRed +#property indicator_style18 STYLE_DASH +#property indicator_width18 1 + +// +// RIBBON 2 ... +// Open ... + +// +#define ribbon2BufferIndex 34 +#define ribbon2BufferPlotIndex 18 +double ribbon2Buffer[]; + +// +#define ribbon2ColorBufferIndex 35 +double ribbon2ColorBuffer[]; + +// +#property indicator_label19 "X121_XMAN RB 2" +#property indicator_type19 DRAW_COLOR_LINE +#property indicator_color19 CLR_NONE, clrGray, clrGreen, clrDarkRed +#property indicator_style19 STYLE_DASH +#property indicator_width19 1 + +// +// RIBBON 3 ... +// Close ... + +// +#define ribbon3BufferIndex 36 +#define ribbon3BufferPlotIndex 19 +double ribbon3Buffer[]; + +// +#define ribbon3ColorBufferIndex 37 +double ribbon3ColorBuffer[]; + +// +#property indicator_label20 "X121_XMAN RB 3" +#property indicator_type20 DRAW_COLOR_LINE +#property indicator_color20 CLR_NONE, clrGray, clrGreen, clrDarkRed +#property indicator_style20 STYLE_DASH +#property indicator_width20 1 + +// +// RIBBON 4 ... +// Median ... + +// +#define ribbon4BufferIndex 38 +#define ribbon4BufferPlotIndex 20 +double ribbon4Buffer[]; + +// +#define ribbon4ColorBufferIndex 39 +double ribbon4ColorBuffer[]; + +// +#property indicator_label21 "X121_XMAN RB 4" +#property indicator_type21 DRAW_COLOR_LINE +#property indicator_color21 CLR_NONE, clrGray, clrGreen, clrDarkRed +#property indicator_style21 STYLE_DASH +#property indicator_width21 1 + +// +// RIBBON 5 ... +// Typical ... + +// +#define ribbon5BufferIndex 40 +#define ribbon5BufferPlotIndex 21 +double ribbon5Buffer[]; + +// +#define ribbon5ColorBufferIndex 41 +double ribbon5ColorBuffer[]; + +// +#property indicator_label22 "X121_XMAN RB 5" +#property indicator_type22 DRAW_COLOR_LINE +#property indicator_color22 CLR_NONE, clrGray, clrGreen, clrDarkRed +#property indicator_style22 STYLE_DASH +#property indicator_width22 1 + +// +// RIBBON 6 ... +// Low ... + +// +#define ribbon6BufferIndex 42 +#define ribbon6BufferPlotIndex 22 +double ribbon6Buffer[]; + +// +#define ribbon6ColorBufferIndex 43 +double ribbon6ColorBuffer[]; + +// +#property indicator_label23 "X121_XMAN RB 6" +#property indicator_type23 DRAW_COLOR_LINE +#property indicator_color23 CLR_NONE, clrGray, clrGreen, clrDarkRed +#property indicator_style23 STYLE_DASH +#property indicator_width23 1 + +// +// XSSLC ... + +// +#define sslcUpBufferIndex 44 +#define sslcUpBufferPlotIndex 23 +double sslcUpBuffer[]; + +// +#define sslcUpColorBufferIndex 45 +double sslcUpColorBuffer[]; + +// +#property indicator_label24 "X121_XMAN SSLC Up" +#property indicator_type24 DRAW_COLOR_LINE +#property indicator_color24 CLR_NONE, clrLime +#property indicator_style24 STYLE_SOLID +#property indicator_width24 1 + +// +#define sslcDownBufferIndex 46 +#define sslcDownBufferPlotIndex 24 +double sslcDownBuffer[]; + +// +#define sslcDownColorBufferIndex 47 +double sslcDownColorBuffer[]; + +// +#property indicator_label25 "X121_XMAN SSLC Down" +#property indicator_type25 DRAW_COLOR_LINE +#property indicator_color25 CLR_NONE, clrRed +#property indicator_style25 STYLE_SOLID +#property indicator_width25 1 + +// +// XHULL ... + +// +// UP Zone ... + +// +#define hullUpZoneBufferIndex 48 +#define hullUpZoneBufferPlotIndex 25 +#define hullUpZoneColorBufferIndex 49 + +// +double hullUpZoneBuffer[]; +double hullUpZoneColorBuffer[]; + +// +#property indicator_label26 "X121_XMAN HULL Up" +#property indicator_type26 DRAW_COLOR_LINE +#property indicator_color26 CLR_NONE, clrGray, clrAqua, clrMagenta +#property indicator_width26 1 + +// +// DOWN Zone ... + +// +#define hullDownZoneBufferIndex 50 +#define hullDownZoneBufferPlotIndex 26 +#define hullDownZoneColorBufferIndex 51 + +// +double hullDownZoneBuffer[]; +double hullDownZoneColorBuffer[]; + +// +#property indicator_label27 "X121_XMAN HULL Down" +#property indicator_type27 DRAW_COLOR_LINE +#property indicator_color27 CLR_NONE, clrGray, clrAqua, clrMagenta +#property indicator_width27 1 + +// +// Open ... +#define hkOpenBufferIndex 52 +double hkOpenBuffer[]; + +// +// High ... +#define hkHighBufferIndex 53 +double hkHighBuffer[]; + +// +// Low ... +#define hkLowBufferIndex 54 +double hkLowBuffer[]; + +// +// Close ... +#define hkCloseBufferIndex 55 +double hkCloseBuffer[]; + +// +// Candle Color ... +#define hkCandleColorBufferIndex 56 +double hkCandleColorBuffer[]; + +// +#define hkCandlesBufferIndex 27 + +// +#property indicator_label28 "X121_XMAN HK Open;X121_XMAN HK High;X121_XMAN HK Low;X121_XMAN HK Close" +#property indicator_type28 DRAW_COLOR_CANDLES +#property indicator_color28 CLR_NONE, clrAqua, clrMagenta + +// +// DATA Buffers ... + +#define lastBufferIndex 56 + +// +#define atrBufferIndex lastBufferIndex + 1 +double atrBuffer[]; + +// +#define trendStateBufferIndex lastBufferIndex + 2 +double trendStateBuffer[]; + +// +#define upBufferIndex lastBufferIndex + 3 +double upBuffer[]; + +// +#define downBufferIndex lastBufferIndex + 4 +double downBuffer[]; + +// +#define priceBufferIndex lastBufferIndex + 5 +double priceBuffer[]; + +// +#define sslcUpMaBufferIndex lastBufferIndex + 6 +double sslcUpMaBuffer[]; + +// +#define sslcDownMaBufferIndex lastBufferIndex + 7 +double sslcDownMaBuffer[]; + +// +#define sslcKpiBufferIndex lastBufferIndex + 8 +double sslcKpiBuffer[]; + +// +// STATE Buffers ... + +// +// When new Peaks Happens it's Valued otherwise EMPTY_VALUE ... +#define peaksStateBufferIndex lastBufferIndex + 9 +double peaksStateBuffer[]; + +// +// When new Vales Happens it's Valued otherwise EMPTY_VALUE ... +#define valesStateBufferIndex lastBufferIndex + 10 +double valesStateBuffer[]; + +// +// SHORT Cycle ... + +// +#define sHHStateBufferIndex lastBufferIndex + 11 +double sHHStateBuffer[]; + +// +#define sLLStateBufferIndex lastBufferIndex + 12 +double sLLStateBuffer[]; + +// +// MEDIUM Cycle ... + +// +#define mHHStateBufferIndex lastBufferIndex + 13 +double mHHStateBuffer[]; + +// +#define mLLStateBufferIndex lastBufferIndex + 14 +double mLLStateBuffer[]; + +// +// LONG Cycle ... + +// +#define lHHStateBufferIndex lastBufferIndex + 15 +double lHHStateBuffer[]; + +// +#define lLLStateBufferIndex lastBufferIndex + 16 +double lLLStateBuffer[]; + +// +// HIND Cycle ... + +// +#define hHHStateBufferIndex lastBufferIndex + 17 +double hHHStateBuffer[]; + +// +#define hLLStateBufferIndex lastBufferIndex + 18 +double hLLStateBuffer[]; + +// +// XSTR ... +#define strTrendStateBufferIndex lastBufferIndex + 19 +double strTrendStateBuffer[]; + +// +// XMRB ... + +// +// RIBBON 1 (High) ... +#define rb1StateBufferIndex lastBufferIndex + 20 +double rb1StateBuffer[]; + +// +// RIBBON 2 (Open) ... +#define rb2StateBufferIndex lastBufferIndex + 21 +double rb2StateBuffer[]; + +// +// RIBBON 3 (Close) ... +#define rb3StateBufferIndex lastBufferIndex + 22 +double rb3StateBuffer[]; + +// +// RIBBON 4 (Median) ... +#define rb4StateBufferIndex lastBufferIndex + 23 +double rb4StateBuffer[]; + +// +// RIBBON 5 (Typical) ... +#define rb5StateBufferIndex lastBufferIndex + 24 +double rb5StateBuffer[]; + +// +// RIBBON 6 (Low) ... +#define rb6StateBufferIndex lastBufferIndex + 25 +double rb6StateBuffer[]; + +// +// XHULL ... + +// +#define hullUpStateBufferIndex lastBufferIndex + 26 +double hullUpStateBuffer[]; + +// +#define hullDownStateBufferIndex lastBufferIndex + 27 +double hullDownStateBuffer[]; + +// +// XHK ... +#define hkStateBufferIndex lastBufferIndex + 28 +double hkStateBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +double lastPeak; +double lastVale; + +// +double mLastSHH = 0; +double mLastSLL = 0; + +// +double mLastMHH = 0; +double mLastMLL = 0; + +// +double mLastLHH = 0; +double mLastLLL = 0; + +// +double mLastHHH = 0; +double mLastHLL = 0; + +// +double mHideColorIDX = 0; + +// +int currentPeriodSecconds = 0; + +// +// CYCLE 1 ... +int mL1Candles; +int mL1PeriodSecconds = 0; +int mLastL1StartBarIndex = 0; +datetime mLastL1StartTime = NULL; +ENUM_TIMEFRAMES mL1Period = NULL; + +// +// CYCLE 2 ... +int mL2Candles; +int mL2PeriodSecconds = 0; +int mLastL2StartBarIndex = 0; +datetime mLastL2StartTime = NULL; +ENUM_TIMEFRAMES mL2Period = NULL; + +// +// CYCLE 3 ... +int mL3Candles; +int mL3PeriodSecconds = 0; +int mLastL3StartBarIndex = 0; +datetime mLastL3StartTime = NULL; +ENUM_TIMEFRAMES mL3Period = NULL; + +// +// CYCLE 4 ... +int mL4Candles; +int mL4PeriodSecconds = 0; +int mLastL4StartBarIndex = 0; +datetime mLastL4StartTime = NULL; +ENUM_TIMEFRAMES mL4Period = NULL; + +// +// XSTR ... + +// +int atrHandler = INVALID_HANDLE; + +// +int changeOfTrend; +int startBearishTrend; +int startBullishTrend; + +// +int mStrLength; + +// +// XMRB ... + +int mMRBLength; +int mMRBAMAFast = 2; +int mMRBAMASlow = 30; + +// +int rb1Handler = INVALID_HANDLE; +int rb2Handler = INVALID_HANDLE; +int rb3Handler = INVALID_HANDLE; +int rb4Handler = INVALID_HANDLE; +int rb5Handler = INVALID_HANDLE; +int rb6Handler = INVALID_HANDLE; + +// +// XSSLC ... + +// +int mSSLCLength; + +// +int sslcUpHandler = INVALID_HANDLE; +int sslcDownHandler = INVALID_HANDLE; + +// +// XHULL ... + +// +int mHULLLength; + +// +XSCHull *mUpZHull; +XSCHull *mDownZHull; + +// +double mLastHullUpValue; +double mLastHullUpColorValue = 1; +double mLastHullDownValue; +double mLastHullDownColorValue = 1; + +// +// XCC ... + +// +XChartStyle chartStyle; +XChartStyle clearStyle; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + InitCandleTimer(); + + // + // Initial Periods ... + InitialCycles(); + + // + drawPrefix = ShortName; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // We Can Choose ATR Length based on Other Cycles ... + mStrLength = mL4Candles; + atrHandler = iATR( + _Symbol, + _Period, + mStrLength); + if (atrHandler == INVALID_HANDLE) + { + return INIT_FAILED; + } + + // + mMRBLength = mL4Candles; + if (!InitRibbons()) + { + return INIT_FAILED; + } + + // + mSSLCLength = mL4Candles; + if (!InitSSLChannel()) + { + return INIT_FAILED; + } + + // + mHULLLength = mL4Candles; + if (!InitHullTrend()) + { + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Apply Chart Style ... + ApplyCustomChartStyle(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + IndicatorRelease(atrHandler); + + // + // XMRB ... + IndicatorRelease(rb1Handler); + IndicatorRelease(rb2Handler); + IndicatorRelease(rb3Handler); + IndicatorRelease(rb4Handler); + IndicatorRelease(rb5Handler); + IndicatorRelease(rb6Handler); + + // + // XSSLC ... + IndicatorRelease(sslcUpHandler); + IndicatorRelease(sslcDownHandler); + + // + // XHULL ... + delete mUpZHull; + delete mDownZHull; + + // + ObjectDelete(0, ShortName); + + // + Comment(""); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Calculate Candle Remain Time ... + CalculateCandleTimer(); + + // + // this counts Available Bars ... + int limit; + + // + limit = prev_calculated - 1; + if (limit < 0) + { + limit = 0; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + // + double upPrice = GetAppliedPrice( + hullUpAppliedTo, + open, high, low, close, i); + + // + double downPrice = GetAppliedPrice( + hullDownAppliedTo, + open, high, low, close, i); + + // + CalculateHull(i, rates_total, upPrice, downPrice); + } + + // + bool isXSTRCalculated = CalculateXSTR( + rates_total, + prev_calculated, + open, + high, + low, + close); + if (!isXSTRCalculated) + { + return prev_calculated; + } + + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + + // + // Checking Handlers Calculated Bars ... + + // + // XMRB ... + int rb1CalculatedBars = BarsCalculated(rb1Handler); + int rb2CalculatedBars = BarsCalculated(rb2Handler); + int rb3CalculatedBars = BarsCalculated(rb3Handler); + int rb4CalculatedBars = BarsCalculated(rb4Handler); + int rb5CalculatedBars = BarsCalculated(rb5Handler); + int rb6CalculatedBars = BarsCalculated(rb6Handler); + + // + // XSSLC ... + int sslcUpCalculatedBars = BarsCalculated(sslcUpHandler); + int sslcDownCalculatedBars = BarsCalculated(sslcDownHandler); + + // + bool isCalculatedBarsNotPassed = + // + // XMRB ... + rb1CalculatedBars < maxLength || + rb2CalculatedBars < maxLength || + rb3CalculatedBars < maxLength || + rb4CalculatedBars < maxLength || + rb5CalculatedBars < maxLength || + rb6CalculatedBars < maxLength || + // + // XSSLC ... + sslcUpCalculatedBars < maxLength || + sslcDownCalculatedBars < maxLength + // + ; + + // + if (isCalculatedBarsNotPassed) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Check Handlers Copied Bars ... + + // + // XMRB ... + int rb1CopiedBars = CopyBuffer(rb1Handler, 0, 0, limit, ribbon1Buffer); + int rb2CopiedBars = CopyBuffer(rb2Handler, 0, 0, limit, ribbon2Buffer); + int rb3CopiedBars = CopyBuffer(rb3Handler, 0, 0, limit, ribbon3Buffer); + int rb4CopiedBars = CopyBuffer(rb4Handler, 0, 0, limit, ribbon4Buffer); + int rb5CopiedBars = CopyBuffer(rb5Handler, 0, 0, limit, ribbon5Buffer); + int rb6CopiedBars = CopyBuffer(rb6Handler, 0, 0, limit, ribbon6Buffer); + + // + // XSSLC ... + int sslcUpCopiedBars = CopyBuffer(sslcUpHandler, 0, 0, limit, sslcUpMaBuffer); + int sslcDownCopiedBars = CopyBuffer(sslcDownHandler, 0, 0, limit, sslcDownMaBuffer); + + // + bool isCopiedBarsNotPassed = + // + // XMRB ... + rb1CopiedBars < 0 || + rb2CopiedBars < 0 || + rb3CopiedBars < 0 || + rb4CopiedBars < 0 || + rb5CopiedBars < 0 || + rb6CopiedBars < 0 || + // + // XSSLC ... + sslcUpCopiedBars < 0 || + sslcDownCopiedBars < 0 + // + ; + + // + if (isCopiedBarsNotPassed) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i); + + // + CalculateRibbonsColors(i, low, high); + + // + CalculateHikenAshi(i, prev_calculated, rates_total, open, high, close, low); + + // + CalculateSSLC(i, limit, rates_total, prev_calculated, close); + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + // Validate User Inputs ... + result = + // + // L1 ... + // Short Cycle ... + ( + // + l1Method == X_PERIOD_AUTO + ? l1Period == NULL + : l1Period != NULL && l1Method != X_PERIOD_NOTHING + // + ) + // + && + // + // L2 ... + // Medium Cycle ... + ( + // + l2Method == X_PERIOD_AUTO + ? l2Period == NULL + : l2Period != NULL && l2Method != X_PERIOD_NOTHING + // + ) + // + && + // + // L3 ... + // Long Cycle ... + ( + // + l3Method == X_PERIOD_AUTO + ? l3Period == NULL + : l3Period != NULL && l3Method != X_PERIOD_NOTHING + // + ) + // + && + // + // L4 ... + // Hind Cycle ... + ( + // + l4Method == X_PERIOD_AUTO + ? l4Period == NULL + : l4Period != NULL && l4Method != X_PERIOD_NOTHING + // + ) + // + && + // + // Validate Ribbon ... + ( + // + ribbonMode != X_MA_NOTHING + // + ) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 1; + + // + result = MathMax(result, mL1Candles); + result = MathMax(result, mL2Candles); + result = MathMax(result, mL3Candles); + result = MathMax(result, mL4Candles); + + // + return result; +} + +// +// Init Candle Timer ... +void InitCandleTimer() +{ + // + // Validate Inputs ... + if (showCandleTimer) + { + CreateIndicatorObject(); + } + else + { + ObjectDelete(0, ShortName); + } +} + +// +// Initial Multi Time Frame Cycles Periods ... +void InitialCycles() +{ + // + // Calculate Current Period Secconds ... + currentPeriodSecconds = PeriodSeconds(_Period); + + // + // Nearest ... + // Calculate Cycle 1 Requirements ... + if (mL1Period == NULL) + { + // + if (l1Method == X_PERIOD_AUTO) + { + mL1Period = GetNearestTimeFrame(_Period); + } + else + { + mL1Period = l1Period; + } + + // + mL1PeriodSecconds = PeriodSeconds(mL1Period); + + // + mL1Candles = mL1PeriodSecconds / currentPeriodSecconds; + } + + // + // Mediest ... + // Calculate Cycle 2 Requirements ... + if (mL2Period == NULL) + { + // + if (l2Method == X_PERIOD_AUTO) + { + mL2Period = GetMediestTimeFrame(_Period); + } + else + { + mL2Period = l2Period; + } + + // + mL2PeriodSecconds = PeriodSeconds(mL2Period); + + // + mL2Candles = mL2PeriodSecconds / currentPeriodSecconds; + } + + // + // Farest ... + // Calculate Cycle 3 Requirements ... + if (mL3Period == NULL) + { + // + if (l3Method == X_PERIOD_AUTO) + { + mL3Period = GetFarestTimeFrame(_Period); + } + else + { + mL3Period = l3Period; + } + + // + mL3PeriodSecconds = PeriodSeconds(mL3Period); + + // + mL3Candles = mL3PeriodSecconds / currentPeriodSecconds; + } + + // + // HindMost ... + // Calculate Cycle 4 Requirements ... + if (mL4Period == NULL) + { + // + if (l4Method == X_PERIOD_AUTO) + { + mL4Period = GetHindmostTimeFrame(_Period); + } + else + { + mL4Period = l4Period; + } + + // + mL4PeriodSecconds = PeriodSeconds(mL4Period); + + // + mL4Candles = mL4PeriodSecconds / currentPeriodSecconds; + } + + // + string comment = GenerateCyclesRepresentation(); + Comment(comment); +} + +// +bool InitRibbons() +{ + // + bool result = false; + + // + if (mMRBLength <= 0) + { + return result; + } + + // + // RIBBON 1 ... + // High ... + result = InitMaHandler( + rb1Handler, + mMRBLength, + ribbonMode, + PRICE_HIGH); + if (!result) + { + return result; + } + + // + // RIBBON 2 ... + // Open ... + result = InitMaHandler( + rb2Handler, + mMRBLength, + ribbonMode, + PRICE_OPEN); + if (!result) + { + return result; + } + + // + // RIBBON 3 ... + // Close ... + result = InitMaHandler( + rb3Handler, + mMRBLength, + ribbonMode, + PRICE_CLOSE); + if (!result) + { + return result; + } + + // + // RIBBON 4 ... + // Median ... + result = InitMaHandler( + rb4Handler, + mMRBLength, + ribbonMode, + PRICE_MEDIAN); + if (!result) + { + return result; + } + + // + // RIBBON 5 ... + // Typical ... + result = InitMaHandler( + rb5Handler, + mMRBLength, + ribbonMode, + PRICE_TYPICAL); + if (!result) + { + return result; + } + + // + // RIBBON 6 ... + // Low ... + result = InitMaHandler( + rb6Handler, + mMRBLength, + ribbonMode, + PRICE_LOW); + + // + return result; +} + +// +bool InitSSLChannel() +{ + // + bool result = false; + + // + if (mSSLCLength <= 0) + { + return result; + } + + // + // SSLUP ... + result = InitMaHandler( + sslcUpHandler, + mSSLCLength, + sslcMode, + sslcUpAppliedTo); + if (!result) + { + return result; + } + + // + // SSLDOWN ... + result = InitMaHandler( + sslcDownHandler, + mSSLCLength, + sslcMode, + sslcDownAppliedTo); + + // + return result; +} + +// +bool InitHullTrend() +{ + // + bool result = false; + + // + if (mHULLLength <= 0) + { + return result; + } + + // + mUpZHull = new XSCHull(); + mUpZHull.Init( + mHULLLength, + hullDivisor); + + // + mDownZHull = new XSCHull(); + mDownZHull.Init( + mHULLLength, + hullDivisor); + + // + result = true; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // RANGE ... + + // + // PEAKS and VALES ... + ENUM_DRAW_TYPE pvDrawType = showPeaksAndVales ? DRAW_ARROW : DRAW_NONE; + + // + // PEAKS ... + ArraySetAsSeries(peaksBuffer, true); + SetIndexBuffer(peaksBufferIndex, peaksBuffer, INDICATOR_DATA); + PlotIndexSetInteger(peaksBufferIndex, PLOT_ARROW, 225); + PlotIndexSetDouble(peaksBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + PlotIndexSetInteger(peaksBufferIndex, PLOT_SHOW_DATA, showPeaksAndVales); + PlotIndexSetInteger(peaksBufferIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + // VALES ... + ArraySetAsSeries(valesBuffer, true); + SetIndexBuffer(valesBufferIndex, valesBuffer, INDICATOR_DATA); + PlotIndexSetInteger(valesBufferIndex, PLOT_ARROW, 225); + PlotIndexSetDouble(valesBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + PlotIndexSetInteger(valesBufferIndex, PLOT_SHOW_DATA, showPeaksAndVales); + PlotIndexSetInteger(valesBufferIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + // SUPPORT and RESISTANCE ... + // + + // + // RESISTANCE ... + ArraySetAsSeries(rBuffer, true); + SetIndexBuffer(rBufferIndex, rBuffer, INDICATOR_DATA); + PlotIndexSetInteger(rBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(rBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // RESISTANCE Color ... + ArraySetAsSeries(rColorBuffer, true); + SetIndexBuffer(rColorBufferIndex, rColorBuffer, INDICATOR_COLOR_INDEX); + + // + // SUPPORT ... + ArraySetAsSeries(sBuffer, true); + SetIndexBuffer(sBufferIndex, sBuffer, INDICATOR_DATA); + PlotIndexSetInteger(sBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(sBufferPlotIndex, PLOT_SHOW_DATA, false); + + // + // SUPPORT Color ... + ArraySetAsSeries(sColorBuffer, true); + SetIndexBuffer(sColorBufferIndex, sColorBuffer, INDICATOR_COLOR_INDEX); + + // + // FIBBO Levels ... + + // + // LEVEL 1 ... + + // + // Buffer ... + ArraySetAsSeries(fl1Buffer, true); + SetIndexBuffer(fl1BufferIndex, fl1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl1BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl1BufferPlotIndex, PLOT_SHOW_DATA, showFibo1Levels); + + // + // Color ... + ArraySetAsSeries(fl1ColorBuffer, true); + SetIndexBuffer(fl1ColorBufferIndex, fl1ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 2 ... + + // + // BULLISH ... + ArraySetAsSeries(fl2Buffer, true); + SetIndexBuffer(fl2BufferIndex, fl2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl2BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl2BufferPlotIndex, PLOT_SHOW_DATA, showFibo2Levels); + + // + // BULLISH Color ... + ArraySetAsSeries(fl2ColorBuffer, true); + SetIndexBuffer(fl2ColorBufferIndex, fl2ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 3 ... + + // + // BULLISH ... + ArraySetAsSeries(fl3Buffer, true); + SetIndexBuffer(fl3BufferIndex, fl3Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl3BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl3BufferPlotIndex, PLOT_SHOW_DATA, showFibo3Levels); + + // + // BULLISH Color ... + ArraySetAsSeries(fl3ColorBuffer, true); + SetIndexBuffer(fl3ColorBufferIndex, fl3ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // SHORT Buffers ... + + // + // HIGH ... + ArraySetAsSeries(sHHBuffer, true); + SetIndexBuffer(sHHBufferIndex, sHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(sHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(sHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(sHHColorBuffer, true); + SetIndexBuffer(sHHColorBufferIndex, sHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(sLLBuffer, true); + SetIndexBuffer(sLLBufferIndex, sLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(sLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(sLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(sLLColorBuffer, true); + SetIndexBuffer(sLLColorBufferIndex, sLLColorBuffer, INDICATOR_COLOR_INDEX); + + // + // MEDIUM Buffer ... + + // + // HIGH ... + ArraySetAsSeries(mHHBuffer, true); + SetIndexBuffer(mHHBufferIndex, mHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(mHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(mHHColorBuffer, true); + SetIndexBuffer(mHHColorBufferIndex, mHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(mLLBuffer, true); + SetIndexBuffer(mLLBufferIndex, mLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(mLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(mLLColorBuffer, true); + SetIndexBuffer(mLLColorBufferIndex, mLLColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LONG Buffer ... + + // + // HIGH ... + ArraySetAsSeries(lHHBuffer, true); + SetIndexBuffer(lHHBufferIndex, lHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(lHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(lHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(lHHColorBuffer, true); + SetIndexBuffer(lHHColorBufferIndex, lHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(lLLBuffer, true); + SetIndexBuffer(lLLBufferIndex, lLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(lLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(lLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(lLLColorBuffer, true); + SetIndexBuffer(lLLColorBufferIndex, lLLColorBuffer, INDICATOR_COLOR_INDEX); + + // + // HIND Buffer ... + + // + // HIGH ... + ArraySetAsSeries(hHHBuffer, true); + SetIndexBuffer(hHHBufferIndex, hHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(hHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(hHHColorBuffer, true); + SetIndexBuffer(hHHColorBufferIndex, hHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(hLLBuffer, true); + SetIndexBuffer(hLLBufferIndex, hLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(hLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(hLLColorBuffer, true); + SetIndexBuffer(hLLColorBufferIndex, hLLColorBuffer, INDICATOR_COLOR_INDEX); + + // + // XSTR ... + + // + // FILLINGS ... + SetIndexBuffer(fillUpBufferIndex, fillUpBuffer, INDICATOR_DATA); + SetIndexBuffer(fillDownBufferIndex, fillDownBuffer, INDICATOR_DATA); + PlotIndexSetInteger(fillingBufferPlotIndex, PLOT_SHOW_DATA, false); + + // + // MAIN ... + SetIndexBuffer(trendBufferIndex, trendBuffer, INDICATOR_DATA); + PlotIndexSetInteger(trendBufferPlotIndex, PLOT_SHOW_DATA, showTrends); + SetIndexBuffer(trendColorBufferIndex, trendColorBuffer, INDICATOR_COLOR_INDEX); + + // + // RIBBON 1 ... + + // + ArraySetAsSeries(ribbon1Buffer, true); + SetIndexBuffer(ribbon1BufferIndex, ribbon1Buffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(ribbon1BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(ribbon1BufferPlotIndex, PLOT_SHOW_DATA, showRibbons); + + // + ArraySetAsSeries(ribbon1ColorBuffer, true); + SetIndexBuffer(ribbon1ColorBufferIndex, ribbon1ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // RIBBON 2 ... + + // + ArraySetAsSeries(ribbon2Buffer, true); + SetIndexBuffer(ribbon2BufferIndex, ribbon2Buffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(ribbon2BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(ribbon2BufferPlotIndex, PLOT_SHOW_DATA, showRibbons); + + // + ArraySetAsSeries(ribbon2ColorBuffer, true); + SetIndexBuffer(ribbon2ColorBufferIndex, ribbon2ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // RIBBON 3 ... + + // + ArraySetAsSeries(ribbon3Buffer, true); + SetIndexBuffer(ribbon3BufferIndex, ribbon3Buffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(ribbon3BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(ribbon3BufferPlotIndex, PLOT_SHOW_DATA, showRibbons); + + // + ArraySetAsSeries(ribbon3ColorBuffer, true); + SetIndexBuffer(ribbon3ColorBufferIndex, ribbon3ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // RIBBON 4 ... + + // + ArraySetAsSeries(ribbon4Buffer, true); + SetIndexBuffer(ribbon4BufferIndex, ribbon4Buffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(ribbon4BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(ribbon4BufferPlotIndex, PLOT_SHOW_DATA, showRibbons); + + // + ArraySetAsSeries(ribbon4ColorBuffer, true); + SetIndexBuffer(ribbon4ColorBufferIndex, ribbon4ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // RIBBON 5 ... + + // + ArraySetAsSeries(ribbon5Buffer, true); + SetIndexBuffer(ribbon5BufferIndex, ribbon5Buffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(ribbon5BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(ribbon5BufferPlotIndex, PLOT_SHOW_DATA, showRibbons); + + // + ArraySetAsSeries(ribbon5ColorBuffer, true); + SetIndexBuffer(ribbon5ColorBufferIndex, ribbon5ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // RIBBON 6 ... + + // + ArraySetAsSeries(ribbon6Buffer, true); + SetIndexBuffer(ribbon6BufferIndex, ribbon6Buffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(ribbon6BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(ribbon6BufferPlotIndex, PLOT_SHOW_DATA, showRibbons); + + // + ArraySetAsSeries(ribbon6ColorBuffer, true); + SetIndexBuffer(ribbon6ColorBufferIndex, ribbon6ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // XSSLC ... + + // + // UP ... + + // + ArraySetAsSeries(sslcUpBuffer, true); + SetIndexBuffer(sslcUpBufferIndex, sslcUpBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(sslcUpBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(sslcUpBufferPlotIndex, PLOT_SHOW_DATA, showSSLChannel); + + // + ArraySetAsSeries(sslcUpColorBuffer, true); + SetIndexBuffer(sslcUpColorBufferIndex, sslcUpColorBuffer, INDICATOR_COLOR_INDEX); + + // + // DOWN ... + + // + ArraySetAsSeries(sslcDownBuffer, true); + SetIndexBuffer(sslcDownBufferIndex, sslcDownBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(sslcDownBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(sslcDownBufferPlotIndex, PLOT_SHOW_DATA, showSSLChannel); + + // + ArraySetAsSeries(sslcDownColorBuffer, true); + SetIndexBuffer(sslcDownColorBufferIndex, sslcDownColorBuffer, INDICATOR_COLOR_INDEX); + + // + // XHULL ... + + // + // UP ... + + // + SetIndexBuffer(hullUpZoneBufferIndex, hullUpZoneBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hullUpZoneBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(hullUpZoneBufferPlotIndex, PLOT_SHOW_DATA, showHull); + + // + SetIndexBuffer(hullUpZoneColorBufferIndex, hullUpZoneColorBuffer, INDICATOR_COLOR_INDEX); + + // + // DOWN ... + + // + SetIndexBuffer(hullDownZoneBufferIndex, hullDownZoneBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hullDownZoneBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(hullDownZoneBufferPlotIndex, PLOT_SHOW_DATA, showHull); + + // + SetIndexBuffer(hullDownZoneColorBufferIndex, hullDownZoneColorBuffer, INDICATOR_COLOR_INDEX); + + // + // XHK ... + + // + // Candles Color ... + ArraySetAsSeries(hkCandleColorBuffer, true); + SetIndexBuffer(hkCandleColorBufferIndex, hkCandleColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on Candles Buffer ... + PlotIndexSetDouble(hkCandlesBufferIndex, PLOT_EMPTY_VALUE, 0.0); + + // + PlotIndexSetInteger(hkCandlesBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(hkCandleColorBufferIndex, PLOT_SHOW_DATA, false); + + // + // Open ... + ArraySetAsSeries(hkOpenBuffer, true); + PlotIndexSetInteger(hkOpenBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(hkOpenBufferIndex, hkOpenBuffer, INDICATOR_DATA); + + // + // High ... + ArraySetAsSeries(hkHighBuffer, true); + SetIndexBuffer(hkHighBufferIndex, hkHighBuffer, INDICATOR_DATA); + PlotIndexSetInteger(hkHighBufferIndex, PLOT_SHOW_DATA, false); + + // + // Close ... + ArraySetAsSeries(hkCloseBuffer, true); + SetIndexBuffer(hkCloseBufferIndex, hkCloseBuffer, INDICATOR_DATA); + PlotIndexSetInteger(hkCloseBufferIndex, PLOT_SHOW_DATA, false); + + // + // Low ... + ArraySetAsSeries(hkLowBuffer, true); + SetIndexBuffer(hkLowBufferIndex, hkLowBuffer, INDICATOR_DATA); + PlotIndexSetInteger(hkLowBufferIndex, PLOT_SHOW_DATA, false); + + // + // DATA Buffers ... + + // + // ATR ... + SetIndexBuffer(atrBufferIndex, atrBuffer, INDICATOR_CALCULATIONS); + + // + // TREND ... + SetIndexBuffer(trendStateBufferIndex, trendStateBuffer, INDICATOR_CALCULATIONS); + + // + // UP ... + SetIndexBuffer(upBufferIndex, upBuffer, INDICATOR_CALCULATIONS); + + // + // DOWN ... + SetIndexBuffer(downBufferIndex, downBuffer, INDICATOR_CALCULATIONS); + + // + // PRICE ... + SetIndexBuffer(priceBufferIndex, priceBuffer, INDICATOR_CALCULATIONS); + + // + // SSLCDOWNMA ... + ArraySetAsSeries(sslcUpMaBuffer, true); + SetIndexBuffer(sslcUpMaBufferIndex, sslcUpMaBuffer, INDICATOR_CALCULATIONS); + + // + // SSLCUPMA ... + ArraySetAsSeries(sslcDownMaBuffer, true); + SetIndexBuffer(sslcDownMaBufferIndex, sslcDownMaBuffer, INDICATOR_CALCULATIONS); + + // + // SSLCKPI ... + ArraySetAsSeries(sslcKpiBuffer, true); + SetIndexBuffer(sslcKpiBufferIndex, sslcKpiBuffer, INDICATOR_CALCULATIONS); + + // + // STATE Buffers ... + + // + // PEAKS ... + ArraySetAsSeries(peaksStateBuffer, true); + SetIndexBuffer(peaksStateBufferIndex, peaksStateBuffer, INDICATOR_CALCULATIONS); + + // + // VALES ... + ArraySetAsSeries(valesStateBuffer, true); + SetIndexBuffer(valesStateBufferIndex, valesStateBuffer, INDICATOR_CALCULATIONS); + + // + // CYCLES ... + + // + // SHORT ... + + // + ArraySetAsSeries(sHHStateBuffer, true); + SetIndexBuffer(sHHStateBufferIndex, sHHStateBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(sLLStateBuffer, true); + SetIndexBuffer(sLLStateBufferIndex, sLLStateBuffer, INDICATOR_CALCULATIONS); + + // + // MEDIUM ... + + // + ArraySetAsSeries(mHHStateBuffer, true); + SetIndexBuffer(mHHStateBufferIndex, mHHStateBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(mLLStateBuffer, true); + SetIndexBuffer(mLLStateBufferIndex, mLLStateBuffer, INDICATOR_CALCULATIONS); + + // + // LONG ... + + // + ArraySetAsSeries(lHHStateBuffer, true); + SetIndexBuffer(lHHStateBufferIndex, lHHStateBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(lLLStateBuffer, true); + SetIndexBuffer(lLLStateBufferIndex, lLLStateBuffer, INDICATOR_CALCULATIONS); + + // + // HIND ... + + // + ArraySetAsSeries(hHHStateBuffer, true); + SetIndexBuffer(hHHStateBufferIndex, hHHStateBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(hLLStateBuffer, true); + SetIndexBuffer(hLLStateBufferIndex, hLLStateBuffer, INDICATOR_CALCULATIONS); + + // + // XSTR ... + SetIndexBuffer(strTrendStateBufferIndex, strTrendStateBuffer, INDICATOR_CALCULATIONS); + + // + // XMBR ... + + // + // RIBBON 1 _ (High) ... + ArraySetAsSeries(rb1StateBuffer, true); + SetIndexBuffer(rb1StateBufferIndex, rb1StateBuffer, INDICATOR_CALCULATIONS); + + // + // RIBBON 2 _ (Open) ... + ArraySetAsSeries(rb2StateBuffer, true); + SetIndexBuffer(rb2StateBufferIndex, rb2StateBuffer, INDICATOR_CALCULATIONS); + + // + // RIBBON 3 _ (Close) ... + ArraySetAsSeries(rb3StateBuffer, true); + SetIndexBuffer(rb3StateBufferIndex, rb3StateBuffer, INDICATOR_CALCULATIONS); + + // + // RIBBON 4 _ (Median) ... + ArraySetAsSeries(rb4StateBuffer, true); + SetIndexBuffer(rb4StateBufferIndex, rb4StateBuffer, INDICATOR_CALCULATIONS); + + // + // RIBBON 5 _ (Typical) ... + ArraySetAsSeries(rb5StateBuffer, true); + SetIndexBuffer(rb5StateBufferIndex, rb5StateBuffer, INDICATOR_CALCULATIONS); + + // + // RIBBON 6 _ (Low) ... + ArraySetAsSeries(rb6StateBuffer, true); + SetIndexBuffer(rb6StateBufferIndex, rb6StateBuffer, INDICATOR_CALCULATIONS); + + // + // XHULL ... + + // + // UP Zone ... + SetIndexBuffer(hullUpStateBufferIndex, hullUpStateBuffer, INDICATOR_CALCULATIONS); + + // + // DOWN Zone ... + SetIndexBuffer(hullDownStateBufferIndex, hullDownStateBuffer, INDICATOR_CALCULATIONS); + + // + // XHK ... + + // + ArraySetAsSeries(hkStateBuffer, true); + SetIndexBuffer(hkStateBufferIndex, hkStateBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // Calculate ... + + // + // Calculate Short Cycle ... + CalculateShortCycle(bar_index); + + // + // Calculate Medium Cycle ... + CalculateMediumCycle(bar_index); + + // + // Calculate Long Cycle ... + CalculateLongCycle(bar_index); + + // + // Calculate Hind Cycle ... + CalculateHindCycle(bar_index); + + // + // Calculate Peaks and Vales ... + CalculatePeaksAndVales(bar_index); + + // + // Calculate Fibonnaci ... + CalculateFibonacci(bar_index); +} + +// +// START Calculation Parts ... +// + +// +// SHORT Cycle ... +void CalculateShortCycle( + int bar_index // Selected Bar Index +) +{ + // + ENUM_TIMEFRAMES mPeriod = mL1Period; + + // + double hhValue = GetCycleHHC( + bar_index, + mPeriod); + + // + double llValue = GetCycleLLC( + bar_index, + mPeriod); + + // + double lastHH = mLastSHH; + double lastLL = mLastSLL; + + // + double mHHState = EMPTY_VALUE; + double mhhColorIDX = mHideColorIDX; + if (showLevels) + { + // + if (hhValue == lastHH) + { + mhhColorIDX = showConsolidations ? 1 : mHideColorIDX; + } + else if (hhValue > lastHH) + { + mhhColorIDX = 2; + } + else if (hhValue < lastHH) + { + mhhColorIDX = 3; + } + + // + mHHState = mhhColorIDX; + } + else + { + mhhColorIDX = mHideColorIDX; + } + + // + double mLLState = EMPTY_VALUE; + double mllColorIDX = mHideColorIDX; + if (showLevels) + { + // + if (llValue == lastLL) + { + mllColorIDX = showConsolidations ? 1 : mHideColorIDX; + } + else if (llValue > lastLL) + { + mllColorIDX = 2; + } + else if (llValue < lastLL) + { + mllColorIDX = 3; + } + + // + mLLState = mllColorIDX; + } + else + { + mllColorIDX = mHideColorIDX; + } + + // + mLastSHH = hhValue; + mLastSLL = llValue; + + // + sHHBuffer[bar_index] = hhValue; + sLLBuffer[bar_index] = llValue; + sHHStateBuffer[bar_index] = mHHState; + sLLStateBuffer[bar_index] = mLLState; + sHHColorBuffer[bar_index] = mhhColorIDX; + sLLColorBuffer[bar_index] = mllColorIDX; +} + +// +// MEDIUM Cycle ... +void CalculateMediumCycle( + int bar_index // Selected Bar Index +) +{ + // + ENUM_TIMEFRAMES mPeriod = mL2Period; + + // + double hhValue = GetCycleHHC( + bar_index, + mPeriod); + + // + double llValue = GetCycleLLC( + bar_index, + mPeriod); + + // + double lastHH = mLastMHH; + double lastLL = mLastMLL; + + // + double mHHState = EMPTY_VALUE; + double mhhColorIDX = mHideColorIDX; + if (showLevels) + { + // + if (hhValue == lastHH) + { + mhhColorIDX = showConsolidations ? 1 : mHideColorIDX; + } + else if (hhValue > lastHH) + { + mhhColorIDX = 2; + } + else if (hhValue < lastHH) + { + mhhColorIDX = 3; + } + + // + mHHState = mhhColorIDX; + } + else + { + mhhColorIDX = mHideColorIDX; + } + + // + double mLLState = EMPTY_VALUE; + double mllColorIDX = mHideColorIDX; + if (showLevels) + { + // + if (llValue == lastLL) + { + mllColorIDX = showConsolidations ? 1 : mHideColorIDX; + } + else if (llValue > lastLL) + { + mllColorIDX = 2; + } + else if (llValue < lastLL) + { + mllColorIDX = 3; + } + + // + mLLState = mllColorIDX; + } + else + { + mllColorIDX = mHideColorIDX; + } + + // + mLastMHH = hhValue; + mLastMLL = llValue; + + // + mHHBuffer[bar_index] = hhValue; + mLLBuffer[bar_index] = llValue; + mHHStateBuffer[bar_index] = mHHState; + mLLStateBuffer[bar_index] = mLLState; + mHHColorBuffer[bar_index] = mhhColorIDX; + mLLColorBuffer[bar_index] = mllColorIDX; +} + +// +// LONG Cycle ... +void CalculateLongCycle( + int bar_index // Selected Bar Index +) +{ + // + ENUM_TIMEFRAMES mPeriod = mL3Period; + + // + double hhValue = GetCycleHHC( + bar_index, + mPeriod); + + // + double llValue = GetCycleLLC( + bar_index, + mPeriod); + + // + double lastHH = mLastLHH; + double lastLL = mLastLLL; + + // + double mHHState = EMPTY_VALUE; + double mhhColorIDX = mHideColorIDX; + if (showLevels) + { + // + if (hhValue == lastHH) + { + mhhColorIDX = showConsolidations ? 1 : mHideColorIDX; + } + else if (hhValue > lastHH) + { + mhhColorIDX = 2; + } + else if (hhValue < lastHH) + { + mhhColorIDX = 3; + } + + // + mHHState = mhhColorIDX; + } + else + { + mhhColorIDX = mHideColorIDX; + } + + // + double mLLState = EMPTY_VALUE; + double mllColorIDX = mHideColorIDX; + if (showLevels) + { + // + if (llValue == lastLL) + { + mllColorIDX = showConsolidations ? 1 : mHideColorIDX; + } + else if (llValue > lastLL) + { + mllColorIDX = 2; + } + else if (llValue < lastLL) + { + mllColorIDX = 3; + } + + // + mLLState = mllColorIDX; + } + else + { + mllColorIDX = mHideColorIDX; + } + + // + mLastLHH = hhValue; + mLastLLL = llValue; + + // + lHHBuffer[bar_index] = hhValue; + lLLBuffer[bar_index] = llValue; + lHHStateBuffer[bar_index] = mHHState; + lLLStateBuffer[bar_index] = mLLState; + lHHColorBuffer[bar_index] = mhhColorIDX; + lLLColorBuffer[bar_index] = mllColorIDX; +} + +// +// HIND Cycle ... +void CalculateHindCycle( + int bar_index // Selected Bar Index +) +{ + // + ENUM_TIMEFRAMES mPeriod = mL4Period; + + // + double hhValue = GetCycleHHC( + bar_index, + mPeriod); + + // + double llValue = GetCycleLLC( + bar_index, + mPeriod); + + // + double lastHH = mLastHHH; + double lastLL = mLastHLL; + + // + double mHHState = EMPTY_VALUE; + double mhhColorIDX = mHideColorIDX; + if (showLevels) + { + // + if (hhValue == lastHH) + { + mhhColorIDX = showConsolidations ? 1 : mHideColorIDX; + } + else if (hhValue > lastHH) + { + mhhColorIDX = 2; + } + else if (hhValue < lastHH) + { + mhhColorIDX = 3; + } + + // + mHHState = mhhColorIDX; + } + else + { + mhhColorIDX = mHideColorIDX; + } + + // + double mLLState = EMPTY_VALUE; + double mllColorIDX = mHideColorIDX; + if (showLevels) + { + // + if (llValue == lastLL) + { + mllColorIDX = showConsolidations ? 1 : mHideColorIDX; + } + else if (llValue > lastLL) + { + mllColorIDX = 2; + } + else if (llValue < lastLL) + { + mllColorIDX = 3; + } + + // + mLLState = mllColorIDX; + } + else + { + mllColorIDX = mHideColorIDX; + } + + // + mLastHHH = hhValue; + mLastHLL = llValue; + + // + hHHBuffer[bar_index] = hhValue; + hLLBuffer[bar_index] = llValue; + hHHStateBuffer[bar_index] = mHHState; + hLLStateBuffer[bar_index] = mLLState; + hHHColorBuffer[bar_index] = mhhColorIDX; + hLLColorBuffer[bar_index] = mllColorIDX; +} + +// +// Calculate Peaks and Values ... +void CalculatePeaksAndVales( + int bar_index // Bar Index +) +{ + // + // Retrieve Requirements ... + + // + // Short ... + double sHHValue = sHHBuffer[bar_index]; + double sLLValue = sLLBuffer[bar_index]; + + // + // Medium ... + double mHHValue = mHHBuffer[bar_index]; + double mLLValue = mLLBuffer[bar_index]; + + // + // Long ... + double lHHValue = lHHBuffer[bar_index]; + double lLLValue = lLLBuffer[bar_index]; + + // + // Hind ... + double hHHValue = hHHBuffer[bar_index]; + double hLLValue = hLLBuffer[bar_index]; + + // + double rColorIDX = mHideColorIDX; + double sColorIDX = mHideColorIDX; + + // + // RESISTANCE ... + double rValue = (sHHValue + mHHValue + lHHValue + hHHValue) / 4; + + // + // PEAKS ... + bool isPeak = rValue == hHHValue && + hHHValue == lHHValue && + lHHValue == mHHValue && + mHHValue == sHHValue; + + // + if (isPeak && lastPeak != rValue) + { + // + rColorIDX = 1; + lastPeak = rValue; + peaksStateBuffer[bar_index] = rColorIDX; + } + else + { + peaksStateBuffer[bar_index] = EMPTY_VALUE; + } + + // + // SUPPORT ... + double sValue = (sLLValue + mLLValue + lLLValue + hLLValue) / 4; + + // + // VALES ... + bool isVale = sValue == hLLValue && + hLLValue == lLLValue && + lLLValue == mLLValue && + mLLValue == sLLValue; + + // + if (isVale && lastVale != sValue) + { + // + sColorIDX = 1; + lastVale = sValue; + valesStateBuffer[bar_index] = sColorIDX; + } + else + { + valesStateBuffer[bar_index] = EMPTY_VALUE; + } + + // + rBuffer[bar_index] = rValue; + sBuffer[bar_index] = sValue; + peaksBuffer[bar_index] = lastPeak; + valesBuffer[bar_index] = lastVale; + + // + if (showPeaksAndVales) + { + // + rColorBuffer[bar_index] = rColorIDX; + sColorBuffer[bar_index] = sColorIDX; + } + else + { + // + rColorBuffer[bar_index] = mHideColorIDX; + sColorBuffer[bar_index] = mHideColorIDX; + } +} + +// +// Calculate Fibonacci Level 1 ... +void CalculateFibonacci( + int bar_index // Bar Index +) +{ + // + // Select Requirements ... + double upPrice = peaksBuffer[bar_index]; + double downPrice = valesBuffer[bar_index]; + + // + // Level 1 ... + double fibLevel1Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel1, + 1); + // + // Level 2 ... + double fibLevel2Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel2, + 1); + + // + // Level 3 ... + double fibLevel3Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel3, + 1); + + // + fl1Buffer[bar_index] = fibLevel1Value; + fl2Buffer[bar_index] = fibLevel2Value; + fl3Buffer[bar_index] = fibLevel3Value; + + // + double fl1ColorIdx = showFibo1Levels ? 1 : mHideColorIDX; + double fl2ColorIdx = showFibo2Levels ? 1 : mHideColorIDX; + double fl3ColorIdx = showFibo3Levels ? 1 : mHideColorIDX; + + // + fl1ColorBuffer[bar_index] = fl1ColorIdx; + fl2ColorBuffer[bar_index] = fl2ColorIdx; + fl3ColorBuffer[bar_index] = fl3ColorIdx; +} + +// +// XSTR ... +bool CalculateXSTR( + const int rates_total, + const int prev_calculated, + const double &open[], + const double &high[], + const double &low[], + const double &close[] // +) +{ + // + bool result = false; + + // + int numOfRequiredAtrs; + if (prev_calculated > rates_total || prev_calculated < 0) + { + numOfRequiredAtrs = rates_total; + } + else + { + // + numOfRequiredAtrs = rates_total - prev_calculated; + if (prev_calculated > 0) + { + numOfRequiredAtrs++; + } + } + + // + // Checking for stop ... + if (IsStopped()) + { + return result; + } + + // + // Check Number of items Copy or not ... + int copiedATRs = CopyBuffer(atrHandler, 0, 0, numOfRequiredAtrs, atrBuffer); + if (copiedATRs <= 0) + { + return result; + } + + // + // + int limit; + + // + // checking for the limit start of calculation of an indicator ... + if (prev_calculated > rates_total || prev_calculated <= 0) + { + // + // starting index for calculation of all bars ... + limit = maxLength; + } + else + { + // + // starting number for calculation of new bars + limit = prev_calculated - 1; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + // + // Calculated Price ... + double price = GetAppliedPrice( + trendPriceAppliedTo, + open, + high, + low, + close, + i); + // price = (high[i] + low[i]) / 2; + priceBuffer[i] = price; + + // + double atr = atrBuffer[i]; + + // + // Up ... + upBuffer[i] = price + (trendMultiplier * atr); + + // + // Down ... + downBuffer[i] = price - (trendMultiplier * atr); + + // + if (close[i] > upBuffer[i - 1]) + { + // + trendStateBuffer[i] = 1; + if (trendStateBuffer[i - 1] == -1) + { + changeOfTrend = 1; + } + } + else if (close[i] < downBuffer[i - 1]) + { + // + trendStateBuffer[i] = -1; + if (trendStateBuffer[i - 1] == 1) + { + changeOfTrend = 1; + } + } + else if (trendStateBuffer[i - 1] == 1) + { + // + trendStateBuffer[i] = 1; + changeOfTrend = 0; + } + else if (trendStateBuffer[i - 1] == -1) + { + // + trendStateBuffer[i] = -1; + changeOfTrend = 0; + } + + // + // Down Trend Starting ... + if (trendStateBuffer[i] < 0 && trendStateBuffer[i - 1] > 0) + { + startBearishTrend = 1; + } + else + { + startBearishTrend = 0; + } + + // + // Up Trend Starting ... + if (trendStateBuffer[i] > 0 && trendStateBuffer[i - 1] < 0) + { + startBullishTrend = 1; + } + else + { + startBullishTrend = 0; + } + + // + if (trendStateBuffer[i] > 0 && downBuffer[i] < downBuffer[i - 1]) + { + downBuffer[i] = downBuffer[i - 1]; + } + + // + if (trendStateBuffer[i] < 0 && upBuffer[i] > upBuffer[i - 1]) + { + upBuffer[i] = upBuffer[i - 1]; + } + + // + if (startBearishTrend == 1) + { + upBuffer[i] = priceBuffer[i] + (trendMultiplier * atr); + } + + // + if (startBullishTrend == 1) + { + downBuffer[i] = priceBuffer[i] - (trendMultiplier * atr); + } + + // + // Draw the indicator ... + + // + double colorIDX = 0; + double state = EMPTY_VALUE; + trendColorBuffer[i] = colorIDX; + + // + if (trendStateBuffer[i] == 1) + { + // + trendBuffer[i] = downBuffer[i]; + if (changeOfTrend == 1) + { + // + trendBuffer[i - 1] = trendBuffer[i - 2]; + changeOfTrend = 0; + + // + state = 2; + } + + // + colorIDX = 1; + } + else if (trendStateBuffer[i] == -1) + { + // + trendBuffer[i] = upBuffer[i]; + if (changeOfTrend == 1) + { + // + trendBuffer[i - 1] = trendBuffer[i - 2]; + changeOfTrend = 0; + + // + state = 3; + } + + // + colorIDX = 2; + } + + // + if (showTrends) + { + trendColorBuffer[i] = colorIDX; + } + strTrendStateBuffer[i] = state; + + // + // Filling ... + if (fillTrends) + { + // + fillUpBuffer[i] = trendBuffer[i]; + fillDownBuffer[i] = close[i]; + } + else + { + // + fillUpBuffer[i] = EMPTY_VALUE; + fillDownBuffer[i] = EMPTY_VALUE; + } + } + + // + result = true; + + // + return true; +} + +// +XMRBColorInfo GetRibbonColorIndex( + double value, + const double h, + const double l // +) +{ + // + XMRBColorInfo result; + + // + result.state = EMPTY_VALUE; + result.clr = mHideColorIDX; + + // + // Color Indexes ... + // 0 => HIDE + // 1 => NEUTURAL + // 2 => BULLISH + // 3 => BEARISH + + // + result.clr = 1; + + // + if (value < l && value < h) + { + result.clr = 2; + } + else if (value > h && value > l) + { + result.clr = 3; + } + else if (value < h && value > l) + { + result.clr = 1; + } + + // + result.state = result.clr; + + // + if (!showRibbons) + { + result.clr = mHideColorIDX; + } + + // + return result; +} + +// +// Calculate Ribbons Color ... +void CalculateRibbonsColors( + int bar_index, // Bar Index + const double &high[], + const double &low[] // +) +{ + // + double tmpVal; + XMRBColorInfo tmpColorIDX; + + // + double h = high[bar_index]; + double l = low[bar_index]; + + // + // RIBBON 1 ... + tmpVal = ribbon1Buffer[bar_index]; + tmpColorIDX = GetRibbonColorIndex( + tmpVal, + h, + l); + rb1StateBuffer[bar_index] = tmpColorIDX.state; + ribbon1ColorBuffer[bar_index] = tmpColorIDX.clr; + + // + // RIBBON 2 ... + tmpVal = ribbon2Buffer[bar_index]; + tmpColorIDX = GetRibbonColorIndex( + tmpVal, + h, + l); + rb2StateBuffer[bar_index] = tmpColorIDX.state; + ribbon2ColorBuffer[bar_index] = tmpColorIDX.clr; + + // + // RIBBON 3 ... + tmpVal = ribbon3Buffer[bar_index]; + tmpColorIDX = GetRibbonColorIndex( + tmpVal, + h, + l); + rb3StateBuffer[bar_index] = tmpColorIDX.state; + ribbon3ColorBuffer[bar_index] = tmpColorIDX.clr; + + // + // RIBBON 4 ... + tmpVal = ribbon4Buffer[bar_index]; + tmpColorIDX = GetRibbonColorIndex( + tmpVal, + h, + l); + rb4StateBuffer[bar_index] = tmpColorIDX.state; + ribbon4ColorBuffer[bar_index] = tmpColorIDX.clr; + + // + // RIBBON 5 ... + tmpVal = ribbon5Buffer[bar_index]; + tmpColorIDX = GetRibbonColorIndex( + tmpVal, + h, + l); + rb5StateBuffer[bar_index] = tmpColorIDX.state; + ribbon5ColorBuffer[bar_index] = tmpColorIDX.clr; + + // + // RIBBON 6 ... + tmpVal = ribbon6Buffer[bar_index]; + tmpColorIDX = GetRibbonColorIndex( + tmpVal, + h, + l); + rb6StateBuffer[bar_index] = tmpColorIDX.state; + ribbon6ColorBuffer[bar_index] = tmpColorIDX.clr; +} + +// +// Calculate SSL Channel ... +void CalculateSSLC( + int bar_index, // Selected Bar Index + int limit, + int ratesTotal, + int prevCalculated, + const double &close[]) +{ + // + double upMaValue = sslcUpMaBuffer[bar_index]; + double downMaValue = sslcDownMaBuffer[bar_index]; + + // + double closeValue = close[bar_index]; + + // + double kpiValue; + if (closeValue > upMaValue) + { + kpiValue = 1; + } + else if (closeValue < downMaValue) + { + kpiValue = -1; + } + else + { + kpiValue = sslcKpiBuffer[bar_index + 1]; + } + + // + sslcKpiBuffer[bar_index] = kpiValue; + + // + double upValue = kpiValue < 0 ? downMaValue : upMaValue; + sslcUpBuffer[bar_index] = upValue; + + // + double downValue = kpiValue < 0 ? upMaValue : downMaValue; + sslcDownBuffer[bar_index] = downValue; + + // + if (showSSLChannel) + { + // + sslcUpColorBuffer[bar_index] = 1; + sslcDownColorBuffer[bar_index] = 1; + } + else + { + // + sslcUpColorBuffer[bar_index] = mHideColorIDX; + sslcDownColorBuffer[bar_index] = mHideColorIDX; + } +} + +// +// Calculate XHULL ... +void CalculateHull( + int bar_index, // Selected Bar Index + int ratesTotal, // Total Rates + double upPrice, // Up Price ... + double downPrice // Down Price ... +) +{ + // + double upValue = mUpZHull.Calculate( + upPrice, + bar_index, + ratesTotal); + hullUpZoneBuffer[bar_index] = upValue; + double upColorIDX = (bar_index > 0) + ? (hullUpZoneBuffer[bar_index] > hullUpZoneBuffer[bar_index - 1]) + ? 2 + : (hullUpZoneBuffer[bar_index] < hullUpZoneBuffer[bar_index - 1]) + ? 3 + : hullUpZoneColorBuffer[bar_index - 1] + : 1; + + // + double downValue = mDownZHull.Calculate( + downPrice, + bar_index, + ratesTotal); + hullDownZoneBuffer[bar_index] = downValue; + double downColorIDX = (bar_index > 0) + ? (hullDownZoneBuffer[bar_index] > hullDownZoneBuffer[bar_index - 1]) + ? 2 + : (hullDownZoneBuffer[bar_index] < hullDownZoneBuffer[bar_index - 1]) + ? 3 + : hullDownZoneColorBuffer[bar_index - 1] + : 1; + + // + if (showHull) + { + // + hullUpZoneColorBuffer[bar_index] = upColorIDX; + hullDownZoneColorBuffer[bar_index] = downColorIDX; + } + else + { + // + hullUpZoneColorBuffer[bar_index] = mHideColorIDX; + hullDownZoneColorBuffer[bar_index] = mHideColorIDX; + } +} + +// +// Calculate HikenAshi Buffers ... +void CalculateHikenAshi( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[]) +{ + // + double mPrevHKOpenValue; + double mPrevHKCloseValue; + + // + if (ArraySize(open) <= bar_index + 1) + { + // + mPrevHKOpenValue = 0; + mPrevHKCloseValue = 0; + } + else + { + // + mPrevHKOpenValue = hkOpenBuffer[bar_index + 1]; + mPrevHKCloseValue = hkCloseBuffer[bar_index + 1]; + } + + // + double mHKOpenValue = (mPrevHKOpenValue + mPrevHKCloseValue) / 2; + double mHKCloseValue = (open[bar_index] + high[bar_index] + close[bar_index] + low[bar_index]) / 4; + double mHKHighValue = MathMax(high[bar_index], MathMax(mHKOpenValue, mHKCloseValue)); + double mHKLowValue = MathMin(low[bar_index], MathMin(mHKOpenValue, mHKCloseValue)); + + // + hkOpenBuffer[bar_index] = mHKOpenValue; + hkHighBuffer[bar_index] = mHKHighValue; + hkLowBuffer[bar_index] = mHKLowValue; + hkCloseBuffer[bar_index] = mHKCloseValue; + + // + double candleColorValue = + mHKOpenValue < mHKCloseValue ? 1 : 2; + + // + hkStateBuffer[bar_index] = candleColorValue + 1; + hkCandleColorBuffer[bar_index] = showHKCandles ? candleColorValue : 0; +} + +// +// Calculate Candle Timer ... +void CalculateCandleTimer() +{ + // + if (!showCandleTimer) + { + return; + } + + // + XCandleRemains remainTime; + GetCandleRemainsTime( + remainTime, + _Symbol, + _Period, + 0); + + // + string msg = ToString( + remainTime, + "", + "", + "", + "", + "", + ":", + true); + + // + long mSpread = SymbolInfoInteger(Symbol(), SYMBOL_SPREAD); + + // + string _sp = ""; + if (mSpread < 10) + _sp = ".."; + else if (mSpread < 100) + _sp = "."; + + // + string objText = "Spread: " + IntegerToString(mSpread) + _sp + " Next Bar in: " + msg; + + // + ObjectSetString(0, ShortName, OBJPROP_TEXT, objText); + ObjectSetInteger(0, ShortName, OBJPROP_FONTSIZE, 10); + ObjectSetString(0, ShortName, OBJPROP_FONT, "Courier"); + ObjectSetInteger(0, ShortName, OBJPROP_COLOR, candleTimerColor); +} + +// +// END Calculation Parts ... +// + +// +// START Utilities ... +// + +// +// Create Candle Timer ... +void CreateIndicatorObject() +{ + // + if (!showCandleTimer) + { + return; + } + + // + ObjectCreate(0, ShortName, OBJ_LABEL, 0, 0, 0); + ObjectSetInteger(0, ShortName, OBJPROP_CORNER, candleTimerCorner); + ObjectSetInteger(0, ShortName, OBJPROP_XDISTANCE, 10); + ObjectSetInteger(0, ShortName, OBJPROP_YDISTANCE, 2); + + // + ENUM_ANCHOR_POINT Anchor = ANCHOR_LEFT_UPPER; + switch (candleTimerCorner) + { + case CORNER_LEFT_UPPER: + Anchor = ANCHOR_LEFT_UPPER; + break; + case CORNER_RIGHT_UPPER: + Anchor = ANCHOR_RIGHT_UPPER; + break; + case CORNER_LEFT_LOWER: + Anchor = ANCHOR_LEFT_LOWER; + break; + case CORNER_RIGHT_LOWER: + Anchor = ANCHOR_RIGHT_LOWER; + break; + } + + // + ObjectSetInteger(0, ShortName, OBJPROP_ANCHOR, Anchor); +} + +// +bool InitMaHandler( + int &handler, + int length, + ENUM_X_MA_METHOD mode, + ENUM_APPLIED_PRICE appliedTo) +{ + // + bool result = false; + + // + if (length <= 0) + { + return result; + } + + // + bool genericMethod = false; + ENUM_MA_METHOD method = NULL; + if (mode == X_MA_AMA) + { + // + handler = iAMA( + _Symbol, + _Period, + length, + mMRBAMAFast, + mMRBAMASlow, + 0, + appliedTo); + } + else if (mode == X_MA_EMA) + { + // + method = MODE_EMA; + genericMethod = true; + } + else if (mode == X_MA_LWMA) + { + // + method = MODE_LWMA; + genericMethod = true; + } + else if (mode == X_MA_SMA) + { + // + method = MODE_SMA; + genericMethod = true; + } + else if (mode == X_MA_SMMA) + { + // + method = MODE_SMMA; + genericMethod = true; + } + + // + if (genericMethod && handler == INVALID_HANDLE) + { + // + handler = iMA( + _Symbol, + _Period, + length, + 0, + method, + appliedTo); + } + + // + result = handler != INVALID_HANDLE; + + // + return result; +} + +// +// Retrieve Cycles Highest High ... +double GetCycleHH( + int bar_index, // Bar Index + ENUM_TIMEFRAMES period // Period +) +{ + // + datetime mCycleStartAt = GetPeriodStartTime( + _Symbol, + period); + + // + int mStartCycleBarIndex = iBarShift( + _Symbol, + _Period, + mCycleStartAt, + false); + + // + int mCycleCount = MathAbs(mStartCycleBarIndex - bar_index); + if (mCycleCount < 1) + { + mCycleCount = 1; + } + + // + // HIGH ... + int hhIndex = iHighest( + _Symbol, + _Period, + hhMode, + mCycleCount, + bar_index); + double result = GetAppliedPrice( + hhIndex, + hhMode); + + // + return result; +} + +// +// Retrieve Cycles Lowest Low ... +double GetCycleLL( + int bar_index, // Bar Index + ENUM_TIMEFRAMES period // Period +) +{ + // + datetime mCycleStartAt = GetPeriodStartTime( + _Symbol, + period); + + // + int mStartCycleBarIndex = iBarShift( + _Symbol, + _Period, + mCycleStartAt, + false); + + // + int mCycleCount = MathAbs(mStartCycleBarIndex - bar_index); + if (mCycleCount < 1) + { + mCycleCount = 1; + } + + // + // LOW ... + int llIndex = iLowest( + _Symbol, + _Period, + llMode, + mCycleCount, + bar_index); + double result = GetAppliedPrice( + llIndex, + llMode); + + // + return result; +} + +// +// Retrieve Cycles Highest High ... +double GetCycleHHC( + int bar_index, // Bar Index + ENUM_TIMEFRAMES period // Period +) +{ + // + int mCycleCount = 0; + if (period == mL1Period) + { + mCycleCount = mL1Candles; + } + else if (period == mL2Period) + { + mCycleCount = mL2Candles; + } + else if (period == mL3Period) + { + mCycleCount = mL3Candles; + } + else if (period == mL4Period) + { + mCycleCount = mL4Candles; + } + + // + // HIGH ... + int hhIndex = iHighest( + _Symbol, + _Period, + hhMode, + mCycleCount, + bar_index); + double result = GetAppliedPrice( + hhIndex, + hhMode); + + // + return result; +} + +// +// Retrieve Cycles Lowest Low ... +double GetCycleLLC( + int bar_index, // Bar Index + ENUM_TIMEFRAMES period // Period +) +{ + // + int mCycleCount = 0; + if (period == mL1Period) + { + mCycleCount = mL1Candles; + } + else if (period == mL2Period) + { + mCycleCount = mL2Candles; + } + else if (period == mL3Period) + { + mCycleCount = mL3Candles; + } + else if (period == mL4Period) + { + mCycleCount = mL4Candles; + } + + // + // LOW ... + int llIndex = iLowest( + _Symbol, + _Period, + llMode, + mCycleCount, + bar_index); + double result = GetAppliedPrice( + llIndex, + llMode); + + // + return result; +} + +// +string GenerateCyclesRepresentation() +{ + // + string result = ""; + + // + result += "C1: " + ToString(mL1Period) + "\n"; + result += "C2: " + ToString(mL2Period) + "\n"; + result += "C3: " + ToString(mL3Period) + "\n"; + result += "C4: " + ToString(mL4Period); + + // + return result; +} + +// +// Apply Custom Chart Style ... +void ApplyCustomChartStyle() +{ + // + // Read Current Chart Config and Store it ... + ReadChartStyle(); + + // + // After Reading Current Chart Style ... + // we have to Save Configs and Change Styles ... + clearStyle = chartStyle; + + // + clearStyle.upColor = CLR_NONE; + clearStyle.downColor = CLR_NONE; + clearStyle.lineColor = CLR_NONE; + clearStyle.bullishColor = CLR_NONE; + clearStyle.bearishColor = CLR_NONE; + + // + // Decide to Show or not Candles based on User Input ... + if (showCandles) + { + SetChartStyle(chartStyle); + } + else + { + SetChartStyle(clearStyle); + } +} + +// +// Read Previous Chart Style ... +void ReadChartStyle() +{ + // + // Retrieve Current Chart ID ... + long chartId = ChartID(); + chartStyle.chartId = chartId; + + // + // Retrieve Chart Mode ... + chartStyle.mode = (ENUM_CHART_MODE)ChartGetInteger(chartId, CHART_MODE); + + // + chartStyle.showBidLine = (bool)ChartGetInteger(chartId, CHART_SHOW_BID_LINE); + chartStyle.showAskLine = (bool)ChartGetInteger(chartId, CHART_SHOW_ASK_LINE); + chartStyle.showGrid = (bool)ChartGetInteger(chartId, CHART_SHOW_GRID); + chartStyle.showVolumes = (bool)ChartGetInteger(chartId, CHART_SHOW_VOLUMES); + chartStyle.showTradeLevels = (bool)ChartGetInteger(chartId, CHART_SHOW_TRADE_LEVELS); + chartStyle.autoScroll = (bool)ChartGetInteger(chartId, CHART_AUTOSCROLL); + chartStyle.quickNavigation = (bool)ChartGetInteger(chartId, CHART_QUICK_NAVIGATION); + + // + chartStyle.foreGroundColor = (color)ChartGetInteger(chartId, CHART_COLOR_FOREGROUND); + chartStyle.backGroundColor = (color)ChartGetInteger(chartId, CHART_COLOR_BACKGROUND); + chartStyle.upColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_UP); + chartStyle.downColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_DOWN); + chartStyle.bullishColor = (color)ChartGetInteger(chartId, CHART_COLOR_CANDLE_BULL); + chartStyle.bearishColor = (color)ChartGetInteger(chartId, CHART_COLOR_CANDLE_BEAR); + chartStyle.gridColor = (color)ChartGetInteger(chartId, CHART_COLOR_GRID); + chartStyle.bidLineColor = (color)ChartGetInteger(chartId, CHART_COLOR_BID); + chartStyle.askLineColor = (color)ChartGetInteger(chartId, CHART_COLOR_ASK); + chartStyle.stopColor = (color)ChartGetInteger(chartId, CHART_COLOR_STOP_LEVEL); + chartStyle.lineColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_LINE); + chartStyle.volumesColor = (color)ChartGetInteger(chartId, CHART_COLOR_VOLUME); + + // + chartStyle.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 Utilities ... +// + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xmrb.ex5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xmrb.ex5 new file mode 100644 index 0000000..88c89c7 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xmrb.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xmrb.mq5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xmrb.mq5 new file mode 100644 index 0000000..ffe9e2e --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xmrb.mq5 @@ -0,0 +1,786 @@ +////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// -------------------------------------- +// Name: X121_XMRB +// Description: Moving Average Ribbon +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121_XMRB Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_XMRB" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Ribbon 1"; +input int fast1Length = 3; // Fast +input int slow1Length = 5; // Slow + +// +input group "Ribbon 2"; +input int fast2Length = 8; // Fast +input int slow2Length = 13; // Slow + +// +input group "Ribbon 3"; +input int fast3Length = 21; // Fast +input int slow3Length = 34; // Slow + +// +input group "Ribbon 4"; +input int fast4Length = 55; // Fast +input int slow4Length = 89; // Slow + +// +input group "Ribbon 5"; +input int fast5Length = 144; // Fast +input int slow5Length = 233; // Slow + +// +input group "Calculation"; +input ENUM_MA_METHOD ribbonMode = MODE_EMA; // Mode +input ENUM_APPLIED_PRICE ribbonAppliedTo = PRICE_CLOSE; // Applied To + +// +input group "Presentation"; +input bool showFastMa = true; // Show Fast +input bool showSlowMa = true; // Show Slow +input bool showRibbon = false; // Show Ribbon + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 12 +#property indicator_plots 12 + +// +// PLOTTED Buffers ... + +// +// MA ... + +// +// FAST ... +#define fastMaBufferIndex 0 +double fastMaBuffer[]; + +// +#property indicator_label1 "X121_XMRB F" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrLime +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +// SLOW ... +#define slowMaBufferIndex 1 +double slowMaBuffer[]; + +// +#property indicator_label2 "X121_XMRB S" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrRed +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +// DATA Buffers ... + +// +// FAST ... + +// +#define fast1BufferIndex 2 +double fast1Buffer[]; + +// +#property indicator_label3 "X121_XMRB 1 F" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrAquamarine +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +#define fast2BufferIndex 3 +double fast2Buffer[]; + +// +#property indicator_label4 "X121_XMRB 2 F" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrAquamarine +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +#define fast3BufferIndex 4 +double fast3Buffer[]; + +// +#property indicator_label5 "X121_XMRB 3 F" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrAquamarine +#property indicator_style5 STYLE_DOT +#property indicator_width5 1 + +// +#define fast4BufferIndex 5 +double fast4Buffer[]; + +// +#property indicator_label6 "X121_XMRB 4 F" +#property indicator_type6 DRAW_LINE +#property indicator_color6 clrAquamarine +#property indicator_style6 STYLE_DOT +#property indicator_width6 1 + +// +#define fast5BufferIndex 6 +double fast5Buffer[]; + +// +#property indicator_label7 "X121_XMRB 5 F" +#property indicator_type7 DRAW_LINE +#property indicator_color7 clrAquamarine +#property indicator_style7 STYLE_DOT +#property indicator_width7 1 + +// +// SLOW ... + +// +#define slow1BufferIndex 7 +double slow1Buffer[]; + +// +#property indicator_label8 "X121_XMRB 1 S" +#property indicator_type8 DRAW_LINE +#property indicator_color8 clrPlum +#property indicator_style8 STYLE_DOT +#property indicator_width8 1 + +// +#define slow2BufferIndex 8 +double slow2Buffer[]; + +// +#property indicator_label9 "X121_XMRB 2 S" +#property indicator_type9 DRAW_LINE +#property indicator_color9 clrPlum +#property indicator_style9 STYLE_DOT +#property indicator_width9 1 + +// +#define slow3BufferIndex 9 +double slow3Buffer[]; + +// +#property indicator_label10 "X121_XMRB 3 S" +#property indicator_type10 DRAW_LINE +#property indicator_color10 clrPlum +#property indicator_style10 STYLE_DOT +#property indicator_width10 1 + +// +#define slow4BufferIndex 10 +double slow4Buffer[]; + +// +#property indicator_label11 "X121_XMRB 4 S" +#property indicator_type11 DRAW_LINE +#property indicator_color11 clrPlum +#property indicator_style11 STYLE_DOT +#property indicator_width11 1 + +// +#define slow5BufferIndex 11 +double slow5Buffer[]; + +// +#property indicator_label12 "X121_XMRB 5 S" +#property indicator_type12 DRAW_LINE +#property indicator_color12 clrPlum +#property indicator_style12 STYLE_DOT +#property indicator_width12 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int fast1MaHandler = INVALID_HANDLE; +int fast2MaHandler = INVALID_HANDLE; +int fast3MaHandler = INVALID_HANDLE; +int fast4MaHandler = INVALID_HANDLE; +int fast5MaHandler = INVALID_HANDLE; + +// +int slow1MaHandler = INVALID_HANDLE; +int slow2MaHandler = INVALID_HANDLE; +int slow3MaHandler = INVALID_HANDLE; +int slow4MaHandler = INVALID_HANDLE; +int slow5MaHandler = INVALID_HANDLE; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Initialize MAs ... + if (!InitializeMas()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + + // + IndicatorRelease(fast1MaHandler); + IndicatorRelease(fast2MaHandler); + IndicatorRelease(fast3MaHandler); + IndicatorRelease(fast4MaHandler); + IndicatorRelease(fast5MaHandler); + + // + IndicatorRelease(slow1MaHandler); + IndicatorRelease(slow2MaHandler); + IndicatorRelease(slow3MaHandler); + IndicatorRelease(slow4MaHandler); + IndicatorRelease(slow5MaHandler); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // Check Calculated Bars ... + // + int fast1MaCalculatedBars = BarsCalculated(fast1MaHandler); + int fast2MaCalculatedBars = BarsCalculated(fast2MaHandler); + int fast3MaCalculatedBars = BarsCalculated(fast3MaHandler); + int fast4MaCalculatedBars = BarsCalculated(fast4MaHandler); + int fast5MaCalculatedBars = BarsCalculated(fast5MaHandler); + // + int slow1MaCalculatedBars = BarsCalculated(slow1MaHandler); + int slow2MaCalculatedBars = BarsCalculated(slow2MaHandler); + int slow3MaCalculatedBars = BarsCalculated(slow3MaHandler); + int slow4MaCalculatedBars = BarsCalculated(slow4MaHandler); + int slow5MaCalculatedBars = BarsCalculated(slow5MaHandler); + if ( + fast1MaCalculatedBars < maxLength || + fast2MaCalculatedBars < maxLength || + fast3MaCalculatedBars < maxLength || + fast4MaCalculatedBars < maxLength || + fast5MaCalculatedBars < maxLength || + slow1MaCalculatedBars < maxLength || + slow2MaCalculatedBars < maxLength || + slow3MaCalculatedBars < maxLength || + slow4MaCalculatedBars < maxLength || + slow5MaCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + // + int copiedFast1Mas = CopyBuffer(fast1MaHandler, 0, 0, limit, fast1Buffer); + int copiedFast2Mas = CopyBuffer(fast2MaHandler, 0, 0, limit, fast2Buffer); + int copiedFast3Mas = CopyBuffer(fast3MaHandler, 0, 0, limit, fast3Buffer); + int copiedFast4Mas = CopyBuffer(fast4MaHandler, 0, 0, limit, fast4Buffer); + int copiedFast5Mas = CopyBuffer(fast5MaHandler, 0, 0, limit, fast5Buffer); + // + int copiedSlow1Mas = CopyBuffer(slow1MaHandler, 0, 0, limit, slow1Buffer); + int copiedSlow2Mas = CopyBuffer(slow2MaHandler, 0, 0, limit, slow2Buffer); + int copiedSlow3Mas = CopyBuffer(slow3MaHandler, 0, 0, limit, slow3Buffer); + int copiedSlow4Mas = CopyBuffer(slow4MaHandler, 0, 0, limit, slow4Buffer); + int copiedSlow5Mas = CopyBuffer(slow5MaHandler, 0, 0, limit, slow5Buffer); + if ( + copiedFast1Mas <= 0 || + copiedFast2Mas <= 0 || + copiedFast3Mas <= 0 || + copiedFast4Mas <= 0 || + copiedFast5Mas <= 0 || + copiedSlow1Mas <= 0 || + copiedSlow2Mas <= 0 || + copiedSlow3Mas <= 0 || + copiedSlow4Mas <= 0 || + copiedSlow5Mas <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateBuffers(i); + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + (fast1Length > 2 && + fast2Length > fast1Length && + fast3Length > fast2Length && + fast4Length > fast3Length && + fast5Length > fast4Length && + slow1Length > fast1Length && + slow2Length > fast2Length && + slow3Length > fast3Length && + slow4Length > fast4Length && + slow5Length > fast5Length && + slow2Length > slow1Length && + slow3Length > slow2Length && + slow4Length > slow3Length && + slow5Length > slow4Length + // + ) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Ma ... + + // + result = MathMax(fast1Length, fast2Length); + result = MathMax(result, fast3Length); + result = MathMax(result, fast4Length); + result = MathMax(result, fast5Length); + + // + result = MathMax(result, slow1Length); + result = MathMax(result, slow2Length); + result = MathMax(result, slow3Length); + result = MathMax(result, slow4Length); + result = MathMax(result, slow5Length); + + // + return result; +} + +// +// Initialize Ma Handlers ... +bool InitializeMas() +{ + // + bool result = false; + + // + fast1MaHandler = iMA( + _Symbol, + _Period, + fast1Length, + 0, + ribbonMode, + ribbonAppliedTo); + fast2MaHandler = iMA( + _Symbol, + _Period, + fast2Length, + 0, + ribbonMode, + ribbonAppliedTo); + fast3MaHandler = iMA( + _Symbol, + _Period, + fast3Length, + 0, + ribbonMode, + ribbonAppliedTo); + fast4MaHandler = iMA( + _Symbol, + _Period, + fast4Length, + 0, + ribbonMode, + ribbonAppliedTo); + fast5MaHandler = iMA( + _Symbol, + _Period, + fast5Length, + 0, + ribbonMode, + ribbonAppliedTo); + + // + slow1MaHandler = iMA( + _Symbol, + _Period, + slow1Length, + 0, + ribbonMode, + ribbonAppliedTo); + slow2MaHandler = iMA( + _Symbol, + _Period, + slow2Length, + 0, + ribbonMode, + ribbonAppliedTo); + slow3MaHandler = iMA( + _Symbol, + _Period, + slow3Length, + 0, + ribbonMode, + ribbonAppliedTo); + slow4MaHandler = iMA( + _Symbol, + _Period, + slow4Length, + 0, + ribbonMode, + ribbonAppliedTo); + slow5MaHandler = iMA( + _Symbol, + _Period, + slow5Length, + 0, + ribbonMode, + ribbonAppliedTo); + + // + result = + fast1MaHandler != INVALID_HANDLE && + fast2MaHandler != INVALID_HANDLE && + fast3MaHandler != INVALID_HANDLE && + fast4MaHandler != INVALID_HANDLE && + fast5MaHandler != INVALID_HANDLE && + slow1MaHandler != INVALID_HANDLE && + slow2MaHandler != INVALID_HANDLE && + slow3MaHandler != INVALID_HANDLE && + slow4MaHandler != INVALID_HANDLE && + slow5MaHandler != INVALID_HANDLE; + + // + if (!result) + { + // + string message = "Error Initializing Handlers ..."; + Print(message); + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // FAST ... + ENUM_DRAW_TYPE fastDrawType = showFastMa ? DRAW_LINE : DRAW_NONE; + + ArraySetAsSeries(fastMaBuffer, true); + SetIndexBuffer(fastMaBufferIndex, fastMaBuffer, INDICATOR_DATA); + PlotIndexSetInteger(fastMaBufferIndex, PLOT_SHOW_DATA, showFastMa); + PlotIndexSetInteger(fastMaBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fastMaBufferIndex, PLOT_DRAW_TYPE, fastDrawType); + + // + // SLOW ... + ENUM_DRAW_TYPE slowDrawType = showSlowMa ? DRAW_LINE : DRAW_NONE; + + ArraySetAsSeries(slowMaBuffer, true); + SetIndexBuffer(slowMaBufferIndex, slowMaBuffer, INDICATOR_DATA); + PlotIndexSetInteger(slowMaBufferIndex, PLOT_SHOW_DATA, showSlowMa); + PlotIndexSetInteger(slowMaBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slowMaBufferIndex, PLOT_DRAW_TYPE, slowDrawType); + + // + // DATA ... + ENUM_DRAW_TYPE ribbonDrawType = showRibbon ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(fast1Buffer, true); + SetIndexBuffer(fast1BufferIndex, fast1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fast1BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(fast1BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fast1BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(fast2Buffer, true); + SetIndexBuffer(fast2BufferIndex, fast2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fast2BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(fast2BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fast2BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(fast3Buffer, true); + SetIndexBuffer(fast3BufferIndex, fast3Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fast3BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(fast3BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fast3BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(fast4Buffer, true); + SetIndexBuffer(fast4BufferIndex, fast4Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fast4BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(fast4BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fast4BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(fast5Buffer, true); + SetIndexBuffer(fast5BufferIndex, fast5Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fast5BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(fast5BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fast5BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(slow1Buffer, true); + SetIndexBuffer(slow1BufferIndex, slow1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(slow1BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(slow1BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slow1BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(slow2Buffer, true); + SetIndexBuffer(slow2BufferIndex, slow2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(slow2BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(slow2BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slow2BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(slow3Buffer, true); + SetIndexBuffer(slow3BufferIndex, slow3Buffer, INDICATOR_DATA); + PlotIndexSetInteger(slow3BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(slow3BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slow3BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(slow4Buffer, true); + SetIndexBuffer(slow4BufferIndex, slow4Buffer, INDICATOR_DATA); + PlotIndexSetInteger(slow4BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(slow4BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slow4BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(slow5Buffer, true); + SetIndexBuffer(slow5BufferIndex, slow5Buffer, INDICATOR_DATA); + PlotIndexSetInteger(slow5BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(slow5BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slow5BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); +} + +// +// 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 +) +{ + // + // Retireve Values ... + + // + double fast1Value = fast1Buffer[bar_index]; + double fast2Value = fast2Buffer[bar_index]; + double fast3Value = fast3Buffer[bar_index]; + double fast4Value = fast4Buffer[bar_index]; + double fast5Value = fast5Buffer[bar_index]; + + // + double slow1Value = slow1Buffer[bar_index]; + double slow2Value = slow2Buffer[bar_index]; + double slow3Value = slow3Buffer[bar_index]; + double slow4Value = slow4Buffer[bar_index]; + double slow5Value = slow5Buffer[bar_index]; + + // + double fastValue = (fast1Value + fast2Value + fast3Value + fast4Value + fast5Value) / 5; + fastMaBuffer[bar_index] = fastValue; + + // + double slowValue = (slow1Value + slow2Value + slow3Value + slow4Value + slow5Value) / 5; + slowMaBuffer[bar_index] = slowValue; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xosc.ex5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xosc.ex5 new file mode 100644 index 0000000..c8b699f Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xosc.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xosc.mq5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xosc.mq5 new file mode 100644 index 0000000..0f0f9ef --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xosc.mq5 @@ -0,0 +1,721 @@ +////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: X121_XOSC +// Description: provides some oscillator values +// as empty Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121_XAMA Indicator" +#property strict + +// +// START Constants ... +// + +#define ShortName "X121_XOSC" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +// ATR ... +input group "ATR"; +input int atrLength = 14; // Length + +// +// RVI ... +// The buffer numbers are the following: 0 - MAIN_LINE, 1 - SIGNAL_LINE. +input group "RVI"; +input int rviLength = 10; // Length + +// +// BULLPOWER ... +input group "Bulls Power"; +input int bullpLength = 13; // Length + +// +// BEARPOWER ... +input group "Bears Power"; +input int bearpLength = 13; // Length + +// +// VOLUME ... +input group "Volumes"; +input ENUM_APPLIED_VOLUME volumeAppliedTo = VOLUME_TICK; // Applied To + +// +// RSI ... +input group "RSI"; +input int rsiLength = 14; // Length +input ENUM_APPLIED_PRICE rsiAppliedTo = PRICE_CLOSE; // Applied To + +// +// CCI ... +input group "CCI"; +input int cciLength = 14; // Length +input ENUM_APPLIED_PRICE cciAppliedTo = PRICE_TYPICAL; // Applied To + +// +// STDDEV ... +input group "Standard Deviation"; +input int stddevLength = 20; // Length +input int stddevShift = 0; // Shift +input ENUM_MA_METHOD stddevMethod = MODE_SMA; // Mode +input ENUM_APPLIED_PRICE stddevAppliedTo = PRICE_CLOSE; // AppliedTo + +// +// MOMENTUM ... +input group "Momentum"; +input int momentumLength = 14; // Length +input ENUM_APPLIED_PRICE momentumAppliedTo = PRICE_CLOSE; // Applied To + +// +// SAR ... +input group "SAR"; +input double sarStep = 0.02; // Step +input double sarMaximum = 0.2; // Maximum + +// +// MACD ... +// The buffer numbers are the following: 0 - MAIN_LINE, 1 - SIGNAL_LINE. +input group "MACD"; +input int macdFastLength = 12; // Fast Length +input int macdSlowLength = 26; // Slow Length +input int macdSignaLength = 9; // Signal Length +input ENUM_APPLIED_PRICE macdAppliedTo = PRICE_CLOSE; // Applied To + +// +// STOCHASTIC ... +// The buffer numbers: 0 - MAIN_LINE, 1 - SIGNAL_LINE. +input group "Stochastic"; +input int stochKLength = 5; // K Length +input int stochDLength = 3; // D Length +input int stochSlowing = 3; // Slowing +input ENUM_MA_METHOD stochMaMethod = MODE_SMA; // Ma Method +input ENUM_STO_PRICE stochMode = STO_LOWHIGH; // Calculation Mode + +// +// END Inputs ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 15 +#property indicator_plots 0 + +// +// ATR ... +#define atrBufferIndex 0 +double atrBuffer[]; + +// +// RVI ... +#define rviMainBufferIndex 1 +#define rviSignalBufferIndex 2 +double rviMainBuffer[]; +double rviSignalBuffer[]; + +// +// BULLPOWER ... +#define bullPBufferIndex 3 +double bullPBuffer[]; + +// +// BEARPOWER ... +#define bearPBufferIndex 4 +double bearPBuffer[]; + +// +// VOLUME ... +#define volumeBufferIndex 5 +double volumeBuffer[]; + +// +// RSI ... +#define rsiBufferIndex 6 +double rsiBuffer[]; + +// +// CCI ... +#define cciBufferIndex 7 +double cciBuffer[]; + +// +// MOMENTUM ... +#define momentumBufferIndex 8 +double momentumBuffer[]; + +// +// SAR ... +#define sarBufferIndex 9 +double sarBuffer[]; + +// +// MACD ... +#define macdMainBufferIndex 10 +#define macdSignalBufferIndex 11 +double macdMainBuffer[]; +double macdSignalBuffer[]; + +// +// STOCHASTIC ... +#define stochMainBufferIndex 12 +#define stochSignalBufferIndex 13 +double stochMainBuffer[]; +double stochSignalBuffer[]; + +// +// STANDARDDEVIATION ... +#define stddevBufferIndex 14 +double stddevBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int atrHandler = INVALID_HANDLE; +int rviHandler = INVALID_HANDLE; +int bullPHandler = INVALID_HANDLE; +int bearPHandler = INVALID_HANDLE; +int volumeHandler = INVALID_HANDLE; +int rsiHandler = INVALID_HANDLE; +int cciHandler = INVALID_HANDLE; +int momentumHandler = INVALID_HANDLE; +int sarHandler = INVALID_HANDLE; +int macdHandler = INVALID_HANDLE; +int stochHandler = INVALID_HANDLE; +int stddevHandler = INVALID_HANDLE; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Initializing Handlers ... + + // + // ATR ... + atrHandler = iATR( + _Symbol, + _Period, + atrLength); + + // + // RVI ... + rviHandler = iRVI( + _Symbol, + _Period, + rviLength); + + // + // BULLSPOWER ... + bullPHandler = iBullsPower( + _Symbol, + _Period, + bullpLength); + + // + // BEARSPOWER ... + bearPHandler = iBearsPower( + _Symbol, + _Period, + bullpLength); + + // + // VOLUMES ... + volumeHandler = iVolumes( + _Symbol, + _Period, + volumeAppliedTo); + + // + // RSI ... + rsiHandler = iRSI( + _Symbol, + _Period, + rsiLength, + rsiAppliedTo); + + // + // CCI ... + cciHandler = iCCI( + _Symbol, + _Period, + cciLength, + cciAppliedTo); + + // + // MOMENTUM ... + momentumHandler = iMomentum( + _Symbol, + _Period, + momentumLength, + momentumAppliedTo); + + // + // SAR ... + sarHandler = iSAR( + _Symbol, + _Period, + sarStep, + sarMaximum); + + // + // MACD ... + macdHandler = iMACD( + _Symbol, + _Period, + macdFastLength, + macdSlowLength, + macdSignaLength, + macdAppliedTo); + + // + // STOCHASTIC ... + stochHandler = iStochastic( + _Symbol, + _Period, + stochKLength, + stochDLength, + stochSlowing, + stochMaMethod, + stochMode); + + // + // STANDARDDEVIATION ... + stddevHandler = iStdDev( + _Symbol, + _Period, + stddevLength, + stddevShift, + stddevMethod, + stddevAppliedTo); + + // + bool isAllHandlersInit = + // + atrHandler != INVALID_HANDLE && + rviHandler != INVALID_HANDLE && + bullPHandler != INVALID_HANDLE && + bearPHandler != INVALID_HANDLE && + volumeHandler != INVALID_HANDLE && + rsiHandler != INVALID_HANDLE && + cciHandler != INVALID_HANDLE && + momentumHandler != INVALID_HANDLE && + sarHandler != INVALID_HANDLE && + macdHandler != INVALID_HANDLE && + stochHandler != INVALID_HANDLE && + stddevHandler != INVALID_HANDLE + // + ; + if (!isAllHandlersInit) + { + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + IndicatorRelease(atrHandler); + IndicatorRelease(rviHandler); + IndicatorRelease(bullPHandler); + IndicatorRelease(bearPHandler); + IndicatorRelease(volumeHandler); + IndicatorRelease(rsiHandler); + IndicatorRelease(cciHandler); + IndicatorRelease(momentumHandler); + IndicatorRelease(sarHandler); + IndicatorRelease(macdHandler); + IndicatorRelease(stochHandler); + IndicatorRelease(stddevHandler); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // Check Calculated Bars ... + int atrCalculatedBars = BarsCalculated(atrHandler); + int rviCalculatedBars = BarsCalculated(rviHandler); + int bullPCalculatedBars = BarsCalculated(bullPHandler); + int bearPCalculatedBars = BarsCalculated(bearPHandler); + int volumeCalculatedBars = BarsCalculated(volumeHandler); + int rsiCalculatedBars = BarsCalculated(rsiHandler); + int cciCalculatedBars = BarsCalculated(cciHandler); + int momentumCalculatedBars = BarsCalculated(momentumHandler); + int sarCalculatedBars = BarsCalculated(sarHandler); + int macdCalculatedBars = BarsCalculated(macdHandler); + int stochCalculatedBars = BarsCalculated(stochHandler); + int stddevCalculatedBars = BarsCalculated(stddevHandler); + + // + bool isCalculatedBarsPassed = + // + atrCalculatedBars >= maxLength && + rviCalculatedBars >= maxLength && + bullPCalculatedBars >= maxLength && + bearPCalculatedBars >= maxLength && + volumeCalculatedBars >= maxLength && + rsiCalculatedBars >= maxLength && + cciCalculatedBars >= maxLength && + momentumCalculatedBars >= maxLength && + sarCalculatedBars >= maxLength && + macdCalculatedBars >= maxLength && + stochCalculatedBars >= maxLength && + stddevCalculatedBars >= maxLength + // + ; + if (!isCalculatedBarsPassed) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int atrCopiedItems = CopyBuffer(atrHandler, 0, 0, limit, atrBuffer); + int rviMainCopiedItems = CopyBuffer(rviHandler, MAIN_LINE, 0, limit, rviMainBuffer); + int rviSignalCopiedItems = CopyBuffer(rviHandler, SIGNAL_LINE, 0, limit, rviSignalBuffer); + int bullPCopiedItems = CopyBuffer(bullPHandler, 0, 0, limit, bullPBuffer); + int bearPCopiedItems = CopyBuffer(bearPHandler, 0, 0, limit, bearPBuffer); + int volumeCopiedItems = CopyBuffer(volumeHandler, 0, 0, limit, volumeBuffer); + int rsiCopiedItems = CopyBuffer(rsiHandler, 0, 0, limit, rsiBuffer); + int cciCopiedItems = CopyBuffer(cciHandler, 0, 0, limit, cciBuffer); + int momentumCopiedItems = CopyBuffer(momentumHandler, 0, 0, limit, momentumBuffer); + int sarCopiedItems = CopyBuffer(sarHandler, 0, 0, limit, sarBuffer); + int macdMainCopiedItems = CopyBuffer(macdHandler, MAIN_LINE, 0, limit, macdMainBuffer); + int macdSignalCopiedItems = CopyBuffer(macdHandler, SIGNAL_LINE, 0, limit, macdSignalBuffer); + int stochMainCopiedItems = CopyBuffer(stochHandler, MAIN_LINE, 0, limit, stochMainBuffer); + int stocSignalhCopiedItems = CopyBuffer(stochHandler, SIGNAL_LINE, 0, limit, stochSignalBuffer); + int stddevCopiedItems = CopyBuffer(stddevHandler, 0, 0, limit, stddevBuffer); + + // + bool isCopiedBarsPassed = + // + atrCopiedItems > 0 && + rviMainCopiedItems > 0 && + rviSignalCopiedItems > 0 && + bullPCopiedItems > 0 && + bearPCopiedItems > 0 && + volumeCopiedItems > 0 && + rsiCopiedItems > 0 && + cciCopiedItems > 0 && + momentumCopiedItems > 0 && + sarCopiedItems > 0 && + macdMainCopiedItems > 0 && + macdSignalCopiedItems > 0 && + stochMainCopiedItems > 0 && + stocSignalhCopiedItems > 0 && + stddevCopiedItems > 0 + // + ; + if (!isCopiedBarsPassed) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + // Do Buffers Calculation ... + // HERE We Do Not anything ... + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + result = + // + atrLength >= 2 && + rviLength >= 2 && + bullpLength >= 2 && + bearpLength >= 2 && + rsiLength >= 2 && + cciLength >= 2 && + momentumLength >= 2 && + sarStep > 0 && + sarStep < sarMaximum && + macdFastLength >= 2 && + macdSlowLength > macdFastLength && + macdSignaLength >= 2 && + stochKLength >= 2 && + stochDLength >= 2 && + stochSlowing >= 2 && + stddevLength >= 2 && + stddevShift >= 0 + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(atrLength, rviLength); + result = MathMax(result, bullpLength); + result = MathMax(result, bearpLength); + result = MathMax(result, rsiLength); + result = MathMax(result, cciLength); + result = MathMax(result, momentumLength); + result = MathMax(result, macdFastLength); + result = MathMax(result, macdSlowLength); + result = MathMax(result, macdSignaLength); + result = MathMax(result, stochKLength); + result = MathMax(result, stochDLength); + result = MathMax(result, stochSlowing); + result = MathMax(result, stddevLength); + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // DATA Buffers ... + + // + // ATR ... + ArraySetAsSeries(atrBuffer, true); + SetIndexBuffer(atrBufferIndex, atrBuffer, INDICATOR_CALCULATIONS); + + // + // RVI ... + + // + // Main ... + ArraySetAsSeries(rviMainBuffer, true); + SetIndexBuffer(rviMainBufferIndex, rviMainBuffer, INDICATOR_CALCULATIONS); + + // + // Signal ... + ArraySetAsSeries(rviSignalBuffer, true); + SetIndexBuffer(rviSignalBufferIndex, rviSignalBuffer, INDICATOR_CALCULATIONS); + + // + // BULLPOWER ... + ArraySetAsSeries(bullPBuffer, true); + SetIndexBuffer(bullPBufferIndex, bullPBuffer, INDICATOR_CALCULATIONS); + + // + // BEARPOWER ... + ArraySetAsSeries(bearPBuffer, true); + SetIndexBuffer(bearPBufferIndex, bearPBuffer, INDICATOR_CALCULATIONS); + + // + // VOLUME ... + ArraySetAsSeries(volumeBuffer, true); + SetIndexBuffer(volumeBufferIndex, volumeBuffer, INDICATOR_CALCULATIONS); + + // + // RSI ... + ArraySetAsSeries(rsiBuffer, true); + SetIndexBuffer(rsiBufferIndex, rsiBuffer, INDICATOR_CALCULATIONS); + + // + // CCI ... + ArraySetAsSeries(cciBuffer, true); + SetIndexBuffer(cciBufferIndex, cciBuffer, INDICATOR_CALCULATIONS); + + // + // MOMENTUM ... + ArraySetAsSeries(momentumBuffer, true); + SetIndexBuffer(momentumBufferIndex, momentumBuffer, INDICATOR_CALCULATIONS); + + // + // SAR ... + ArraySetAsSeries(sarBuffer, true); + SetIndexBuffer(sarBufferIndex, sarBuffer, INDICATOR_CALCULATIONS); + + // + // STANDARDDEVIATION ... + ArraySetAsSeries(stddevBuffer, true); + SetIndexBuffer(stddevBufferIndex, stddevBuffer, INDICATOR_CALCULATIONS); + + // + // MACD ... + + // + // Main ... + ArraySetAsSeries(macdMainBuffer, true); + SetIndexBuffer(macdMainBufferIndex, macdMainBuffer, INDICATOR_CALCULATIONS); + + // + // Signal ... + ArraySetAsSeries(macdSignalBuffer, true); + SetIndexBuffer(macdSignalBufferIndex, macdSignalBuffer, INDICATOR_CALCULATIONS); +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xpv.ex5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xpv.ex5 new file mode 100644 index 0000000..6bfb4db Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xpv.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xpv.mq5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xpv.mq5 new file mode 100644 index 0000000..6110e12 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xpv.mq5 @@ -0,0 +1,992 @@ +/////////////////////////////////////////////////////// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------- +// Name: X121_XPV +// Description: Market Peaks and Vales +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121_XPV Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_XPV" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Makret Cycles"; +input int shortLength = 9; // Short Length +input int mediumLength = 17; // Medium Length +input int longLength = 26; // Long Length +input int hindLength = 35; // Hind Length +input double fiboLevel1 = 0.382; // Fibio 1st Level +input double fiboLevel2 = 0.5; // Fibio 2st Level +input double fiboLevel3 = 0.618; // Fibio 3rd Level + +// +input group "Detection Modes"; +input ENUM_SERIESMODE hhMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE llMode = MODE_LOW; // Lowest Low Calculation Method + +// +input group "Presentation"; +input bool showPeaksAndVales = true; // Show Peaks and Vales +input bool showLevels = false; // Show Levels +input bool showFibo1Levels = true; // Show Fibo 1st Level +input bool showFibo2Levels = true; // Show Fibo 2nd Level +input bool showFibo3Levels = true; // Show Fibo 3rd Level + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 26 +#property indicator_plots 18 + +// +// PEKSANDVALES ... + +// +// PEAKS ... + +// +#define peaksBufferIndex 0 +double peaksBuffer[]; + +// +#property indicator_label1 "X121_XPV PEAKS" +#property indicator_type1 DRAW_ARROW +#property indicator_color1 clrAqua +#property indicator_width1 1 + +// +// VALES ... + +// +#define valesBufferIndex 1 +double valesBuffer[]; + +// +#property indicator_label2 "X121_XPV VALES" +#property indicator_type2 DRAW_ARROW +#property indicator_color2 clrMagenta +#property indicator_width2 1 + +// +#define rBufferIndex 2 +double rBuffer[]; + +// +#define rColorBufferIndex 3 +double rColorBuffer[]; + +// +#property indicator_label3 "X121_XPV R" +#property indicator_type3 DRAW_COLOR_LINE +#property indicator_color3 clrAqua, CLR_NONE +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +#define sBufferIndex 4 +#define sBufferPlotIndex 3 +double sBuffer[]; + +// +#define sColorBufferIndex 5 +double sColorBuffer[]; + +// +#property indicator_label4 "X121_XPV S" +#property indicator_type4 DRAW_COLOR_LINE +#property indicator_color4 clrMagenta, CLR_NONE +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +// FIBBO Level 1 ... + +// +#define fl1BufferIndex 6 +#define fl1BufferPlotIndex 4 +double fl1Buffer[]; + +// +#define fl1ColorBufferIndex 7 +double fl1ColorBuffer[]; + +// +#property indicator_label5 "X121_XPV FL1" +#property indicator_type5 DRAW_COLOR_LINE +#property indicator_color5 CLR_NONE, clrGold +#property indicator_style5 STYLE_DASHDOTDOT +#property indicator_width5 1 + +// +// FIBBO Level 2 ... + +// +#define fl2BufferIndex 8 +#define fl2BufferPlotIndex 5 +double fl2Buffer[]; + +// +#define fl2ColorBufferIndex 9 +double fl2ColorBuffer[]; + +// +#property indicator_label6 "X121_XPV FL2" +#property indicator_type6 DRAW_COLOR_LINE +#property indicator_color6 CLR_NONE, clrGold +#property indicator_style6 STYLE_DASHDOTDOT +#property indicator_width6 1 + +// +// FIBBO Level 3 ... + +// +#define fl3BufferIndex 10 +#define fl3BufferPlotIndex 6 +double fl3Buffer[]; + +// +#define fl3ColorBufferIndex 11 +double fl3ColorBuffer[]; + +// +#property indicator_label7 "X121_XPV FL3" +#property indicator_type7 DRAW_COLOR_LINE +#property indicator_color7 CLR_NONE, clrGold +#property indicator_style7 STYLE_DASHDOTDOT +#property indicator_width7 1 + +// +// LEVELS ... + +// +#define sHHBufferIndex 12 +#define sHHBufferPlotIndex 7 +double sHHBuffer[]; + +// +#property indicator_label8 "X121_XPV SHH" +#property indicator_type8 DRAW_LINE +#property indicator_color8 clrLightGray +#property indicator_style8 STYLE_DOT +#property indicator_width8 1 + +#define sLLBufferIndex 13 +#define sLLBufferPlotIndex 8 +double sLLBuffer[]; + +// +#property indicator_label9 "X121_XPV SLL" +#property indicator_type9 DRAW_LINE +#property indicator_color9 clrLightGray +#property indicator_style9 STYLE_DOT +#property indicator_width9 1 + +// +#define mHHBufferIndex 14 +#define mHHBufferPlotIndex 9 +double mHHBuffer[]; + +// +#property indicator_label10 "X121_XPV MHH" +#property indicator_type10 DRAW_LINE +#property indicator_color10 clrLightGray +#property indicator_style10 STYLE_DOT +#property indicator_width10 1 + +// +#define mLLBufferIndex 15 +#define mLLBufferPlotIndex 10 +double mLLBuffer[]; + +// +#property indicator_label11 "X121_XPV MLL" +#property indicator_type11 DRAW_LINE +#property indicator_color11 clrLightGray +#property indicator_style11 STYLE_DOT +#property indicator_width11 1 + +// +#define lHHBufferIndex 16 +#define lHHBufferPlotIndex 11 +double lHHBuffer[]; + +// +#property indicator_label12 "X121_XPV LHH" +#property indicator_type12 DRAW_LINE +#property indicator_color12 clrLightGray +#property indicator_style12 STYLE_DOT +#property indicator_width12 1 + +// +#define lLLBufferIndex 17 +#define lLLBufferPlotIndex 12 +double lLLBuffer[]; + +// +#property indicator_label13 "X121_XPV LLL" +#property indicator_type13 DRAW_LINE +#property indicator_color13 clrLightGray +#property indicator_style13 STYLE_DOT +#property indicator_width13 1 + +// +#define hHHBufferIndex 18 +#define hHHBufferPlotIndex 13 +double hHHBuffer[]; + +// +#property indicator_label14 "X121_XPV HHH" +#property indicator_type14 DRAW_LINE +#property indicator_color14 clrLightGray +#property indicator_style14 STYLE_DOT +#property indicator_width14 1 + +// +#define hLLBufferIndex 19 +#define hLLBufferPlotIndex 14 +double hLLBuffer[]; + +// +#property indicator_label15 "X121_XPV HLL" +#property indicator_type15 DRAW_LINE +#property indicator_color15 clrLightGray +#property indicator_style15 STYLE_DOT +#property indicator_width15 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +double lastPeak; +double lastVale; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (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 = + // + (shortLength > 2 && + mediumLength > shortLength && + longLength > mediumLength && + hindLength > longLength) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Peaks and Vales ... + result = MathMax(shortLength, mediumLength); + result = MathMax(result, longLength); + result = MathMax(result, hindLength); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // RANGE ... + + // + // PEAKS and VALES ... + ENUM_DRAW_TYPE pvDrawType = showPeaksAndVales ? DRAW_ARROW : DRAW_NONE; + + // + // PEAKS ... + ArraySetAsSeries(peaksBuffer, true); + SetIndexBuffer(peaksBufferIndex, peaksBuffer, INDICATOR_DATA); + PlotIndexSetInteger(peaksBufferIndex, PLOT_ARROW, 225); + // PlotIndexSetInteger(peaksBufferIndex, PLOT_ARROW_SHIFT, -20); + PlotIndexSetDouble(peaksBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + PlotIndexSetInteger(peaksBufferIndex, PLOT_SHOW_DATA, showPeaksAndVales); + PlotIndexSetInteger(peaksBufferIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + // VALES ... + ArraySetAsSeries(valesBuffer, true); + SetIndexBuffer(valesBufferIndex, valesBuffer, INDICATOR_DATA); + PlotIndexSetInteger(valesBufferIndex, PLOT_ARROW, 225); + // PlotIndexSetInteger(valesBufferIndex, PLOT_ARROW_SHIFT, 20); + PlotIndexSetDouble(valesBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + PlotIndexSetInteger(valesBufferIndex, PLOT_SHOW_DATA, showPeaksAndVales); + PlotIndexSetInteger(valesBufferIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + // SUPPORT and RESISTANCE ... + // + + // + // RESISTANCE ... + ArraySetAsSeries(rBuffer, true); + SetIndexBuffer(rBufferIndex, rBuffer, INDICATOR_DATA); + PlotIndexSetInteger(rBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(rBufferIndex, PLOT_SHOW_DATA, false); + + // + // RESISTANCE Color ... + ArraySetAsSeries(rColorBuffer, true); + SetIndexBuffer(rColorBufferIndex, rColorBuffer, INDICATOR_COLOR_INDEX); + + // + // SUPPORT ... + ArraySetAsSeries(sBuffer, true); + SetIndexBuffer(sBufferIndex, sBuffer, INDICATOR_DATA); + PlotIndexSetInteger(sBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(sBufferPlotIndex, PLOT_SHOW_DATA, false); + + // + // SUPPORT Color ... + ArraySetAsSeries(sColorBuffer, true); + SetIndexBuffer(sColorBufferIndex, sColorBuffer, INDICATOR_COLOR_INDEX); + + // + // FIBBO Levels ... + + // + // LEVEL 1 ... + + // + // BULLISH ... + ArraySetAsSeries(fl1Buffer, true); + SetIndexBuffer(fl1BufferIndex, fl1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl1BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl1BufferIndex, PLOT_SHOW_DATA, showFibo1Levels); + + // + // BULLISH Color ... + ArraySetAsSeries(fl1ColorBuffer, true); + SetIndexBuffer(fl1ColorBufferIndex, fl1ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 2 ... + + // + // BULLISH ... + ArraySetAsSeries(fl2Buffer, true); + SetIndexBuffer(fl2BufferIndex, fl2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl2BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl2BufferIndex, PLOT_SHOW_DATA, showFibo2Levels); + + // + // BULLISH Color ... + ArraySetAsSeries(fl2ColorBuffer, true); + SetIndexBuffer(fl2ColorBufferIndex, fl2ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 3 ... + + // + // BULLISH ... + ArraySetAsSeries(fl3Buffer, true); + SetIndexBuffer(fl3BufferIndex, fl3Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl3BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl3BufferIndex, PLOT_SHOW_DATA, showFibo3Levels); + + // + // BULLISH Color ... + ArraySetAsSeries(fl3ColorBuffer, true); + SetIndexBuffer(fl3ColorBufferIndex, fl3ColorBuffer, INDICATOR_COLOR_INDEX); + + // + ENUM_DRAW_TYPE zoneDrawType = showLevels ? DRAW_LINE : DRAW_NONE; + + // + // SHORT Buffers ... + + // + // HIGH ... + ArraySetAsSeries(sHHBuffer, true); + SetIndexBuffer(sHHBufferIndex, sHHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(sHHBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + PlotIndexSetInteger(sHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + PlotIndexSetInteger(sHHBufferPlotIndex, PLOT_DRAW_TYPE, zoneDrawType); + + // + // LOW ... + ArraySetAsSeries(sLLBuffer, true); + SetIndexBuffer(sLLBufferIndex, sLLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(sLLBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + PlotIndexSetInteger(sLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + PlotIndexSetInteger(sLLBufferPlotIndex, PLOT_DRAW_TYPE, zoneDrawType); + + // + // MEDIUM Buffer ... + + // + // HIGH ... + ArraySetAsSeries(mHHBuffer, true); + SetIndexBuffer(mHHBufferIndex, mHHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mHHBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + PlotIndexSetInteger(mHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + PlotIndexSetInteger(mHHBufferPlotIndex, PLOT_DRAW_TYPE, zoneDrawType); + + // + // LOW ... + ArraySetAsSeries(mLLBuffer, true); + SetIndexBuffer(mLLBufferIndex, mLLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mLLBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + PlotIndexSetInteger(mLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + PlotIndexSetInteger(mLLBufferPlotIndex, PLOT_DRAW_TYPE, zoneDrawType); + + // + // LONG Buffer ... + + // + // HIGH ... + ArraySetAsSeries(lHHBuffer, true); + SetIndexBuffer(lHHBufferIndex, lHHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lHHBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + PlotIndexSetInteger(lHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + PlotIndexSetInteger(lHHBufferPlotIndex, PLOT_DRAW_TYPE, zoneDrawType); + + // + // LOW ... + ArraySetAsSeries(lLLBuffer, true); + SetIndexBuffer(lLLBufferIndex, lLLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lLLBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + PlotIndexSetInteger(lLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + PlotIndexSetInteger(lLLBufferPlotIndex, PLOT_DRAW_TYPE, zoneDrawType); + + // + // HIND Buffer ... + + // + // HIGH ... + ArraySetAsSeries(hHHBuffer, true); + SetIndexBuffer(hHHBufferIndex, hHHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(hHHBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + PlotIndexSetInteger(hHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + PlotIndexSetInteger(hHHBufferPlotIndex, PLOT_DRAW_TYPE, zoneDrawType); + + // + // LOW ... + ArraySetAsSeries(hLLBuffer, true); + SetIndexBuffer(hLLBufferIndex, hLLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(hLLBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + PlotIndexSetInteger(hLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + PlotIndexSetInteger(hLLBufferPlotIndex, PLOT_DRAW_TYPE, zoneDrawType); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // Calculate ... + + // + double rColorIDX = 1; + double sColorIDX = 1; + + // + // SHORT ... + + // + // HIGH ... + int sHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + shortLength, + bar_index); + double sHHValue = GetAppliedPrice( + sHHIndex, + hhMode); + + // + sHHBuffer[bar_index] = sHHValue; + + // + // LOW ... + int sLLIndex = iLowest( + _Symbol, + _Period, + llMode, + shortLength, + bar_index); + double sLLValue = GetAppliedPrice( + sLLIndex, + llMode); + + // + sLLBuffer[bar_index] = sLLValue; + + // + // MEDIUM ... + + // + // HIGH ... + int mHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + mediumLength, + bar_index); + double mHHValue = GetAppliedPrice( + mHHIndex, + hhMode); + + // + mHHBuffer[bar_index] = mHHValue; + + // + // LOW ... + int mLLIndex = iLowest( + _Symbol, + _Period, + llMode, + mediumLength, + bar_index); + double mLLValue = GetAppliedPrice( + mLLIndex, + llMode); + + // + mLLBuffer[bar_index] = mLLValue; + + // + // LONG ... + + // + // HIGH ... + int lHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + longLength, + bar_index); + double lHHValue = GetAppliedPrice( + lHHIndex, + hhMode); + + // + lHHBuffer[bar_index] = lHHValue; + + // + // LOW ... + int lLLIndex = iLowest( + _Symbol, + _Period, + llMode, + longLength, + bar_index); + double lLLValue = GetAppliedPrice( + lLLIndex, + llMode); + + // + lLLBuffer[bar_index] = lLLValue; + + // + // HIND ... + + // + // HIGH ... + int hHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + hindLength, + bar_index); + double hHHValue = GetAppliedPrice( + hHHIndex, + hhMode); + + // + hHHBuffer[bar_index] = hHHValue; + + // + // LOW ... + int hLLIndex = iLowest( + _Symbol, + _Period, + llMode, + hindLength, + bar_index); + double hLLValue = GetAppliedPrice( + hLLIndex, + llMode); + + // + hLLBuffer[bar_index] = hLLValue; + + // + // RESISTANCE SUPPORT ... + + // + // RESISTANCE ... + double rValue = (sHHValue + mHHValue + lHHValue + hHHValue) / 4; + rBuffer[bar_index] = rValue; + + // + // SUPPORT ... + double sValue = (sLLValue + mLLValue + lLLValue + hLLValue) / 4; + sBuffer[bar_index] = sValue; + + // + // PEAKS and VALES ... + + // + // PEAKS ... + bool isPeak = rValue == hHHValue && + hHHValue == lHHValue && + lHHValue == mHHValue && + mHHValue == sHHValue; + // + if (isPeak && lastPeak != rValue) + { + // + if (showPeaksAndVales) + { + rColorIDX = 0; + } + + // + lastPeak = rValue; + peaksBuffer[bar_index] = lastPeak; + } + else + { + peaksBuffer[bar_index] = lastPeak; + } + + // + // VALES ... + bool isVale = sValue == hLLValue && + hLLValue == lLLValue && + lLLValue == mLLValue && + mLLValue == sLLValue; + + // + if (isVale && lastVale != sValue) + { + // + if (showPeaksAndVales) + { + sColorIDX = 0; + } + + // + lastVale = sValue; + valesBuffer[bar_index] = lastVale; + } + else + { + valesBuffer[bar_index] = lastVale; + } + + // + // Set Default Colors ... + + // + rColorBuffer[bar_index] = rColorIDX; + sColorBuffer[bar_index] = sColorIDX; + + // + // Calculate Fibonacci ... + double upPrice = peaksBuffer[bar_index]; + double downPrice = valesBuffer[bar_index]; + + // + // Level 1 ... + + // + // Bullish ... + double fibLevel1BullishValue = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel1, + 1); + fl1Buffer[bar_index] = fibLevel1BullishValue; + double fl1BullColorIdx = showFibo1Levels ? 1 : 0; + fl1ColorBuffer[bar_index] = fl1BullColorIdx; + + // // + // // Bearish ... + // double fibLevel1BearishValue = GetFibonacciLevel( + // upPrice, + // downPrice, + // fiboLevel1, + // 0); + // fl1BearBuffer[bar_index] = fibLevel1BearishValue; + // double fl1BearColorIdx = showFibo1Levels ? 1 : 0; + // fl1BearColorBuffer[bar_index] = fl1BearColorIdx; + + // + // Level 2 ... + + // + // Bullish ... + double fibLevel2BullishValue = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel2, + 1); + fl2Buffer[bar_index] = fibLevel2BullishValue; + double fl2BullColorIdx = showFibo2Levels ? 1 : 0; + fl2ColorBuffer[bar_index] = fl2BullColorIdx; + + // // + // // Bearish ... + // double fibLevel2BearishValue = GetFibonacciLevel( + // upPrice, + // downPrice, + // fiboLevel2, + // 0); + // fl2BearBuffer[bar_index] = fibLevel2BearishValue; + // double fl2BearColorIdx = showFibo2Levels ? 1 : 0; + // fl2BearColorBuffer[bar_index] = fl2BearColorIdx; + + // + // Level 3 ... + + // + // Bullish ... + double fibLevel3BullishValue = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel3, + 1); + fl3Buffer[bar_index] = fibLevel3BullishValue; + double fl3BullColorIdx = showFibo3Levels ? 1 : 0; + fl3ColorBuffer[bar_index] = fl3BullColorIdx; + + // // + // // Bearish ... + // double fibLevel3BearishValue = GetFibonacciLevel( + // upPrice, + // downPrice, + // fiboLevel3, + // 0); + // fl3BearBuffer[bar_index] = fibLevel3BearishValue; + // double fl3BearColorIdx = showFibo3Levels ? 1 : 0; + // fl3BearColorBuffer[bar_index] = fl3BearColorIdx; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xsslc.ex5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xsslc.ex5 new file mode 100644 index 0000000..fe36f13 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xsslc.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xsslc.mq5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xsslc.mq5 new file mode 100644 index 0000000..e682067 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xsslc.mq5 @@ -0,0 +1,437 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ---------------------------------------------------- +// Name: X121_XSSLC +// Description: SSL Channel Indicator +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121_XSSLC Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_XSSLC" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Market"; +input int length = 36; // Length + +// +input group "Calculation"; +input ENUM_MA_METHOD method = MODE_SMA; // Method +input ENUM_APPLIED_PRICE upAppliedTo = PRICE_HIGH; // Up Applied To +input ENUM_APPLIED_PRICE downAppliedTo = PRICE_LOW; // Down Applied To + +// +input group "Presentation"; +input bool showUp = true; // Show Up +input bool showDown = true; // Show Down + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 5 +#property indicator_plots 2 + +// +// PLOTTED Buffers ... + +// +#define upBufferIndex 0 +double upBuffer[]; + +// +#property indicator_label1 "X121_XSSLC Up" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrLime +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +#define downBufferIndex 1 +double downBuffer[]; + +// +#property indicator_label2 "X121_XSSLC Down" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrRed +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +// DATA Buffers ... + +// +#define upMaBufferIndex 2 +double upMaBuffer[]; + +// +#define downMaBufferIndex 3 +double downMaBuffer[]; + +// +#define kpiBufferIndex 4 +double kpiBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int upHandler = INVALID_HANDLE; +int downHandler = INVALID_HANDLE; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Initialize Requierd Handlers ... + upHandler = iMA( + _Symbol, + _Period, + length, + 0, + method, + upAppliedTo); + downHandler = iMA( + _Symbol, + _Period, + length, + 0, + method, + downAppliedTo); + if (upHandler == INVALID_HANDLE || downHandler == INVALID_HANDLE) + { + // + string msg = "Error in Initilizing Indicator ..."; + Print(msg); + + // + return INIT_FAILED; + } + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Release Indicators ... + IndicatorRelease(upHandler); + IndicatorRelease(downHandler); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // Check Calculated Bars ... + int upCalculatedBars = BarsCalculated(upHandler); + int downCalculatedBars = BarsCalculated(downHandler); + if (upCalculatedBars < maxLength || + downCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedUps = CopyBuffer(upHandler, 0, 0, limit, upMaBuffer); + int copiedDowns = CopyBuffer(downHandler, 0, 0, limit, downMaBuffer); + if (copiedUps <= 0 || + copiedDowns <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateBuffers(i, limit, rates_total, prev_calculated, close); + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + (length > 2) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(result, length); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // UP ... + + // + ENUM_DRAW_TYPE upDrawType = showUp ? DRAW_LINE : DRAW_NONE; + + + ArraySetAsSeries(upBuffer, true); + SetIndexBuffer(upBufferIndex, upBuffer, INDICATOR_DATA); + PlotIndexSetInteger(upBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(upBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(upBufferIndex, PLOT_DRAW_TYPE, upDrawType); + + // + // DOWN ... + + // + ENUM_DRAW_TYPE downDrawType = showDown ? DRAW_LINE : DRAW_NONE; + + + ArraySetAsSeries(downBuffer, true); + SetIndexBuffer(downBufferIndex, downBuffer, INDICATOR_DATA); + PlotIndexSetInteger(downBufferIndex, PLOT_SHOW_DATA, showDown); + PlotIndexSetInteger(downBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(downBufferIndex, PLOT_DRAW_TYPE, downDrawType); + + // + // DATA Buffers ... + + // + // UP MA ... + ArraySetAsSeries(upMaBuffer, true); + SetIndexBuffer(upMaBufferIndex, upMaBuffer, INDICATOR_CALCULATIONS); + + // + // DOWN MA ... + ArraySetAsSeries(downMaBuffer, true); + SetIndexBuffer(downMaBufferIndex, downMaBuffer, INDICATOR_CALCULATIONS); + + // + // KPI ... + ArraySetAsSeries(kpiBuffer, true); + SetIndexBuffer(kpiBufferIndex, kpiBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, // Selected Bar Index + int limit, + int ratesTotal, + int prevCalculated, + const double &close[]) +{ + // + double upMaValue = upMaBuffer[bar_index]; + double downMaValue = downMaBuffer[bar_index]; + + // + double closeValue = close[bar_index]; + + // + double kpiValue; + if (closeValue > upMaValue) { + kpiValue = 1; + } else if (closeValue < downMaValue) { + kpiValue = -1; + } else { + kpiValue = kpiBuffer[bar_index + 1]; + } + + // + kpiBuffer[bar_index] = kpiValue; + + // + double upValue = kpiValue < 0 ? downMaValue : upMaValue; + upBuffer[bar_index] = upValue; + + // + double downValue = kpiValue < 0 ? upMaValue : downMaValue; + downBuffer[bar_index] = downValue; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xstr.ex5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xstr.ex5 new file mode 100644 index 0000000..fcb6351 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xstr.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xstr.mq5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xstr.mq5 new file mode 100644 index 0000000..bca9597 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xstr.mq5 @@ -0,0 +1,580 @@ +////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: X121_XSTR +// Description: Super Trend Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121_XAMA Indicator" +#property strict + +// +// START Constants ... +// + +#define ShortName "X121_XSTR" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +// Market ... +input group "ATR"; +input int atrLength = 14; // Length +input double atrMultiplier = 3.0; // Multiplier +input ENUM_APPLIED_PRICE atrAppliedTo = PRICE_MEDIAN; // Applied To + +// +// Presentation ... +input group "Presentation"; +input bool showTrends = true; // Show Trends +input bool fillTrends = true; // Fill Trends + +// +// END Inputs ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 9 +#property indicator_plots 2 + +// +#define fillUpBufferIndex 0 +double fillUpBuffer[]; + +#define fillDownBufferIndex 1 +double fillDownBuffer[]; + +// +#define fillingPlotBufferIndex 0 + +// +#property indicator_label1 "X121_XSTR Filling" +#property indicator_type1 DRAW_FILLING +#property indicator_color1 clrBisque, clrPaleGreen + +// +#define mainBufferIndex 2 +#define mainPlotBufferIndex 1 +double mainBuffer[]; + +// +#define mainColorBufferIndex 3 +double mainColorBuffer[]; + +// +#property indicator_label2 "X121_XSTR" +#property indicator_type2 DRAW_COLOR_LINE +#property indicator_color2 CLR_NONE, clrGreen, clrDarkRed +#property indicator_style2 STYLE_DOT + +// +// DATA Buffers ... + +// +#define atrBufferIndex 4 +double atrBuffer[]; + +// +#define trendBufferIndex 5 +double trendBuffer[]; + +// +#define upBufferIndex 6 +double upBuffer[]; + +// +#define downBufferIndex 7 +double downBuffer[]; + +// +#define priceBufferIndex 8 +double priceBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int atrHandler = INVALID_HANDLE; + +// +int changeOfTrend; +int startBearishTrend; +int startBullishTrend; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + atrHandler = iATR( + _Symbol, + _Period, + atrLength); + if (atrHandler == INVALID_HANDLE) + { + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + IndicatorRelease(atrHandler); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + int numOfRequiredAtrs; + if (prev_calculated > rates_total || prev_calculated < 0) + { + numOfRequiredAtrs = rates_total; + } + else + { + // + numOfRequiredAtrs = rates_total - prev_calculated; + if (prev_calculated > 0) + { + numOfRequiredAtrs++; + } + } + + // + // Checking for stop ... + if (IsStopped()) + { + return 0; + } + + // + // Check Number of items Copy or not ... + int copiedATRs = CopyBuffer(atrHandler, 0, 0, numOfRequiredAtrs, atrBuffer); + if (copiedATRs <= 0) + { + return 0; + } + + // + int limit; + + // + // checking for the limit start of calculation of an indicator ... + if (prev_calculated > rates_total || prev_calculated <= 0) + { + // + // starting index for calculation of all bars ... + limit = maxLength; + } + else + { + // + // starting number for calculation of new bars + limit = prev_calculated - 1; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + // + // Calculated Price ... + double price = getPrice( + atrAppliedTo, + open, + high, + low, + close, + i); + // price = (high[i] + low[i]) / 2; + priceBuffer[i] = price; + + // + double atr = atrBuffer[i]; + + // + // Up ... + upBuffer[i] = price + (atrMultiplier * atr); + + // + // Down ... + downBuffer[i] = price - (atrMultiplier * atr); + + // + if (close[i] > upBuffer[i - 1]) + { + // + trendBuffer[i] = 1; + if (trendBuffer[i - 1] == -1) + { + changeOfTrend = 1; + } + } + else if (close[i] < downBuffer[i - 1]) + { + // + trendBuffer[i] = -1; + if (trendBuffer[i - 1] == 1) + { + changeOfTrend = 1; + } + } + else if (trendBuffer[i - 1] == 1) + { + // + trendBuffer[i] = 1; + changeOfTrend = 0; + } + else if (trendBuffer[i - 1] == -1) + { + // + trendBuffer[i] = -1; + changeOfTrend = 0; + } + + // + // Down Trend Starting ... + if (trendBuffer[i] < 0 && trendBuffer[i - 1] > 0) + { + startBearishTrend = 1; + } + else + { + startBearishTrend = 0; + } + + // + // Up Trend Starting ... + if (trendBuffer[i] > 0 && trendBuffer[i - 1] < 0) + { + startBullishTrend = 1; + } + else + { + startBullishTrend = 0; + } + + // + if (trendBuffer[i] > 0 && downBuffer[i] < downBuffer[i - 1]) + { + downBuffer[i] = downBuffer[i - 1]; + } + + // + if (trendBuffer[i] < 0 && upBuffer[i] > upBuffer[i - 1]) + { + upBuffer[i] = upBuffer[i - 1]; + } + + // + if (startBearishTrend == 1) + { + upBuffer[i] = priceBuffer[i] + (atrMultiplier * atr); + } + + // + if (startBullishTrend == 1) + { + downBuffer[i] = priceBuffer[i] - (atrMultiplier * atr); + } + + // + // Draw the indicator ... + + // + double colorIDX = 0; + mainColorBuffer[i] = colorIDX; + + // + if (trendBuffer[i] == 1) + { + // + mainBuffer[i] = downBuffer[i]; + if (changeOfTrend == 1) + { + mainBuffer[i - 1] = mainBuffer[i - 2]; + changeOfTrend = 0; + } + + // + colorIDX = 1; + } + else if (trendBuffer[i] == -1) + { + // + mainBuffer[i] = upBuffer[i]; + if (changeOfTrend == 1) + { + // + mainBuffer[i - 1] = mainBuffer[i - 2]; + changeOfTrend = 0; + } + + // + colorIDX = 2; + } + + // + if (showTrends) + { + mainColorBuffer[i] = colorIDX; + } + + // + // Filling ... + if (fillTrends) + { + // + fillUpBuffer[i] = mainBuffer[i]; + fillDownBuffer[i] = close[i]; + } + else + { + // + fillUpBuffer[i] = EMPTY_VALUE; + fillDownBuffer[i] = EMPTY_VALUE; + } + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + result = + // + atrLength >= 2 + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = atrLength; + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // PLOT Buffers ... + + // + // FILLINGS ... + SetIndexBuffer(fillUpBufferIndex, fillUpBuffer, INDICATOR_DATA); + SetIndexBuffer(fillDownBufferIndex, fillDownBuffer, INDICATOR_DATA); + PlotIndexSetInteger(fillingPlotBufferIndex, PLOT_SHOW_DATA, false); + + // + // MAIN ... + SetIndexBuffer(mainBufferIndex, mainBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mainPlotBufferIndex, PLOT_SHOW_DATA, showTrends); + SetIndexBuffer(mainColorBufferIndex, mainColorBuffer, INDICATOR_COLOR_INDEX); + + // + // DATA Buffers ... + + // + // ATR ... + SetIndexBuffer(atrBufferIndex, atrBuffer, INDICATOR_CALCULATIONS); + + // + // TREND ... + SetIndexBuffer(trendBufferIndex, trendBuffer, INDICATOR_CALCULATIONS); + + // + // UP ... + SetIndexBuffer(upBufferIndex, upBuffer, INDICATOR_CALCULATIONS); + + // + // DOWN ... + SetIndexBuffer(downBufferIndex, downBuffer, INDICATOR_CALCULATIONS); + + // + // PRICE ... + SetIndexBuffer(priceBufferIndex, priceBuffer, INDICATOR_CALCULATIONS); +} + +// +// END Functions ... +// + +// +// TEMPLATE Function ... + +template +double getPrice(ENUM_APPLIED_PRICE tprice, T &open[], T &high[], T &low[], T &close[], int i) +{ + switch (tprice) + { + case PRICE_CLOSE: + return (close[i]); + case PRICE_OPEN: + return (open[i]); + case PRICE_HIGH: + return (high[i]); + case PRICE_LOW: + return (low[i]); + case PRICE_MEDIAN: + return ((high[i] + low[i]) / 2.0); + case PRICE_TYPICAL: + return ((high[i] + low[i] + close[i]) / 3.0); + case PRICE_WEIGHTED: + return ((high[i] + low[i] + close[i] + close[i]) / 4.0); + } + return (0); +} diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xtm.ex5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xtm.ex5 new file mode 100644 index 0000000..326e17f Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xtm.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xtm.mq5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xtm.mq5 new file mode 100644 index 0000000..c483d3b --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xtm.mq5 @@ -0,0 +1,354 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: X121_XTM +// 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 X121_XTM Indicator" +#property strict + +// +// START Constants ... +// +#define ShortName "X121_XTM" + +// +// XTM Indicator States ... +enum ENUM_X_XTM_STATES +{ + X_XTM_BULLISH = 0, + X_XTM_BEARISH = 2, + X_XTM_NEUTURAL = 1, +}; +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Makret"; +input int length = 35; // Length +input int shift = 0; // Shift + +// +input group "Calculations"; +input ENUM_MA_METHOD method = MODE_SMA; // Method +input ENUM_APPLIED_PRICE appliedTo = PRICE_LOW; // Applied To + +// +input group "Presentation"; +input bool showLine = true; // Show Line + +// +// END Inputs ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 2 +#property indicator_plots 2 + +// +// maBuffer ... +#define maBufferIndex 0 +double maBuffer[]; + +#define maColorBufferIndex 1 +double maColorBuffer[]; + +// +#property indicator_label1 "X121_XTM" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrLime, clrGray, clrRed +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int maHandler = INVALID_HANDLE; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Initializing MA Handler ... + maHandler = iMA( + _Symbol, + _Period, + length, + shift, + method, + appliedTo); + if (maHandler == INVALID_HANDLE) + { + // + string message = "Error Initializing Ma Handler ..."; + Print(message); + + // + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + IndicatorRelease(maHandler); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // Check Calculated Bars ... + int maCalculatedBars = BarsCalculated(maHandler); + if (maCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedMas = CopyBuffer(maHandler, 0, 0, limit, maBuffer); + if (copiedMas <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + // Do Buffers Calculation ... + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 2) + { + result = true; + } + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = length; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + ENUM_DRAW_TYPE drawType = showLine ? DRAW_COLOR_LINE : DRAW_NONE; + + // + // Ma Buffer ... + ArraySetAsSeries(maBuffer, true); + SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_DATA); + PlotIndexSetInteger(maBufferIndex, PLOT_DRAW_TYPE, drawType); + PlotIndexSetInteger(maBufferIndex, PLOT_SHOW_DATA, showLine); + + // + // Ma Color Buffer ... + ArraySetAsSeries(maColorBuffer, true); + SetIndexBuffer(maColorBufferIndex, maColorBuffer, INDICATOR_COLOR_INDEX); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers(int bar_index) +{ + // + // Requirements ... + XOHCL candle = GetCandle(bar_index); + + // + double maValue = maBuffer[bar_index]; + + // + double lineColorIndex = + maValue < candle.low ? 0 : maValue > candle.high ? 2 + : 1; + + // + // Set Ma Buffer Color Index ... + maColorBuffer[bar_index] = lineColorIndex; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xtrnd.ex5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xtrnd.ex5 new file mode 100644 index 0000000..76db2cf Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xtrnd.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xtrnd.mq5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xtrnd.mq5 new file mode 100644 index 0000000..a5d92fc --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.x121.xtrnd.mq5 @@ -0,0 +1,1253 @@ +///////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// -------------------------------------------------- +// Name: X121_XTRND +// Description: Market 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 X121_XTRND Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_XTRND" + +// +// XPERIOD Calculation Method ... +// USED For Multiple Time Frames ... +enum ENUM_X_PERIOD_METHOD +{ + // + X_PERIOD_NOTHING, + // + X_PERIOD_AUTO, + // + X_PERIOD_MANUALLY +}; + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Makret"; +input int cycleLength = 2; // Cycle Length to Check +input int numberOfVerifications = 2; // Number of Verifications + +// +input group "Calculation"; +input ENUM_SERIESMODE hhMode = MODE_HIGH; // Detect Up +input ENUM_SERIESMODE llMode = MODE_LOW; // Detect Low + +// +input group "Cycles"; + +// +input group "Level 1"; +input ENUM_X_PERIOD_METHOD l1Method = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES l1Period = NULL; // Time Period + +// +input group "Level 2"; +input ENUM_X_PERIOD_METHOD l2Method = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES l2Period = NULL; // Time Period + +// +input group "Level 3"; +input ENUM_X_PERIOD_METHOD l3Method = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES l3Period = NULL; // Time Period + +// +input group "Presentation"; +input bool showConsolidations = false; // Show Consolidations +input bool showTrend = true; // Show Trend +input bool showL1Trend = false; // Show Cycle 1 Trend +input bool showL2Trend = false; // Show Cycle 2 Trend +input bool showL3Trend = false; // Show Cycle 3 Trend + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 24 +#property indicator_plots 16 + +// +// Higher High ... +#define hhBufferIndex 0 +#define hhPlotBufferIndex 0 +double hhBuffer[]; + +#define hhColorBufferIndex 1 +double hhColorBuffer[]; + +// +#property indicator_label1 "X121_XTRND U" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style1 STYLE_DOT +#property indicator_width1 1 + +// +// Lower Low ... +#define llBufferIndex 2 +#define llPlotBufferIndex 1 +double llBuffer[]; + +#define llColorBufferIndex 3 +double llColorBuffer[]; + +// +#property indicator_label2 "X121_XTRND D" +#property indicator_type2 DRAW_COLOR_LINE +#property indicator_color2 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style2 STYLE_DOT +#property indicator_width2 1 + +// +// CYCLE 1 ... + +// +// Higher High ... +#define l1hhBufferIndex 4 +#define l1hhPlotBufferIndex 2 +double l1hhBuffer[]; + +#define l1hhColorBufferIndex 5 +double l1hhColorBuffer[]; + +// +#property indicator_label3 "X121_XTRND C1 U" +#property indicator_type3 DRAW_COLOR_LINE +#property indicator_color3 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +// Lower Low ... +#define l1llBufferIndex 6 +#define l1llPlotBufferIndex 3 +double l1llBuffer[]; + +#define l1llColorBufferIndex 7 +double l1llColorBuffer[]; + +// +#property indicator_label4 "X121_XTRND C1 D" +#property indicator_type4 DRAW_COLOR_LINE +#property indicator_color4 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +// CYCLE 2 ... + +// +// Higher High ... +#define l2hhBufferIndex 8 +#define l2hhPlotBufferIndex 4 +double l2hhBuffer[]; + +#define l2hhColorBufferIndex 9 +double l2hhColorBuffer[]; + +// +#property indicator_label5 "X121_XTRND C2 U" +#property indicator_type5 DRAW_COLOR_LINE +#property indicator_color5 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style5 STYLE_DOT +#property indicator_width5 1 + +// +// Lower Low ... +#define l2llBufferIndex 10 +#define l2llPlotBufferIndex 5 +double l2llBuffer[]; + +#define l2llColorBufferIndex 11 +double l2llColorBuffer[]; + +// +#property indicator_label6 "X121_XTRND C2 D" +#property indicator_type6 DRAW_COLOR_LINE +#property indicator_color6 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style6 STYLE_DOT +#property indicator_width6 1 + +// +// CYCLE 3 ... + +// +// Higher High... +#define l3hhBufferIndex 12 +#define l3hhPlotBufferIndex 6 +double l3hhBuffer[]; + +#define l3hhColorBufferIndex 13 +double l3hhColorBuffer[]; + +// +#property indicator_label7 "X121_XTRND C3 U" +#property indicator_type7 DRAW_COLOR_LINE +#property indicator_color7 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style7 STYLE_DOT +#property indicator_width7 1 + +// +// Lower Low ... +#define l3llBufferIndex 14 +#define l3llPlotBufferIndex 7 +double l3llBuffer[]; + +#define l3llColorBufferIndex 15 +double l3llColorBuffer[]; + +// +#property indicator_label8 "X121_XTRND C3 D" +#property indicator_type8 DRAW_COLOR_LINE +#property indicator_color8 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style8 STYLE_DOT +#property indicator_width8 1 + +// +// DATA Buffers ... + +#define hhStateBufferIndex 16 +#define llStateBufferIndex 17 +double hhStateBuffer[]; +double llStateBuffer[]; + +#define l1HHStateBufferIndex 18 +#define l1LLStateBufferIndex 19 +double l1HHStateBuffer[]; +double l1LLStateBuffer[]; + +#define l2HHStateBufferIndex 20 +#define l2LLStateBufferIndex 21 +double l2HHStateBuffer[]; +double l2LLStateBuffer[]; + +#define l3HHStateBufferIndex 22 +#define l3LLStateBufferIndex 23 +double l3HHStateBuffer[]; +double l3LLStateBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int currentPeriodSecconds = 0; + +// +// CYCLE 1 ... +int mL1Candles; +int mL1PeriodSecconds = 0; +int mLastL1StartBarIndex = 0; +datetime mLastL1StartTime = NULL; +ENUM_TIMEFRAMES mL1Period = NULL; + +// +// CYCLE 2 ... +int mL2Candles; +int mL2PeriodSecconds = 0; +int mLastL2StartBarIndex = 0; +datetime mLastL2StartTime = NULL; +ENUM_TIMEFRAMES mL2Period = NULL; + +// +// CYCLE 3 ... +int mL3Candles; +int mL3PeriodSecconds = 0; +int mLastL3StartBarIndex = 0; +datetime mLastL3StartTime = NULL; +ENUM_TIMEFRAMES mL3Period = NULL; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Initial Periods ... + InitialCycles(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (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 = + // + (cycleLength > 0 && + numberOfVerifications > 0) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Peaks and Vales ... + result = MathMax( + cycleLength, + numberOfVerifications); + + // + return result; +} + +// +// Initial Multi Time Frame Cycles Periods ... +void InitialCycles() +{ + // + // Calculate Current Period Secconds ... + currentPeriodSecconds = PeriodSeconds(_Period); + + // + // Nearest ... + // Calculate Cycle 1 Requirements ... + if (mL1Period == NULL) + { + // + if (l1Method == X_PERIOD_AUTO) + { + mL1Period = GetNearestTimeFrame(_Period); + } + else + { + mL1Period = l1Period; + } + + // + mL1PeriodSecconds = PeriodSeconds(mL1Period); + + // + mL1Candles = mL1PeriodSecconds / currentPeriodSecconds; + } + + // + // Mediest ... + // Calculate Cycle 2 Requirements ... + if (mL2Period == NULL) + { + // + if (l2Method == X_PERIOD_AUTO) + { + mL2Period = GetMediestTimeFrame(_Period); + } + else + { + mL2Period = l2Period; + } + + // + mL2PeriodSecconds = PeriodSeconds(mL2Period); + + // + mL2Candles = mL2PeriodSecconds / currentPeriodSecconds; + } + + // + // Farest ... + // Calculate Cycle 3 Requirements ... + if (mL3Period == NULL) + { + // + if (l3Method == X_PERIOD_AUTO) + { + mL3Period = GetFarestTimeFrame(_Period); + } + else + { + mL3Period = l3Period; + } + + // + mL3PeriodSecconds = PeriodSeconds(mL3Period); + + // + mL3Candles = mL3PeriodSecconds / currentPeriodSecconds; + } +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // HH Buffer ... + + // + // SERIES ... + ArraySetAsSeries(hhBuffer, true); + SetIndexBuffer(hhBufferIndex, hhBuffer, INDICATOR_DATA); + + // + // PLOT Config ... + PlotIndexSetInteger(hhPlotBufferIndex, PLOT_SHOW_DATA, showTrend); + PlotIndexSetInteger(hhPlotBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // COLOR Buffer ... + ArraySetAsSeries(hhColorBuffer, true); + SetIndexBuffer(hhColorBufferIndex, hhColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LL Buffer ... + + // + // SERIES ... + ArraySetAsSeries(llBuffer, true); + SetIndexBuffer(llBufferIndex, llBuffer, INDICATOR_DATA); + + // + // PLOT Config ... + PlotIndexSetInteger(llPlotBufferIndex, PLOT_SHOW_DATA, showTrend); + PlotIndexSetInteger(llPlotBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // COLOR Buffer ... + ArraySetAsSeries(llColorBuffer, true); + SetIndexBuffer(llColorBufferIndex, llColorBuffer, INDICATOR_COLOR_INDEX); + + // + // CYCLES ... + + // + // NEAREST ... + + // + // HH Buffer ... + + // + // SERIES ... + ArraySetAsSeries(l1hhBuffer, true); + SetIndexBuffer(l1hhBufferIndex, l1hhBuffer, INDICATOR_DATA); + + // + // PLOT Config ... + PlotIndexSetInteger(l1hhPlotBufferIndex, PLOT_SHOW_DATA, showL1Trend); + PlotIndexSetInteger(l1hhPlotBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // COLOR Buffer ... + ArraySetAsSeries(l1hhColorBuffer, true); + SetIndexBuffer(l1hhColorBufferIndex, l1hhColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LL Buffer ... + + // + // SERIES ... + ArraySetAsSeries(l1llBuffer, true); + SetIndexBuffer(l1llBufferIndex, l1llBuffer, INDICATOR_DATA); + + // + // PLOT Config ... + PlotIndexSetInteger(l1llPlotBufferIndex, PLOT_SHOW_DATA, showL1Trend); + PlotIndexSetInteger(l1llPlotBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // COLOR Buffer ... + ArraySetAsSeries(l1llColorBuffer, true); + SetIndexBuffer(l1llColorBufferIndex, l1llColorBuffer, INDICATOR_COLOR_INDEX); + + // + // MEDIEST ... + + // + // HH Buffer ... + + // + // SERIES ... + ArraySetAsSeries(l2hhBuffer, true); + SetIndexBuffer(l2hhBufferIndex, l2hhBuffer, INDICATOR_DATA); + + // + // PLOT Config ... + PlotIndexSetInteger(l2hhPlotBufferIndex, PLOT_SHOW_DATA, showL2Trend); + PlotIndexSetInteger(l2hhPlotBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // COLOR Buffer ... + ArraySetAsSeries(l2hhColorBuffer, true); + SetIndexBuffer(l2hhColorBufferIndex, l2hhColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LL Buffer ... + + // + // SERIES ... + ArraySetAsSeries(l2llBuffer, true); + SetIndexBuffer(l2llBufferIndex, l2llBuffer, INDICATOR_DATA); + + // + // PLOT Config ... + PlotIndexSetInteger(l2llPlotBufferIndex, PLOT_SHOW_DATA, showL2Trend); + PlotIndexSetInteger(l2llPlotBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // COLOR Buffer ... + ArraySetAsSeries(l2llColorBuffer, true); + SetIndexBuffer(l2llColorBufferIndex, l2llColorBuffer, INDICATOR_COLOR_INDEX); + + // + // FAREST ... + + // + // HH Buffer ... + + // + // SERIES ... + ArraySetAsSeries(l3hhBuffer, true); + SetIndexBuffer(l3hhBufferIndex, l3hhBuffer, INDICATOR_DATA); + + // + // PLOT Config ... + PlotIndexSetInteger(l3hhPlotBufferIndex, PLOT_SHOW_DATA, showL3Trend); + PlotIndexSetInteger(l3hhPlotBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // COLOR Buffer ... + ArraySetAsSeries(l3hhColorBuffer, true); + SetIndexBuffer(l3hhColorBufferIndex, l3hhColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LL Buffer ... + + // + // SERIES ... + ArraySetAsSeries(l3llBuffer, true); + SetIndexBuffer(l3llBufferIndex, l3llBuffer, INDICATOR_DATA); + + // + // PLOT Config ... + PlotIndexSetInteger(l3llPlotBufferIndex, PLOT_SHOW_DATA, showL3Trend); + PlotIndexSetInteger(l3llPlotBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // COLOR Buffer ... + ArraySetAsSeries(l3llColorBuffer, true); + SetIndexBuffer(l3llColorBufferIndex, l3llColorBuffer, INDICATOR_COLOR_INDEX); + + // + // DATA Buffers ... + ArraySetAsSeries(hhStateBuffer, true); + SetIndexBuffer(hhStateBufferIndex, hhStateBuffer, INDICATOR_CALCULATIONS); + + ArraySetAsSeries(llStateBuffer, true); + SetIndexBuffer(llStateBufferIndex, llStateBuffer, INDICATOR_CALCULATIONS); + + // + // LEVEL 1 ... + ArraySetAsSeries(l1HHStateBuffer, true); + SetIndexBuffer(l1HHStateBufferIndex, l1HHStateBuffer, INDICATOR_CALCULATIONS); + + ArraySetAsSeries(l1LLStateBuffer, true); + SetIndexBuffer(l1LLStateBufferIndex, l1LLStateBuffer, INDICATOR_CALCULATIONS); + + // + // LEVEL 2 ... + ArraySetAsSeries(l2HHStateBuffer, true); + SetIndexBuffer(l2HHStateBufferIndex, l2HHStateBuffer, INDICATOR_CALCULATIONS); + + ArraySetAsSeries(l2LLStateBuffer, true); + SetIndexBuffer(l2LLStateBufferIndex, l2LLStateBuffer, INDICATOR_CALCULATIONS); + + // + // LEVEL 3 ... + ArraySetAsSeries(l3HHStateBuffer, true); + SetIndexBuffer(l3HHStateBufferIndex, l3HHStateBuffer, INDICATOR_CALCULATIONS); + + ArraySetAsSeries(l3LLStateBuffer, true); + SetIndexBuffer(l3LLStateBufferIndex, l3LLStateBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // HIGHER Highs ... + double hh = GetHighestHigh( + _Symbol, + _Period, + hhMode, + cycleLength, + bar_index); + + // + hhBuffer[bar_index] = hh; + + // + // LOWER Lows ... + double ll = GetLowestLow( + _Symbol, + _Period, + llMode, + cycleLength, + bar_index); + + // + llBuffer[bar_index] = ll; + + // + // Set Default Color ... + // in Consolidations use index 0 for CLR_NONE ... + double hhColorIDX = showConsolidations && showTrend ? 1 : 0; + double llColorIDX = showConsolidations && showTrend ? 1 : 0; + hhColorBuffer[bar_index] = hhColorIDX; + llColorBuffer[bar_index] = llColorIDX; + + // + // Calculate Cycle Changes ... + + // + int cycleCLength = cycleLength * numberOfVerifications; + bool isCycleCLengthPassed = MathAbs(ArraySize(hhBuffer) - bar_index) > cycleCLength + 1; + + // + if (isCycleCLengthPassed) + { + // + bool isLowestLowUp = true; + bool isLowestLowDown = true; + bool isHighsestHighUp = true; + bool isHighsestHighDown = true; + for (int i = bar_index; i < bar_index + cycleCLength; i++) + { + // + double iHH = hhBuffer[i]; + double iLL = llBuffer[i]; + + // + if (hh < iHH) + { + isHighsestHighUp = false; + } + else if (hh > iHH) + { + isHighsestHighDown = false; + } + + // + if (ll < iLL) + { + isLowestLowUp = false; + } + else if (ll > iLL) + { + isLowestLowDown = false; + } + } + + // + // Detect Trends and Change Colors ... + + // + if (isLowestLowUp && + isHighsestHighUp) + { + // + hhColorIDX = 2; + llColorIDX = 2; + } + + // + if (isLowestLowDown && + isHighsestHighDown) + { + // + hhColorIDX = 3; + llColorIDX = 3; + } + } + + // + if (showTrend) + { + // + hhColorBuffer[bar_index] = hhColorIDX; + llColorBuffer[bar_index] = llColorIDX; + } + + // + hhColorIDX = + hhColorIDX == 0 || hhColorIDX == 1 + ? 0 + : hhColorIDX - 1; + llColorIDX = + llColorIDX == 0 || llColorIDX == 1 + ? 0 + : llColorIDX - 1; + + // + hhStateBuffer[bar_index] = hhColorIDX; + llStateBuffer[bar_index] = llColorIDX; + + // + // CYCLE 1 ... + + // + int l1cycleLength = cycleLength * mL1Candles; + + // + // HIGHER Highs ... + double l1hh = GetHighestHigh( + _Symbol, + _Period, + hhMode, + l1cycleLength, + bar_index); + + // + l1hhBuffer[bar_index] = l1hh; + + // + // LOWER Lows ... + double l1ll = GetLowestLow( + _Symbol, + _Period, + llMode, + l1cycleLength, + bar_index); + + // + l1llBuffer[bar_index] = l1ll; + + // + // Set Default Color ... + // in Consolidations use index 0 for CLR_NONE ... + double l1hhColorIDX = showConsolidations && showL1Trend ? 1 : 0; + double l1llColorIDX = showConsolidations && showL1Trend ? 1 : 0; + l1hhColorBuffer[bar_index] = l1hhColorIDX; + l1llColorBuffer[bar_index] = l1llColorIDX; + + // + // Calculate Cycle Changes ... + + // + int l1cycleCLength = l1cycleLength * numberOfVerifications; + bool isl1CycleCLengthPassed = MathAbs(ArraySize(l1hhBuffer) - bar_index) > l1cycleCLength + 1; + + // + if (isl1CycleCLengthPassed) + { + // + bool isLowestLowUp = true; + bool isLowestLowDown = true; + bool isHighsestHighUp = true; + bool isHighsestHighDown = true; + for (int i = bar_index; i < bar_index + l1cycleCLength; i++) + { + // + double iHH = l1hhBuffer[i]; + double iLL = l1llBuffer[i]; + + // + if (l1hh < iHH) + { + isHighsestHighUp = false; + } + else if (l1hh > iHH) + { + isHighsestHighDown = false; + } + + // + if (l1ll < iLL) + { + isLowestLowUp = false; + } + else if (l1ll > iLL) + { + isLowestLowDown = false; + } + } + + // + // Detect Trends and Change Colors ... + + // + if (isLowestLowUp && + isHighsestHighUp) + { + // + l1hhColorIDX = 2; + l1llColorIDX = 2; + } + + // + if (isLowestLowDown && + isHighsestHighDown) + { + // + l1hhColorIDX = 3; + l1llColorIDX = 3; + } + } + + // + if (showL1Trend) + { + // + l1hhColorBuffer[bar_index] = l1hhColorIDX; + l1llColorBuffer[bar_index] = l1llColorIDX; + } + + // + l1hhColorIDX = + l1hhColorIDX == 0 || l1hhColorIDX == 1 + ? 0 + : l1hhColorIDX - 1; + l1llColorIDX = + l1llColorIDX == 0 || l1llColorIDX == 1 + ? 0 + : l1llColorIDX - 1; + + // + l1HHStateBuffer[bar_index] = l1hhColorIDX; + l1LLStateBuffer[bar_index] = l1llColorIDX; + + + // + // CYCLE 2 ... + + // + int l2cycleLength = cycleLength * mL2Candles; + + // + // HIGHER Highs ... + double l2hh = GetHighestHigh( + _Symbol, + _Period, + hhMode, + l2cycleLength, + bar_index); + + // + l2hhBuffer[bar_index] = l2hh; + + // + // LOWER Lows ... + double l2ll = GetLowestLow( + _Symbol, + _Period, + llMode, + l2cycleLength, + bar_index); + + // + l2llBuffer[bar_index] = l2ll; + + // + // Set Default Color ... + // in Consolidations use index 0 for CLR_NONE ... + double l2hhColorIDX = showConsolidations && showL2Trend ? 1 : 0; + double l2llColorIDX = showConsolidations && showL2Trend ? 1 : 0; + l2hhColorBuffer[bar_index] = l2hhColorIDX; + l2llColorBuffer[bar_index] = l2llColorIDX; + + // + // Calculate Cycle Changes ... + + // + int l2cycleCLength = l2cycleLength * numberOfVerifications; + bool isl2CycleCLengthPassed = MathAbs(ArraySize(l2hhBuffer) - bar_index) > l2cycleCLength + 1; + + // + if (isl2CycleCLengthPassed) + { + // + bool isLowestLowUp = true; + bool isLowestLowDown = true; + bool isHighsestHighUp = true; + bool isHighsestHighDown = true; + for (int i = bar_index; i < bar_index + l2cycleCLength; i++) + { + // + double iHH = l2hhBuffer[i]; + double iLL = l2llBuffer[i]; + + // + if (l2hh < iHH) + { + isHighsestHighUp = false; + } + else if (l2hh > iHH) + { + isHighsestHighDown = false; + } + + // + if (l2ll < iLL) + { + isLowestLowUp = false; + } + else if (l2ll > iLL) + { + isLowestLowDown = false; + } + } + + // + // Detect Trends and Change Colors ... + + // + if (isLowestLowUp && + isHighsestHighUp) + { + // + l2hhColorIDX = 2; + l2llColorIDX = 2; + } + + // + if (isLowestLowDown && + isHighsestHighDown) + { + // + l2hhColorIDX = 3; + l2llColorIDX = 3; + } + } + + // + if (showL2Trend) + { + // + l2hhColorBuffer[bar_index] = l2hhColorIDX; + l2llColorBuffer[bar_index] = l2llColorIDX; + } + + // + l2hhColorIDX = + l2hhColorIDX == 0 || l2hhColorIDX == 1 + ? 0 + : l2hhColorIDX - 1; + l2llColorIDX = + l2llColorIDX == 0 || l2llColorIDX == 1 + ? 0 + : l2llColorIDX - 1; + + // + l2HHStateBuffer[bar_index] = l2hhColorIDX; + l2LLStateBuffer[bar_index] = l2llColorIDX; + + // + // CYCLE 3 ... + + // + int l3cycleLength = cycleLength * mL3Candles; + + // + // HIGHER Highs ... + double l3hh = GetHighestHigh( + _Symbol, + _Period, + hhMode, + l3cycleLength, + bar_index); + + // + l3hhBuffer[bar_index] = l3hh; + + // + // LOWER Lows ... + double l3ll = GetLowestLow( + _Symbol, + _Period, + llMode, + l3cycleLength, + bar_index); + + // + l3llBuffer[bar_index] = l3ll; + + // + // Set Default Color ... + // in Consolidations use index 0 for CLR_NONE ... + double l3hhColorIDX = showConsolidations && showL3Trend ? 1 : 0; + double l3llColorIDX = showConsolidations && showL3Trend ? 1 : 0; + l3hhColorBuffer[bar_index] = l3hhColorIDX; + l3llColorBuffer[bar_index] = l3llColorIDX; + + // + // Calculate Cycle Changes ... + + // + int l3cycleCLength = l3cycleLength * numberOfVerifications; + bool isl3CycleCLengthPassed = MathAbs(ArraySize(l3hhBuffer) - bar_index) > l3cycleCLength + 1; + + // + if (isl3CycleCLengthPassed) + { + // + bool isLowestLowUp = true; + bool isLowestLowDown = true; + bool isHighsestHighUp = true; + bool isHighsestHighDown = true; + for (int i = bar_index; i < bar_index + l3cycleCLength; i++) + { + // + double iHH = l3hhBuffer[i]; + double iLL = l3llBuffer[i]; + + // + if (l3hh < iHH) + { + isHighsestHighUp = false; + } + else if (l3hh > iHH) + { + isHighsestHighDown = false; + } + + // + if (l3ll < iLL) + { + isLowestLowUp = false; + } + else if (l3ll > iLL) + { + isLowestLowDown = false; + } + } + + // + // Detect Trends and Change Colors ... + + // + if (isLowestLowUp && + isHighsestHighUp) + { + // + l3hhColorIDX = 2; + l3llColorIDX = 2; + } + + // + if (isLowestLowDown && + isHighsestHighDown) + { + // + l3hhColorIDX = 3; + l3llColorIDX = 3; + } + } + + // + if (showL3Trend) + { + // + l3hhColorBuffer[bar_index] = l3hhColorIDX; + l3llColorBuffer[bar_index] = l3llColorIDX; + } + + // + l3hhColorIDX = + l3hhColorIDX == 0 || l3hhColorIDX == 1 + ? 0 + : l3hhColorIDX - 1; + l3llColorIDX = + l3llColorIDX == 0 || l3llColorIDX == 1 + ? 0 + : l3llColorIDX - 1; + + // + l3HHStateBuffer[bar_index] = l3hhColorIDX; + l3LLStateBuffer[bar_index] = l3llColorIDX; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.xchnl.ex5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.xchnl.ex5 new file mode 100644 index 0000000..391ac56 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.xchnl.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.xchnl.mq5 b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.xchnl.mq5 new file mode 100644 index 0000000..c850540 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Indicators/x-saherelm.xchnl.mq5 @@ -0,0 +1,775 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: X121_XCHNL +// Description: XCHL Channel Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121_XCHNL Indicator" +#property strict + +// +// START Constants ... +// + +// +#define ShortName "X121_XCHNL" + +// +// END Constants ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Includes Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START XSCHULL Class Definition ... +// + +// +// END XSCHULL Class Definition ... +// + +// +// START Inputs ... +// + +// +input group "Makret Cycles"; +input int shortLength = 9; // Short Length +input int mediumLength = 17; // Medium Length +input int longLength = 26; // Long Length +input int hindLength = 35; // Hind Length + +// +input group "Trend"; +input int numOfShoulder = 10; // Number of Shoulders for Swings + +// +input group "Detection Modes"; +input ENUM_SERIESMODE hhMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE llMode = MODE_LOW; // Lowest Low Calculation Method + +// +input group "Presentation"; +input bool showTrend = false; // Show Trend +input bool showSRs = false; // Show Support and Resistance + +// +// END Inputs ... +// + +// +// START Buffers ... +// + +// +// PEKSANDVALES ... + +#property indicator_chart_window + +// +#property indicator_buffers 8 +#property indicator_plots 0 + +#define sHHBufferIndex 0 +#define sLLBufferIndex 1 +#define mHHBufferIndex 2 +#define mLLBufferIndex 3 +#define lHHBufferIndex 4 +#define lLLBufferIndex 5 +#define hHHBufferIndex 6 +#define hLLBufferIndex 7 + +double sHHBuffer[]; +double sLLBuffer[]; +double mHHBuffer[]; +double mLLBuffer[]; +double lHHBuffer[]; +double lLLBuffer[]; +double hHHBuffer[]; +double hLLBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + drawPrefix = ShortName; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Make an Instance of Hull Class ... + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart mPeriod is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + RemoveDraws(drawPrefix); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // this counts Available Bars ... + int limit; + + // + limit = prev_calculated - 1; + if (limit < 0) + { + limit = 0; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + result = + // + // Validate Peaks and Vales ... + (shortLength > 2 && + mediumLength > shortLength && + longLength > mediumLength && + hindLength > longLength) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Peaks and Vales ... + result = MathMax(shortLength, mediumLength); + result = MathMax(result, longLength); + result = MathMax(result, hindLength); + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + ArraySetAsSeries(sHHBuffer, true); + SetIndexBuffer(sHHBufferIndex, sHHBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(sLLBuffer, true); + SetIndexBuffer(sLLBufferIndex, sLLBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(mHHBuffer, true); + SetIndexBuffer(mHHBufferIndex, mHHBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(mLLBuffer, true); + SetIndexBuffer(mLLBufferIndex, mLLBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(lHHBuffer, true); + SetIndexBuffer(lHHBufferIndex, lHHBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(lLLBuffer, true); + SetIndexBuffer(lLLBufferIndex, lLLBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(hHHBuffer, true); + SetIndexBuffer(hHHBufferIndex, hHHBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(hLLBuffer, true); + SetIndexBuffer(hLLBufferIndex, hLLBuffer, INDICATOR_CALCULATIONS); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // Calculate ... + + // + // SHORT ... + + // + // HIGH ... + int sHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + shortLength, + bar_index); + double sHHValue = GetAppliedPrice( + sHHIndex, + hhMode); + + // + sHHBuffer[bar_index] = sHHValue; + + // + // LOW ... + int sLLIndex = iLowest( + _Symbol, + _Period, + llMode, + shortLength, + bar_index); + double sLLValue = GetAppliedPrice( + sLLIndex, + llMode); + + // + sLLBuffer[bar_index] = sLLValue; + + // + // MEDIUM ... + + // + // HIGH ... + int mHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + mediumLength, + bar_index); + double mHHValue = GetAppliedPrice( + mHHIndex, + hhMode); + + // + mHHBuffer[bar_index] = mHHValue; + + // + // LOW ... + int mLLIndex = iLowest( + _Symbol, + _Period, + llMode, + mediumLength, + bar_index); + double mLLValue = GetAppliedPrice( + mLLIndex, + llMode); + + // + mLLBuffer[bar_index] = mLLValue; + + // + // LONG ... + + // + // HIGH ... + int lHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + longLength, + bar_index); + double lHHValue = GetAppliedPrice( + lHHIndex, + hhMode); + + // + lHHBuffer[bar_index] = lHHValue; + + // + // LOW ... + int lLLIndex = iLowest( + _Symbol, + _Period, + llMode, + longLength, + bar_index); + double lLLValue = GetAppliedPrice( + lLLIndex, + llMode); + + // + lLLBuffer[bar_index] = lLLValue; + + // + // HIND ... + + // + // HIGH ... + int hHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + hindLength, + bar_index); + double hHHValue = GetAppliedPrice( + hHHIndex, + hhMode); + + // + hHHBuffer[bar_index] = hHHValue; + + // + // LOW ... + int hLLIndex = iLowest( + _Symbol, + _Period, + llMode, + hindLength, + bar_index); + double hLLValue = GetAppliedPrice( + hLLIndex, + llMode); + + // + hLLBuffer[bar_index] = hLLValue; + + // + // Find Swings ... + + // + // High ... + int hSwing1 = FindSwing( + _Symbol, + _Period, + MODE_HIGH, + numOfShoulder, + bar_index + 1); + + int hSwing2 = FindSwing( + _Symbol, + _Period, + MODE_HIGH, + numOfShoulder, + hSwing1 + 1); + + // + // High ... + int hSwing3 = FindSwing( + _Symbol, + _Period, + MODE_HIGH, + numOfShoulder, + hSwing2 + 1); + + // int hSwing4 = FindSwing( + // _Symbol, + // _Period, + // MODE_HIGH, + // numOfShoulder, + // hSwing3 + 1); + + // + // Low ... + int lSwing1 = FindSwing( + _Symbol, + _Period, + MODE_LOW, + numOfShoulder, + bar_index + 1); + + int lSwing2 = FindSwing( + _Symbol, + _Period, + MODE_LOW, + numOfShoulder, + lSwing1 + 1); + + int lSwing3 = FindSwing( + _Symbol, + _Period, + MODE_LOW, + numOfShoulder, + lSwing2 + 1); + + // int lSwing4 = FindSwing( + // _Symbol, + // _Period, + // MODE_LOW, + // numOfShoulder, + // lSwing3 + 1); + + // + if (bar_index < 50) + { + + // + bool isStrongResistance = + // + hHHBuffer[bar_index + 1] == hHHBuffer[bar_index + 2] && + hHHBuffer[bar_index + 2] == hHHBuffer[bar_index + 3] && + // + lHHBuffer[bar_index + 1] == lHHBuffer[bar_index + 2] && + lHHBuffer[bar_index + 2] == lHHBuffer[bar_index + 3] && + // + mHHBuffer[bar_index + 1] == mHHBuffer[bar_index + 2] && + mHHBuffer[bar_index + 2] == mHHBuffer[bar_index + 3] && + // + sHHBuffer[bar_index + 1] == sHHBuffer[bar_index + 2] && + sHHBuffer[bar_index + 2] == sHHBuffer[bar_index + 3] + // + ; + + // + bool isStrongSupport = + // + hLLBuffer[bar_index + 1] == hLLBuffer[bar_index + 2] && + hLLBuffer[bar_index + 2] == hLLBuffer[bar_index + 3] && + // + lLLBuffer[bar_index + 1] == lLLBuffer[bar_index + 2] && + lLLBuffer[bar_index + 2] == lLLBuffer[bar_index + 3] && + // + mLLBuffer[bar_index + 1] == mLLBuffer[bar_index + 2] && + mLLBuffer[bar_index + 2] == mLLBuffer[bar_index + 3] && + // + sLLBuffer[bar_index + 1] == sLLBuffer[bar_index + 2] && + sLLBuffer[bar_index + 2] == sLLBuffer[bar_index + 3] + // + ; + + // + if (isStrongResistance && showSRs) + { + // + DrawSupportResistance( + "R", + clrRed, + sHHBuffer[bar_index + 3], + bar_index + 3); + } + + // + if (isStrongSupport && showSRs) + { + // + DrawSupportResistance( + "S", + clrGreen, + sLLBuffer[bar_index + 3], + bar_index + 3); + } + } + + // + if (showTrend && bar_index < 20) + { + // + DrawSwing( + "High1", + MODE_HIGH, + clrAqua, + hSwing1, + hSwing2); + + // + DrawSwing( + "Low1", + MODE_LOW, + clrAqua, + lSwing1, + lSwing2); + + // + DrawSwing( + "High2", + MODE_HIGH, + clrMagenta, + hSwing2, + hSwing3); + + // + DrawSwing( + "Low2", + MODE_LOW, + clrMagenta, + lSwing2, + lSwing3); + } +} + +// +void DrawSwing( + string prefix, // Prefix ... + ENUM_SERIESMODE mode, // Swing Mode ... + color swingColor, // Color ... + int index1, // Index 1 ... + int index2 // Index 2 ... +) +{ + // + if (mode != MODE_HIGH && mode != MODE_LOW) + { + return; + } + + // + XOHCL c1 = GetCandle( + _Symbol, + _Period, + index1); + + // + datetime time1 = GetCandleTime( + _Symbol, + _Period, + index1); + + // + XOHCL c2 = GetCandle( + _Symbol, + _Period, + index2); + + // + datetime time2 = GetCandleTime( + _Symbol, + _Period, + index2); + + // + double value1 = -1; + double value2 = -1; + + // + switch (mode) + { + // + case MODE_HIGH: + value1 = c1.high; + value2 = c2.high; + break; + + // + case MODE_LOW: + value1 = c1.low; + value2 = c2.low; + break; + } + + // + if (value1 == -1 || value2 == -1) + { + return; + } + + // + long chartId = ChartID(); + string tlName = prefix + "_" + "TrendLine"; + + // // + // if (IsDrawExists(tlName)) { + // RemoveDraw(tlName); + // } + + // + DrawTrendLine( + chartId, + tlName, + 0, + time2, + value2, + time1, + value1, + swingColor, + STYLE_DOT, + 3, + false, + false, + true); +} + +// +// Draw Support and Resistance ... +void DrawSupportResistance( + string prefix, // Prefix ... + color lColor, // Color ... + double price, // Support or Resistance price ... + int bar_index // Start Bar Index ... +) +{ + // + datetime time1 = GetCandleTime( + _Symbol, + _Period, + bar_index); + + // + datetime time2 = GetCandleTime( + _Symbol, + _Period, + bar_index - 1); + + // + long chartId = ChartID(); + string tlName = prefix + "_" + "TL" + "_" + (string)(NormalizePrice(price, _Symbol)); + + // + DrawTrendLine( + chartId, + tlName, + 0, + time1, + price, + time2, + price, + lColor, + STYLE_DOT, + 3, + false, + false, + true); +} diff --git a/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.alert.lib.ex5 b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.alert.lib.ex5 new file mode 100644 index 0000000..b958914 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.alert.lib.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.alert.lib.mq5 b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.alert.lib.mq5 new file mode 100644 index 0000000..429d830 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.alert.lib.mq5 @@ -0,0 +1,187 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Alert Library +// -------------------------------------- +// Name: XAlert +// Description: provides Alerts abilities ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Inputs ... +// +input group "Alerts"; +input bool enableAlerts = true; // Enable Alerts +input bool logAlerts = true; // Log Alerts +input bool terminalAlerts = false; // Terminal Alerts +input bool mailAlerts = false; // Mail Alerts +input bool pushAlerts = false; // Push Alerts +// +// END Inputs ... +// + +// +#include "x-saherelm.log.lib.mq5" + +// +// START Global Definitions: Variables, Properties and etc ... +// +string alertPrefix = "X-Alert"; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// +// +// Initial Library if required ... +bool OnInInitAlertLibrary() +{ + return false; +} + +// +// DeInitial Library if required ... +void OnDeinitAlertLibrary() +{ +} + +// +// Attach Alert Prefix to Message ... +string PrepareAlertMessage(string message) +{ + // + StringReplace(message, "\n", " | "); + + // + StringConcatenate(message, alertPrefix, " > ", message); + + // + return message; +} + +// +// Logging an Alert ... +void LogAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts || !logAlerts) + { + return; + } + + // + LogMessage(alertPrefix, message); +} + +// +// Terminal Alert ... +void TerminalAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts || !terminalAlerts) + { + return; + } + + // + // Prepare Message ... + message = PrepareAlertMessage(message); + + // Send Terminal Alert ... + Alert(message); +} + +// +// Mail Alert ... +void MailAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts || !mailAlerts) + { + return; + } + + // + // Send Mail Alert ... + SendMail(alertPrefix, message); +} + +// +// Send Push Notification ... +void PushAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts || !pushAlerts) + { + return; + } + + // + // Prepare Message ... + message = PrepareAlertMessage(message); + + // + // Send Push Notification Alert ... + SendNotification(message); +} + +// +// Alert Sending ... +void SendAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts) + { + return; + } + + // + // Log ... + if (logAlerts) + { + LogAlert(message); + } + + // + // Terminal ... + if (terminalAlerts) + { + TerminalAlert(message); + } + + // + // Mail ... + if (mailAlerts) + { + MailAlert(message); + } + + // + // Push ... + if (pushAlerts) + { + PushAlert(message); + } +} +// +// END Provided Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.common.lib.ex5 b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.common.lib.ex5 new file mode 100644 index 0000000..b15d6ec Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.common.lib.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.common.lib.mq5 b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.common.lib.mq5 new file mode 100644 index 0000000..dd7d431 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.common.lib.mq5 @@ -0,0 +1,4635 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Common Library +// -------------------------------------- +// Name: XCommon +// Description: provide all commonly used functions ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Inputs ... +// + +// +// END Inputs ... +// + +// +// Include Models Library ... +#include "x-saherelm.models.lib.mq5" + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// + +// +// Detect is new Candle or not ... +bool IsNewCandle() +{ + // + bool result = false; + + // + static int barsOnChart = 0; + int currentBarsOnChart = Bars(_Symbol, _Period); + result = currentBarsOnChart > barsOnChart; + if (!result) + { + return result; + } + + // + barsOnChart = currentBarsOnChart; + result = true; + + // + return result; +} +bool IsNewCandle( + string mSymbol, // Trading Symbol ... + ENUM_TIMEFRAMES mPeriod // Trading Time Frame ... +) +{ + // + bool result = false; + + // + static string mChartTags[]; + static int mChartBars[]; + + // + string chTag = mSymbol + "," + ToString(mPeriod); + + // + int currChTagIdx = -1; + int chCountedBars = 0; + int currentBars = Bars(mSymbol, mPeriod); + + // + if (ArraySize(mChartTags) > 0) + { + // + for (int i = 0; i < ArraySize(mChartTags); i++) + { + // + string iTag = mChartTags[i]; + if (iTag != chTag) + { + continue; + } + + // + currChTagIdx = i; + break; + } + + // + if (currChTagIdx > -1) + { + chCountedBars = mChartBars[currChTagIdx]; + } + } + + // + result = currentBars > chCountedBars; + if (result) + { + // + if (currChTagIdx > -1) + { + // + mChartTags[currChTagIdx] = chTag; + mChartBars[currChTagIdx] = currentBars; + } + else + { + // + Add(chTag, mChartTags); + Add(currentBars, mChartBars); + } + } + + // + return result; +} + +// +double XNZ(double check, double val = 0) +{ + if (check == EMPTY_VALUE || check == 0) + { + return val; + } + else + { + return check; + } +} + +// +// Retrive Ask Price ... +double GetAsk() +{ + return SymbolInfoDouble(_Symbol, SYMBOL_ASK); +} +double GetAsk( + string symbol // selected symbol for calculations +) +{ + // + double result = SymbolInfoDouble(symbol, SYMBOL_ASK); + + // + return result; +} + +// +// Retrieve Bid Price ... +double GetBid() +{ + return SymbolInfoDouble(_Symbol, SYMBOL_BID); +} +double GetBid( + string symbol // selected symbol for calculations +) +{ + // + double result = SymbolInfoDouble(symbol, SYMBOL_BID); + + // + return result; +} + +// +// Calculate and Retrieve Spread Price ... +double GetSpread() +{ + // + double ask = GetAsk(); + double bid = GetBid(); + double result = MathAbs(ask - bid); + + // + return result; +} +double GetSpread( + string symbol // selected symbol for calculations +) +{ + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + double result = MathAbs(ask - bid); + + // + return result; +} + +// +// Get Points ... +double GetPoints() +{ + return _Point; +} +double GetPoints( + string symbol // selected symbol for calculations +) +{ + // + double result = SymbolInfoDouble(symbol, SYMBOL_POINT); + + // + return result; +} + +// +// Get Digits ... +int GetDigits() +{ + return _Digits; +} +int GetDigits( + string symbol // selected symbol for calculations +) +{ + // + int result = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS); + + // + return result; +} + +// +// Get Signal Entry ... +double GetEntry( + ENUM_POSITION_TYPE type // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + bool isLong = type == POSITION_TYPE_BUY; + result = isLong ? GetAsk() : GetBid(); + result = NormalizePrice(result); + + // + return result; +} +double GetEntry( + string symbol, // Specified Symbol + ENUM_POSITION_TYPE type // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + bool isLong = type == POSITION_TYPE_BUY; + result = isLong ? GetAsk(symbol) : GetBid(symbol); + result = NormalizePrice(result, symbol); + + // + return result; +} + +// +// Get Signal Exit ... +double GetExit( + ENUM_POSITION_TYPE type // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + bool isLong = type == POSITION_TYPE_BUY; + result = isLong ? GetBid() : GetAsk(); + result = NormalizePrice(result); + + // + return result; +} +double GetExit( + string symbol, // Specified Symbol + ENUM_POSITION_TYPE type // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + bool isLong = type == POSITION_TYPE_BUY; + result = isLong ? GetBid(symbol) : GetAsk(symbol); + result = NormalizePrice(result, symbol); + + // + return result; +} + +// +// Determine a Position type is Long or not ... +bool IsLong(ENUM_POSITION_TYPE type) +{ + // + bool result = type == POSITION_TYPE_BUY; + + // + return result; +} +bool IsLong(ENUM_ORDER_TYPE type) +{ + // + bool result = type == ORDER_TYPE_BUY; + + // + return result; +} + +// +// Determine a Position type is Short or not ... +bool IsShort(ENUM_POSITION_TYPE type) +{ + // + bool result = type == POSITION_TYPE_SELL; + + // + return result; +} +bool IsShort(ENUM_ORDER_TYPE type) +{ + // + bool result = type == ORDER_TYPE_SELL; + + // + return result; +} + +// +// Get 1 Pip in Price Value ... +double GetPipPrice() +{ + // + double result = _Point; + if (_Digits == 3 || _Digits == 5) + { + result *= 10; + } + + // + return result; +} +double GetPipPrice( + string symbol // selected symbol for calculations +) +{ + // + double symbolPoint = GetPoints(symbol); + int symbolDigits = GetDigits(symbol); + + // + double result = symbolPoint; + if (symbolDigits == 3 || symbolDigits == 5) + { + result *= 10; + } + + // + return result; +} + +// +// Converts Pips To Price ... +double PipsToPrice( + int pips // pips amount +) +{ + // + int digits = GetDigits(); + double pipValue = GetPipPrice(); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PipsToPrice( + double pips // pips amount +) +{ + // + int digits = GetDigits(); + double pipValue = GetPipPrice(); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PipsToPrice( + string symbol, // selected symbol for calculation + int pips // pips amount +) +{ + // + int digits = GetDigits(symbol); + double pipValue = GetPipPrice(symbol); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PipsToPrice( + string symbol, // selected symbol for calculation + double pips // pips amount +) +{ + // + int digits = GetDigits(symbol); + double pipValue = GetPipPrice(symbol); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} + +// +// Converts Price to Pips ... +double PriceToPips( + double price // the price amount which required to calculate +) +{ + // + int digits = GetDigits(); + double pipPrice = GetPipPrice(); + + // + double result = price / pipPrice; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PriceToPips( + string symbol, // Selected Symbol + double price // the price amount which required to calculate +) +{ + // + int digits = GetDigits(symbol); + double pipPrice = GetPipPrice(symbol); + + // + double result = price / pipPrice; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} + +// +// Convert Price to Point ... +double PriceToPoint( + double price // the price amount which required to calculate +) +{ + return PriceToPoint(_Symbol, price); +} +double PriceToPoint( + string symbol, // Selected Symbol + double price // the price amount which required to calculate +) +{ + // + double result = 0; + + // + double point = GetPoints(symbol); + result = price / point; + + // + return result; +} + +// +// Converts Point to Price ... +double PointToPrice( + double points // Points Size +) +{ + return PointToPrice(_Symbol, points); +} +double PointToPrice( + string symbol, // Selected Symbol + double points // Points Size +) +{ + // + double result = 0; + + // + double point = GetPoints(symbol); + result = points * point; + + // + return result; +} + +// +// Get a Candle Body ... +double GetCandleBody( + XOHCL &candle // specified candle +) +{ + // + double result = MathAbs(candle.open - candle.close); + + // + return result; +} + +// +// Get a Candle Range ... +double GetCandleRange( + XOHCL &candle // specified candle +) +{ + // + double result = MathAbs(candle.high - candle.low); + + // + return result; +} + +// +// Get a Candle Shadow ... +double GetCandleShadow( + XOHCL &candle // specified candle +) +{ + // + double range = GetCandleRange(candle); + double body = GetCandleBody(candle); + + // + double result = MathAbs(range - body); + + // + return result; +} + +// +// Check a Candle is Base Candle for RTM or not ... +bool IsBaseCandle( + XOHCL &candle // specified candle +) +{ + // + double range = GetCandleRange(candle); + double body = GetCandleBody(candle); + + // + bool result = body > range; + + // + return result; +} + +// +// Retrieve Applied Price at Specific Candle ... +double GetAppliedPrice( + XOHCL &candle, // specified candle + ENUM_APPLIED_PRICE source = PRICE_CLOSE // specified Applied To +) +{ + // + double result = EMPTY_VALUE; + + // + switch (source) + { + // + // Open ... + case PRICE_OPEN: + result = candle.open; + break; + + // + // High ... + case PRICE_HIGH: + result = candle.high; + break; + + // + // Low ... + case PRICE_LOW: + result = candle.low; + break; + + // + // Median ((High + Low) / 2) ... + case PRICE_MEDIAN: + result = (candle.high + candle.low) / 2; + break; + + // + // Typical ((High + Low + Close)/3) ... + case PRICE_TYPICAL: + result = (candle.high + candle.low + candle.close) / 3; + break; + + // + // Weighted ((High + Low + Close + Close)/4) ... + case PRICE_WEIGHTED: + result = (candle.high + candle.low + (candle.close * 2)) / 4; + break; + + // + // Close ... + default: + case PRICE_CLOSE: + result = candle.close; + break; + } + + // + return result; +} +double GetAppliedPrice( + int bar_index, // specify candle index + ENUM_APPLIED_PRICE source = PRICE_CLOSE // specified Applied To +) +{ + // + double result = EMPTY_VALUE; + + // + XOHCL candle = GetCandle(bar_index); + result = GetAppliedPrice(candle, source); + + // + return result; +} +double GetAppliedPrice( + int bar_index, // specify candle index + ENUM_SERIESMODE mode // converts Series Mode to Applied Price ... +) +{ + // + double result = 0; + + // + ENUM_APPLIED_PRICE mAppliedTo = To(mode); + result = GetAppliedPrice( + bar_index, + mAppliedTo); + + // + return result; +} + +// +template +double GetAppliedPrice(ENUM_APPLIED_PRICE tprice, T &open[], T &high[], T &low[], T &close[], int i) +{ + switch (tprice) + { + case PRICE_CLOSE: + return (close[i]); + case PRICE_OPEN: + return (open[i]); + case PRICE_HIGH: + return (high[i]); + case PRICE_LOW: + return (low[i]); + case PRICE_MEDIAN: + return ((high[i] + low[i]) / 2.0); + case PRICE_TYPICAL: + return ((high[i] + low[i] + close[i]) / 3.0); + case PRICE_WEIGHTED: + return ((high[i] + low[i] + close[i] + close[i]) / 4.0); + } + return (0); +} + +// +// Converts ... +ENUM_APPLIED_PRICE To( + ENUM_SERIESMODE mode // converts Series Mode to Applied Price ... +) +{ + // + ENUM_APPLIED_PRICE result = PRICE_CLOSE; + + // + switch (mode) + { + // + // High ... + case MODE_HIGH: + result = PRICE_HIGH; + break; + + // + // Open ... + case MODE_OPEN: + result = PRICE_OPEN; + break; + + // + // Low ... + case MODE_LOW: + result = PRICE_LOW; + break; + + // + // Close ... + // Default ... + case MODE_CLOSE: + default: + result = PRICE_CLOSE; + break; + } + + // + return result; +} + +// +// Retrieve a Candel Data ... +XOHCL GetCandle(int bar_index) +{ + // + XOHCL result = {}; + + // + double open = iOpen(_Symbol, _Period, bar_index); + double high = iHigh(_Symbol, _Period, bar_index); + double close = iClose(_Symbol, _Period, bar_index); + double low = iLow(_Symbol, _Period, bar_index); + + // + result.low = low; + result.open = open; + result.high = high; + result.close = close; + + // + return result; +} +XOHCL GetCandle( + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + XOHCL result = {}; + + // + double open = iOpen(_Symbol, mPeriod, bar_index); + double high = iHigh(_Symbol, mPeriod, bar_index); + double close = iClose(_Symbol, mPeriod, bar_index); + double low = iLow(_Symbol, mPeriod, bar_index); + + // + result.low = low; + result.open = open; + result.high = high; + result.close = close; + + // + return result; +} +XOHCL GetCandle( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + XOHCL result = {}; + + // + double open = iOpen(symbol, mPeriod, bar_index); + double high = iHigh(symbol, mPeriod, bar_index); + double close = iClose(symbol, mPeriod, bar_index); + double low = iLow(symbol, mPeriod, bar_index); + + // + result.low = low; + result.open = open; + result.high = high; + result.close = close; + + // + return result; +} + +// +// Get a Series Of Candles ... +bool GetCandles( + XOHCL &result[], // Hold Result ... + string mSymbol = NULL, // Specified Symbol ... + ENUM_TIMEFRAMES mPeriod = NULL, // Specified Period ... + int mStart = 0, // Start Bar Index ... + int mCount = 1 // Specified Number of Candles ... +) +{ + // + bool mResult = false; + + // + if (mStart < 0) + { + mStart = 0; + } + + // + if (mCount <= 0) + { + mCount = 1; + } + + // + Clean(result); + + // + for (int i = mStart; i < mStart + mCount; i++) + { + // + XOHCL iC = GetCandle( + mSymbol, + mPeriod, + i); + + // + Add( + iC, + result); + } + + // + mResult = ArraySize(result) > 0; + + // + return mResult; +} + +// +// Retrieve a candle index in current timeframe inside another timeframe ... +int GetCandleBarIndex( + int bar_index, // Specify Candle index in current timeframe + ENUM_TIMEFRAMES destPeriod // Specify destination timeframe +) +{ + // + int result = -1; + + // + datetime barTime = iTime(_Symbol, _Period, bar_index); + result = iBarShift(_Symbol, destPeriod, barTime); + + // + return result; +} + +// +// Retrieve a symbol candle index in source time frame inside dest timeframe ... +int GetCandleBarIndex( + int bar_index, // Specify Candle index in current timeframe + string symbol, // Specify desired Symbol + ENUM_TIMEFRAMES sourcePeriod, // Specify bar_index timeframe + ENUM_TIMEFRAMES destPeriod // Specify destination timeframe +) +{ + // + int result = -1; + + // + datetime barTime = iTime(symbol, sourcePeriod, bar_index); + result = iBarShift(symbol, destPeriod, barTime); + + // + return result; +} + +// +// Check a Candle is Bullish or not ... +bool IsBullishCandle( + XOHCL &candle // specified candle +) +{ + // + bool result = false; + + // + result = candle.open < candle.close; + + // + return result; +} +bool IsBullishCandle( + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle(bar_index); + + // + result = IsBullishCandle(candle); + + // + return result; +} +bool IsBullishCandle( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle( + symbol, + mPeriod, + bar_index); + + // + result = IsBullishCandle(candle); + + // + return result; +} + +// +// Check a Candle is Bullish or not ... +bool IsBearishCandle( + XOHCL &candle // specified candle +) +{ + // + bool result = false; + + // + result = candle.open > candle.close; + + // + return result; +} +bool IsBearishCandle( + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle(bar_index); + + // + result = IsBearishCandle(candle); + + // + return result; +} +bool IsBearishCandle( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle( + symbol, + mPeriod, + bar_index); + + // + result = IsBearishCandle(candle); + + // + return result; +} + +// +// Check Candle Body Bigger Than it's Shadow ... +bool CandleHasStrongBody(XOHCL &candle) +{ + // + double bodySize = MathAbs(candle.open - candle.close); + double shadowSize = MathAbs(candle.high - candle.low) - bodySize; + + // + bool result = bodySize > (shadowSize * 1.5); + + // + return result; +} + +// +// Determines a cnadle is Swing High +// or Swing Low order block ... +ENUM_X_SWING_TYPE GetCandleSwing(int bar_index) +{ + // + ENUM_X_SWING_TYPE result = X_NO_SWING; + + // + // Reading Candle Models ... + XOHCL candles[3]; + candles[0] = GetCandle(bar_index + 1); + candles[1] = GetCandle(bar_index + 2); + candles[2] = GetCandle(bar_index + 3); + + // + // Check Swing Start Candle has Strong Body ... + bool isStrongBodyCandle = CandleHasStrongBody(candles[2]); + if (!isStrongBodyCandle) + { + return result; + } + + // + // Check Swing Low Conditions ... + bool isSwingLowOrderBlock = + candles[2].low < candles[1].low && + candles[1].low < candles[0].low && + candles[2].low < candles[0].low; + if (isSwingLowOrderBlock) + { + result = X_SWING_LOW; + } + + // + // Check Swing High Conditions ... + bool isSwingHighOrderBlock = + candles[2].high > candles[1].high && + candles[1].high > candles[0].high && + candles[2].high > candles[0].high; + if (isSwingHighOrderBlock) + { + result = X_SWING_HIGH; + } + + // + return result; +} +ENUM_X_SWING_TYPE GetCandleSwing( + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + ENUM_X_SWING_TYPE result = X_NO_SWING; + + // + // Reading Candle Models ... + XOHCL candles[3]; + candles[0] = GetCandle(mPeriod, bar_index + 1); + candles[1] = GetCandle(mPeriod, bar_index + 2); + candles[2] = GetCandle(mPeriod, bar_index + 3); + + // + // Check Swing Start Candle has Strong Body ... + bool isStrongBodyCandle = CandleHasStrongBody(candles[2]); + if (!isStrongBodyCandle) + { + return result; + } + + // + // Check Swing Low Conditions ... + bool isSwingLowOrderBlock = + candles[2].low < candles[1].low && + candles[1].low < candles[0].low && + candles[2].low < candles[0].low; + if (isSwingLowOrderBlock) + { + result = X_SWING_LOW; + } + + // + // Check Swing High Conditions ... + bool isSwingHighOrderBlock = + candles[2].high > candles[1].high && + candles[1].high > candles[0].high && + candles[2].high > candles[0].high; + if (isSwingHighOrderBlock) + { + result = X_SWING_HIGH; + } + + // + return result; +} +ENUM_X_SWING_TYPE GetCandleSwing( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + ENUM_X_SWING_TYPE result = X_NO_SWING; + + // + // Reading Candle Models ... + XOHCL candles[3]; + candles[0] = GetCandle(symbol, mPeriod, bar_index + 1); + candles[1] = GetCandle(symbol, mPeriod, bar_index + 2); + candles[2] = GetCandle(symbol, mPeriod, bar_index + 3); + + // + // Check Swing Start Candle has Strong Body ... + bool isStrongBodyCandle = CandleHasStrongBody(candles[2]); + if (!isStrongBodyCandle) + { + return result; + } + + // + // Check Swing Low Conditions ... + bool isSwingLowOrderBlock = + candles[2].low < candles[1].low && + candles[1].low < candles[0].low && + candles[2].low < candles[0].low; + if (isSwingLowOrderBlock) + { + result = X_SWING_LOW; + } + + // + // Check Swing High Conditions ... + bool isSwingHighOrderBlock = + candles[2].high > candles[1].high && + candles[1].high > candles[0].high && + candles[2].high > candles[0].high; + if (isSwingHighOrderBlock) + { + result = X_SWING_HIGH; + } + + // + return result; +} + +// +// Find Swing Points ... +int FindSwing( + string mSymbol, // Trading Symbol ... + ENUM_TIMEFRAMES mPeriod, // Trading Period ... + ENUM_SERIESMODE mode, // Swing Based On Price mode ... + int mLength, // Loopback ... + int bar_index // BarIndex ... +) +{ + // + int result = -1; + + // + if (StringLen(mSymbol) == 0 || (mode != MODE_HIGH && mode != MODE_LOW)) + { + return result; + } + + // + int current = bar_index; + int founded = FindNextSwing( + mSymbol, + mPeriod, + mode, + (mLength * 2) + 1, + current - mLength); + + // + while (founded != current) + { + // + current = FindNextSwing( + mSymbol, + mPeriod, + mode, + mLength, + current + 1); + + // + founded = FindNextSwing( + mSymbol, + mPeriod, + mode, + (mLength * 2) + 1, + current - mLength); + } + + // + result = current; + + // + return result; +} + +// +// Find Next Swing ... +int FindNextSwing( + string mSymbol, // Trading Symbol ... + ENUM_TIMEFRAMES mPeriod, // Trading Period ... + ENUM_SERIESMODE mode, // Swing Based On Price mode ... + int mLength, // Loopback ... + int bar_index // BarIndex ... +) +{ + // + int result = -1; + + // + if (bar_index < 0) + { + mLength += bar_index; + bar_index = 0; + } + + // + result = mode == MODE_HIGH + ? iHighest( + mSymbol, + mPeriod, + mode, + mLength, + bar_index) + : iLowest( + mSymbol, + mPeriod, + mode, + mLength, + bar_index); + + // + return result; +} + +// +// Retrieve Market Highest High ... +double GetHighestHigh( + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + mLength, + bar_index); + + // + result = iHigh( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetHighestHigh( + int mLength, // Which market Length use + int bar_index, // bar index + ENUM_SERIESMODE mode // Calculation mode +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + _Symbol, + _Period, + mode, + mLength, + bar_index); + + // + result = iHigh( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetHighestHigh( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + symbol, + mPeriod, + MODE_HIGH, + mLength, + bar_index); + + // + result = iHigh( + symbol, + mPeriod, + rIdx); + + // + return result; +} +double GetHighestHigh( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + ENUM_SERIESMODE mode, // Calculation mode + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + symbol, + mPeriod, + mode, + mLength, + bar_index); + + // + result = iHigh( + symbol, + mPeriod, + rIdx); + + // + return result; +} + +// +// Retrieve Market Lowest Low ... +double GetLowestLow( + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + mLength, + bar_index); + + // + result = iLow( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetLowestLow( + int mLength, // Which market Length use + int bar_index, // bar index + ENUM_SERIESMODE mode // Calculation mode +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + _Symbol, + _Period, + mode, + mLength, + bar_index); + + // + result = iLow( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetLowestLow( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + symbol, + mPeriod, + MODE_LOW, + mLength, + bar_index); + + // + result = iLow( + symbol, + mPeriod, + rIdx); + + // + return result; +} +double GetLowestLow( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + ENUM_SERIESMODE mode, // Calculation mode + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + symbol, + mPeriod, + mode, + mLength, + bar_index); + + // + result = iLow( + symbol, + mPeriod, + rIdx); + + // + return result; +} + +// +// Find Support and Resistance for Specific Bar based on provided Buffer ... +XOHCLSupRes ExtractSupportAndResistance( + int barIndex, // Bar Index ... + const double &pivots[], // Provided Pivot Points ... + int count = 3, // Number of Requireds ... + string mSymbol = NULL, // Trading Symbol ... + ENUM_TIMEFRAMES mPeriod = NULL // Trading Period ... +) +{ + // + if (StringLen(mSymbol) == 0 || mSymbol == NULL) + { + mSymbol = _Symbol; + } + + // + if (mPeriod == NULL) + { + mPeriod = _Period; + } + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + XOHCLSupRes result; + Clean(result.res); + Clean(result.sup); + + // + int pivotsCount = ArraySize(pivots); + if (pivotsCount <= 0) + { + return result; + } + + // + if (count <= 0 || + count > pivotsCount - 1) + { + return result; + } + + // + XOHCL cBar = GetCandle( + mSymbol, + mPeriod, + barIndex); + + // + double tmpR[]; + + // + double tmpS[]; + + // + // Extract Supports ... + // which prices is under low of candle ... + // + // Extract Resistance ... + // which prices is over high of candle ... + for (int i = 0; i < pivotsCount; i++) + { + // + double iFlat = pivots[i]; + + // + if (iFlat > cBar.high) + { + Add( + iFlat, + tmpR); + } + else if (iFlat < cBar.low) + { + Add( + iFlat, + tmpS); + } + } + + // + // Sorting Founded Resistance and Supports ... + + // + // Since Resistance Levels must be Increasing ... + ArraySort(tmpR); + + // + // Since Support Levels must be Decreasing ... + ArraySort(tmpS); + ArrayReverse(tmpS); + + // + // Fill Resistance ... + int tmpRCount = ArraySize(tmpR); + if (tmpRCount > 0) + { + // + if (tmpRCount < count) + { + // + ArrayCopy( + result.res, + tmpR); + } + else + { + // + ArrayCopy( + result.res, + tmpR, + 0, + 0, + count); + } + } + + // + // Fill Supports ... + int tmpSCount = ArraySize(tmpS); + if (tmpSCount > 0) + { + // + if (tmpSCount < count) + { + // + ArrayCopy( + result.sup, + tmpS); + } + else + { + // + ArrayCopy( + result.sup, + tmpS, + 0, + 0, + count); + } + } + + // + return result; +} + +// +// Find Support and Resistance for Specific Price based on provided Buffer ... +XOHCLSupRes ExtractSupportAndResistance( + double price, // Price ... + const double &pivots[], // Provided Pivot Points ... + int count = 3 // Number of Requireds ... +) +{ + // + XOHCLSupRes result; + Clean(result.res); + Clean(result.sup); + + // + if (price <= 0) + { + return result; + } + + // + int pivotsCount = ArraySize(pivots); + if (pivotsCount <= 0) + { + return result; + } + + // + if (count <= 0 || + count > pivotsCount - 1) + { + return result; + } + + // + double tmpR[]; + + // + double tmpS[]; + + // + // Extract Supports ... + // which prices is under low of candle ... + // + // Extract Resistance ... + // which prices is over high of candle ... + for (int i = 0; i < pivotsCount; i++) + { + // + double iFlat = pivots[i]; + + // + if (iFlat > price) + { + Add( + iFlat, + tmpR); + } + else if (iFlat < price) + { + Add( + iFlat, + tmpS); + } + } + + // + // Sorting Founded Resistance and Supports ... + + // + // Since Resistance Levels must be Increasing ... + ArraySort(tmpR); + + // + // Since Support Levels must be Decreasing ... + ArraySort(tmpS); + ArrayReverse(tmpS); + + // + // Fill Resistance ... + int tmpRCount = ArraySize(tmpR); + if (tmpRCount > 0) + { + // + if (tmpRCount < count) + { + // + ArrayCopy( + result.res, + tmpR); + } + else + { + // + ArrayCopy( + result.res, + tmpR, + 0, + 0, + count); + } + } + + // + // Fill Supports ... + int tmpSCount = ArraySize(tmpS); + if (tmpSCount > 0) + { + // + if (tmpSCount < count) + { + // + ArrayCopy( + result.sup, + tmpS); + } + else + { + // + ArrayCopy( + result.sup, + tmpS, + 0, + 0, + count); + } + } + + // + return result; +} + +// +// Find a Value less than Specified ... +double FindLesserThanValue( + double value, // Specified Value ... + const double &source[], // Source ... + bool isDescend = false // Find Biggest Lesser Value ... +) +{ + // + double result = -1; + + // + int itemsCount = ArraySize(source); + if (itemsCount <= 0) + { + return result; + } + + // + // Make a Copy of source ... + double tmp[]; + + // + ArrayResize( + tmp, + ArraySize(source)); + + // + ArrayCopy( + tmp, + source); + + // + // Sort Temp Buffer ... + ArraySort(tmp); + if (isDescend) + { + ArrayReverse(tmp); + } + + // + int tmpCount = ArraySize(tmp); + for (int i = 0; i < tmpCount; i++) + { + // + double iValue = tmp[i]; + + // + if (iValue < value) + { + // + result = iValue; + break; + } + } + + // + return result; +} + +// +// Find a Value less than Specified ... +double FindBiggerThanValue( + double value, // Specified Value ... + const double &source[], // Source ... + bool isDescend = false // Find Smallest Bigger Value ... +) +{ + // + double result = -1; + + // + int itemsCount = ArraySize(source); + if (itemsCount <= 0) + { + return result; + } + + // + // Make a Copy of source ... + double tmp[]; + + // + ArrayResize( + tmp, + ArraySize(source)); + + // + ArrayCopy( + tmp, + source); + + // + // Sort Temp Buffer ... + ArraySort(tmp); + if (!isDescend) + { + ArrayReverse(tmp); + } + + // + int tmpCount = ArraySize(tmp); + for (int i = 0; i < tmpCount; i++) + { + // + double iValue = tmp[i]; + + // + if (iValue > value) + { + // + result = iValue; + break; + } + } + + // + return result; +} + +// +// Calculate Fib Level ... +double GetFibonacciLevel( + double upPrice, + double downPrice, + double level, + int direction) +{ + // + double ling = upPrice - downPrice; + double pLevel = (ling / 100) * (level * 100); + + // + double result = direction > 0 ? upPrice - pLevel : downPrice + pLevel; + result = NormalizeDouble(result, _Digits); + + // + return result; +} + +// +// Check first Cross Over second at bar_index ... +bool IsCrossOver( + const double &first[], // the buffer which check crossing over second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] > second[bar_index] && + !(first[bar_index + 1] > second[bar_index + 1]); + + // + return result; +} + +// +// Check first is Over second at bar_index ... +bool IsOver( + const double &first[], // the buffer which check over second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] > second[bar_index] && + first[bar_index + 1] > second[bar_index + 1]; + + // + return result; +} + +// +// Check first Cross Under second at bar_index ... +bool IsCrossUnder( + const double &first[], // the buffer which check crossing under second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] < second[bar_index] && + !(first[bar_index + 1] < second[bar_index + 1]); + + // + return result; +} + +// +// Check first is Under second at bar_index ... +bool IsUnder( + const double &first[], // the buffer which check under second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] < second[bar_index] && + first[bar_index + 1] < second[bar_index + 1]; + + // + return result; +} + +// +// Calculate Slope of Specified Buffer at Specified Index ... +double GetSlope( + int from, // In Past Index ... + int to, // In Past Index ... + double &buffer[]) +{ + // + double result = 0; + + // + double toValue = buffer[to]; + double fromValue = buffer[from]; + double deltaValue = toValue - fromValue; + double deltaTime = from - to; + + // + result = deltaValue / deltaTime; + + // + return result; +} + +// +// Check if a Value Increasing in Loopback ... +bool IsIncreasing( + int from, // Last Time Index + int to, // Fisr Tima Index + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + result = toValue > fromValue; + for (int i = to + 1; i <= from - 1; i++) + { + // + double iValue = buffer[i]; + bool isPassed = toValue >= iValue; + + // + bool isIIncreasing = IsIncreasing( + from, + i, + buffer); + + // + // Check Result ... + result = result && isPassed && isIIncreasing; + if (!result) + { + break; + } + } + + // + return result; +} + +// +// Check if a Value Decreasing in Loopback ... +bool IsDecreasing( + int from, // Last Time Index + int to, // Fisr Tima Index + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + result = toValue < fromValue; + for (int i = to + 1; i <= from - 1; i++) + { + // + double iValue = buffer[i]; + bool isPassed = toValue <= iValue; + + // + bool isIDecreasing = IsDecreasing( + from, + i, + buffer); + + // + // Check Result ... + result = result && isPassed && isIDecreasing; + if (!result) + { + break; + } + } + + // + return result; +} + +// +// Get Max Value of Specific Loopback of a Buffer ... +double GetMaxValue( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback) + { + return result; + } + + // + // Loop Through LoopBack ... + for (int i = 0; i < mLoopback; i++) + { + // + double iValue = buffer[i]; + + // + result = + // + result == 0 || result < iValue + // + ? iValue + // + : result + // + ; + } + + // + return result; +} + +// +// Get Min Value of Specific Loopback of a Buffer ... +double GetMinValue( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback) + { + return result; + } + + // + // Loop Through LoopBack ... + for (int i = 0; i < mLoopback; i++) + { + // + double iValue = buffer[i]; + + // + result = + // + result == 0 || result > iValue + // + ? iValue + // + : result + // + ; + } + + // + return result; +} + +// +// Find Same Values in Array ... +void FindSameValueInBuffer( + double &result[], // Holds Result ... + double &source[], // Source ... + int verifications = 3 // Number of Consequence Repeat ... +) +{ + // + Clean(result); + + // + // TenkanSen Flats ... + int sourceCount = ArraySize(source); + if (sourceCount > verifications) + { + // + double mLast = 0; + int mVerified = 0; + for (int i = 0; i < sourceCount; i++) + { + // + double iVal = source[i]; + if (mLast == 0) + { + mLast = iVal; + } + else if (mLast == iVal) + { + mVerified++; + } + else + { + mLast = iVal; + mVerified = 0; + } + + // + if (iVal == mLast && mVerified >= verifications) + { + // + Add( + iVal, + result); + + // + mLast = 0; + mVerified = 0; + } + } + } +} + +// +bool IsInPeak( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback + 1) + { + return result; + } + + // + int q1Length = mLoopback / 4; + int halfLength = mLoopback / 2; + int q2Length = halfLength + q1Length; + + // + double firstValue = buffer[1]; + double q1Value = buffer[q1Length]; + double q2Value = buffer[q2Length]; + double halfValue = buffer[halfLength]; + double lastValue = buffer[ArraySize(buffer) - 1]; + + // + // Peak ... + result = + // + firstValue > lastValue + // + && + // + ( + firstValue > q1Value && + firstValue > halfValue) + // + ; + + // + return result; +} + +// +bool IsInVale( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback + 1) + { + return result; + } + + // + int q1Length = mLoopback / 4; + int halfLength = mLoopback / 2; + int q2Length = halfLength + q1Length; + + // + double firstValue = buffer[1]; + double q1Value = buffer[q1Length]; + double q2Value = buffer[q2Length]; + double halfValue = buffer[halfLength]; + double lastValue = buffer[ArraySize(buffer) - 1]; + + // + // Peak ... + result = + // + firstValue < lastValue + // + && + // + ( + firstValue < q1Value && + firstValue < halfValue) + // + ; + + // + return result; +} + +// +// Check Sharp Happens or not ... +bool IsSharpChanged( + double fromValue, // Past Value + double toValue, // Present Value + double maxValue, // Max in Range Value + double minValue // Min in Range Value +) +{ + // + bool result = false; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double toFromDelta = MathAbs(toValue - fromValue); + double minMaxDelta = maxValue - minValue; + + // + result = toFromDelta >= (minMaxDelta / 3); + + // + return result; +} +bool IsSharpChanged( + int from, // Past Index in Series + int to, // Present Index in Series + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double minValue = GetMinValue( + ArraySize(buffer) - 1, + buffer); + double maxValue = GetMaxValue( + ArraySize(buffer) - 1, + buffer); + double minMaxDelta = maxValue - minValue; + + // + // Sharp Detection ... + result = IsSharpChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} +bool IsSharpChanged( + int from, // Past Bar Index + int to, // Present Bar Index + ENUM_APPLIED_PRICE appliedPrice // Which Price Choose in From or To +) +{ + // + bool result = false; + + // + double toValue = GetAppliedPrice( + to, + appliedPrice); + double fromValue = GetAppliedPrice( + from, + appliedPrice); + + // + int hIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + from, + to); + double maxValue = iHigh( + _Symbol, + _Period, + hIdx); + + // + int lIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + from, + to); + double minValue = iLow( + _Symbol, + _Period, + lIdx); + + // + result = IsSharpChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} + +// +// Check InCreased Sharp Happens or not ... +bool IsSharpIncreasedChanged( + double fromValue, // Past Value + double toValue, // Present Value + double maxValue, // Max in Range Value + double minValue // Min in Range Value +) +{ + // + bool result = false; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double toFromDelta = MathAbs(toValue - fromValue); + double minMaxDelta = maxValue - minValue; + + // + result = + isIncreased && + toFromDelta >= (minMaxDelta / 3); + + // + return result; +} +bool IsSharpIncreasedChanged( + int from, // Past Index in Series + int to, // Present Index in Series + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + + // + double minValue = GetMinValue( + ArraySize(buffer) - 1, + buffer); + double maxValue = GetMaxValue( + ArraySize(buffer) - 1, + buffer); + double minMaxDelta = maxValue - minValue; + + // + // Sharp Detection ... + result = IsSharpIncreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} +bool IsSharpIncreasedChanged( + int from, // Past Bar Index + int to, // Present Bar Index + ENUM_APPLIED_PRICE appliedPrice // Which Price Choose in From or To +) +{ + // + bool result = false; + + // + double toValue = GetAppliedPrice( + to, + appliedPrice); + double fromValue = GetAppliedPrice( + from, + appliedPrice); + + // + int hIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + from, + to); + double maxValue = iHigh( + _Symbol, + _Period, + hIdx); + + // + int lIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + from, + to); + double minValue = iLow( + _Symbol, + _Period, + lIdx); + + // + result = IsSharpIncreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} + +// +// Check Decreased Sharp Happens or not ... +bool IsSharpDecreasedChanged( + double fromValue, // Past Value + double toValue, // Present Value + double maxValue, // Max in Range Value + double minValue // Min in Range Value +) +{ + // + bool result = false; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double toFromDelta = MathAbs(toValue - fromValue); + double minMaxDelta = maxValue - minValue; + + // + result = + !isIncreased && + toFromDelta >= (minMaxDelta / 3); + + // + return result; +} +bool IsSharpDecreasedChanged( + int from, // Past Index in Series + int to, // Present Index in Series + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + + // + double minValue = GetMinValue( + ArraySize(buffer) - 1, + buffer); + double maxValue = GetMaxValue( + ArraySize(buffer) - 1, + buffer); + double minMaxDelta = maxValue - minValue; + + // + // Sharp Detection ... + result = IsSharpDecreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} +bool IsSharpDecreasedChanged( + int from, // Past Bar Index + int to, // Present Bar Index + ENUM_APPLIED_PRICE appliedPrice // Which Price Choose in From or To +) +{ + // + bool result = false; + + // + double toValue = GetAppliedPrice( + to, + appliedPrice); + double fromValue = GetAppliedPrice( + from, + appliedPrice); + + // + int hIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + from, + to); + double maxValue = iHigh( + _Symbol, + _Period, + hIdx); + + // + int lIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + from, + to); + double minValue = iLow( + _Symbol, + _Period, + lIdx); + + // + result = IsSharpDecreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} + +// +void Clean(int &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void Clean(ulong &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void Clean(string &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void Clean(double &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} + +// +bool GetLastItem( + double &item, // Holds Result + double &buffer[] // Specified Buffer +) +{ + // + bool result = false; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + item = buffer[bufferSize - 1]; + + // + result = true; + return result; +} +bool GetLastItem( + datetime &item, // Holds Result + datetime &buffer[] // Specified Buffer +) +{ + // + bool result = false; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + item = buffer[bufferSize - 1]; + + // + result = true; + return result; +} + +// +void Add( + int item, // item want to add + int &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + ulong item, // item want to add + ulong &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + string item, // item want to add + string &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + double item, // item want to add + double &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + XOHCL &item, // item want to add + XOHCL &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + datetime &item, // item want to add + datetime &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} + +// +// Add an Item to a Buffer if not Exists ... +void AddIfNotExists( + double value, + double &values[], + double smoothingPoint = 3) +{ + // + double smoothingValue = smoothingPoint * GetPoints(_Symbol); + + // + int valuesCount = ArraySize(values); + if (valuesCount <= 0) + { + // + Add(value, + values); + } + else + { + // + bool isExists = false; + for (int i = 0; i < valuesCount; i++) + { + // + double iVal = values[i]; + + // + double diff = MathAbs(iVal - value); + + // + if (iVal == value || diff < smoothingValue) + { + // + isExists = true; + break; + } + } + + // + if (!isExists) + { + // + Add(value, + values); + } + } +} + +// +// Add a Buffers Child to another Buffer +// if it's not Contains them ... +void AddsIfNotExists( + double &source[], + double &dest[], + double smoothingPoint = 3) +{ + // + double smoothingValue = smoothingPoint * GetPoints(_Symbol); + + // + int sourceCount = ArraySize(source); + if (sourceCount <= 0) + { + return; + } + + // + for (int i = 0; i < sourceCount; i++) + { + // + double iSource = source[i]; + + // + AddIfNotExists( + iSource, + dest, + smoothingPoint); + } +} + +// +// Converts a Buffer to String Representation ... +string ToString( + const int &buffer[], // Specified Buffer + string separator = ",", // Specified Separator + bool addIndex = false, // Specified Add Items Indexes or Not + string indexLabel = "i:", // Specified Index Label + string indexSeparator = ">" // Specified Index Separator + +) +{ + // + string result = ""; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + for (int i = 0; i < bufferSize; i++) + { + // + if (addIndex) + { + // + if (StringLen(indexLabel) > 0) + { + result += indexLabel + " "; + } + + // + result += (string)i + " "; + + // + if (StringLen(indexSeparator) > 0) + { + result += indexSeparator + " "; + } + } + + // + string iItemString = (string)buffer[i]; + + // + result += iItemString; + + // + if (i < bufferSize - 1) + { + result += separator; + } + } + + // + return result; +} +string ToString( + const double &buffer[], // Specified Buffer + string separator = ",", // Specified Separator + bool addIndex = false, // Specified Add Items Indexes or Not + string indexLabel = "i:", // Specified Index Label + string indexSeparator = ">" // Specified Index Separator + +) +{ + // + string result = ""; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + for (int i = 0; i < bufferSize; i++) + { + // + if (addIndex) + { + // + if (StringLen(indexLabel) > 0) + { + result += indexLabel + " "; + } + + // + result += (string)i + " "; + + // + if (StringLen(indexSeparator) > 0) + { + result += indexSeparator + " "; + } + } + + // + string iItemString = (string)buffer[i]; + + // + result += iItemString; + + // + if (i < bufferSize - 1) + { + result += separator; + } + } + + // + return result; +} +string ToString( + const string &buffer[], // Specified Buffer + string separator = ",", // Specified Separator + bool addIndex = false, // Specified Add Items Indexes or Not + string indexLabel = "i:", // Specified Index Label + string indexSeparator = ">" // Specified Index Separator + +) +{ + // + string result = ""; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + for (int i = 0; i < bufferSize; i++) + { + // + if (addIndex) + { + // + if (StringLen(indexLabel) > 0) + { + result += indexLabel + " "; + } + + // + result += (string)i + " "; + + // + if (StringLen(indexSeparator) > 0) + { + result += indexSeparator + " "; + } + } + + // + string iItemString = (string)buffer[i]; + + // + result += iItemString; + + // + if (i < bufferSize - 1) + { + result += separator; + } + } + + // + return result; +} +string ToString( + const datetime &buffer[], // Specified Buffer + string separator = ",", // Specified Separator + bool addIndex = false, // Specified Add Items Indexes or Not + string indexLabel = "i:", // Specified Index Label + string indexSeparator = ">" // Specified Index Separator +) +{ + // + string result = ""; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + for (int i = 0; i < bufferSize; i++) + { + // + if (addIndex) + { + // + if (StringLen(indexLabel) > 0) + { + result += indexLabel + " "; + } + + // + result += (string)i + " "; + + // + if (StringLen(indexSeparator) > 0) + { + result += indexSeparator + " "; + } + } + + // + string iItemString = (string)buffer[i]; + + // + result += iItemString; + + // + if (i < bufferSize - 1) + { + result += separator; + } + } + + // + return result; +} +template +string ToString(T value) +{ + return (string)value; +} + +// +// Search Array For Specific Item ... +template +int FindIndex( + T item, // What is Search ... + T &buffer[] // Search in ... +) +{ + // + int result = -1; + + // + int count = ArraySize(buffer); + if (count <= 0) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + T iT = buffer[i]; + + // + if (iT == item) + { + // + result = i; + break; + } + } + + // + return result; +} + +template +bool Contains( + T item, // What is Search ... + T &buffer[] // Search in ... +) +{ + // + bool result = false; + + // + int idx = FindIndex( + item, + buffer); + result = idx > -1; + + // + return result; +} + +// +// Split an String Representation of an Array ... +void SplitContent( + string &result[], // Hold Result ... + string content, // Source ... + string separator = ",", // Separator ... + bool forceCleanResult = true // Clean Result ... +) +{ + // + if (forceCleanResult) + { + Clean(result); + } + + // + if (separator == NULL || StringLen(separator) == 0) + { + separator = ","; + } + + // + if (StringLen(content) == 0) + { + return; + } + + // + StringSplit( + content, + StringGetCharacter( + separator, + 0), + result); +} + +// +// Extract Data from String ... +string ExtractString( + const string source, // Source String used for Extracting + const string startString, // Expression Start String must be Unique + const string endString // Where to End Extraction, usually a Sign +) +{ + // + string result = ""; + + // + // Validate String ... + if ( + StringLen(source) == 0 || + StringLen(endString) == 0 || + StringLen(startString) == 0) + { + return result; + } + + // + // Find Start String Position ... + int sPos = StringFind( + source, + startString); + if (sPos < 0) + { + return result; + } + + // + // Find End String Position after Start String ... + int searchEndFromPos = sPos + StringLen(startString); + int ePos = StringFind( + source, + endString, + searchEndFromPos); + if (ePos < 0) + { + return result; + } + + // + // Extract Data from Source ... + int dLength = ePos - searchEndFromPos; + result = StringSubstr( + source, + searchEndFromPos, + dLength); + + // + return result; +} + +// +// Normalize a give Volume ... +double NormalizeVolume( + double volume, // desired volume to normalize + string symbol = NULL, // Specified Symbol for Normalization + int mLength = 2 // Length of Digits +) +{ + // + double result = volume; + + // + // Normalize Symbol ... + if (StringLen(symbol) == 0) + { + symbol = _Symbol; + } + + // + // Normalize Digits ... + int digits = GetDigits(symbol); + mLength = + mLength == 0 || mLength > digits + ? digits + : MathMin(mLength, digits); + + // + // Normalize Volume ... + result = NormalizeDouble(result, mLength); + + // + double maxAvailableVolume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX); + double minAvailableVolume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN); + + // + // Validate Result ... + if (result > maxAvailableVolume) + { + result = maxAvailableVolume; + } + else if (result < minAvailableVolume) + { + result = minAvailableVolume; + } + + // + return result; +} + +// +// Normallize Price ... +double NormalizePrice( + double price, // desired Price for normalization + string symbol = NULL // Specified Symbol for Normalization +) +{ + // + double result = 0; + + // + // Mormalize Symbol ... + if (StringLen(symbol) == 0) + { + symbol = _Symbol; + } + + // + int digits = GetDigits(symbol); + result = NormalizeDouble(price, digits); + + // + return result; +} + +// +// Do All Normalization on Specific Signal ... +void NormalizeSignal(XSignal &signal) +{ + // + // ENTRY ... + if (signal.entry > 0) + { + signal.entry = NormalizePrice(signal.entry, signal.symbol); + } + + // + // TP ... + if (signal.tp > 0) + { + signal.tp = NormalizePrice(signal.tp, signal.symbol); + } + + // + // SL ... + if (signal.sl > 0) + { + signal.sl = NormalizePrice(signal.sl, signal.symbol); + } + + // + // VOLUME ... + if (signal.volume > 0) + { + signal.volume = NormalizeVolume(signal.volume, signal.symbol); + } +} + +// +// Check Expert Running in Testing Mode or not ... +bool IsRunningOnTestMode() +{ + // + bool result = false; + + // + // check programm mode ... + result = MQL5InfoInteger(MQL5_TESTING); + + // + return result; +} + +// +// Calculate Volume Weighted Moving Average ... +double iVWMA( + double price, + double volume, + int period, + int i, + int bars, + int instance = 0 // +) +{ +#define ¤ instance +#ifdef _averageInstances +#define _functionInstances _averageInstances +#else #define _functionInstances 1 +#endif + struct sVwmaArrayStruct + { + double price; + double volume; + double sump; + double sumv; + }; + static sVwmaArrayStruct m_array[][_functionInstances]; + static int m_arraySize = 0; + if (m_arraySize < bars) + { + int _res = ArrayResize(m_array, bars + 500); + if (_res <= bars) + return (0); + m_arraySize = _res; + } + + // + //--- + // + + if (volume == 0) + volume = 1; + m_array[i][¤].price = volume * price; + m_array[i][¤].volume = volume; + if (i > period) + { + m_array[i][¤].sump = m_array[i - 1][¤].sump + m_array[i][¤].price - m_array[i - period][¤].price; + m_array[i][¤].sumv = m_array[i - 1][¤].sumv + volume - m_array[i - period][¤].volume; + } + else + { + m_array[i][¤].sump = m_array[i][¤].price; + m_array[i][¤].sumv = m_array[i][¤].volume; + for (int k = 1; k < period && i >= k; k++) + { + m_array[i][¤].sump += m_array[i - k][¤].price; + m_array[i][¤].sumv += m_array[i - k][¤].volume; + } + } + return (m_array[i][¤].sump / m_array[i][¤].sumv); + + // + //--- + // + +#undef ¤ #undef _functionInstances +} + +// +// Date Time Manipulation Functions ... +// + +// +// Representation of Time Struct ... +// struct MqlDateTime +// { +// int year; // Year +// int mon; // Month +// int day; // Day +// int hour; // Hour +// int min; // Minutes +// int sec; // Seconds +// int day_of_week; // Day of week (0-Sunday, 1-Monday, ... ,6-Saturday) +// int day_of_year; // Day number of the year (January 1st is assigned the number value of zero) +// }; + +// +// Converts Time to Seconds ... +ulong TimeToSeconds( + datetime time // Specify time to Convert ... +) +{ + // + ulong result = (ulong)time; + + // + return result; +} +ulong TimeToSeconds( + MqlDateTime &time // Specify time to Convert ... +) +{ + // + datetime dTime = StructToTime(time); + + // + ulong result = TimeToSeconds(dTime); + + // + return result; +} + +// +// Converts Seconds To Time ... +datetime SecondsToTime( + ulong seconds // Specify Seconds to Convert ... +) +{ + // + datetime result = (datetime)seconds; + + // + return result; +} +MqlDateTime SecondsToStruct( + ulong seconds // Specify Seconds to Convert ... +) +{ + // + datetime dTime = SecondsToTime(seconds); + + // + MqlDateTime result = {}; + TimeToStruct( + dTime, + result); + + // + return result; +} + +// +// Converts Time to MilliSeconds ... +ulong TimeToMilliSeconds( + datetime time // Specify time to Convert ... +) +{ + // + ulong result = TimeToSeconds(time) * 1000; + + // + return result; +} +ulong TimeToMilliSeconds( + MqlDateTime &time // Specify time to Convert ... +) +{ + // + datetime dTime = StructToTime(time); + + // + ulong result = TimeToMilliSeconds(dTime); + + // + return result; +} + +// +// Converts MillisSeconds to Time ... +datetime MilliSecondsToTiem( + ulong milliSeconds // Specify MilliSeconds to Convert ... +) +{ + // + ulong seconds = milliSeconds / 1000; + + // + datetime result = SecondsToTime(seconds); + + // + return result; +} +MqlDateTime MilliSecondsToStruct( + ulong milliSeconds // Specify MilliSeconds to Convert ... +) +{ + // + datetime dTime = MilliSecondsToTiem(milliSeconds); + + // + MqlDateTime result = {}; + TimeToStruct( + dTime, + result); + + // + return result; +} + +// +// Retrieve DateTime Structure ... +MqlDateTime GetCurrentTime() +{ + // + MqlDateTime result = {}; + + // + TimeCurrent(result); + + // + return result; +} + +// +// Retrieve Current Time as Seconds ... +ulong GetCurrentTimeAsSeconds() +{ + // + datetime time = TimeCurrent(); + + // + ulong result = TimeToSeconds(time); + + // + return result; +} + +// +// Retrieve Current Time as MilliSeconds ... +ulong GetCurrentTimeAsMilliSeconds() +{ + // + datetime time = TimeCurrent(); + + // + ulong result = TimeToMilliSeconds(time); + + // + return result; +} + +// +// Retrieve Specified Candle Time ... +datetime GetCandleTime( + string symbol = "", // Specify Symbol + ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame + int bar_index = 0 // Specify Bar Index +) +{ + // + // Validate and Normalize Args ... + + // + // Normalize Symbol ... + symbol = StringLen(symbol) == 0 + ? _Symbol + : symbol; + + // + // Normalize Period ... + period = period == NULL + ? _Period + : period; + + // + // Retrieve Bar Time ... + datetime result = iTime( + symbol, + period, + bar_index); + + // + return result; +} + +// +// Retrieve Specified Candle Time ... +ulong GetCandleTimeAsSeconds( + string symbol = "", // Specify Symbol + ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame + int bar_index = 0 // Specify Bar Index +) +{ + // + // Retrieve Bar Time ... + datetime time = GetCandleTime( + symbol, + period, + bar_index); + + // + ulong result = TimeToSeconds(time); + + // + return result; +} + +// +// Retrieve Specified Candle Time ... +ulong GetCandleTimeAsMilliSeconds( + string symbol = "", // Specify Symbol + ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame + int bar_index = 0 // Specify Bar Index +) +{ + // + // Retrieve Bar Time ... + datetime time = GetCandleTime( + symbol, + period, + bar_index); + + // + ulong result = TimeToMilliSeconds(time); + + // + return result; +} + +// +// Retrieve a Candle Time Structure ... +MqlDateTime GetCandleTimeStruct( + string symbol = "", // Specify Symbol + ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame + int bar_index = 0 // Specify Bar Index +) +{ + // + MqlDateTime result = {}; + + // + // Retrieve Bar Time ... + datetime barTime = GetCandleTime( + symbol, + period, + bar_index); + + // + // Convert to Structure ... + TimeToStruct(barTime, result); + + // + return result; +} + +// +// Retrieve Number of Candles in a Day ... +int GetDailyCandleCount(ENUM_TIMEFRAMES mPeriod) +{ + // + int seconds = PeriodSeconds(mPeriod); + + // + int daySeconds = 24 * 60 * 60; + + // + int result = daySeconds / seconds; + + // + return result; +} + +int GetDailyCandleCount() +{ + // + int result = GetDailyCandleCount(_Period); + + // + return result; +} + +// +// +// + +// +// Holds Month ... +static int xMonth = -1; + +// +// Holds Day Of Week ... +static int xDayOfWeek = -1; +static int xForWeekDay = -1; + +// +// Holds Day ... +static int xDay = -1; + +// +// Holds Hour ... +static int xHour = -1; + +// +// Reset Timing Variables ... +void ResetTiming() +{ + // + xHour = -1; + xDay = -1; + xDayOfWeek = -1; + xMonth = -1; +} + +// +// Detecting New Houre ... +bool IsNewHour() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Houre ... + result = timeStruct.hour != xHour; + if (result) + { + xHour = timeStruct.hour; + } + + // + return result; +} + +// +// Detecting New Day ... +bool IsNewDay() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Houre ... + result = timeStruct.day_of_year != xDay; + if (result) + { + xDay = timeStruct.day_of_year; + } + + // + return result; +} + +// +// Detecting New Week ... +bool IsNewWeek() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Week ... + // Since Week Starts From Monday in Forex World ... + // we Calculate Start of Week by 1-Monday ... + result = + xDayOfWeek == -1 && + xForWeekDay == -1 + ? true + : timeStruct.day_of_week == 1 && + timeStruct.day_of_year > xForWeekDay; + + // + xForWeekDay = timeStruct.day_of_year; + xDayOfWeek = timeStruct.day_of_week; + + // + return result; +} + +// +// Detecting End Of Week ... +bool IsWeekEnd() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check WeekEnd ... + // Since Week Starts From Monday in Forex World ... + // we Calculate End of Week by 5-Friday ... + result = + xDayOfWeek != -1 && + timeStruct.day_of_week == 5 && + timeStruct.hour == 23 && + timeStruct.min == 59 && + timeStruct.sec == 59; + + // + return result; +} + +// +// Detecting New Month ... +bool IsNewMonth() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Houre ... + result = timeStruct.mon != xMonth; + if (result) + { + xMonth = timeStruct.mon; + } + + // + return result; +} + +// +// Find Hindmost Time Frame ... +ENUM_TIMEFRAMES GetHindmostTimeFrame( + ENUM_TIMEFRAMES mPeriod // Specified Period +) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + // Normalize Period ... + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + switch (mPeriod) + { + // + case PERIOD_M1: + case PERIOD_M2: + case PERIOD_M3: + case PERIOD_M4: + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + case PERIOD_M15: + result = PERIOD_H12; + break; + + // + case PERIOD_M20: + case PERIOD_M30: + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + case PERIOD_H4: + result = PERIOD_D1; + break; + + // + case PERIOD_H6: + case PERIOD_H8: + case PERIOD_H12: + case PERIOD_D1: + result = PERIOD_W1; + break; + + // + default: + result = PERIOD_MN1; + break; + } + + // + return result; +} + +// +// Find Farest Time Frame ... +ENUM_TIMEFRAMES GetFarestTimeFrame( + ENUM_TIMEFRAMES mPeriod // Specified Period +) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + // Normalize Period ... + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + switch (mPeriod) + { + // + case PERIOD_M1: + case PERIOD_M2: + case PERIOD_M3: + case PERIOD_M4: + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + case PERIOD_M15: + case PERIOD_M20: + case PERIOD_M30: + result = PERIOD_H4; + break; + + // + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + case PERIOD_H4: + result = PERIOD_H12; + break; + + // + case PERIOD_H6: + case PERIOD_H8: + case PERIOD_H12: + case PERIOD_D1: + result = PERIOD_W1; + break; + + // + default: + result = PERIOD_MN1; + break; + } + + // + return result; +} + +// +// Find Medium Time Frame ... +ENUM_TIMEFRAMES GetMediestTimeFrame( + ENUM_TIMEFRAMES mPeriod // Specified Period +) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + // Normalize Period ... + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + switch (mPeriod) + { + // + case PERIOD_M1: + case PERIOD_M2: + case PERIOD_M3: + case PERIOD_M4: + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + case PERIOD_M15: + case PERIOD_M20: + result = PERIOD_H1; + break; + + // + case PERIOD_M30: + result = PERIOD_H2; + break; + + // + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + result = PERIOD_H4; + break; + + // + case PERIOD_H4: + case PERIOD_H6: + case PERIOD_H8: + result = PERIOD_H12; + break; + + // + case PERIOD_H12: + result = PERIOD_D1; + break; + + // + case PERIOD_D1: + result = PERIOD_W1; + break; + + // + case PERIOD_W1: + result = PERIOD_MN1; + break; + + // + default: + result = PERIOD_MN1; + break; + } + + // + return result; +} + +// +// Find Nearest Time Frame ... +ENUM_TIMEFRAMES GetNearestTimeFrame( + ENUM_TIMEFRAMES mPeriod // Specified Period +) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + // Normalize Period ... + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + switch (mPeriod) + { + // + case PERIOD_M1: + case PERIOD_M2: + case PERIOD_M3: + case PERIOD_M4: + result = PERIOD_M5; + break; + + // + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + result = PERIOD_M15; + break; + + // + case PERIOD_M15: + case PERIOD_M20: + result = PERIOD_M30; + break; + + // + case PERIOD_M30: + result = PERIOD_H1; + break; + + // + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + result = PERIOD_H4; + break; + + // + case PERIOD_H4: + case PERIOD_H6: + case PERIOD_H8: + result = PERIOD_H12; + break; + + // + case PERIOD_H12: + result = PERIOD_D1; + break; + + // + case PERIOD_D1: + result = PERIOD_W1; + break; + + // + case PERIOD_W1: + result = PERIOD_MN1; + break; + + // + default: + result = PERIOD_MN1; + break; + } + + // + return result; +} + +// +// Get Specific Time Frame Start Candle Time ... +datetime GetPeriodStartTime( + string mSymbol = NULL, // Specified Symbol ... + ENUM_TIMEFRAMES mPeriod = NULL, // Specified Period ... + datetime mTime = NULL // Specified Bar Time ... +) +{ + // + // Normalize Arg ... + + // + if ( + mSymbol == NULL || + StringLen(mSymbol) == 0) + { + mSymbol = _Symbol; + } + + // + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + if ( + mTime < 0 || + mTime == NULL) + { + mTime = TimeCurrent(); + } + + // + int barIndex = iBarShift( + mSymbol, + mPeriod, + mTime, + false); + + // + datetime result = iTime( + mSymbol, + mPeriod, + barIndex); + + // + return result; +} + +// +struct XCandleRemains +{ + // + int days; + int hours; + int minutes; + int seconds; +}; + +// +string ToString( + XCandleRemains &item, + string dayId = "d", + string hourId = "h", + string minuteId = "m", + string secondId = "s", + string idSeparator = ": ", + string separator = ", ", + bool ignoreZeroValues = true) +{ + // + string result = ""; + + // + // Days ... + if (!ignoreZeroValues || item.days > 0) + { + result += dayId + idSeparator + (string)item.days + separator; + } + + // + // Hours ... + if (!ignoreZeroValues || item.hours > 0) + { + // + string strHour = ToString(item.hours); + if (StringLen(strHour) == 1) { + strHour = "0" + strHour; + } + + // + result += hourId + idSeparator + strHour + separator; + } + + // + // Minutes ... + if (!ignoreZeroValues || item.minutes > 0) + { + // + string strMinute = ToString(item.minutes); + if (StringLen(strMinute) == 1) { + strMinute = "0" + strMinute; + } + + // + result += minuteId + idSeparator + strMinute + separator; + } + + // + // Seconds ... + if (!ignoreZeroValues || item.seconds > 0) + { + // + string strSec = ToString(item.seconds); + if (StringLen(strSec) == 1) { + strSec = "0" + strSec; + } + + // + result += secondId + idSeparator + strSec; + } + + // + return result; +} + +// +// Retrieve Specific Candles Ramained Time ... +void GetCandleRemainsTime( + XCandleRemains &result, // Holds Result ... + string mSymbol = NULL, // Specified Symbol ... + ENUM_TIMEFRAMES mPeriod = NULL, // Specified Period ... + int mBarIndex = 0 // Specified Bar Index ... +) +{ + // + int minuteSecoonds = 60; + int hourSeconds = minuteSecoonds * 60; + int daySeconds = 24 * hourSeconds; + + // + int periodSeconds = PeriodSeconds( + mPeriod); + datetime startTime = GetCandleTime( + mSymbol, + mPeriod, + mBarIndex); + + // + int secondsDiff = (int)startTime + periodSeconds - (int)TimeCurrent(); + + // + int days = 0; + int hours = 0; + int minutes = 0; + int seconds = 0; + + // + int mWorkingSecondsDiff = secondsDiff; + if (mWorkingSecondsDiff > daySeconds) + { + // + days = mWorkingSecondsDiff / daySeconds; + mWorkingSecondsDiff -= days * daySeconds; + } + if (mWorkingSecondsDiff > hourSeconds) + { + // + hours = mWorkingSecondsDiff / hourSeconds; + mWorkingSecondsDiff -= hours * hourSeconds; + } + if (mWorkingSecondsDiff > minuteSecoonds) + { + // + minutes = mWorkingSecondsDiff / minuteSecoonds; + mWorkingSecondsDiff -= minutes * minuteSecoonds; + } + seconds = mWorkingSecondsDiff; + + // + result.days = days; + result.hours = hours; + result.minutes = minutes; + result.seconds = seconds; +} + +// +// Converts an String to TimeFrame ... +ENUM_TIMEFRAMES ToPeriod(string value) +{ + // + if (StringLen(value) == 0) + { + return _Period; + } + + // + StringTrimLeft(value); + StringTrimRight(value); + + // + ENUM_TIMEFRAMES result = _Period; + + // + if (value == "M1") + { + result = PERIOD_M1; + } + else if (value == "M2") + { + result = PERIOD_M2; + } + else if (value == "M3") + { + result = PERIOD_M3; + } + else if (value == "M4") + { + result = PERIOD_M4; + } + else if (value == "M5") + { + result = PERIOD_M5; + } + else if (value == "M6") + { + result = PERIOD_M6; + } + else if (value == "M10") + { + result = PERIOD_M10; + } + else if (value == "M12") + { + result = PERIOD_M12; + } + else if (value == "M15") + { + result = PERIOD_M15; + } + else if (value == "M20") + { + result = PERIOD_M20; + } + else if (value == "M30") + { + result = PERIOD_M30; + } + else if (value == "H1") + { + result = PERIOD_H1; + } + else if (value == "H2") + { + result = PERIOD_H2; + } + else if (value == "H3") + { + result = PERIOD_H3; + } + else if (value == "H4") + { + result = PERIOD_H4; + } + else if (value == "H6") + { + result = PERIOD_H6; + } + else if (value == "H8") + { + result = PERIOD_H8; + } + else if (value == "H12") + { + result = PERIOD_H12; + } + else if (value == "D1") + { + result = PERIOD_D1; + } + else if (value == "W1") + { + result = PERIOD_W1; + } + else if (value == "MN1") + { + result = PERIOD_MN1; + } + + // + return result; +} + +// +// Converts Period to String ... +string ToString(ENUM_TIMEFRAMES period) +{ + // + string result = ""; + + // + string mPStr = EnumToString(period); + + string mPStrParts[]; + int partsCount = StringSplit( + mPStr, + StringGetCharacter("_", 0), + mPStrParts); + if (partsCount <= 0) + { + return result; + } + + // + result = mPStrParts[1]; + + // + return result; +} + +// +// END Provided Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.draw.lib.ex5 b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.draw.lib.ex5 new file mode 100644 index 0000000..bb12572 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.draw.lib.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.draw.lib.mq5 b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.draw.lib.mq5 new file mode 100644 index 0000000..7771f54 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.draw.lib.mq5 @@ -0,0 +1,2462 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Draw Library +// -------------------------------------- +// Name: XDraw +// Description: provides Draw abilities ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Inputs ... +// +// +// END Inputs ... +// + +// +// Include Logger Library ... +#include "x-saherelm.log.lib.mq5" +#include "x-saherelm.common.lib.mq5" + +// +// START Global Definitions: Variables, Properties and etc ... +// +string drawPrefix = "X-OBJ"; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// +// +// DeInitial Library if required ... +void OnDeinitDrawLibrary() +{ + RemoveDraws(); +} + +// +// remove drawn objects ... +void RemoveDraws( + string tag = NULL, + int chartId = -1, + int subWindow = -1) +{ + // + // Normalize Args ... + // + if (tag == NULL) + { + tag = drawPrefix; + } + + // + if (chartId == -1) + { + chartId = 0; + } + + // + if (subWindow == -1) + { + subWindow = 0; + } + + // + for (int iObj = ObjectsTotal(chartId, subWindow) - 1; iObj >= 0; iObj--) + { + // + string on = ObjectName(chartId, iObj, subWindow); + if (StringFind(on, tag) >= 0) + { + ObjectDelete(chartId, on); + } + } + + // + // Redraw Chart ... + ChartRedraw(); +} + +// +bool RemoveDraw( + string name, + int chartId = -1, + int subWindow = -1) +{ + // + bool result = false; + + // + if (chartId == -1) + { + chartId = 0; + } + + // + if (subWindow == -1) + { + subWindow = 0; + } + + // + string objName = ""; + for (int iObj = ObjectsTotal(chartId, subWindow) - 1; iObj >= 0; iObj--) + { + // + string on = ObjectName(chartId, iObj, subWindow); + if (StringFind(on, name) >= 0) + { + // + objName = on; + break; + } + } + + // + if (StringLen(objName) > 0) + { + result = ObjectDelete(chartId, objName); + } + + // + return result; +} + +// +// Deselect All Draws ... +void DeselectAllDraws() +{ + // + int objs = ObjectsTotal(ChartID(), 0); + for (int o = 0; o < objs; o++) + { + ObjectSetInteger(ChartID(), ObjectName(ChartID(), o, 0), OBJPROP_SELECTED, false); + } + + // + ChartRedraw(); +} + +// +// Check Object Exists ... +bool IsDrawExists( + string name, + int chartId = -1, + int subWindow = -1) +{ + // + bool result = false; + + // + if (chartId == -1) + { + chartId = 0; + } + + // + if (subWindow == -1) + { + subWindow = 0; + } + + // + for (int iObj = ObjectsTotal(chartId, subWindow) - 1; iObj >= 0; iObj--) + { + // + string on = ObjectName(chartId, iObj, subWindow); + result = StringFind(on, name) >= 0; + if (result) + { + break; + } + } + + // + return result; +} +// +// END Provided Functions ... +// + +// +// START Regular Draws ... +// + +// +// START Arrow Functions ... +// +// +// Draw an Arrow Object on Chart ... +bool DrawArrow( + const long chartID = 0, // chart's ID + const string name = "Arrow", // arrow name + const int subWindow = 0, // subwindow index + datetime time = 0, // anchor point time + double price = 0, // anchor point price + const uchar arrowCode = 252, // arrow code + const ENUM_ARROW_ANCHOR anchor = ANCHOR_BOTTOM, // anchor point position + const color clr = clrAqua, // arrow color + const ENUM_LINE_STYLE style = STYLE_SOLID, // border line style + const int width = 3, // arrow size + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // Order Object ... +) +{ + // + // set anchor point coordinates if they are not set ... + ChangeArrowEmptyPoint(time, price); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create an arrow ... + if (!ObjectCreate(chartID, objName, OBJ_ARROW, subWindow, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to create an arrow! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set the arrow code ... + ObjectSetInteger(chartID, objName, OBJPROP_ARROWCODE, arrowCode); + + // + // set anchor type ... + ObjectSetInteger(chartID, objName, OBJPROP_ANCHOR, anchor); + + // + // set the arrow color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set the border line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set the arrow's size ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving the arrow by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is false by default, if you want making it possible to highlight and move the object + // change it to true ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return true; +} + +// +// Move the anchor point of Arrow ... +bool MoveArrow( + const long chartID = 0, // chart's ID + const string name = "Arrow", // object name + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + // if point position is not set, move it to the current bar having Bid price ... + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // reset the error value + ResetLastError(); + + // + // move the anchor point ... + if (!ObjectMove(chartID, name, 0, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the anchor point! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Delete an arrow ... +bool DeleteArrow( + const long chartID = 0, // chart's ID + const string name = "Arrow" // arrow name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete an arrow ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete an arrow! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Change the arrow code ... +bool ArrowCodeChange( + const long chartID = 0, // chart's ID + const string name = "Arrow", // object name + const uchar code = 252 // arrow code +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change the arrow code ... + if (!ObjectSetInteger(chartID, name, OBJPROP_ARROWCODE, code)) + { + // + string message = + __FUNCTION__ + + ": failed to change the arrow code! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Change anchor type ... +bool ArrowAnchorChange( + const long chartID = 0, // chart's ID + const string name = "Arrow", // object name + const ENUM_ARROW_ANCHOR anchor = ANCHOR_TOP // anchor type +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change anchor type ... + if (!ObjectSetInteger(chartID, name, OBJPROP_ANCHOR, anchor)) + { + // + string message = + __FUNCTION__ + + ": failed to change anchor type! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Check anchor point values and set default values +// for empty ones ... +void ChangeArrowEmptyPoint( + datetime &time, + double &price) +{ + // + // if the point's time is not set, it will be on the current bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // if the point's price is not set, it will have Bid value ... + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } +} +// +// END Arrow Functions ... +// + +// +// START Horizontal Line Functions ... +// +// +// Create, Draw the horizontal line ... +bool DrawHorizontalLine( + const long chartID = 0, // chart's ID + const string name = "HLine", // line name + const int subWindow = 0, // subwindow index + double price = 0, // line price + const color clr = clrRed, // line color + const ENUM_LINE_STYLE style = STYLE_SOLID, // line style + const int width = 1, // line width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // if the price is not set, set it at the current Bid price level ... + if (!price) + { + price = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create a horizontal line ... + if (!ObjectCreate(chartID, objName, OBJ_HLINE, subWindow, 0, price)) + { + // + string message = + __FUNCTION__ + + ": failed to create a horizontal line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set line color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line display style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving the line by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, selection); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return true; +} + +// +// Move horizontal line ... +bool MoveHorizontalLine( + const long chartID = 0, // chart's ID + const string name = "HLine", // line name + double price = 0 // line price +) +{ + // + // if the line price is not set, move it to the current Bid price level ... + if (!price) + { + price = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move a horizontal line ... + if (!ObjectMove(chartID, name, 0, 0, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the horizontal line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Delete a horizontal line ... +bool DeleteHorizontalLine( + const long chartID = 0, // chart's ID + const string name = "HLine" // line name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete a horizontal line ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete a horizontal line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} +// +// END Horizontal Line Functions ... +// + +// +// START Vertical Line Functions ... +// +// +// Create the vertical line ... +bool DrawVerticalLine( + const long chartID = 0, // chart's ID + const string name = "VLine", // line name + const int subWindow = 0, // subwindow index + datetime time = 0, // line time + const color clr = clrRed, // line color + const ENUM_LINE_STYLE style = STYLE_SOLID, // line style + const int width = 1, // line width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // if the line time is not set, draw it via the last bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // reset the error value + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create a vertical line ... + if (!ObjectCreate(chartID, objName, OBJ_VLINE, subWindow, time, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to create a vertical line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set line color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line display style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving the line by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return true; +} + +// +// Move the vertical line ... +bool MoveVerticalLine( + const long chartID = 0, // chart's ID + const string name = "VLine", // line name + datetime time = 0 // line time +) +{ + // + // if line time is not set, move the line to the last bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move the vertical line ... + if (!ObjectMove(chartID, name, 0, time, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to move the vertical line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Delete the vertical line ... +bool DeleteVerticalLine( + const long chartID = 0, // chart's ID + const string name = "VLine" // line name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete the vertical line ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete the vertical line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} +// +// END Vertical Line Functions ... +// + +// +// START RectangleLabel Functions ... +// +// +// Create Rectangle Label Object ... +bool DrawRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const int subWindow = 0, // subwindow index + const int x = 0, // X coordinate + const int y = 0, // Y coordinate + const int width = 50, // width + const int height = 18, // height + const color bgColor = clrWhiteSmoke, // background color + const ENUM_BORDER_TYPE border = BORDER_SUNKEN, // border type + const ENUM_BASE_CORNER corner = CORNER_LEFT_UPPER, // chart corner for anchoring + const color clr = clrRed, // flat border color (Flat) + const ENUM_LINE_STYLE style = STYLE_SOLID, // flat border style + const int lineWidth = 1, // flat border width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // + // create a rectangle label + if (!ObjectCreate(chartID, objName, OBJ_RECTANGLE_LABEL, subWindow, 0, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to create a rectangle label! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set label coordinates ... + ObjectSetInteger(chartID, objName, OBJPROP_XDISTANCE, x); + ObjectSetInteger(chartID, objName, OBJPROP_YDISTANCE, y); + + // + // set label size ... + ObjectSetInteger(chartID, objName, OBJPROP_XSIZE, width); + ObjectSetInteger(chartID, objName, OBJPROP_YSIZE, height); + + // + // set background color ... + ObjectSetInteger(chartID, objName, OBJPROP_BGCOLOR, bgColor); + + // + // set border type ... + ObjectSetInteger(chartID, objName, OBJPROP_BORDER_TYPE, border); + + // + // set the chart's corner, relative to which point coordinates are defined ... + ObjectSetInteger(chartID, objName, OBJPROP_CORNER, corner); + + // + // set flat border color (in Flat mode) ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set flat border line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set flat border width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, lineWidth); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving the label by mouse ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, selection); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return true; +} + +// +// Move Rectangle Label .. +bool MoveRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const int x = 0, // X coordinate + const int y = 0 // Y coordinate +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // move the rectangle label ... + if (!ObjectSetInteger(chartID, name, OBJPROP_XDISTANCE, x)) + { + // + string message = + __FUNCTION__ + + ": failed to move X coordinate of the label! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + if (!ObjectSetInteger(chartID, name, OBJPROP_YDISTANCE, y)) + { + // + string message = + __FUNCTION__ + + ": failed to move Y coordinate of the label! Error code = " + + (string)GetLastError(); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Delete the rectangle label ... +bool DeleteRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel" // label name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete the label ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete a rectangle label! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Change Rectangle Label Size ... +bool ChangeSizeRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const int width = 50, // label width + const int height = 18 // label height +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change label size ... + if (!ObjectSetInteger(chartID, name, OBJPROP_XSIZE, width)) + { + // + string message = + __FUNCTION__ + + ": failed to change the label's width! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + if (!ObjectSetInteger(chartID, name, OBJPROP_YSIZE, height)) + { + // + string message = + __FUNCTION__ + + ": failed to change the label's height! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Change rectangle label border type ... +bool RectLabelChangeBorderType( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const ENUM_BORDER_TYPE border = BORDER_SUNKEN // border type +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change border type ... + if (!ObjectSetInteger(chartID, name, OBJPROP_BORDER_TYPE, border)) + { + // + string message = + __FUNCTION__ + + ": failed to change the border type! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} +// +// END RectangleLabel Functions ... +// + +// +// START TrendLine Funcions ... +// +// Create a trend line by the given coordinates ... +bool DrawTrendLine( + const long chartID = 0, // chart's ID + const string name = "TrendLine", // line name + const int subWindow = 0, // subwindow index + datetime time1 = 0, // first point time + double price1 = 0, // first point price + datetime time2 = 0, // second point time + double price2 = 0, // second point price + const color clr = clrYellow, // line color + const ENUM_LINE_STYLE style = STYLE_SOLID, // line style + const int width = 1, // line width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool rayRight = false, // line's continuation to the right + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // set anchor points' coordinates if they are not set ... + ChangeTrendLineEmptyPoints( + time1, + price1, + time2, + price2); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create a trend line by the given coordinates ... + if (!ObjectCreate(chartID, objName, OBJ_TREND, subWindow, time1, price1, time2, price2)) + { + // + string message = + __FUNCTION__ + + ": failed to create a trend line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set line color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line display style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving the line by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // enable true or disable false the mode of continuation of the line's display to the right ... + ObjectSetInteger(chartID, objName, OBJPROP_RAY_RIGHT, rayRight); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return true; +} + +// +// Move trend line anchor point ... | +bool ChangeTrendLinePoint( + const long chartID = 0, // chart's ID + const string name = "TrendLine", // line name + const int pointindex = 0, // anchor point index + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + // if point position is not set, move it to the current bar having Bid price ... + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move trend line's anchor point ... + if (!ObjectMove(chartID, name, pointindex, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the anchor point! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// The function deletes the trend line from the chart ... +bool DeleteTrendLine( + const long chartID = 0, // chart's ID + const string name = "TrendLine" // line name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete a trend line ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete a trend line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Check the values of trend line's anchor points and set default ... +// values for empty ones ... +void ChangeTrendLineEmptyPoints( + datetime &time1, + double &price1, + datetime &time2, + double &price2) +{ + // + // if the first point's time is not set, it will be on the current bar ... + if (!time1) + { + time1 = TimeCurrent(); + } + + // + // if the first point's price is not set, it will have Bid value ... + if (!price1) + { + price1 = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // if the second point's time is not set, it is located 9 bars left from the second one ... + if (!time2) + { + // + // array for receiving the open time of the last 10 bars ... + datetime temp[10]; + CopyTime(Symbol(), Period(), time1, 10, temp); + + // + // set the second point 9 bars left from the first one ... + time2 = temp[0]; + } + + // + // if the second point's price is not set, it is equal to the first point's one ... + if (!price2) + { + price2 = price1; + } +} +// +// END TrendLine Functions ... +// + +// +// START Text Functions ... +// +// Create and Draw a Text Object ... +bool DrawText( + const long chartID = 0, // chart's ID + const string name = "Text", // object name + const int subWindow = 0, // subwindow index + datetime time = 0, // anchor point time + double price = 0, // anchor point price + const string text = "Text", // the text itself + const string font = "Arial", // font + const int fontSize = 10, // font size + const color clr = clrRed, // color + const double angle = 0.0, // text slope + const ENUM_ANCHOR_POINT anchor = ANCHOR_CENTER, // anchor type + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // set anchor point coordinates if they are not set ... + ChangeTextEmptyPoint(time, price); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // + // create Text object + if (!ObjectCreate(chartID, objName, OBJ_TEXT, subWindow, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to create \"Text\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set the text ... + ObjectSetString(chartID, objName, OBJPROP_TEXT, text); + + // + // set text font ... + ObjectSetString(chartID, objName, OBJPROP_FONT, font); + + // + // set font size ... + ObjectSetInteger(chartID, objName, OBJPROP_FONTSIZE, fontSize); + + // + // set the slope angle of the text ... + ObjectSetDouble(chartID, objName, OBJPROP_ANGLE, angle); + + // + // set anchor type ... + ObjectSetInteger(chartID, objName, OBJPROP_ANCHOR, anchor); + + // + // set color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving the object by mouse ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return true; +} + +// +// Move the anchor point ... +bool MoveText( + const long chartID = 0, // chart's ID + const string name = "Text", // object name + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + // + // if point position is not set, move it to the current bar having Bid price + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move the anchor point .. + if (!ObjectMove(chartID, name, 0, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the anchor point! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Change the object text ... +bool ChangeText( + const long chartID = 0, // chart's ID + const string name = "Text", // object name + const string text = "Text" // text +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change object text ... + if (!ObjectSetString(chartID, name, OBJPROP_TEXT, text)) + { + // + string message = + __FUNCTION__ + + ": failed to change the text! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Delete Text object ... +bool DeleteText( + const long chartID = 0, // chart's ID + const string name = "Text" // object name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete the object ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete \"Text\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution + return true; +} + +// +// Check anchor point values and set default values +// for empty ones ... +void ChangeTextEmptyPoint( + datetime &time, + double &price) +{ + // + // if the point's time is not set, it will be on the current bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // if the point's price is not set, it will have Bid value ... + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } +} +// +// END Text Functions ... +// + +// +// START Fibonacchi Functions ... +// +// +// Create Fibonacci Retracement by the given coordinates ... +bool DrawFibonacci( + const long chartID = 0, // chart's ID + const string name = "Fibonacci", // object name + const int subWindow = 0, // subwindow index + datetime time1 = 0, // first point time + double price1 = 0, // first point price + datetime time2 = 0, // second point time + double price2 = 0, // second point price + const color clr = clrRed, // object color + const ENUM_LINE_STYLE style = STYLE_SOLID, // object line style + const int width = 1, // object line width + const bool back = false, // in the background + const bool selection = true, // highlight to move + const bool rayRight = false, // object's continuation to the right + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // set anchor points' coordinates if they are not set ... + ChangeFibonacciEmptyPoints(time1, price1, time2, price2); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // Create Fibonacci Retracement by the given coordinates ... + if (!ObjectCreate(chartID, objName, OBJ_FIBO, subWindow, time1, price1, time2, price2)) + { + // + string message = + __FUNCTION__ + + ": failed to create \"Fibonacci Retracement\"! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of highlighting the channel for moving + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // enable true or disable false the mode of continuation of the object's display to the right ... + ObjectSetInteger(chartID, objName, OBJPROP_RAY_RIGHT, rayRight); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return true; +} + +// +// Create Fibonacci Retracement by the given coordinates ... +bool DrawCustomFibonacci( + // + int levels, // number of level lines + double &values[], // values of level lines + color &colors[], // color of level lines + ENUM_LINE_STYLE &styles[], // style of level lines + int &widths[], // width of level lines + string &descriptions[], // level Descriptions + // + const long chartID = 0, // chart's ID + const string name = "Fibonacci", // object name + const int subWindow = 0, // subwindow index + datetime time1 = 0, // first point time + double price1 = 0, // first point price + datetime time2 = 0, // second point time + double price2 = 0, // second point price + const color clr = clrAqua, // object color + const ENUM_LINE_STYLE style = STYLE_DOT, // object line style + const int width = 1, // object line width + const bool back = false, // in the background + const bool selection = true, // highlight to move + const bool rayRight = false, // object's continuation to the right + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // set anchor points' coordinates if they are not set ... + ChangeFibonacciEmptyPoints(time1, price1, time2, price2); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // Create Fibonacci Retracement by the given coordinates ... + if (!ObjectCreate(chartID, name, OBJ_FIBO, subWindow, time1, price1, time2, price2)) + { + // + string message = + __FUNCTION__ + + ": failed to create \"Fibonacci Retracement\"! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of highlighting the channel for moving + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // enable true or disable false the mode of continuation of the object's display to the right ... + ObjectSetInteger(chartID, objName, OBJPROP_RAY_RIGHT, rayRight); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // Change Levels Of Fibonacci ... + bool result = FibonacciLevelsSet( + levels, + values, + colors, + styles, + widths, + descriptions, + chartID, + objName); + + // + // successful execution ... + return result; +} + +// +// Set number of levels and their parameters ... +bool FibonacciLevelsSet( + int levels, // number of level lines + double &values[], // values of level lines + color &colors[], // color of level lines + ENUM_LINE_STYLE &styles[], // style of level lines + int &widths[], // width of level lines + string &descriptions[], // level Descriptions + const long chartID = 0, // chart's ID + const string name = "Fibonacci" // object name +) +{ + // + // check array sizes ... + if ( + levels != ArraySize(colors) || + levels != ArraySize(styles) || + levels != ArraySize(widths) || + levels != ArraySize(widths)) + { + // + string message = + __FUNCTION__ + + ": array length does not correspond to the number of levels, error!"; + + // + LogMessage(message); + + // + return false; + } + + // + // set the number of levels ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELS, levels); + + // + // set the properties of levels in the loop ... + for (int i = 0; i < levels; i++) + { + // + // level value ... + ObjectSetDouble(chartID, name, OBJPROP_LEVELVALUE, i, values[i]); + + // + // level color ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELCOLOR, i, colors[i]); + + // + // level style ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELSTYLE, i, styles[i]); + + // + // level width ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELWIDTH, i, widths[i]); + + // + // level description ... + // ObjectSetString(chartID, name, OBJPROP_LEVELTEXT, i, DoubleToString(100 * values[i], 1)); + ObjectSetString(chartID, name, OBJPROP_LEVELTEXT, i, descriptions[i]); + } + + // + // successful execution ... + return true; +} + +// +// Move Fibonacci Retracement anchor point ... +bool FibonacciPointChange( + const long chartID = 0, // chart's ID + const string name = "Fibonacci", // object name + const int pointIndex = 0, // anchor point index + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + // if point position is not set, move it to the current bar having Bid price ... + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move the anchor point ... + if (!ObjectMove(chartID, name, pointIndex, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the anchor point! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Delete Fibonacci Retracement ... +bool DeleteFibonachi( + const long chartID = 0, // chart's ID + const string name = "Fibonacci" // object name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete the object ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete \"Fibonacci Retracement\"! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Check the values of Fibonacci Retracement anchor points and set +// default values for empty ones ... +void ChangeFibonacciEmptyPoints( + datetime &time1, + double &price1, + datetime &time2, + double &price2) +{ + // + // if the second point's time is not set, it will be on the current bar ... + if (!time2) + { + time2 = TimeCurrent(); + } + + // + // if the second point's price is not set, it will have Bid value ... + if (!price2) + { + price2 = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // if the first point's time is not set, it is located 9 bars left from the second one ... + if (!time1) + { + // + // array for receiving the open time of the last 10 bars ... + datetime temp[10]; + CopyTime(Symbol(), Period(), time2, 10, temp); + + // + // set the first point 9 bars left from the second one ... + time1 = temp[0]; + } + + // + // if the first point's price is not set, move it 200 points below the second one ... + if (!price1) + { + price1 = price2 - 200 * SymbolInfoDouble(_Symbol, SYMBOL_POINT); + } +} +// +// END Fibonacci Functions ... +// + +// +// START Event Functions ... +// + +// +// Create an Event ... +bool EventCreate( + const long chartID = 0, // chart's ID + const string name = "Event", // object name + const int subWindow = 0, // subwindow index + const string text = "Content", // event text + datetime time = 0, // anchor point time + const color clr = clrRed, // color + const int width = 1, // point width when highlighted + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + if (!time) + { + time = TimeCurrent(); + } + + // + ResetLastError(); + + // + if (!ObjectCreate(chartID, name, OBJ_EVENT, subWindow, time, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to create \"Event\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set event text + ObjectSetString(chartID, name, OBJPROP_TEXT, text); + + // + // set color + ObjectSetInteger(chartID, name, OBJPROP_COLOR, clr); + + // + // set anchor point width if the object is highlighted + ObjectSetInteger(chartID, name, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true + ObjectSetInteger(chartID, name, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving event by mouse + ObjectSetInteger(chartID, name, OBJPROP_SELECTABLE, selection); + ObjectSetInteger(chartID, name, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list + ObjectSetInteger(chartID, name, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart + ObjectSetInteger(chartID, name, OBJPROP_ZORDER, zOrder); + + // + // successful execution + return true; +} + +// +// Change Event object text +bool EventTextChange( + const long chartID = 0, // chart's ID + const string name = "Event", // event name + const string text = "Content" // text +) +{ + // + // reset the error value + ResetLastError(); + + // + // change object text + if (!ObjectSetString(chartID, name, OBJPROP_TEXT, text)) + { + // + string message = + __FUNCTION__ + + ": failed to change the text! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution + return true; +} + +// +// Move Event object +bool EventMove( + const long chartID = 0, // chart's ID + const string name = "Event", // event name + datetime time = 0 // time +) +{ + // + // if time is not set, move event to the last bar + if (!time) + { + time = TimeCurrent(); + } + + // + // reset the error value + ResetLastError(); + + // + // move the object + if (!ObjectMove(chartID, name, 0, time, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to move \"Event\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution + return true; +} + +// +// Delete Event object +bool EventDelete( + const long chartID = 0, // chart's ID + const string name = "Event" // event name +) +{ + // + // reset the error value + ResetLastError(); + + // + // delete the object + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete \"Event\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution + return true; +} + +// +// END Event Functions ... +// + +// +// START Button Functions ... +// + +// +// Create the button ... +bool ButtonCreate( + const long chartID = 0, // chart's ID + const string name = "Button", // button name + const int subWindow = 0, // subwindow index + const int x = 0, // X coordinate + const int y = 0, // Y coordinate + const int width = 50, // button width + const int height = 15, // button height + const ENUM_BASE_CORNER corner = CORNER_LEFT_UPPER, // chart corner for anchoring + const string text = "Button", // text + const string font = "Arial", // font + const int fontSize = 8, // font size + const color clr = clrBlack, // text color + const color bgColor = clrLightGray, // background color + const color borderColor = clrNONE, // border color + const bool state = false, // pressed/released + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + bool result = false; + + // + // create the button + result = ObjectCreate(chartID, name, OBJ_BUTTON, subWindow, 0, 0); + if (!result) + { + return result; + } + + // + // set button coordinates + ObjectSetInteger(chartID, name, OBJPROP_XDISTANCE, x); + ObjectSetInteger(chartID, name, OBJPROP_YDISTANCE, y); + + // + // set button size + ObjectSetInteger(chartID, name, OBJPROP_XSIZE, width); + ObjectSetInteger(chartID, name, OBJPROP_YSIZE, height); + + // + // set the chart's corner, relative to which point coordinates are defined + ObjectSetInteger(chartID, name, OBJPROP_CORNER, corner); + + // + // set the text + ObjectSetString(chartID, name, OBJPROP_TEXT, text); + + // + // set text font + ObjectSetString(chartID, name, OBJPROP_FONT, font); + + // + // set font size + ObjectSetInteger(chartID, name, OBJPROP_FONTSIZE, fontSize); + + // + // set text color + ObjectSetInteger(chartID, name, OBJPROP_COLOR, clr); + + // + // set background color + ObjectSetInteger(chartID, name, OBJPROP_BGCOLOR, bgColor); + + // + // set border color + ObjectSetInteger(chartID, name, OBJPROP_BORDER_COLOR, borderColor); + + // + // display in the foreground false or background true + ObjectSetInteger(chartID, name, OBJPROP_BACK, back); + + // + // set button state + ObjectSetInteger(chartID, name, OBJPROP_STATE, state); + + // + // enable true or disable false the mode of moving the button by mouse + ObjectSetInteger(chartID, name, OBJPROP_SELECTABLE, selection); + ObjectSetInteger(chartID, name, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list + ObjectSetInteger(chartID, name, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart + ObjectSetInteger(chartID, name, OBJPROP_ZORDER, zOrder); + + // + return result; +} + +// +// Move the button ... +bool ButtonMove( + const long chartID = 0, // chart's ID + const string name = "Button", // button name + const int x = 0, // X coordinate + const int y = 0 // Y coordinate +) +{ + // + bool result = false; + + // + // move the button + + // + result = ObjectSetInteger(chartID, name, OBJPROP_XDISTANCE, x); + if (!result) + { + return result; + } + + // + result = ObjectSetInteger(chartID, name, OBJPROP_YDISTANCE, y); + + // + return result; +} + +// +// Change button size ... +bool ButtonChangeSize( + const long chartID = 0, // chart's ID + const string name = "Button", // button name + const int width = 50, // button width + const int height = 18 // button height +) +{ + // + bool result = false; + + // + // change the button size + + // + result = ObjectSetInteger(chartID, name, OBJPROP_XSIZE, width); + if (!result) + { + return result; + } + + // + result = ObjectSetInteger(chartID, name, OBJPROP_YSIZE, height); + + // + return result; +} + +// +// Change corner of the chart for binding the button ... +bool ButtonChangeCorner( + const long chartID = 0, // chart's ID + const string name = "Button", // button name + const ENUM_BASE_CORNER corner = CORNER_LEFT_UPPER // chart corner for anchoring +) +{ + // + bool result = false; + + // + // change anchor corner + + // + result = ObjectSetInteger(chartID, name, OBJPROP_CORNER, corner); + + // + return result; +} + +// +// Change button text ... +bool ButtonTextChange( + const long chartID = 0, // chart's ID + const string name = "Button", // button name + const string text = "Text" // text +) +{ + // + bool result = false; + + // + // change object text + result = ObjectSetString(chartID, name, OBJPROP_TEXT, text); + + // + return result; +} + +// +// Delete the button ... +bool ButtonDelete( + const long chartID = 0, // chart's ID + const string name = "Button" // button name +) +{ + // + bool result = false; + + // + // delete the button + result = ObjectDelete(chartID, name); + + // + return result; +} +// +// END Button Functions ... +// + +// +// END Regular Draws ... +// + +// +// START Chart Style Drawers ... +// +// +// Apply Styles On Chart ... +void ApplyChartStyle( + long mChartId = -1, // chart's ID + ENUM_CHART_MODE mMode = CHART_CANDLES, // chart's mMode + bool mShowBidLine = true, // show bid line + bool mShowAskLine = true, // show ask line + bool mShowGrid = false, // show grids on chart + bool mShowVolumes = false, // show volumes + bool mShowTradeLevels = true, // Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders) + bool mAutoScroll = true, // chart autoscroll + bool mQuickNavigation = true, // chart quick navigation state + color mForeGroundColor = clrWhite, // chart's foreground color + color mBackGroundColor = clrBlack, // chart's background color + color mUpColor = clrGreen, // Up Color + color mDownColor = clrRed, // Down Color + color mBullishColor = clrGreen, // Bullish color + color mBearishColor = clrRed, // Bearish color + color mGridColor = clrGray, // grid color + color mBidLineColor = clrGray, // bid line color + color mAskLineColor = clrRed, // ask line color + color mLineColor = clrLime, // line mMode and doji candlestick color + color mStopColor = clrGold, // Color of stop order levels (Stop Loss and Take Profit) + color mVolumesColor = clrGreen // volumes color +) +{ + // + // Validate Args ... + if (mChartId == -1) + { + mChartId = 0; + } + + // + ChartSetInteger(mChartId, CHART_MODE, mMode); + ChartSetInteger(mChartId, CHART_SHOW_BID_LINE, mShowBidLine); + ChartSetInteger(mChartId, CHART_SHOW_ASK_LINE, mShowAskLine); + ChartSetInteger(mChartId, CHART_SHOW_GRID, mShowGrid); + ChartSetInteger(mChartId, CHART_SHOW_VOLUMES, mShowVolumes); + ChartSetInteger(mChartId, CHART_SHOW_TRADE_LEVELS, mShowTradeLevels); + ChartSetInteger(mChartId, CHART_AUTOSCROLL, mAutoScroll); + ChartSetInteger(mChartId, CHART_QUICK_NAVIGATION, mQuickNavigation); + ChartSetInteger(mChartId, CHART_COLOR_FOREGROUND, mForeGroundColor); + ChartSetInteger(mChartId, CHART_COLOR_BACKGROUND, mBackGroundColor); + ChartSetInteger(mChartId, CHART_COLOR_CHART_UP, mUpColor); + ChartSetInteger(mChartId, CHART_COLOR_CHART_DOWN, mDownColor); + ChartSetInteger(mChartId, CHART_COLOR_CANDLE_BULL, mBullishColor); + ChartSetInteger(mChartId, CHART_COLOR_CANDLE_BEAR, mBearishColor); + ChartSetInteger(mChartId, CHART_COLOR_GRID, mGridColor); + ChartSetInteger(mChartId, CHART_COLOR_BID, mBidLineColor); + ChartSetInteger(mChartId, CHART_COLOR_ASK, mAskLineColor); + ChartSetInteger(mChartId, CHART_COLOR_STOP_LEVEL, mStopColor); + ChartSetInteger(mChartId, CHART_COLOR_CHART_LINE, mLineColor); + ChartSetInteger(mChartId, CHART_COLOR_VOLUME, mVolumesColor); +} + +// +// Retrieve Chart Size in Pixel ... +struct XSize +{ + long width; + long height; + + // + int x; + int y; + int w; + int h; + + // + int wStep; + int hStep; +}; + +// +// Retrieve Chart Size ... +bool GetChartSize( + XSize &result, // Holds Result ... + long chartID = 0 // Specified Chart ID ... +) +{ + // + bool mResult = false; + + // + mResult = ChartGetInteger(0, CHART_WIDTH_IN_PIXELS, 0, result.width); + if (!mResult) + { + return mResult; + } + + // + mResult = ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS, 0, result.height); + + // + return mResult; +} + +// +// END Chart Style Drawers ... +// \ No newline at end of file diff --git a/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.http.lib.ex5 b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.http.lib.ex5 new file mode 100644 index 0000000..8e36336 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.http.lib.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.http.lib.mq5 b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.http.lib.mq5 new file mode 100644 index 0000000..97f7ac0 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.http.lib.mq5 @@ -0,0 +1,177 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Http Library +// ------------------------------------------ +// Name: XHttp +// Description: provide http communication +// abilities ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Model Definition ... +// +enum X_HTTP_METHOD +{ + X_HTTP_GET, + X_HTTP_POST +}; +// +// END Model Definition ... +// + +// +// START Inputs ... +// +// +// END Inputs ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// +// +// Initial Library if required ... +bool OnInInitHttpLibrary() +{ + return false; +} + +// +// DeInitial Library if required ... +void OnDeinitHttpLibrary() +{ +} + +// +// Convert enum to String ... +string ToString(X_HTTP_METHOD method) +{ + // + string result = ""; + + // + switch (method) + { + // + case X_HTTP_GET: + result = "GET"; + break; + + // + case X_HTTP_POST: + result = "POST"; + break; + } + + // + return result; +} + +// +// Send Global Request ... +int SendRequest( + X_HTTP_METHOD method, // Httm Request Method + const string url, // Server Address + const string headers, // Headers providing + const char &payload[], // the Data which needs to Send + char &response[], // Response of request + string responseHeaders, // Response Headers + int timeout = 500 // Timeout for response default is 500 +) +{ + // + int result = -1; + + // + string strMethod = ToString(method); + if (StringLen(strMethod) == 0) { + return result; + } + + // + result = WebRequest( + strMethod, + url, + headers, + timeout, + payload, + response, + responseHeaders + ); + + // + return result; +} + +// +// Get Request ... +int GetRequest( + const string url, // Server Address + const string headers, // Headers providing + const char &payload[], // the Data which needs to Send + char &response[], // Response of request + string responseHeaders, // Response Headers + int timeout = 500 // Timeout for response default is 500 +) { + // + int result = SendRequest( + X_HTTP_GET, + url, + headers, + payload, + response, + responseHeaders, + timeout + ); + + // + return result; +} + +// +// Post Request ... +int PostRequest( + const string url, // Server Address + const string headers, // Headers providing + const char &payload[], // the Data which needs to Send + char &response[], // Response of request + string responseHeaders, // Response Headers + int timeout = 500 // Timeout for response default is 500 +) { + // + int result = SendRequest( + X_HTTP_POST, + url, + headers, + payload, + response, + responseHeaders, + timeout + ); + + // + return result; +} +// +// END Provided Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.log.lib.ex5 b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.log.lib.ex5 new file mode 100644 index 0000000..31ee4ba Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.log.lib.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.log.lib.mq5 b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.log.lib.mq5 new file mode 100644 index 0000000..3e30eb9 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.log.lib.mq5 @@ -0,0 +1,1088 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Logger Library +// --------------------------------------- +// Name: XLogger +// Description: provides Logging abilities ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Inputs ... +// +// input group "Logging"; +// input bool enableLogging = true; // Enable Logging +bool enableLogging = true; // Enable Logging +// +// END Inputs ... +// + +// +// Including Models ... +#include "x-saherelm.models.lib.mq5" + +// +// START Global Definitions: Variables, Properties and etc ... +// +string logTag = "X-Logger"; // LogTag +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// +// +// Logging a Message ... +void LogMessage(string message) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(logTag, " > ", message); +} +void LogMessage(string tag, string message) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(tag, " > ", message); +} + +// +void LogEmptyLine() +{ + LogMessage(" "); +} + +// +void LogError( + int error = -1 // Specific Error +) { + // + if (error <= -1) { + error = GetLastError(); + } + + // + string errorMsg = GetErrorDescription(error); + + // + LogMessage("Error: " + errorMsg); +} + +// +// Logging an Array ... +void LogArray(int &array[]) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(logTag, ">"); + ArrayPrint(array); +} +void LogArray(double &array[]) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(logTag, ">"); + ArrayPrint(array); +} +void LogArray(string &array[]) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(logTag, ">"); + ArrayPrint(array); +} +// +// END Provided Functions ... +// + + +// +// Error Descriptions Functions ... +// + +// +// Retrieve Specified Error Code Description ... +string GetErrorDescription(int err_code) +{ + // + string result = ""; + + // + switch (err_code) + { + // + //--- Constant Description + + // + case ERR_SUCCESS: + result = "The operation completed successfully"; + break; + + // + case ERR_INTERNAL_ERROR: + result = "Unexpected internal error"; + break; + + // + case ERR_WRONG_INTERNAL_PARAMETER: + result = "Wrong parameter in the inner call of the client terminal function"; + break; + + // + case ERR_INVALID_PARAMETER: + result = "Wrong parameter when calling the system function"; + break; + + // + case ERR_NOT_ENOUGH_MEMORY: + result = "Not enough memory to perform the system function"; + break; + + // + case ERR_STRUCT_WITHOBJECTS_ORCLASS: + result = "The structure contains objects of strings and/or dynamic arrays and/or structure of such objects and/or classes"; + break; + + // + case ERR_INVALID_ARRAY: + result = "Array of a wrong type, wrong size, or a damaged object of a dynamic array"; + break; + + // + case ERR_ARRAY_RESIZE_ERROR: + result = "Not enough memory for the relocation of an array, or an attempt to change the size of a static array"; + break; + + // + case ERR_STRING_RESIZE_ERROR: + result = "Not enough memory for the relocation of string"; + break; + + // + case ERR_NOTINITIALIZED_STRING: + result = "Not initialized string"; + break; + + // + case ERR_INVALID_DATETIME: + result = "Invalid date and/or time"; + break; + + // + case ERR_ARRAY_BAD_SIZE: + result = "Requested array size exceeds 2 GB"; + break; + + // + case ERR_INVALID_POINTER: + result = "Wrong pointer"; + break; + + // + case ERR_INVALID_POINTER_TYPE: + result = "Wrong type of pointer"; + break; + + // + case ERR_FUNCTION_NOT_ALLOWED: + result = "System function is not allowed to call"; + break; + + // + //--- Charts + + // + case ERR_CHART_WRONG_ID: + result = "Wrong chart ID"; + break; + + // + case ERR_CHART_NO_REPLY: + result = "Chart does not respond"; + break; + + // + case ERR_CHART_NOT_FOUND: + result = "Chart not found"; + break; + + // + case ERR_CHART_NO_EXPERT: + result = "No Expert Advisor in the chart that could handle the event"; + break; + + // + case ERR_CHART_CANNOT_OPEN: + result = "Chart opening error"; + break; + + // + case ERR_CHART_CANNOT_CHANGE: + result = "Failed to change chart symbol and period"; + break; + + // + case ERR_CHART_CANNOT_CREATE_TIMER: + result = "Failed to create timer"; + break; + + // + case ERR_CHART_WRONG_PROPERTY: + result = "Wrong chart property ID"; + break; + + // + case ERR_CHART_SCREENSHOT_FAILED: + result = "Error creating screenshots"; + break; + + // + case ERR_CHART_NAVIGATE_FAILED: + result = "Error navigating through chart"; + break; + + // + case ERR_CHART_TEMPLATE_FAILED: + result = "Error applying template"; + break; + + // + case ERR_CHART_WINDOW_NOT_FOUND: + result = "Subwindow containing the indicator was not found"; + break; + + // + case ERR_CHART_INDICATOR_CANNOT_ADD: + result = "Error adding an indicator to chart"; + break; + + // + case ERR_CHART_INDICATOR_CANNOT_DEL: + result = "Error deleting an indicator from the chart"; + break; + + // + case ERR_CHART_INDICATOR_NOT_FOUND: + result = "Indicator not found on the specified chart"; + break; + + // + //--- Graphical Objects + case ERR_OBJECT_ERROR: + result = "Error working with a graphical object"; + break; + + // + case ERR_OBJECT_NOT_FOUND: + result = "Graphical object was not found"; + break; + + // + case ERR_OBJECT_WRONG_PROPERTY: + result = "Wrong ID of a graphical object property"; + break; + + // + case ERR_OBJECT_GETDATE_FAILED: + result = "Unable to get date corresponding to the value"; + break; + + // + case ERR_OBJECT_GETVALUE_FAILED: + result = "Unable to get value corresponding to the date"; + break; + + // + //--- MarketInfo + + // + case ERR_MARKET_UNKNOWN_SYMBOL: + result = "Unknown symbol"; + break; + + // + case ERR_MARKET_NOT_SELECTED: + result = "Symbol is not selected in MarketWatch"; + break; + + // + case ERR_MARKET_WRONG_PROPERTY: + result = "Wrong identifier of a symbol property"; + break; + + // + case ERR_MARKET_LASTTIME_UNKNOWN: + result = "Time of the last tick is not known (no ticks)"; + break; + + // + case ERR_MARKET_SELECT_ERROR: + result = "Error adding or deleting a symbol in MarketWatch"; + break; + + // + //--- History Access + + // + case ERR_HISTORY_NOT_FOUND: + result = "Requested history not found"; + break; + + // + case ERR_HISTORY_WRONG_PROPERTY: + result = "Wrong ID of the history property"; + break; + + // + //--- Global_Variables + + // + case ERR_GLOBALVARIABLE_NOT_FOUND: + result = "Global variable of the client terminal is not found"; + break; + + // + case ERR_GLOBALVARIABLE_EXISTS: + result = "Global variable of the client terminal with the same name already exists"; + break; + + // + case ERR_MAIL_SEND_FAILED: + result = "Email sending failed"; + break; + + // + case ERR_PLAY_SOUND_FAILED: + result = "Sound playing failed"; + break; + + // + case ERR_MQL5_WRONG_PROPERTY: + result = "Wrong identifier of the program property"; + break; + + // + case ERR_TERMINAL_WRONG_PROPERTY: + result = "Wrong identifier of the terminal property"; + break; + + // + case ERR_FTP_SEND_FAILED: + result = "File sending via ftp failed"; + break; + + // + case ERR_NOTIFICATION_SEND_FAILED: + result = "Error in sending notification"; + break; + + // + //--- Custom Indicator Buffers + + // + case ERR_BUFFERS_NO_MEMORY: + result = "Not enough memory for the distribution of indicator buffers"; + break; + + // + case ERR_BUFFERS_WRONG_INDEX: + result = "Wrong indicator buffer index"; + break; + + // + //--- Custom Indicator Properties + + // + case ERR_CUSTOM_WRONG_PROPERTY: + result = "Wrong ID of the custom indicator property"; + break; + + // + //--- Account + + // + case ERR_ACCOUNT_WRONG_PROPERTY: + result = "Wrong account property ID"; + break; + + // + case ERR_TRADE_WRONG_PROPERTY: + result = "Wrong trade property ID"; + break; + + // + case ERR_TRADE_DISABLED: + result = "Trading by Expert Advisors prohibited"; + break; + + // + case ERR_TRADE_POSITION_NOT_FOUND: + result = "Position not found"; + break; + + // + case ERR_TRADE_ORDER_NOT_FOUND: + result = "Order not found"; + break; + + // + case ERR_TRADE_DEAL_NOT_FOUND: + result = "Deal not found"; + break; + + // + case ERR_TRADE_SEND_FAILED: + result = "Trade request sending failed"; + break; + + // + //--- Indicators + + // + case ERR_INDICATOR_UNKNOWN_SYMBOL: + result = "Unknown symbol"; + break; + + // + case ERR_INDICATOR_CANNOT_CREATE: + result = "Indicator cannot be created"; + break; + + // + case ERR_INDICATOR_NO_MEMORY: + result = "Not enough memory to add the indicator"; + break; + + // + case ERR_INDICATOR_CANNOT_APPLY: + result = "The indicator cannot be applied to another indicator"; + break; + + // + case ERR_INDICATOR_CANNOT_ADD: + result = "Error applying an indicator to chart"; + break; + + // + case ERR_INDICATOR_DATA_NOT_FOUND: + result = "Requested data not found"; + break; + + // + case ERR_INDICATOR_WRONG_HANDLE: + result = "Wrong indicator handle"; + break; + + // + case ERR_INDICATOR_WRONG_PARAMETERS: + result = "Wrong number of parameters when creating an indicator"; + break; + + // + case ERR_INDICATOR_PARAMETERS_MISSING: + result = "No parameters when creating an indicator"; + break; + + // + case ERR_INDICATOR_CUSTOM_NAME: + result = "The first parameter in the array must be the name of the custom indicator"; + break; + + // + case ERR_INDICATOR_PARAMETER_TYPE: + result = "Invalid parameter type in the array when creating an indicator"; + break; + + // + case ERR_INDICATOR_WRONG_INDEX: + result = "Wrong index of the requested indicator buffer"; + break; + + // + //--- Depth of Market + + // + case ERR_BOOKS_CANNOT_ADD: + result = "Depth Of Market can not be added"; + break; + + // + case ERR_BOOKS_CANNOT_DELETE: + result = "Depth Of Market can not be removed"; + break; + + // + case ERR_BOOKS_CANNOT_GET: + result = "The data from Depth Of Market can not be obtained"; + break; + + // + case ERR_BOOKS_CANNOT_SUBSCRIBE: + result = "Error in subscribing to receive new data from Depth Of Market"; + break; + + // + //--- File Operations + + // + case ERR_TOO_MANY_FILES: + result = "More than 64 files cannot be opened at the same time"; + break; + + // + case ERR_WRONG_FILENAME: + result = "Invalid file name"; + break; + + // + case ERR_TOO_LONG_FILENAME: + result = "Too long file name"; + break; + + // + case ERR_CANNOT_OPEN_FILE: + result = "File opening error"; + break; + + // + case ERR_FILE_CACHEBUFFER_ERROR: + result = "Not enough memory for cache to read"; + break; + + // + case ERR_CANNOT_DELETE_FILE: + result = "File deleting error"; + break; + + // + case ERR_INVALID_FILEHANDLE: + result = "A file with this handle was closed, or was not opening at all"; + break; + + // + case ERR_WRONG_FILEHANDLE: + result = "Wrong file handle"; + break; + + // + case ERR_FILE_NOTTOWRITE: + result = "The file must be opened for writing"; + break; + + // + case ERR_FILE_NOTTOREAD: + result = "The file must be opened for reading"; + break; + + // + case ERR_FILE_NOTBIN: + result = "The file must be opened as a binary one"; + break; + + // + case ERR_FILE_NOTTXT: + result = "The file must be opened as a text"; + break; + + // + case ERR_FILE_NOTTXTORCSV: + result = "The file must be opened as a text or CSV"; + break; + + // + case ERR_FILE_NOTCSV: + result = "The file must be opened as CSV"; + break; + + // + case ERR_FILE_READERROR: + result = "File reading error"; + break; + + // + case ERR_FILE_BINSTRINGSIZE: + result = "String size must be specified, because the file is opened as binary"; + break; + + // + case ERR_INCOMPATIBLE_FILE: + result = "A text file must be for string arrays, for other arrays - binary"; + break; + + // + case ERR_FILE_IS_DIRECTORY: + result = "This is not a file, this is a directory"; + break; + + // + case ERR_FILE_NOT_EXIST: + result = "File does not exist"; + break; + + // + case ERR_FILE_CANNOT_REWRITE: + result = "File can not be rewritten"; + break; + + // + case ERR_WRONG_DIRECTORYNAME: + result = "Wrong directory name"; + break; + + // + case ERR_DIRECTORY_NOT_EXIST: + result = "Directory does not exist"; + break; + + // + case ERR_FILE_ISNOT_DIRECTORY: + result = "This is a file, not a directory"; + break; + + // + case ERR_CANNOT_DELETE_DIRECTORY: + result = "The directory cannot be removed"; + break; + + // + case ERR_CANNOT_CLEAN_DIRECTORY: + result = "Failed to clear the directory (probably one or more files are blocked and removal operation failed)"; + break; + + // + case ERR_FILE_WRITEERROR: + result = "Failed to write a resource to a file"; + break; + + // + //--- String Casting + + // + case ERR_NO_STRING_DATE: + result = "No date in the string"; + break; + + // + case ERR_WRONG_STRING_DATE: + result = "Wrong date in the string"; + break; + + // + case ERR_WRONG_STRING_TIME: + result = "Wrong time in the string"; + break; + + // + case ERR_STRING_TIME_ERROR: + result = "Error converting string to date"; + break; + + // + case ERR_STRING_OUT_OF_MEMORY: + result = "Not enough memory for the string"; + break; + + // + case ERR_STRING_SMALL_LEN: + result = "The string length is less than expected"; + break; + + // + case ERR_STRING_TOO_BIGNUMBER: + result = "Too large number, more than ULONG_MAX"; + break; + + // + case ERR_WRONG_FORMATSTRING: + result = "Invalid format string"; + break; + + // + case ERR_TOO_MANY_FORMATTERS: + result = "Amount of format specifiers more than the parameters"; + break; + + // + case ERR_TOO_MANY_PARAMETERS: + result = "Amount of parameters more than the format specifiers"; + break; + + // + case ERR_WRONG_STRING_PARAMETER: + result = "Damaged parameter of string type"; + break; + + // + case ERR_STRINGPOS_OUTOFRANGE: + result = "Position outside the string"; + break; + + // + case ERR_STRING_ZEROADDED: + result = "0 added to the string end, a useless operation"; + break; + + // + case ERR_STRING_UNKNOWNTYPE: + result = "Unknown data type when converting to a string"; + break; + + // + case ERR_WRONG_STRING_OBJECT: + result = "Damaged string object"; + break; + + // + //--- Operations with Arrays + + // + case ERR_INCOMPATIBLE_ARRAYS: + result = "Copying incompatible arrays. String array can be copied only to a string array, and a numeric array - in numeric array only"; + break; + + // + case ERR_SMALL_ASSERIES_ARRAY: + result = "The receiving array is declared as AS_SERIES, and it is of insufficient size"; + break; + + // + case ERR_SMALL_ARRAY: + result = "Too small array, the starting position is outside the array"; + break; + + // + case ERR_ZEROSIZE_ARRAY: + result = "An array of zero length"; + break; + + // + case ERR_NUMBER_ARRAYS_ONLY: + result = "Must be a numeric array"; + break; + + // + case ERR_ONEDIM_ARRAYS_ONLY: + result = "Must be a one-dimensional array"; + break; + + // + case ERR_SERIES_ARRAY: + result = "Timeseries cannot be used"; + break; + + // + case ERR_DOUBLE_ARRAY_ONLY: + result = "Must be an array of type double"; + break; + + // + case ERR_FLOAT_ARRAY_ONLY: + result = "Must be an array of type float"; + break; + + // + case ERR_LONG_ARRAY_ONLY: + result = "Must be an array of type long"; + break; + + // + case ERR_INT_ARRAY_ONLY: + result = "Must be an array of type int"; + break; + + // + case ERR_SHORT_ARRAY_ONLY: + result = "Must be an array of type short"; + break; + + // + case ERR_CHAR_ARRAY_ONLY: + result = "Must be an array of type char"; + break; + + // + //--- Operations with OpenCL + + // + case ERR_OPENCL_NOT_SUPPORTED: + result = "OpenCL functions are not supported on this computer"; + break; + + // + case ERR_OPENCL_INTERNAL: + result = "Internal error occurred when running OpenCL"; + break; + + // + case ERR_OPENCL_INVALID_HANDLE: + result = "Invalid OpenCL handle"; + break; + + // + case ERR_OPENCL_CONTEXT_CREATE: + result = "Error creating the OpenCL context"; + break; + + // + case ERR_OPENCL_QUEUE_CREATE: + result = "Failed to create a run queue in OpenCL"; + break; + + // + case ERR_OPENCL_PROGRAM_CREATE: + result = "Error occurred when compiling an OpenCL program"; + break; + + // + case ERR_OPENCL_TOO_LONG_KERNEL_NAME: + result = "Too long kernel name (OpenCL kernel)"; + break; + + // + case ERR_OPENCL_KERNEL_CREATE: + result = "Error creating an OpenCL kernel"; + break; + + // + case ERR_OPENCL_SET_KERNEL_PARAMETER: + result = "Error occurred when setting parameters for the OpenCL kernel"; + break; + + // + case ERR_OPENCL_EXECUTE: + result = "OpenCL program runtime error"; + break; + + // + case ERR_OPENCL_WRONG_BUFFER_SIZE: + result = "Invalid size of the OpenCL buffer"; + break; + + // + case ERR_OPENCL_WRONG_BUFFER_OFFSET: + result = "Invalid offset in the OpenCL buffer"; + break; + + // + case ERR_OPENCL_BUFFER_CREATE: + result = "Failed to create and OpenCL buffer"; + break; + + // + //--- User-Defined Errors + default: + result = "UNKNOWN Erro ..."; + break; + } + + // + return result; +} + +// +// Retrieve Specified Error Code Description ... +string GetTradeServerReturnCodeDescription(int return_code) +{ + // + string result = ""; + + // + switch (return_code) + { + // + case TRADE_RETCODE_REQUOTE: + result = "Requote"; + break; + + // + case TRADE_RETCODE_REJECT: + result = "Request rejected"; + break; + + // + case TRADE_RETCODE_CANCEL: + result = "Request canceled by trader"; + break; + + // + case TRADE_RETCODE_PLACED: + result = "Order placed"; + break; + + // + case TRADE_RETCODE_DONE: + result = "Request completed"; + break; + + // + case TRADE_RETCODE_DONE_PARTIAL: + result = "Only part of the request was completed"; + break; + + // + case TRADE_RETCODE_ERROR: + result = "Request processing error"; + break; + + // + case TRADE_RETCODE_TIMEOUT: + result = "Request canceled by timeout"; + break; + + // + case TRADE_RETCODE_INVALID: + result = "Invalid request"; + break; + + // + case TRADE_RETCODE_INVALID_VOLUME: + result = "Invalid volume in the request"; + break; + + // + case TRADE_RETCODE_INVALID_PRICE: + result = "Invalid price in the request"; + break; + + // + case TRADE_RETCODE_INVALID_STOPS: + result = "Invalid stops in the request"; + break; + + // + case TRADE_RETCODE_TRADE_DISABLED: + result = "Trade is disabled"; + break; + + // + case TRADE_RETCODE_MARKET_CLOSED: + result = "Market is closed"; + break; + + // + case TRADE_RETCODE_NO_MONEY: + result = "There is not enough money to complete the request"; + break; + + // + case TRADE_RETCODE_PRICE_CHANGED: + result = "Prices changed"; + break; + + // + case TRADE_RETCODE_PRICE_OFF: + result = "There are no quotes to process the request"; + break; + + // + case TRADE_RETCODE_INVALID_EXPIRATION: + result = "Invalid order expiration date in the request"; + break; + + // + case TRADE_RETCODE_ORDER_CHANGED: + result = "Order state changed"; + break; + + // + case TRADE_RETCODE_TOO_MANY_REQUESTS: + result = "Too frequent requests"; + break; + + // + case TRADE_RETCODE_NO_CHANGES: + result = "No changes in request"; + break; + + // + case TRADE_RETCODE_SERVER_DISABLES_AT: + result = "Autotrading disabled by server"; + break; + + // + case TRADE_RETCODE_CLIENT_DISABLES_AT: + result = "Autotrading disabled by client terminal"; + break; + + // + case TRADE_RETCODE_LOCKED: + result = "Request locked for processing"; + break; + + // + case TRADE_RETCODE_FROZEN: + result = "Order or position frozen"; + break; + + // + case TRADE_RETCODE_INVALID_FILL: + result = "Invalid order filling type"; + break; + + // + case TRADE_RETCODE_CONNECTION: + result = "No connection with the trade server"; + break; + + // + case TRADE_RETCODE_ONLY_REAL: + result = "Operation is allowed only for live accounts"; + break; + + // + case TRADE_RETCODE_LIMIT_ORDERS: + result = "The number of pending orders has reached the limit"; + break; + + // + case TRADE_RETCODE_LIMIT_VOLUME: + result = "The volume of orders and positions for the symbol has reached the limit"; + break; + + // + default: + result = "Invalid return code of the trade server"; + break; + } + + // + return result; +} diff --git a/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.models.lib.ex5 b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.models.lib.ex5 new file mode 100644 index 0000000..358e61c Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.models.lib.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.models.lib.mq5 b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.models.lib.mq5 new file mode 100644 index 0000000..925909e --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.models.lib.mq5 @@ -0,0 +1,292 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Models Library +// --------------------------------------- +// Name: XModels +// Description: provides all required models ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Inputs ... +// +// +// END Inputs ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// + +// +// How To Calculate Static Volume ... +enum ENUM_STATIC_VOLUME_METHODS +{ + // + // Based On Deposit ... + X_STATIC_VOLUME_BASED_ON_DEPOSIT, + // + // Based On Balance ... + X_STATIC_VOLUME_BASED_ON_BALANCE, +}; + +// +// START Model Definitions ... +// +// +// OHCL Candel Model ... +enum ENUM_X_PRICE +{ + X_PRICE_HIGH, + X_PRICE_OPEN, + X_PRICE_CLOSE, + X_PRICE_LOW +}; + +// +// Swing Types Enum ... +enum ENUM_X_SWING_TYPE +{ + X_NO_SWING = 0, + X_SWING_HIGH = 1, + X_SWING_LOW = -1, +}; + +// +// Select Positions Type ... +enum ENUM_X_POSITION_SELECT_METHODS +{ + X_POSITION_SELECT_NONE, // None + X_POSITION_SELECT_MAX, // Max + X_POSITION_SELECT_MIN, // Min + X_POSITION_SELECT_ALL, // Min +}; + +// +// Available Guard Action ... +enum ENUM_X_GUARD_ACTIONS +{ + X_GUARD_ACTION_NOTHING, // Nothing + X_GUARD_ACTION_HEDGE, // Hedge + X_GUARD_PARTIAL_CLOSE, // Partial Close + X_GUARD_ACTION_TRAIL_STOP, // Trail StopLoss + X_GUARD_ACTION_FORCE_CLOSE, // Force Close + X_GUARD_ACTION_ADD_SUPPORT_SIGNAL, // Add Support Signal + X_GUARD_ACTION_CANCEL_PENDING_ORDERS, // Cancel Pending Orders +}; + +// +// Model Guard Info ... +struct XGuard +{ + string symbol; + string provider; + ENUM_TIMEFRAMES period; + ENUM_POSITION_TYPE type; + ENUM_X_GUARD_ACTIONS action; + + // + double dblPayLoad; + string strPayload; +}; + +// +// Describe an Specific Candle ... +struct XOHCL +{ + double high; + double open; + double close; + double low; +}; + +// +// Model Support and Resistance +// for Specific Bar ... +struct XOHCLSupRes +{ + // + double res[]; + + // + double sup[]; +}; + +// +// Available Order Modes ... +enum ENUM_X_ORDER_MODES +{ + X_ORDER_MODE_MARKET = 0, // Market Order + X_ORDER_MODE_STOP = 1, // Pending Stop Order + X_ORDER_MODE_LIMIT = 2, // Pending Limit Order + X_ORDER_MODE_STOP_LIMIT = 3, // Pending Stop Limit Order +}; + +// +// Model a Signal ... +struct XSignal +{ + // + string providers[]; + + // + string symbol; + + // + ENUM_TIMEFRAMES period; + + // + ENUM_POSITION_TYPE type; + + // + ENUM_X_ORDER_MODES mode; + + // + double entry; + + // + double riskAmount; + + // + double tp; + + // + double sl; + + // + double r2r; + + // + double volume; + + // + bool calculateTP; + + // + bool ignoreSL; + bool ignoreTP; + + // + bool useSupportAndResistance; + + // + bool useRiskAmountAsVolume; + + // + // Support Signals ... + XSignal supports[]; +}; +// +// EXTENSION Methods ... + +// +// Clear an Specific Signal Item ... +void Clean(XSignal &item) +{ + // + ArrayFree(item.providers); + ArrayResize(item.providers, 0); + + // + ArrayFree(item.supports); + ArrayResize(item.supports, 0); + + // + item.symbol = ""; + item.type = NULL; + item.mode = NULL; + item.period = NULL; + + // + item.tp = 0; + item.sl = 0; + item.r2r = 0; + item.entry = 0; + item.volume = 0; + item.riskAmount = 0; + + // + item.ignoreSL = false; + item.ignoreTP = false; + item.calculateTP = false; + item.useRiskAmountAsVolume = false; + item.useSupportAndResistance = false; +} + +template +void Add( + T &item, + T &buffer[]) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} + +template +void Clean(T &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} + +template +void Copy( + T &source[], // Source Buffer ... + T &dest[], // Dest Buffer ... + bool cleanDest = true // Force Clen Dest Buffer ... +) +{ + // + if (cleanDest) + { + Clean(dest); + } + + // + int sourceCount = ArraySize(source); + if (sourceCount <= 0) + { + return; + } + + // + for (int i = 0; i < sourceCount; i++) + { + // + T iSource = source[i]; + + // + Add( + iSource, + dest); + } +} + +// +// END Provided Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.seriallizer.lib.ex5 b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.seriallizer.lib.ex5 new file mode 100644 index 0000000..57aca86 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.seriallizer.lib.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.seriallizer.lib.mq5 b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.seriallizer.lib.mq5 new file mode 100644 index 0000000..f9f266e --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.seriallizer.lib.mq5 @@ -0,0 +1,371 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Seriallize Library +// --------------------------------------- +// Name: XSeriallizer +// Description: provides Seriallizing EA abilities ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +#include "../Libraries/x-saherelm.models.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xtrade.class.mq5" + +// +string XProviderToken = "PRV"; +string XSupportToken = "SP"; +string XSLTrailToken = "SLT"; +string XPeriodToken = "PR"; + +// +// PERIOD ... + +// +// Detect a Comment has period or not ... +bool HasPeriod(string comment) +{ + // + bool result = false; + + // + if (StringLen(comment) == 0) + { + return result; + } + + // + int tokenPos = StringFind( + comment, + XPeriodToken); + result = tokenPos >= 0; + + // + return result; +} + +// +// Extract Period String ... +string ExtractPeriodString(string comment) +{ + // + string result = ""; + + // + bool hasPeriod = HasPeriod(comment); + if (!hasPeriod) + { + return result; + } + + // + result = ExtractString( + comment, + XPeriodToken + "(", + ")"); + + // + return result; +} + +// +// Extract Time Frame From Comment ... +ENUM_TIMEFRAMES ExtractPeriod(string comment) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + if (StringLen(comment) <= 0) + { + return result; + } + + // + string periodStr = ExtractPeriodString(comment); + if (StringLen(periodStr) <= 0) + { + return result; + } + + // + result = ToPeriod(periodStr); + + // + return result; +} + +// +// PROVIDER ... + +// +// Extract a Provider name if exists from a Comment ... +string ExtractProvider(string comment) +{ + // + string result = ""; + if (StringLen(comment) <= 0) + { + return result; + } + + // + result = ExtractString( + comment, + XProviderToken + "(", + ")"); + + // + return result; +} + +// +// Generate Provider String for Using in Positions Comment ... +// NOTE: if there is more than One Provider, it takes first +// provider as main and the others used to increase volume ... +string GenerateProvidersString(XSignal &signal) +{ + // + string result = ""; + + // + int providersCount = ArraySize(signal.providers); + if (providersCount <= 0) + { + return result; + } + + // + result = XProviderToken + "(" + signal.providers[0] + ")"; + + // + return result; +} + +// +// SLTRAIL ... + +// +string GenerateSLTrailComment(int level) +{ + // + string result = ""; + + // + if (level <= 0) + { + return result; + } + + // + result = XSLTrailToken + "(" + ToString(level) + ")"; + + // + return result; +} + +// +int ExtractSLTrailLevel(string comment) +{ + // + int result = 0; + + // + if (StringLen(comment) == 0) + { + return result; + } + + // + string levelStr = ExtractString( + comment, + XSLTrailToken + "(", + ")"); + if (StringLen(levelStr) == 0) + { + return result; + } + + // + result = (int)levelStr; + + // + return result; +} + +// +string PrepareSLTrailComment( + const string comment // Original Position Comment ... +) +{ + // + string result = ""; + + // + if (StringLen(comment) == 0) + { + return result; + } + + // + int level = 0; + result = comment; + + // + // Check Comment Contains SL Trailing or not ... + int lastTrailLevel = ExtractSLTrailLevel(comment); + if (lastTrailLevel <= 0) + { + level++; + } + else + { + // + level = lastTrailLevel + 1; + string lastLevelStr = GenerateSLTrailComment(lastTrailLevel); + StringReplace( + result, + lastLevelStr, + ""); + } + + // + // Generate level Comment ... + string levelStr = GenerateSLTrailComment(level); + result += levelStr; + + // + return result; +} + +// +// SUPPORT ... + +// +// Generate Specific Position's Support Comment +// index is number of Supports ... +string GenerateSupportSignalComment( + ulong ticket, // Position/Order Ticket + int index // Support Index ... +) +{ + // + string result = ""; + + // + result = XSupportToken + "(" + (string)ticket + "," + ToString(index) + ")"; + + // + return result; +} + +// +// Extract Support Parameters String from specified Comment ... +string ExtractSupportParam(string comment) +{ + // + string result = ""; + if (StringLen(comment) <= 0) + { + return result; + } + + // + result = ExtractString( + comment, + XSupportToken + "(", + ")"); + + // + return result; +} + +// +// Extract Support Info as String array for Specific Comment ... +bool ExtractSupportParams( + string comment, // Specified Comment ... + string ¶ms[] // Hold Result ... +) +{ + // + bool result = false; + + // + string supParam = ExtractSupportParam(comment); + if (StringLen(supParam) == 0) + { + return result; + } + + // + SplitContent( + params, + supParam); + int paramsCount = ArraySize(params); + + // + result = paramsCount == 2; + + // + return result; +} + +// +// Extract Support Parent Ticket ... +ulong ExtractParentTicket(string comment) +{ + // + ulong result = 0; + + // + string params[]; + bool isSupport = ExtractSupportParams( + comment, + params); + if (!isSupport) + { + return result; + } + + // + result = (ulong)params[0]; + + // + return result; +} + +// +// Extract Support Index ... +int ExtractSupportIndex(string comment) +{ + // + int result = -1; + + // + string params[]; + bool isSupport = ExtractSupportParams( + comment, + params); + if (!isSupport) + { + return result; + } + + // + result = (int)params[1]; + + // + return result; +} diff --git a/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.x121.draw.lib.ex5 b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.x121.draw.lib.ex5 new file mode 100644 index 0000000..9f87861 Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.x121.draw.lib.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.x121.draw.lib.mq5 b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.x121.draw.lib.mq5 new file mode 100644 index 0000000..941d61b --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.x121.draw.lib.mq5 @@ -0,0 +1,241 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X12 Draw Library +// ------------------------------------------ +// Name: X121Draw +// Description: provides Draw Requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +#include "../Libraries/x-saherelm.draw.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Libraries/x-saherelm.models.lib.mq5" + +// +// START Draw Functions ... +// + +// +// Draw Signal ... +void DrawSignal(const ulong ticket, XSignal &signal) +{ + // + bool isLong = IsLong(signal.type); + + // + string prefix = (string)ticket + "_" + ToString(signal.period); + + // + // Retrieve Time ... + datetime time = iTime( + signal.symbol, + signal.period, + 0); + + // + // Retrieve 3 Time ... + datetime time3 = iTime( + signal.symbol, + signal.period, + 3); + + // + color posColor = isLong + ? clrSpringGreen + : clrTomato; + color tpColor = clrSpringGreen; + color slColor = clrTomato; + color entryColor = clrGold; + + // + ENUM_LINE_STYLE vLineStyle = STYLE_DOT; + ENUM_LINE_STYLE tpLineStyle = STYLE_SOLID; + ENUM_LINE_STYLE slLineStyle = STYLE_SOLID; + ENUM_LINE_STYLE entryLineStyle = STYLE_SOLID; + + // + int lineWidth = 2; + + // + long chartID = ChartID(); + + // + // Vertical Line ... + string vlName = prefix + "_" + (string)time; + + // + DrawVerticalLine( + chartID, + vlName, + 0, + time, + posColor, + vLineStyle, + lineWidth); + + // + // TP ... + double profit = (MathAbs(signal.tp - signal.entry)) * signal.volume; + string tpName = prefix + "_TP_" + (string)profit; + + // + DrawTrendLine( + chartID, + tpName, + 0, + time3, + signal.tp, + time, + signal.tp, + tpColor, + tpLineStyle, + lineWidth); + + // + // SL ... + double lost = (MathAbs(signal.sl - signal.entry)) * signal.volume; + string slName = prefix + "_SL_" + (string)lost; + + // + DrawTrendLine( + chartID, + slName, + 0, + time3, + signal.sl, + time, + signal.sl, + slColor, + slLineStyle, + lineWidth); + + // + // ENTRY ... + string entryName = prefix + "_ENTRY_" + (string)lost; + + // + DrawTrendLine( + chartID, + entryName, + 0, + time3, + signal.entry, + time, + signal.entry, + entryColor, + entryLineStyle, + lineWidth); +} + +// +// Draw Support and Resistance ... +void DrawSupportResistance( + int bar_index, + XOHCLSupRes &data, + string prefix = "", + color supportColor = clrOrange, + color resistanceColor = clrOrange) +{ + // + datetime barTime = GetCandleTime( + _Symbol, + _Period, + bar_index); + + // + datetime prevBarTime = GetCandleTime( + _Symbol, + _Period, + bar_index + 5); + + // + long chID = ChartID(); + int subWindiw = 0; + int lineWidth = 1; + + // + string mPrefix = prefix + "_" + (string)barTime + "_"; + + // + // SUPPORTS ... + + // + int supCount = ArraySize(data.sup); + if (supCount > 0) + { + // + for (int i = 0; i < supCount; i++) + { + // + double iSup = data.sup[i]; + + // + string supTlName = mPrefix + "SUP[" + (string)(i + 1) + "]_(" + (string)iSup + ")"; + + // + // Draw Support ... + DrawTrendLine( + chID, + supTlName, + subWindiw, + prevBarTime, + iSup, + barTime, + iSup, + supportColor, + STYLE_DOT, + lineWidth, + true); + } + } + + // + // RESISTANCES ... + + // + int resCount = ArraySize(data.res); + if (resCount > 0) + { + // + for (int i = 0; i < resCount; i++) + { + // + double iRes = data.res[i]; + + // + string resTlName = mPrefix + "RES[" + (string)(i + 1) + "]_(" + (string)iRes + ")"; + + // + // Draw Support ... + DrawTrendLine( + chID, + resTlName, + subWindiw, + prevBarTime, + iRes, + barTime, + iRes, + resistanceColor, + STYLE_DOT, + lineWidth, + true); + } + } +} + +// +// END Draw Functions ... +// diff --git a/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.x121.signaller.lib.ex5 b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.x121.signaller.lib.ex5 new file mode 100644 index 0000000..25845ef Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.x121.signaller.lib.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.x121.signaller.lib.mq5 b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.x121.signaller.lib.mq5 new file mode 100644 index 0000000..0520fbc --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.x121.signaller.lib.mq5 @@ -0,0 +1,245 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Seriallize Library +// --------------------------------------- +// Name: XSignal +// Description: provides Template Signalling ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +#include "../Libraries/x-saherelm.x121.support.lib.mq5" +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +bool XTMPGetLongSignal( + X121MarketConditions &conditions, // Market Conditions, Result + XSCX121Provider *analyzer // Market Analyzer +) +{ + // + bool result = false; + + // + double entry = GetEntry( + conditions.symbol, + POSITION_TYPE_BUY); + + // + // XCHE Breakout ... + + // + double ll5 = GetLowestLow( + conditions.symbol, + conditions.period, + 5, + 0); + + // + bool isXCHELongExitsExists = + // + conditions.xcheInfo.le1[1] != EMPTY_VALUE && + conditions.xcheInfo.le2[1] != EMPTY_VALUE + // + ; + + // + bool isXCHELongSign = + // + conditions.xcheInfo.le1[2] != EMPTY_VALUE && + conditions.xcheInfo.le2[2] == EMPTY_VALUE && + // + isXCHELongExitsExists && + // + !(ll5 > conditions.xcheInfo.le1[1] || + ll5 > conditions.xcheInfo.le1[2]) + // + ; + + // + bool isCandleBullish = + // + IsBullishCandle(conditions.candles[1]) + // + ; + + // + result = + // + isXCHELongSign && + isCandleBullish + // + ; + + // + if (result) + { + // + conditions.hasSignal = true; + + // + Add( + "XTMP", + conditions.signal.providers); + + // + conditions.signal.type = POSITION_TYPE_BUY; + conditions.signal.mode = X_ORDER_MODE_MARKET; + + // + conditions.signal.symbol = conditions.symbol; + conditions.signal.period = conditions.period; + + // + conditions.signal.r2r = 1; + conditions.signal.volume = 0.01; + conditions.signal.ignoreTP = false; + conditions.signal.ignoreSL = false; + conditions.signal.riskAmount = 0.01; + conditions.signal.calculateTP = false; + conditions.signal.useRiskAmountAsVolume = false; + conditions.signal.useSupportAndResistance = false; + + // + Clean( + conditions.signal.supports); + + // + double tp = 0; + double sl = 0; + + // + // TODO: + // Calculate TP and SL ... + + // + conditions.signal.tp = tp; + conditions.signal.sl = sl; + conditions.signal.entry = entry; + } + + // + return result; +} + +// +bool XTMPGetShortSignal( + X121MarketConditions &conditions, // Market Conditions, Result + XSCX121Provider *analyzer // Market Analyzer +) +{ + // + bool result = false; + + // + double entry = GetEntry( + conditions.symbol, + POSITION_TYPE_SELL); + + // + result = + // + false + // + ; + + // + if (result) + { + // + conditions.hasSignal = true; + + // + Add( + "XTMP", + conditions.signal.providers); + + // + conditions.signal.type = POSITION_TYPE_BUY; + conditions.signal.mode = X_ORDER_MODE_MARKET; + + // + conditions.signal.symbol = conditions.symbol; + conditions.signal.period = conditions.period; + + // + conditions.signal.r2r = 1; + conditions.signal.volume = 0.01; + conditions.signal.ignoreTP = false; + conditions.signal.ignoreSL = false; + conditions.signal.riskAmount = 0.01; + conditions.signal.calculateTP = false; + conditions.signal.useRiskAmountAsVolume = false; + conditions.signal.useSupportAndResistance = false; + + // + Clean( + conditions.signal.supports); + + // + double tp = 0; + double sl = 0; + + // + // TODO: + // Calculate TP and SL ... + + // + conditions.signal.tp = tp; + conditions.signal.sl = sl; + conditions.signal.entry = entry; + } + + // + return result; +} + +// +bool XTMPProcessSignal( + X121MarketConditions &conditions, // Market Conditions, Result + XSCX121Provider *analyzer // Market Analyzer +) +{ + // + bool result = false; + + // + X121MarketConditions mConditions = analyzer.GetMarketConditions(0); + + // + bool hasLong = XTMPGetLongSignal( + mConditions, + analyzer); + if (hasLong) + { + // + conditions = mConditions; + return true; + } + + // + bool hasShort = XTMPGetShortSignal( + mConditions, + analyzer); + if (hasShort) + { + // + conditions = mConditions; + return true; + } + + // + return result; +} \ No newline at end of file diff --git a/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.x121.support.lib.ex5 b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.x121.support.lib.ex5 new file mode 100644 index 0000000..93661ef Binary files /dev/null and b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.x121.support.lib.ex5 differ diff --git a/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.x121.support.lib.mq5 b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.x121.support.lib.mq5 new file mode 100644 index 0000000..ed81b42 --- /dev/null +++ b/MQLTestWorkspace/X121/Old/Libraries/x-saherelm.x121.support.lib.mq5 @@ -0,0 +1,584 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Seriallize Library +// --------------------------------------- +// Name: XSupportSignal +// Description: provides Seriallizing EA abilities ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +#include "../Libraries/x-saherelm.models.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xtrade.class.mq5" +#include "../Libraries/x-saherelm.seriallizer.lib.mq5" +#include "../Classes/x-saherelm.x121.provider.class.mq5" + +// +// TODO: add this to Configurations ... +double supportVolumeMultiplier = 2; +int oldAgeSupportForReNewFactor = 35; +int oldAgePositionForSupportFactor = 17; + +// +// Required Variables ... +double minProfitPerTrade = 0.15; +double minProfitPerVolumeFactor = 0.01; + +// +double supportsSginalTpPoint = 30; + +// +// NOTE: +// Define some tokens to Specify types of Supports ... +string XEQMSupportToken = "XEQM"; + +// +// Define Two Main Support Types of EQM ... +enum ENUM_X121EQM_SUPPORT_TYPES +{ + // + XEQM_UNBOUND = 0, // Without TP ... + XEQM_INBOUND = 1, // With TP ... +}; + +// +// Generate Signal Period Comment Part ... +string GeneratePeriodComment( + ENUM_TIMEFRAMES period = NULL // Time Frame ... +) +{ + // + string result = ""; + + // + if (period == NULL) + { + return result; + } + + // + result = XPeriodToken + "(" + ToString(period) + ")"; + + // + return result; +} + +// +// Generate String Tag for EQM Support Signals ... +string GenerateXEQMSupportComment( + ENUM_TIMEFRAMES period = NULL // Time Frame ... +) +{ + // + string result = XEQMSupportToken; + + // + return result; +} + +// +// Check a Comment belongs to a EQM Support or not ... +bool IsEQMSupport(string comment) +{ + // + bool result = false; + + // + if (StringLen(comment) <= 0) + { + return result; + } + + // + int tokenPosition = StringFind( + comment, + XEQMSupportToken); + result = tokenPosition >= 0; + + // + return result; +} + +// +// Select EQM Support Orders ... +int GetEQMSupportOrders( + XOrder &supports[], // Hold Result ... + XOrder &orders[], // List of All Orders ... + ENUM_TIMEFRAMES period = NULL // Specified Period ... +) +{ + // + int result = 0; + + // + Clean(supports); + + // + int ordersCount = ArraySize(orders); + if (ordersCount <= 0) + { + return result; + } + + // + // Loop through Orders ... + for (int i = 0; i < ordersCount; i++) + { + // + XOrder iOrder = orders[i]; + + // + // Check Order is Support or not ... + bool isSupport = IsEQMSupport(iOrder.comment); + if (!isSupport) + { + continue; + } + + // + // Check Order is not Triggered ... + if (iOrder.state != ORDER_STATE_PLACED) + { + continue; + } + + // + // Check Period ... + if (period != NULL && iOrder.period != period) + { + continue; + } + + // + // we now sure this order is EQM Support ... + Add( + iOrder, + supports); + } + + // + // Count Result ... + result = ArraySize(supports); + + // + return result; +} + +// +// Select EQM Support Orders by Type ... +int GetEQMSupportsByType( + XOrder &supports[], // Hold Result ... + XOrder &orders[], // List of All Orders ... + ENUM_TIMEFRAMES period = NULL, // Specified Period ... + ENUM_X121EQM_SUPPORT_TYPES type = NULL // EQM Support Type ... +) +{ + // + int result = 0; + + // + XOrder mOrders[]; + result = GetEQMSupportOrders(mOrders, orders, period); + if (result <= 0) + { + return result; + } + + // + if (type == NULL) + { + // + Copy( + mOrders, + supports); + } + else + { + // + for (int i = 0; i < result; i++) + { + // + XOrder iOrder = mOrders[i]; + + // + if (iOrder.tp > 0 && type == XEQM_INBOUND) + { + // + Add( + iOrder, + supports); + } + else if (iOrder.tp == 0 && type == XEQM_UNBOUND) + { + // + Add( + iOrder, + supports); + } + } + } + + // + result = ArraySize(supports); + + // + return result; +} + +// +// NOTE: +// here we add all Supporting Signals preparations ... +// 1- must have at least TWO Support Signal without tp ... +// 2- there are some signals by providing tp ... +// 3- Trend base and Conditional Supports by tp ... + +// +// UNBOUND Support => Support Signals with TP ... +// INBOUND Support => Support Signals without TP ... + +// +// in each time when there are an open positions in DrawDown and it's passed +// a certain candles ... +// we Have to Placed atleast 2 UNBOUND Support Signals ... + +// +// LIFETIME of Supports ... +// Each Support Signal must be Cancel if their doesn't triggered +// for an specific Number of Candels ... + +// +// SUPPORT GENERATORs ... + +// +// Generate Supports Signal For Market ... +int GenerateMarketSupports( + XSignal &supports[], // Hold Result + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Timeframe + XSCX121Provider *analyzer, // Market Analizer + double volume = 0.01 // Provided Volume +) +{ + // + int result = 0; + + // + // TODO: Variable ... + int numberOfItems = 10; + + // + Clean(supports); + + // + // Calculate Lng Exit Price ... + double longExit = GetExit(symbol, POSITION_TYPE_BUY); + + // + // Generate Support and Resistances ... + XOHCLSupRes longSupRes = analyzer.GenerateSupportAndResistance( + longExit, + numberOfItems); + + // + // Calculate Short Exit Price ... + double shortExit = GetExit(symbol, POSITION_TYPE_SELL); + + // + // Generate Support and Resistances ... + XOHCLSupRes shortSupRes = analyzer.GenerateSupportAndResistance( + shortExit, + numberOfItems); + + // + X121MarketConditions mConditions = analyzer.GetMarketConditions(1); + + // + double tp = 0; + double sl = 0; + double max = 0; + double med = 0; + double min = 0; + double entry = 0; + double tpPointPrice = PointToPrice( + symbol, + supportsSginalTpPoint); + + // + XSignal mSignal; + Clean(mSignal); + + // + // 1- Breakout PEAK to UP ... + // 2- Breakout PEAK to Down ... + // 3- Breakeout VALE Down ... + + // + mSignal.ignoreTP = false; + mSignal.ignoreSL = false; + mSignal.calculateTP = false; + mSignal.useRiskAmountAsVolume = true; + + // + mSignal.symbol = symbol; + mSignal.period = period; + mSignal.riskAmount = volume; + + // + // 1 + + // + mSignal.mode = X_ORDER_MODE_LIMIT; + mSignal.type = POSITION_TYPE_SELL; + + // + entry = mConditions.xpvInfo.peak; + tp = entry - tpPointPrice; + + // + mSignal.tp = tp; + mSignal.entry = entry; + + // + Add( + mSignal, + supports); + + // + Clean(mSignal); + + // + mSignal.ignoreTP = false; + mSignal.ignoreSL = false; + mSignal.calculateTP = false; + mSignal.useRiskAmountAsVolume = true; + + // + mSignal.symbol = symbol; + mSignal.period = period; + mSignal.riskAmount = volume; + + // + // 2 + + // + mSignal.mode = X_ORDER_MODE_STOP; + mSignal.type = POSITION_TYPE_BUY; + + // + entry = mConditions.xpvInfo.peak; + tp = entry + tpPointPrice; + + // + mSignal.tp = tp; + mSignal.entry = entry; + + // + Add( + mSignal, + supports); + + // + Clean(mSignal); + + // + mSignal.ignoreTP = false; + mSignal.ignoreSL = false; + mSignal.calculateTP = false; + mSignal.useRiskAmountAsVolume = true; + + // + mSignal.symbol = symbol; + mSignal.period = period; + mSignal.riskAmount = volume; + + // + // 3 + + // + mSignal.mode = X_ORDER_MODE_STOP; + mSignal.type = POSITION_TYPE_SELL; + + // + entry = mConditions.xpvInfo.vale; + tp = entry + tpPointPrice; + + // + mSignal.tp = tp; + mSignal.entry = entry; + + // + Add( + mSignal, + supports); + + // + Clean(mSignal); + + // + result = ArraySize(supports); + + // + return result; +} + +// +// Generate Support Signal for Specific Signal ... +bool GenerateSignalSupports( + XSignal &signal, // Source Signal + XSCX121Provider *analyzer // Market Analizer +) +{ + // + bool result = false; + + // + Clean(signal.supports); + + // + string providerStr = signal.providers[0]; + if (StringLen(providerStr) == 0) + { + return result; + } + + // + ENUM_X121_SIGNAL_PROVIDERS provider = ToProvider(providerStr); + bool isAllowed = analyzer.IsAllowdSignaller(provider); + if (!isAllowed) + { + return result; + } + + // + bool isLong = IsLong( + signal.type); + bool isLongSupport = !isLong; + + // + ENUM_POSITION_TYPE type = + isLong + ? POSITION_TYPE_SELL + : POSITION_TYPE_BUY; + + // + double tp = 0; + double sl = 0; + double volume = signal.volume * 2; + double entry = GetEntry( + type); + + // + double tpPriceDistance = MathAbs(signal.entry - signal.tp); + double tpPoint = PriceToPoint( + signal.symbol, + tpPriceDistance); + + // + double ll3 = GetLowestLow( + signal.symbol, + signal.period, + 3, + 0); + + // + double hh3 = GetHighestHigh( + signal.symbol, + signal.period, + 3, + 0); + + // + // XPV ... + double fl1 = analyzer.mXPVHelper.fl1Buffer[0]; + double fl2 = analyzer.mXPVHelper.fl2Buffer[0]; + double fl3 = analyzer.mXPVHelper.fl3Buffer[0]; + double peak = analyzer.mXPVHelper.peaksBuffer[0]; + double vales = analyzer.mXPVHelper.valesBuffer[0]; + + // + double distancePrice = + isLong + ? MathAbs(signal.entry - ll3) + : MathAbs(signal.entry - hh3); + double distancePoint = + PriceToPoint( + signal.symbol, + distancePrice); + double supportTpPrice = + PointToPrice( + signal.symbol, + distancePoint + tpPoint); + + entry = + isLongSupport + ? hh3 + : ll3; + tp = + isLongSupport + ? entry + supportTpPrice + : entry - supportTpPrice; + + // + XSignal tmpSignal; + Clean(tmpSignal); + + // + tmpSignal.r2r = 0; + tmpSignal.volume = volume; + tmpSignal.ignoreTP = false; + tmpSignal.ignoreSL = false; + tmpSignal.riskAmount = volume; + tmpSignal.calculateTP = false; + tmpSignal.symbol = signal.symbol; + tmpSignal.period = signal.period; + tmpSignal.useRiskAmountAsVolume = true; + tmpSignal.useSupportAndResistance = false; + + // + tmpSignal.type = type; + + // + Add( + providerStr, + tmpSignal.providers); + + // + switch (provider) + { + // + // X92 ... + case X92: + // + tmpSignal.tp = tp; + tmpSignal.sl = sl; + tmpSignal.entry = entry; + tmpSignal.mode = X_ORDER_MODE_STOP; + + // + Add( + tmpSignal, + signal.supports); + + // + break; + } + + // + result = ArraySize(signal.supports) > 0; + + // + return result; +} \ No newline at end of file