///////////////////////////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 XICHIHLP Indicator Helper for Signal Providers // -------------------------------------------------------------------------- // // 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 Includes ... // // // Includes ... #include "../../Libraries/x-saherelm.alert.lib.mq5" #include "../../Libraries/x-saherelm.models.lib.mq5" #include "../../Libraries/x-saherelm.common.lib.mq5" // // END Includes ... // // // START Constants/Enums ... // // // 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 }; // // Ichimoku Indicator Exported Buffers ... enum ENUM_X_ICHIMOKU_BUFFERS { // X_TENKANSEN_LINE = 0, X_KIJUNSEN_LINE = 1, X_CHIKOUSPAN_LINE = 4, X_SENKOUSPAN_A_LINE = 5, X_SENKOUSPAN_B_LINE = 6, }; // // Model Ichimoku Data ... struct XIchiInfo { // int bar; // double tenkanSen; double kijunSen; // double chikouSpan; // double senkouSpanA; double senkouSpanB; // double senkouSpanAFuture; double senkouSpanBFuture; }; // double ichiPivots[]; // // END Constants/Enums ... // // // START Definitions ... // // double ichiTenkanSenBuffer[]; double ichiKijunSenBuffer[]; double ichiChikouSpanBuffer[]; double ichiSenkouSpanABuffer[]; double ichiSenkouSpanBBuffer[]; // int ichiHandler = INVALID_HANDLE; // // END Definitions ... // // // START Handler Functions ... // // bool XICHIHLPOnInit() { // bool result = false; // ArraySetAsSeries(ichiTenkanSenBuffer, true); ArraySetAsSeries(ichiKijunSenBuffer, true); ArraySetAsSeries(ichiChikouSpanBuffer, true); ArraySetAsSeries(ichiSenkouSpanABuffer, true); ArraySetAsSeries(ichiSenkouSpanBBuffer, true); // ArraySetAsSeries(ichiPivots, true); // // Initial Handler ... ichiHandler = iCustom( _Symbol, _Period, "x-saherelm.x121.xich", // // Inputs ... // // TENKANSEN ... "", 9, X_XICH_HH_LL_MODE, // // KIJUNSEN ... "", 26, X_XICH_HH_LL_MODE, // // SENKOUSPANB ... "", 52, X_XICH_HH_LL_MODE, // // CHIKOUSPAN ... "", PRICE_CLOSE, // // PRESENTATION ... "", true, true, false, false, false, false, false, true, true // Shift Kumo ... // ); result = ichiHandler != INVALID_HANDLE; // return result; } // void XICHIHLPOnDeInit() { // // Release Indicators ... IndicatorRelease(ichiHandler); } // void XICHIHLPReadBuffers() { // // TENKANSEN ... CopyBuffer( ichiHandler, X_TENKANSEN_LINE, 0, 26, ichiTenkanSenBuffer); // // KIJUNSEN ... CopyBuffer( ichiHandler, X_KIJUNSEN_LINE, 0, 26, ichiKijunSenBuffer); // // CHIKOUSPAN ... CopyBuffer( ichiHandler, X_CHIKOUSPAN_LINE, 27, 52, ichiChikouSpanBuffer); // // SENKOUSPANA ... CopyBuffer( ichiHandler, X_SENKOUSPAN_A_LINE, -26, 52, ichiSenkouSpanABuffer); // // SENKOUSPANB ... CopyBuffer( ichiHandler, X_SENKOUSPAN_B_LINE, -26, 52, ichiSenkouSpanBBuffer); // XICHIHLPFindPivotPoints(); } // // END Handler Functions ... // // // START Helper Functions ... // // // Retrieve Ichimoku Data at Specific Bar Index ... XIchiInfo XICHIHLPGetInfo( int bar_index // Bar Index ... ) { // XIchiInfo result = {}; // result.bar = bar_index; result.tenkanSen = ichiTenkanSenBuffer[bar_index]; result.kijunSen = ichiKijunSenBuffer[bar_index]; result.chikouSpan = ichiChikouSpanBuffer[bar_index + 26]; result.senkouSpanA = ichiSenkouSpanABuffer[bar_index + 26]; result.senkouSpanB = ichiSenkouSpanBBuffer[bar_index + 26]; result.senkouSpanAFuture = ichiSenkouSpanABuffer[bar_index]; result.senkouSpanBFuture = ichiSenkouSpanBBuffer[bar_index]; // return result; } // // Check Tenkan Sen Over Kijun Sen ... bool XICHIHLPIsTenkanSenOverKijunSen( int bar_index // Bar Index ... ) { // bool result = false; // XIchiInfo point = XICHIHLPGetInfo(bar_index); // result = // point.tenkanSen > point.kijunSen // ; // return result; } // // Is Tenkan Sen Under Kijun Sen ... bool XICHIHLPIsTenkanSenUnderKijunSen( int bar_index // Bar Index ... ) { // bool result = false; // XIchiInfo point = XICHIHLPGetInfo(bar_index); // result = // point.tenkanSen < point.kijunSen // ; // return result; } // // Tenkan Sen Croosed Over Kijun Sen ... bool XICHIHLPIsTenkanSenCrossedOverKijunSen( int bar_index // Bar Index ... ) { // bool result = false; // XIchiInfo point = XICHIHLPGetInfo(bar_index); XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); // result = // point.tenkanSen > point.kijunSen && pointPrev.tenkanSen <= pointPrev.kijunSen // ; // return result; } // // Tenkan Sen Croosed Under Kijun Sen ... bool XICHIHLPIsTenkanSenCrossedUnderKijunSen( int bar_index // Bar Index ... ) { // bool result = false; // XIchiInfo point = XICHIHLPGetInfo(bar_index); XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); // result = // point.tenkanSen < point.kijunSen && pointPrev.tenkanSen >= pointPrev.kijunSen // ; // return result; } // // Check Kumo is Bullish ... bool XICHIHLPIsKumoBullish( int bar_index, // Bar Index ... bool onFuture = false // Future Check ... ) { // bool result = false; // XIchiInfo point = XICHIHLPGetInfo(bar_index); XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); // double ssa = onFuture ? point.senkouSpanAFuture : point.senkouSpanA; // double ssb = onFuture ? point.senkouSpanBFuture : point.senkouSpanB; // result = // ssa > ssb // ; // return result; } // // Check Kumo is Bearish ... bool XICHIHLPIsKumoBearish( int bar_index, // Bar Index ... bool onFuture = false // Future Check ... ) { // bool result = false; // XIchiInfo point = XICHIHLPGetInfo(bar_index); XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); // double ssa = onFuture ? point.senkouSpanAFuture : point.senkouSpanA; // double ssb = onFuture ? point.senkouSpanBFuture : point.senkouSpanB; // result = // ssa < ssb // ; // return result; } // // Check Kumo is Change to Bullish ... bool XICHIHLPIsKumoSwitchedToBullish( int bar_index, // Bar Index ... bool onFuture = false // Future Check ... ) { // bool result = false; // XIchiInfo point = XICHIHLPGetInfo(bar_index); XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); // double ssa = onFuture ? point.senkouSpanAFuture : point.senkouSpanA; // double ssb = onFuture ? point.senkouSpanBFuture : point.senkouSpanB; // double ssaPrev = onFuture ? pointPrev.senkouSpanAFuture : pointPrev.senkouSpanA; // double ssbPrev = onFuture ? pointPrev.senkouSpanBFuture : pointPrev.senkouSpanB; // result = // ssa > ssb && ssaPrev <= ssbPrev // ; // return result; } // // Check Kumo is Change to Bearish ... bool XICHIHLPIsKumoSwitchedToBearish( int bar_index, // Bar Index ... bool onFuture = false // Future Check ... ) { // bool result = false; // XIchiInfo point = XICHIHLPGetInfo(bar_index); XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); // double ssa = onFuture ? point.senkouSpanAFuture : point.senkouSpanA; // double ssb = onFuture ? point.senkouSpanBFuture : point.senkouSpanB; // double ssaPrev = onFuture ? pointPrev.senkouSpanAFuture : pointPrev.senkouSpanA; // double ssbPrev = onFuture ? pointPrev.senkouSpanBFuture : pointPrev.senkouSpanB; // result = // ssa < ssb && ssaPrev >= ssbPrev // ; // return result; } // // TENKANSEN and SENKOUSPAN ... // bool XICHIHLPIsTenkanSenCrossedOverSenkouSpanA( int bar_index, // Bar Index ... bool onFuture = false // Future Check ... ) { // bool result = false; // XIchiInfo point = XICHIHLPGetInfo(bar_index); XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); // double dest = onFuture ? point.senkouSpanAFuture : point.senkouSpanA; // double destPrev = onFuture ? pointPrev.senkouSpanAFuture : pointPrev.senkouSpanA; // result = // point.tenkanSen > dest && pointPrev.tenkanSen <= destPrev // ; // return result; } // bool XICHIHLPIsTenkanSenCrossedUnderSenkouSpanA( int bar_index, // Bar Index ... bool onFuture = false // Future Check ... ) { // bool result = false; // XIchiInfo point = XICHIHLPGetInfo(bar_index); XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); // double dest = onFuture ? point.senkouSpanAFuture : point.senkouSpanA; // double destPrev = onFuture ? pointPrev.senkouSpanAFuture : pointPrev.senkouSpanA; // result = // point.tenkanSen < dest && pointPrev.tenkanSen >= destPrev // ; // return result; } // bool XICHIHLPIsTenkanSenCrossedOverSenkouSpanB( int bar_index, // Bar Index ... bool onFuture = false // Future Check ... ) { // bool result = false; // XIchiInfo point = XICHIHLPGetInfo(bar_index); XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); // double dest = onFuture ? point.senkouSpanBFuture : point.senkouSpanB; // double destPrev = onFuture ? pointPrev.senkouSpanBFuture : pointPrev.senkouSpanB; // result = // point.tenkanSen > dest && pointPrev.tenkanSen <= destPrev // ; // return result; } // bool XICHIHLPIsTenkanSenCrossedUnderSenkouSpanB( int bar_index, // Bar Index ... bool onFuture = false // Future Check ... ) { // bool result = false; // XIchiInfo point = XICHIHLPGetInfo(bar_index); XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); // double dest = onFuture ? point.senkouSpanBFuture : point.senkouSpanB; // double destPrev = onFuture ? pointPrev.senkouSpanBFuture : pointPrev.senkouSpanB; // result = // point.tenkanSen < dest && pointPrev.tenkanSen >= destPrev // ; // return result; } // // KIJUNSEN and SENKOUSPAN ... // bool XICHIHLPIsKijunSenCrossedOverSenkouSpanA( int bar_index, // Bar Index ... bool onFuture = false // Future Check ... ) { // bool result = false; // XIchiInfo point = XICHIHLPGetInfo(bar_index); XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); // double dest = onFuture ? point.senkouSpanAFuture : point.senkouSpanA; // double destPrev = onFuture ? pointPrev.senkouSpanAFuture : pointPrev.senkouSpanA; // result = // point.kijunSen > dest && pointPrev.kijunSen <= destPrev // ; // return result; } // bool XICHIHLPIsKijunSenCrossedUnderSenkouSpanA( int bar_index, // Bar Index ... bool onFuture = false // Future Check ... ) { // bool result = false; // XIchiInfo point = XICHIHLPGetInfo(bar_index); XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); // double dest = onFuture ? point.senkouSpanAFuture : point.senkouSpanA; // double destPrev = onFuture ? pointPrev.senkouSpanAFuture : pointPrev.senkouSpanA; // result = // point.kijunSen < dest && pointPrev.kijunSen >= destPrev // ; // return result; } // bool XICHIHLPIsKijunSenCrossedOverSenkouSpanB( int bar_index, // Bar Index ... bool onFuture = false // Future Check ... ) { // bool result = false; // XIchiInfo point = XICHIHLPGetInfo(bar_index); XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); // double dest = onFuture ? point.senkouSpanBFuture : point.senkouSpanB; // double destPrev = onFuture ? pointPrev.senkouSpanBFuture : pointPrev.senkouSpanB; // result = // point.kijunSen > dest && pointPrev.kijunSen <= destPrev // ; // return result; } // bool XICHIHLPIsKijunSenCrossedUnderSenkouSpanB( int bar_index, // Bar Index ... bool onFuture = false // Future Check ... ) { // bool result = false; // XIchiInfo point = XICHIHLPGetInfo(bar_index); XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); // double dest = onFuture ? point.senkouSpanBFuture : point.senkouSpanB; // double destPrev = onFuture ? pointPrev.senkouSpanBFuture : pointPrev.senkouSpanB; // result = // point.kijunSen < dest && pointPrev.kijunSen >= destPrev // ; // return result; } // bool XICHIHLPIsValidArraySize(int bar_index) { // bool result = false; // if (bar_index < 0) { return result; } // int rCount = ArraySize(ichiTenkanSenBuffer); result = rCount > bar_index + 1; // return result; } // // SUPPORT and RESISTANCE ... // // Find Pivot Areas in Ichimooku ... void XICHIHLPFindPivotPoints() { // double smoothingPoint = 3; int verifications = 3; // // FLATS ... double tmpFlats[]; int tmpFlatsCount = 0; // // TenkanSen Flats ... FindSameValueInBuffer( tmpFlats, ichiTenkanSenBuffer); tmpFlatsCount = ArraySize(tmpFlats); if (tmpFlatsCount > 0) { // AddsIfNotExists( tmpFlats, ichiPivots, smoothingPoint); // Clean(tmpFlats); } // // KijunSen Flats ... FindSameValueInBuffer( tmpFlats, ichiKijunSenBuffer); tmpFlatsCount = ArraySize(tmpFlats); if (tmpFlatsCount > 0) { // AddsIfNotExists( tmpFlats, ichiPivots, smoothingPoint); // Clean(tmpFlats); } // // SenkouSpanA Flats ... FindSameValueInBuffer( tmpFlats, ichiSenkouSpanABuffer); tmpFlatsCount = ArraySize(tmpFlats); if (tmpFlatsCount > 0) { // AddsIfNotExists( tmpFlats, ichiPivots, smoothingPoint); // Clean(tmpFlats); } // // SenkouSpanB Flats ... FindSameValueInBuffer( tmpFlats, ichiSenkouSpanBBuffer); tmpFlatsCount = ArraySize(tmpFlats); if (tmpFlatsCount > 0) { // AddsIfNotExists( tmpFlats, ichiPivots, smoothingPoint); // Clean(tmpFlats); } } // // Extract Support and Resistances ... XOHCLSupRes XICHIHLPFindCandleSupprtAndResistance( int bar_index, // Bar Index ... int count = 3 // Number of Requireds ... ) { // XOHCLSupRes result = ExtractSupportAndResistance( bar_index, ichiPivots, count, _Symbol, _Period); // return result; } // // END Helper Functions ... //