/////////////////////////////////////////////////////// // // SaherElm IT Center MQL4 SHP Signal Global Library // --------------------------------------------------- // saherelm useful tools and definitions ... // // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// #property library #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://www.saherelm.ir" #property version "1.00" #property strict // // Includes library ... #include "../Libraries/x-saherelm.lib.mq4" // // Includes Indicator library ... #include "../Libraries/x-saherelm.indicator.lib.mq4" // // Includes Models library ... #include "../Libraries/x-saherelm.models.lib.mq4" // // START Global Requirement Functions ... // // // SHP Based Signal Conditions ... struct XSHPLongSignalConditions { // datetime start; datetime stop; }; // static XSHPLongSignalConditions shpLongConds; // // END Global Requirement Functions ... // // // START Functions ... // // // Check and Fill CC Signal Conditions ... void CheckSHPLongSignalConditions( const int bar_index, const int marketLen, const double shpDetectMult, const double smoother = 30 ) { // datetime barTime = iTime( _Symbol, _Period, bar_index ); // double high = iHigh( _Symbol, _Period, bar_index ); // double low = iLow( _Symbol, _Period, bar_index + 1 ); // double mHH = GetMarketHighestHigh( bar_index, marketLen ); // double mLL = GetMarketLowestLow( bar_index, marketLen ); double m2LL = GetMarketLowestLow( bar_index, marketLen * 2 ); // int mHLIdx = iHighest( _Symbol, _Period, MODE_LOW, marketLen, bar_index ); datetime mHLTime = iTime( _Symbol, _Period, mHLIdx ); double mHL = iHigh( _Symbol, _Period, mHLIdx ); // double hlDiff = (mHL - mLL); double sharpDetectValue = shpDetectMult * _Point; // bool isSharpDetected = // ( // low == mLL // || MathAbs(mLL - low) < (smoother * _Point) // ) // && // !( // mLL > m2LL // && MathAbs(m2LL - mLL) > sharpDetectValue / 2 // ) // && ( hlDiff > sharpDetectValue || hlDiff > sharpDetectValue - (smoother * _Point) ) ; // if (isSharpDetected) { // shpLongConds.start = mHLTime; shpLongConds.stop = barTime; } } // // Convert Long Signal Conditions to XSignal ... XSignalRequest GenerateSHPLongSignal( const int bar_index, // Bar Index ... const int marketLen, // MarketLength for TP and SL ... const double r2r, // Risk to Reward ratio ... const double shpDetectMultiplier // Sharp Detect Multiplier ... ) { // XSignalRequest result = {}; // result.hasSignal = false; result.type = X_SIGNAL_NONE; result.provider = X_UNKNOWN_PROVIDER; // if (!ValidateSHPLongConditions(shpDetectMultiplier)) { return result; } // // Price Calculations ... // RefreshRates(); // double entryPrice = SymbolInfoDouble( _Symbol, SYMBOL_ASK ); // double exitPrice = SymbolInfoDouble( _Symbol, SYMBOL_BID ); // double priceGap = MathAbs(entryPrice - exitPrice); // double ll = GetMarketLowestLow( bar_index, marketLen ); // double openPrice = iOpen( _Symbol, _Period, bar_index ); // double closePrice = iClose( _Symbol, _Period, bar_index ); // double risk = MathMin(openPrice, closePrice) - ll; double reward = 300 * _Point; // risk * r2r; // double sl = 0; // ll; // // this means Market Lowest Low ... double shpValue = shpDetectMultiplier * _Point; if ( reward == 0 || reward < 20 * _Point ) { reward = shpValue; } double tp = entryPrice + reward; // datetime barTime = iTime( _Symbol, _Period, bar_index ); // result.signal.tp = tp; result.signal.sl = sl; result.signal.symbol = _Symbol; result.signal.type = X_SIGNAL_LONG; result.signal.id = totalSignals + 1; result.signal.entry = entryPrice; result.signal.provider = X_SHP_PROVIDER; result.signal.time = barTime; // result.hasSignal = true; result.type = X_SIGNAL_LONG; result.provider = X_SHP_PROVIDER; // return result; } // // Validate Signal Conditions ... bool ValidateSHPLongConditions( const double shpDetectMultiplier ) { // double shpDetectValue = shpDetectMultiplier * _Point; // bool isConditionsFilled = shpLongConds.stop != 0 && shpLongConds.start != 0 && shpLongConds.stop > shpLongConds.start ; // bool isBLFilled = true; // bool result = isBLFilled && isConditionsFilled ; // // Since maybe Conditions Filled but // Slope is Negative, for Handling Next Signals and // Prevent from infinity loop, here we Clear Signal Conditions ... if ( !result && isConditionsFilled ) { ClearSHPLongSignalConditions(); } // return result; } // // Clear Long Signal Conditions for New One ... void ClearSHPLongSignalConditions() { // shpLongConds.stop = 0; shpLongConds.start = 0; } // // Check State for Long Signals ... bool IsReadyForSHPLongSignals( const XSignal &signal, const XState &states[] ) { // bool result = false; // XStateInfo info = ParseXMAStates(states); // int xmaMarketLen = ArraySize(states); double mHH = GetMarketHighestHigh(0, xmaMarketLen); double m2HH = GetMarketHighestHigh(0, (int) (xmaMarketLen * 1.5)); // int lcUpDownTouches = 0; int cciHundredTouches = 0; for (int i = 0; i < xmaMarketLen; i++) { // double high = iHigh( _Symbol, _Period, i ); // double low = iLow( _Symbol, _Period, i ); // double up = MathMax(states[i].lc.fast, states[i].lc.slow); double down = MathMax(states[i].lc.fast, states[i].lc.slow); // if (high >= up && low <= down) { lcUpDownTouches++; } // if ( i < xmaMarketLen - 1 && i < 10 ) { if ( states[i].cci < 100 && states[i + 1].cci > 100 ) { cciHundredTouches++; } } } // result = // true // && states[0].mc.fast > states[0].mc.slow && states[0].lc.fast > states[0].lc.slow // && states[0].sc.fast < states[0].sc.slow && states[1].sc.fast < states[1].sc.slow // && states[0].marketMiddleage < states[0].sc.fast && states[1].marketMiddleage < states[1].sc.fast && !( states[1].sc.fast < states[1].mc.fast && states[1].sc.slow < states[1].mc.fast && states[1].sc.fast > states[1].mc.slow && states[1].sc.slow > states[1].mc.slow ) && !( states[0].marketMiddleage < states[0].mc.fast && states[0].marketMiddleage > states[0].mc.slow ) // && mHH != m2HH && lcUpDownTouches == 0 && cciHundredTouches == 0 ; // return result; } // // END Functions ... //