////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Cycle Channel LH Oscillator // --------------------------------------------------- // Name: XCHLH // Description: detecting HH and LL based on cycles ... // // // 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 XCHLH Oscillator" #property strict // // START Constants ... // #define ShortName "XCHLH" // // XCHLH Hot States ... enum ENUM_X_XCHLH_HOT_STATES { X_XCHLH_HOT_HH = 1, X_XCHLH_NEUTURAL = 0, X_XCHLH_HOT_LL = -1, }; // // XCHLH Signal Calculation Types ... enum ENUM_X_XCHLH_SIGNAL_TYPES { X_XCHLH_AVG_SIGNAL, X_XCHLH_DELTA_SIGNAL, }; // // Including Models Library ... #include "..\Libraries\x-saherelm.models.lib.mq5"; // // END Constants ... // // // START Inputs ... // // // Signal Calculations ... input group "Signal Calculations"; input ENUM_X_XCHLH_SIGNAL_TYPES signalType = X_XCHLH_AVG_SIGNAL; // Signal Method // // Common ... input group "Hot Areas"; input bool drawHotAreas = true; // Draw Hot Areas Symbol input uchar hotHHArrowCode = 234; // Hot HH Arrow Code input color hotHHArrowColor = clrAqua; // Hot HH Arrow Color input uchar hotLLArrowCode = 233; // Hot LL Arrow Code input color hotLLArrowColor = clrFuchsia; // Hot LL Arrow Color // // LC Inputs ... input group "Long Cycle"; input group "LC Market"; input int lcLength = 28; // Length input double lcThresholdInPips = 0.3; // Threshold In Pips input ENUM_SERIESMODE lcHHMode = MODE_HIGH; // Highest High Calculation Method input ENUM_SERIESMODE lcLLMode = MODE_LOW; // Lowest Low Calculation Method input group "LC Style"; input int lcDrawWidth = 1; // Draw Width input ENUM_DRAW_TYPE lcDrawType = DRAW_LINE; // Draw Type input ENUM_LINE_STYLE lcDrawStyle = STYLE_DOT; // Draw Style input color lcHHColor = clrAqua; // Highest High Color input color lcLLColor = clrFuchsia; // Lowest Low Color input group "LC Drawings"; input bool lcDrawHH = true; // Draw Highest High input bool lcDrawLL = true; // Draw Lowest Low // // MC Inputs ... input group "Medium Cycle"; input group "MC Market"; input int mcLength = 14; // Length input double mcThresholdInPips = 0.3; // Threshold In Pips input ENUM_SERIESMODE mcHHMode = MODE_HIGH; // Highest High Calculation Method input ENUM_SERIESMODE mcLLMode = MODE_LOW; // Lowest Low Calculation Method input group "MC Style"; input int mcDrawWidth = 1; // Draw Width input ENUM_DRAW_TYPE mcDrawType = DRAW_LINE; // Draw Type input ENUM_LINE_STYLE mcDrawStyle = STYLE_DOT; // Draw Style input color mcHHColor = clrLime; // Highest High Color input color mcLLColor = clrRed; // Lowest Low Color input group "MC Drawings"; input bool mcDrawHH = true; // Draw Highest High input bool mcDrawLL = true; // Draw Lowest Low // // SC Inputs ... input group "Short Cycle"; input group "SC Market"; input int scLength = 7; // Length input double scThresholdInPips = 0.3; // Threshold In Pips input ENUM_SERIESMODE scHHMode = MODE_HIGH; // Highest High Calculation Method input ENUM_SERIESMODE scLLMode = MODE_LOW; // Lowest Low Calculation Method input group "SC Style"; input int scDrawWidth = 1; // Draw Width input ENUM_DRAW_TYPE scDrawType = DRAW_LINE; // Draw Type input ENUM_LINE_STYLE scDrawStyle = STYLE_DOT; // Draw Style input color scHHColor = clrLightBlue; // Highest High Color input color scLLColor = clrLightSalmon; // Lowest Low Color input group "SC Drawings"; input bool scDrawHH = true; // Draw Highest High input bool scDrawLL = true; // Draw Lowest Low // // END Inputs ... // // // Includes Logging Library ... #include "../Libraries/x-saherelm.log.lib.mq5"; // // Includes Common Library ... #include "../Libraries/x-saherelm.common.lib.mq5"; // // Includes Draw Library ... #include "../Libraries/x-saherelm.draw.lib.mq5"; // // START Buffers ... // #property indicator_separate_window // #property indicator_buffers 9 #property indicator_plots 8 // // LC ... #define lcHHBufferIndex 0 #define lcLLBufferIndex 1 // double lcHHBuffer[]; double lcLLBuffer[]; // // MC ... #define mcHHBufferIndex 2 #define mcLLBufferIndex 3 // double mcHHBuffer[]; double mcLLBuffer[]; // // SC ... #define scHHBufferIndex 4 #define scLLBufferIndex 5 // double scHHBuffer[]; double scLLBuffer[]; // // SIGNAL ... #define signalTBufferIndex 6 #define signalBBufferIndex 7 // double signalTBuffer[]; double signalBBuffer[]; // #property indicator_label7 "XSignal T" #property indicator_type7 DRAW_LINE #property indicator_color7 clrGold #property indicator_style7 STYLE_DOT #property indicator_width7 1 // #property indicator_label8 "XSignal B" #property indicator_type8 DRAW_LINE #property indicator_color8 clrBlueViolet #property indicator_style8 STYLE_DOT #property indicator_width8 1 // // Hot State ... // #define hotStateBufferIndex 8 // double hotStateBuffer[]; // // 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 (!ValidateInputs()) { return INIT_PARAMETERS_INCORRECT; } // logTag = ShortName; drawPrefix = ShortName; // // Define Index Buffers ... DefineBuffers(); // // Set Indicator ShortName ... SetIndicatorName(); // // Init Succeed ... return INIT_SUCCEEDED; } // // DeInitialization ... void OnDeinit(const int reason) { // // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function // REASON_REMOVE 1 Program removed from a chart // REASON_RECOMPILE 2 Program recompiled // REASON_CHARTCHANGE 3 A symbol or a chart period is changed // REASON_CHARTCLOSE 4 Chart closed // REASON_PARAMETERS 5 Inputs changed by a user // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings // REASON_TEMPLATE 7 Another chart template applied // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value // REASON_CLOSE 9 Terminal closed // // Here we can handle De Initialization Reasons ... // // ReDraw Chart ... ChartRedraw(); // // De Init Draw Library ... OnDeinitDrawLibrary(); // Comment(""); } // // Calculations ... // // 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; // // 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 ... int maxLength = MathMax(lcLength, mcLength); maxLength = MathMax(maxLength, scLength); // limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; // // Main Loop ... for (int i = limit; i >= 0 && !IsStopped(); i--) { // CalculateBuffers(i); } // return rates_total; } // // END Event Handlers ... // // // START Functions ... // // // Validate Input Args for Initialization ... bool ValidateInputs() { // bool result = false; // // Validate Args ... bool isLCInputsValid = lcLength >= 4 && lcLength > mcLength && lcLength > scLength; bool isMCInputsValid = mcLength >= 4 && mcLength > scLength && mcLength < lcLength; bool isSCInputsValid = scLength >= 4 && scLength < mcLength && scLength < lcLength; if ( isLCInputsValid && isMCInputsValid && isSCInputsValid) { result = true; } // return result; } // // Define Indexes and Styles ... void DefineBuffers() { // // LC ... LCDefineBuffers(); // // MC ... MCDefineBuffers(); // // SC ... SCDefineBuffers(); // // SIGNAL ... SignalDefineBuffers(); // // Hot State Buffer ... HotStateDefineBuffers(); } // // Set Indicator Short Name and also we can define Buffers Labels ... void SetIndicatorName() { // string indicatorShortName = ""; StringConcatenate(indicatorShortName, ShortName, ""); // IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); } // // Calculate Buffers ... void CalculateBuffers( int bar_index // Current Candle Index ... ) { // // LC ... LCCalculateBuffers(bar_index); // // MC ... MCCalculateBuffers(bar_index); // // SC ... SCCalculateBuffers(bar_index); // // SIGNAL ... SignalCalculateBuffers(bar_index); // // HOT State Buffer ... HotStateCalculateBuffers(bar_index); // // After all Calculations we are ready to Draw what we want ... DrawBuffers(bar_index); } // // LC Buffers Definitions ... void LCDefineBuffers() { // // LC HH Buffer ... string lcHHBufferLabel = ShortName + " LC HH (" + (string)lcLength + ")"; ENUM_DRAW_TYPE lcHHDrawType = lcDrawHH ? lcDrawType : DRAW_NONE; ArraySetAsSeries(lcHHBuffer, true); SetIndexBuffer(lcHHBufferIndex, lcHHBuffer, INDICATOR_DATA); PlotIndexSetInteger(lcHHBufferIndex, PLOT_DRAW_BEGIN, lcLength); PlotIndexSetString(lcHHBufferIndex, PLOT_LABEL, lcHHBufferLabel); PlotIndexSetInteger(lcHHBufferIndex, PLOT_LINE_COLOR, lcHHColor); PlotIndexSetInteger(lcHHBufferIndex, PLOT_LINE_STYLE, lcDrawStyle); PlotIndexSetInteger(lcHHBufferIndex, PLOT_LINE_WIDTH, lcDrawWidth); PlotIndexSetInteger(lcHHBufferIndex, PLOT_DRAW_TYPE, lcHHDrawType); // // LC LL Buffer ... string lcLLBufferLabel = ShortName + " LC LL (" + (string)lcLength + ")"; ENUM_DRAW_TYPE lcLLDrawType = lcDrawLL ? lcDrawType : DRAW_NONE; ArraySetAsSeries(lcLLBuffer, true); SetIndexBuffer(lcLLBufferIndex, lcLLBuffer, INDICATOR_DATA); PlotIndexSetInteger(lcLLBufferIndex, PLOT_DRAW_BEGIN, lcLength); PlotIndexSetString(lcLLBufferIndex, PLOT_LABEL, lcLLBufferLabel); PlotIndexSetInteger(lcLLBufferIndex, PLOT_LINE_COLOR, lcLLColor); PlotIndexSetInteger(lcLLBufferIndex, PLOT_LINE_STYLE, lcDrawStyle); PlotIndexSetInteger(lcLLBufferIndex, PLOT_LINE_WIDTH, lcDrawWidth); PlotIndexSetInteger(lcLLBufferIndex, PLOT_DRAW_TYPE, lcLLDrawType); } // // MC Buffers Definitions ... void MCDefineBuffers() { // // MC HH Buffer ... string mcHHBufferLabel = ShortName + " MC HH (" + (string)mcLength + ")"; ENUM_DRAW_TYPE mcHHDrawType = mcDrawHH ? lcDrawType : DRAW_NONE; ArraySetAsSeries(mcHHBuffer, true); SetIndexBuffer(mcHHBufferIndex, mcHHBuffer, INDICATOR_DATA); PlotIndexSetInteger(mcHHBufferIndex, PLOT_DRAW_BEGIN, mcLength); PlotIndexSetString(mcHHBufferIndex, PLOT_LABEL, mcHHBufferLabel); PlotIndexSetInteger(mcHHBufferIndex, PLOT_LINE_COLOR, mcHHColor); PlotIndexSetInteger(mcHHBufferIndex, PLOT_LINE_STYLE, mcDrawStyle); PlotIndexSetInteger(mcHHBufferIndex, PLOT_LINE_WIDTH, mcDrawWidth); PlotIndexSetInteger(mcHHBufferIndex, PLOT_DRAW_TYPE, mcHHDrawType); // // MC LL Buffer ... string mcLLBufferLabel = ShortName + " MC LL (" + (string)mcLength + ")"; ENUM_DRAW_TYPE mcLLDrawType = mcDrawLL ? lcDrawType : DRAW_NONE; ArraySetAsSeries(mcLLBuffer, true); SetIndexBuffer(mcLLBufferIndex, mcLLBuffer, INDICATOR_DATA); PlotIndexSetInteger(mcLLBufferIndex, PLOT_DRAW_BEGIN, mcLength); PlotIndexSetString(mcLLBufferIndex, PLOT_LABEL, mcLLBufferLabel); PlotIndexSetInteger(mcLLBufferIndex, PLOT_LINE_COLOR, mcLLColor); PlotIndexSetInteger(mcLLBufferIndex, PLOT_LINE_STYLE, mcDrawStyle); PlotIndexSetInteger(mcLLBufferIndex, PLOT_LINE_WIDTH, mcDrawWidth); PlotIndexSetInteger(mcLLBufferIndex, PLOT_DRAW_TYPE, mcLLDrawType); } // // SC Buffers Definitions ... void SCDefineBuffers() { // // SC HH Buffer ... string scHHBufferLabel = ShortName + " SC HH (" + (string)scLength + ")"; ENUM_DRAW_TYPE scHHDrawType = scDrawHH ? lcDrawType : DRAW_NONE; ArraySetAsSeries(scHHBuffer, true); SetIndexBuffer(scHHBufferIndex, scHHBuffer, INDICATOR_DATA); PlotIndexSetInteger(scHHBufferIndex, PLOT_DRAW_BEGIN, scLength); PlotIndexSetString(scHHBufferIndex, PLOT_LABEL, scHHBufferLabel); PlotIndexSetInteger(scHHBufferIndex, PLOT_LINE_COLOR, scHHColor); PlotIndexSetInteger(scHHBufferIndex, PLOT_LINE_STYLE, scDrawStyle); PlotIndexSetInteger(scHHBufferIndex, PLOT_LINE_WIDTH, scDrawWidth); PlotIndexSetInteger(scHHBufferIndex, PLOT_DRAW_TYPE, scHHDrawType); // // SC LL Buffer ... string scLLBufferLabel = ShortName + " SC LL (" + (string)scLength + ")"; ENUM_DRAW_TYPE scLLDrawType = scDrawLL ? lcDrawType : DRAW_NONE; ArraySetAsSeries(scLLBuffer, true); SetIndexBuffer(scLLBufferIndex, scLLBuffer, INDICATOR_DATA); PlotIndexSetInteger(scLLBufferIndex, PLOT_DRAW_BEGIN, scLength); PlotIndexSetString(scLLBufferIndex, PLOT_LABEL, scLLBufferLabel); PlotIndexSetInteger(scLLBufferIndex, PLOT_LINE_COLOR, scLLColor); PlotIndexSetInteger(scLLBufferIndex, PLOT_LINE_STYLE, scDrawStyle); PlotIndexSetInteger(scLLBufferIndex, PLOT_LINE_WIDTH, scDrawWidth); PlotIndexSetInteger(scLLBufferIndex, PLOT_DRAW_TYPE, scLLDrawType); } // // SIGNAL Buffers Definitions ... void SignalDefineBuffers() { // // SIGNAL T Buffer ... string signalTBufferLabel = ShortName + " Signal T"; ArraySetAsSeries(signalTBuffer, true); SetIndexBuffer(signalTBufferIndex, signalTBuffer, INDICATOR_DATA); PlotIndexSetInteger(signalTBufferIndex, PLOT_DRAW_BEGIN, lcLength); PlotIndexSetString(signalTBufferIndex, PLOT_LABEL, signalTBufferLabel); // // SIGNAL B Buffer ... string signalBBufferLabel = ShortName + " Signal B"; ArraySetAsSeries(signalBBuffer, true); SetIndexBuffer(signalBBufferIndex, signalBBuffer, INDICATOR_DATA); PlotIndexSetInteger(signalBBufferIndex, PLOT_DRAW_BEGIN, lcLength); PlotIndexSetString(signalBBufferIndex, PLOT_LABEL, signalBBufferLabel); } // // Hot State Buffer ... void HotStateDefineBuffers() { // // Hot State Buffer ... ArraySetAsSeries(hotStateBuffer, true); SetIndexBuffer(hotStateBufferIndex, hotStateBuffer, INDICATOR_CALCULATIONS); } // // LC Calculations ... void LCCalculateBuffers( int bar_index // Current Candle Index ... ) { // // Detect Cycle HH and LL ... int length = lcLength; ENUM_SERIESMODE hhMode = lcHHMode; ENUM_SERIESMODE llMode = lcLLMode; double threshold = PipsToPrice(lcThresholdInPips); double hh = GetHighestHigh( length, bar_index, hhMode); double hhValue = hh + threshold; double ll = GetLowestLow( length, bar_index, llMode); double llValue = ll - threshold; // lcHHBuffer[bar_index] = hhValue; lcLLBuffer[bar_index] = llValue; } // // MC Calculations ... void MCCalculateBuffers( int bar_index // Current Candle Index ... ) { // // Detect Cycle HH and LL ... int length = mcLength; ENUM_SERIESMODE hhMode = mcHHMode; ENUM_SERIESMODE llMode = mcLLMode; double threshold = PipsToPrice(mcThresholdInPips); double hh = GetHighestHigh( length, bar_index, hhMode); double hhValue = hh + threshold; double ll = GetLowestLow( length, bar_index, llMode); double llValue = ll - threshold; // mcHHBuffer[bar_index] = hhValue; mcLLBuffer[bar_index] = llValue; } // // SC Calculations ... void SCCalculateBuffers( int bar_index // Current Candle Index ... ) { // // Detect Cycle HH and LL ... int length = scLength; ENUM_SERIESMODE hhMode = scHHMode; ENUM_SERIESMODE llMode = scLLMode; double threshold = PipsToPrice(scThresholdInPips); double hh = GetHighestHigh( length, bar_index, hhMode); double hhValue = hh + threshold; double ll = GetLowestLow( length, bar_index, llMode); double llValue = ll - threshold; // scHHBuffer[bar_index] = hhValue; scLLBuffer[bar_index] = llValue; } // // SIGNAL Calculations ... void SignalCalculateBuffers( int bar_index // Current Candle Index ... ) { // // LC Values ... double lcHH = lcHHBuffer[bar_index]; double lcLL = lcLLBuffer[bar_index]; double lcDelta = lcHH - lcLL; double lcAvg = lcDelta / 2; // // MC Values ... double mcHH = mcHHBuffer[bar_index]; double mcLL = mcLLBuffer[bar_index]; double mcDelta = mcHH - mcLL; double mcAvg = mcDelta / 2; // // SC Values ... double scHH = scHHBuffer[bar_index]; double scLL = scLLBuffer[bar_index]; double scDelta = scHH - scLL; double scAvg = scDelta / 2; // // Min Value ... double minValue = MathMin( scLL, mcLL); minValue = MathMin( lcLL, minValue); // // Max Value ... double maxValue = MathMin( scHH, mcHH); maxValue = MathMin( lcHH, maxValue); // double operationalValue = 0; switch(signalType) { // case X_XCHLH_DELTA_SIGNAL: operationalValue = ((lcDelta + mcDelta + scDelta) / 3); break; // case X_XCHLH_AVG_SIGNAL: default: operationalValue = ((lcAvg + mcAvg + scAvg) / 3); break; } // double signalTValue = minValue + operationalValue; double signalBValue = maxValue - operationalValue; // signalTBuffer[bar_index] = signalTValue; signalBBuffer[bar_index] = signalBValue; } // // HOT State Calculate Buffers ... void HotStateCalculateBuffers( int bar_index // Current Candle Index ... ) { // // LC ... double lcHH = lcHHBuffer[bar_index]; double lcLL = lcLLBuffer[bar_index]; // double lcHH1 = lcHHBuffer[bar_index + 1]; double lcLL1 = lcLLBuffer[bar_index + 1]; // // MC ... double mcHH = mcHHBuffer[bar_index]; double mcLL = mcLLBuffer[bar_index]; // double mcHH1 = mcHHBuffer[bar_index + 1]; double mcLL1 = mcLLBuffer[bar_index + 1]; // // SC ... double scHH = scHHBuffer[bar_index]; double scLL = scLLBuffer[bar_index]; // double scHH1 = scHHBuffer[bar_index + 1]; double scLL1 = scLLBuffer[bar_index + 1]; // bool isHotLLState = scLL == mcLL && mcLL == lcLL; bool isHotLLState1 = scLL1 == mcLL1 && mcLL1 == lcLL1; // bool isHotHHState = scHH == mcHH && mcHH == lcHH; bool isHotHHState1 = scHH1 == mcHH1 && mcHH1 == lcHH1; // bool isHotLL = isHotLLState && !isHotLLState1; bool isHotHH = isHotHHState && !isHotHHState1; // double hotStateValue = X_XCHLH_NEUTURAL; if (isHotHH) { hotStateValue = X_XCHLH_HOT_HH; } else if (isHotLL) { hotStateValue = X_XCHLH_HOT_LL; } // hotStateBuffer[bar_index] = hotStateValue; } // // Draw Buffers ... void DrawBuffers( int bar_index // Current Candle Index ... ) { // // General Requirements ... // // Retrieve Candle Model ... XOHCL candle = GetCandle(bar_index); datetime time = iTime(_Symbol, _Period, bar_index); // // Draw Arrow on Hot Areas ... if (drawHotAreas) { // double hotStateValue = hotStateBuffer[bar_index]; bool isHotHHArea = hotStateValue == 1; bool isHotLLArea = hotStateValue == -1; if (isHotHHArea || isHotLLArea) { // bool isHH = isHotHHArea; // double price = isHH ? candle.high : candle.low; ENUM_ARROW_ANCHOR anchor = isHH ? ANCHOR_BOTTOM : ANCHOR_TOP; color clr = isHH ? hotHHArrowColor : hotLLArrowColor; uchar arrowCode = isHH ? hotHHArrowCode : hotLLArrowCode; string name = "HOT " + (isHH ? "HH" : "LL") + "_" + (string)price + "_" + (string)time; // DrawArrow( 0, name, 0, time, price, arrowCode, anchor, clr, STYLE_SOLID, 1); } } } // // END Functions ... //