/////////////////////////////////////////////////////// // SaherElm IT Center MQL5 Indicator // ------------------------------------------- // Name: XCHM // Description: XCHMrend 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 XCHM Indicator" #property strict // #define ShortName "XCHSAR" // // Includes Common Library ... #include "../Libraries/x-saherelm.common.lib.mq5" // // Inputs ... // // Market ... input group "Market"; input double sarStep = 0.02; // Step input double sarMax = 0.2; // Maximum // input group "Cycles"; // input group "Short"; input ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Period input ENUM_TIMEFRAMES scPeriod = NULL; // Time Period // input group "Medium"; input ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Period input ENUM_TIMEFRAMES mcPeriod = NULL; // Time Period // input group "Long"; input ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Period input ENUM_TIMEFRAMES lcPeriod = NULL; // Time Period // input group "Hind"; input ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Period input ENUM_TIMEFRAMES hcPeriod = NULL; // Time Period // // Presentation ... input group "Presentation"; // input int cArrowCode = 225; // Current Cycle Arrow Code input int sArrowCode = 225; // Short Cycle Arrow Code input int mArrowCode = 225; // Medium Cycle Arrow Code input int lArrowCode = 225; // Long Cycle Arrow Code input int hArrowCode = 225; // Hind Cycle Arrow Code // input bool showCurrent = true; // Show Current Cycle input bool showShort = false; // Show Short Cycle input bool showMedium = false; // Show Medium Cycle input bool showLong = false; // Show Long Cycle input bool showHind = false; // Show Hind Cycle // // Buffers ... // #property indicator_chart_window // #property indicator_buffers 5 #property indicator_plots 5 // // Current ... #define cBufferIndex 0 double cBuffer[]; // #property indicator_label1 "XCHSAR C" #property indicator_type1 DRAW_ARROW #property indicator_color1 clrYellow #property indicator_width1 2 // // Short ... #define sBufferIndex 1 double sBuffer[]; // #property indicator_label2 "XCHSAR S" #property indicator_type2 DRAW_ARROW #property indicator_color2 clrMagenta #property indicator_width2 2 // // Medium ... #define mBufferIndex 2 double mBuffer[]; // #property indicator_label3 "XCHSAR M" #property indicator_type3 DRAW_ARROW #property indicator_color3 clrDodgerBlue #property indicator_width3 2 // // Long ... #define lBufferIndex 3 double lBuffer[]; // #property indicator_label4 "XCHSAR L" #property indicator_type4 DRAW_ARROW #property indicator_color4 clrLime #property indicator_width4 2 // // Hind ... #define hBufferIndex 4 double hBuffer[]; // #property indicator_label5 "XCHSAR H" #property indicator_type5 DRAW_ARROW #property indicator_color5 clrRed #property indicator_width5 2 // // Variables ... // int maxLength; // // Current ... int cHandler = INVALID_HANDLE; // // Short ... ENUM_TIMEFRAMES mSCPeriod = NULL; int sHandler = INVALID_HANDLE; // // Medium ... ENUM_TIMEFRAMES mMCPeriod = NULL; int mHandler = INVALID_HANDLE; // // Long ... ENUM_TIMEFRAMES mLCPeriod = NULL; int lHandler = INVALID_HANDLE; // // Hind ... ENUM_TIMEFRAMES mHCPeriod = NULL; int hHandler = INVALID_HANDLE; // // EVENT Handlers ... // // Initialization ... int OnInit() { // // Validate Inputs ... if (!ValidateInputs()) { return INIT_PARAMETERS_INCORRECT; } // if (!InitMarketCycles()) { 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 // // Current ... IndicatorRelease(cHandler); // // Short ... IndicatorRelease(sHandler); // // Medium ... IndicatorRelease(mHandler); // // Long ... IndicatorRelease(lHandler); // // Hind ... IndicatorRelease(hHandler); } // // Calculating what we want ... int OnCalculate( const int rates_total, // Total Bars on Chart ... const int prev_calculated, // Total Calculated Bars on Charts ... const datetime &time[], // History of Open Time ... const double &open[], // History of Open Price ... const double &high[], // History of High Price ... const double &low[], // History of Low Price ... const double &close[], // History of Close Price ... const long &tick_volume[], // History of Tick Volumes on Bar ... const long &volume[], // History of Trade Volumes ... const int &spread[] // History of Spread Price ... ) { // ArraySetAsSeries(low, true); ArraySetAsSeries(open, true); ArraySetAsSeries(high, true); ArraySetAsSeries(close, true); // // this counts Available Bars ... int limit; // // Validate Calculated Bars ... bool isPassedRequiredCalculatedBars = // // Current ... BarsCalculated(cHandler) >= maxLength && // // Short ... BarsCalculated(sHandler) >= maxLength && // // Medium ... BarsCalculated(mHandler) >= maxLength && // // Long ... BarsCalculated(lHandler) >= maxLength && // // Hind ... BarsCalculated(hHandler) >= maxLength // ; if (!isPassedRequiredCalculatedBars) { return prev_calculated; } // limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; // // Buffers Copy ... // // Current ... int copiedCs = CopyBuffer(cHandler, 0, 0, limit, cBuffer); // // Short ... int copiedSs = CopyBuffer(sHandler, 0, 0, limit, sBuffer); // // Medium ... int copiedMs = CopyBuffer(mHandler, 0, 0, limit, mBuffer); // // Long ... int copiedLs = CopyBuffer(lHandler, 0, 0, limit, lBuffer); // // Hind ... int copiedHs = CopyBuffer(hHandler, 0, 0, limit, hBuffer); // // Validate Copied Items ... bool isPassedRequiredCopiedItems = // // // Current ... copiedCs > 0 && // // Short ... copiedSs > 0 && // // Medium ... copiedMs > 0 && // // Long ... copiedLs > 0 && // // Hind ... copiedHs > 0 // ; if (!isPassedRequiredCopiedItems) { return prev_calculated; } // // Main Loop ... // for (int i = limit - 1; i >= 0 && !IsStopped(); i--) // { // CalculateBuffers(i); // } // return rates_total; } // // CUSTOM Functions ... // // Validate Input Args for Initialization ... bool ValidateInputs() { // bool result = // sarStep > 0 && sarMax > sarStep && // (IsValid(scMethod, scPeriod) && IsValid(mcMethod, mcPeriod) && IsValid(lcMethod, lcPeriod) && IsValid(hcMethod, hcPeriod)) // ; // return result; } // // Retrieve all Exists Input Max Length ... // use for Start Of Drawing ... int ExtractMaxLengthOfInputs() { // int result = 0; // return result; } // // Set Indicator Short Name and also we can define Buffers Labels ... void SetIndicatorName() { // IndicatorSetInteger(INDICATOR_DIGITS, _Digits); IndicatorSetString(INDICATOR_SHORTNAME, ShortName); } // // Define Indexes and Styles ... void DefineBuffers() { // // CURRENT ... // ENUM_DRAW_TYPE cDrawType = showCurrent ? DRAW_ARROW : DRAW_NONE; // ArraySetAsSeries(cBuffer, true); SetIndexBuffer(cBufferIndex, cBuffer, INDICATOR_DATA); PlotIndexSetInteger(cBufferIndex, PLOT_ARROW, cArrowCode); PlotIndexSetDouble(cBufferIndex, PLOT_EMPTY_VALUE, 0); // PlotIndexSetInteger(cBufferIndex, PLOT_SHOW_DATA, showCurrent); PlotIndexSetInteger(cBufferIndex, PLOT_DRAW_TYPE, cDrawType); // // SHORT ... // ENUM_DRAW_TYPE sDrawType = showShort ? DRAW_ARROW : DRAW_NONE; // ArraySetAsSeries(sBuffer, true); SetIndexBuffer(sBufferIndex, sBuffer, INDICATOR_DATA); PlotIndexSetInteger(mBufferIndex, PLOT_ARROW, sArrowCode); PlotIndexSetDouble(mBufferIndex, PLOT_EMPTY_VALUE, 0); // PlotIndexSetInteger(sBufferIndex, PLOT_SHOW_DATA, showShort); PlotIndexSetInteger(sBufferIndex, PLOT_DRAW_TYPE, sDrawType); // // MEDIUM ... // ENUM_DRAW_TYPE mDrawType = showMedium ? DRAW_ARROW : DRAW_NONE; // ArraySetAsSeries(mBuffer, true); SetIndexBuffer(mBufferIndex, mBuffer, INDICATOR_DATA); PlotIndexSetInteger(mBufferIndex, PLOT_ARROW, mArrowCode); PlotIndexSetDouble(mBufferIndex, PLOT_EMPTY_VALUE, 0); // PlotIndexSetInteger(mBufferIndex, PLOT_SHOW_DATA, showMedium); PlotIndexSetInteger(mBufferIndex, PLOT_DRAW_TYPE, mDrawType); // // LONG ... // ENUM_DRAW_TYPE lDrawType = showLong ? DRAW_ARROW : DRAW_NONE; // ArraySetAsSeries(lBuffer, true); SetIndexBuffer(lBufferIndex, lBuffer, INDICATOR_DATA); PlotIndexSetInteger(lBufferIndex, PLOT_ARROW, lArrowCode); PlotIndexSetDouble(lBufferIndex, PLOT_EMPTY_VALUE, 0); // PlotIndexSetInteger(lBufferIndex, PLOT_SHOW_DATA, showLong); PlotIndexSetInteger(lBufferIndex, PLOT_DRAW_TYPE, lDrawType); // // HIND ... // ENUM_DRAW_TYPE hDrawType = showHind ? DRAW_ARROW : DRAW_NONE; // ArraySetAsSeries(hBuffer, true); SetIndexBuffer(hBufferIndex, hBuffer, INDICATOR_DATA); PlotIndexSetInteger(hBufferIndex, PLOT_ARROW, hArrowCode); PlotIndexSetDouble(hBufferIndex, PLOT_EMPTY_VALUE, 0); // PlotIndexSetInteger(hBufferIndex, PLOT_SHOW_DATA, showHind); PlotIndexSetInteger(hBufferIndex, PLOT_DRAW_TYPE, hDrawType); } // // Initial Market Cycles ... bool InitMarketCycles() { // bool result = false; // // Current Cycle Initialization ... // int cPeriodSeconds = PeriodSeconds(_Period); // // Initialize Handlers ... // // Current ... cHandler = iSAR( _Symbol, _Period, sarStep, sarMax // ); result = cHandler != INVALID_HANDLE; if (!result) { return result; } // // Short Cycle Initialization ... // // Find Cycle Period ... if (scMethod == X_PERIOD_AUTO) { // // Select Period ... mSCPeriod = GetCyclePeriod( X_MARKET_CYCLE_SHORT, _Period // ); } else { mSCPeriod = scPeriod; } // result = IsValid(mSCPeriod); if (!result) { return result; } // sHandler = iSAR( _Symbol, mSCPeriod, sarStep, sarMax // ); result = sHandler != INVALID_HANDLE; if (!result) { return result; } // // Medium Cycle Initialization ... // // Find Cycle Period ... if (mcMethod == X_PERIOD_AUTO) { // // Select Period ... mMCPeriod = GetCyclePeriod( X_MARKET_CYCLE_MEDIUM, _Period // ); } else { mMCPeriod = mcPeriod; } // result = IsValid(mMCPeriod); if (!result) { return result; } // mHandler = iSAR( _Symbol, mMCPeriod, sarStep, sarMax // ); result = mHandler != INVALID_HANDLE; if (!result) { return result; } // // Long Cycle Initialization ... // // Find Cycle Period ... if (lcMethod == X_PERIOD_AUTO) { // // Select Period ... mLCPeriod = GetCyclePeriod( X_MARKET_CYCLE_LONG, _Period // ); } else { mLCPeriod = lcPeriod; } // result = IsValid(mLCPeriod); if (!result) { return result; } // lHandler = iSAR( _Symbol, mLCPeriod, sarStep, sarMax // ); result = lHandler != INVALID_HANDLE; if (!result) { return result; } // // Hind Cycle Initialization ... // // Find Cycle Period ... if (hcMethod == X_PERIOD_AUTO) { // // Select Period ... mHCPeriod = GetCyclePeriod( X_MARKET_CYCLE_HIND, _Period // ); } else { mHCPeriod = hcPeriod; } // result = IsValid(mHCPeriod); if (!result) { return result; } // hHandler = iSAR( _Symbol, mHCPeriod, sarStep, sarMax // ); result = hHandler != INVALID_HANDLE; if (!result) { return result; } // return result; } // // Do all Custom Calculations ... void CalculateBuffers(int barIndex) { } //