/////////////////////////////////////////////////////// // // SaherElm IT Center MQL4 XMA 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 ... // // // XMA Based Signal Conditions ... struct XMASCLongSignalConditions { // datetime scFastCrossUnderSlowTime; double crossUnderSCFast; double crossUnderSCSlow; // datetime scFastCrossOverSlowTime; double crossOverSCFast; double crossOverSCSlow; // datetime scFastBiggerThanCrossUnderSlowTime; }; // static XMASCLongSignalConditions xmaSCLongConds; // // END Global Requirement Functions ... // // // START Functions ... // // // Check and Fill CC Signal Conditions ... void CheckXMASCLongSignalConditions( const int bar_index, const int marketLen, // double stp, double mxm, // int scFMult, int scSMult, // int mcFMult, int mcSMult ) { // XCycleState scs[]; int positionsMarketLen = bar_index + marketLen; // // Retrieve Bar Time ... datetime barTime = iTime( _Symbol, _Period, bar_index ); // // Resize Arrays ... ArrayResize( scs, marketLen ); // int index = 0; for (int i = bar_index; i < positionsMarketLen; i++) { // XCycleState sc = GetXMASC( i, marketLen, scFMult, scSMult ); scs[index] = sc; // index++; } // bool isSCFastCrossUnderSlow = scs[0].fast < scs[0].slow && !(scs[1].fast <= scs[1].slow) ; bool isSCFastCrossOverSlow = scs[0].fast > scs[0].slow && !(scs[1].fast >= scs[1].slow) ; // if ( isSCFastCrossUnderSlow && xmaSCLongConds.scFastCrossUnderSlowTime == 0 ) { // xmaSCLongConds.crossUnderSCFast = scs[0].fast; xmaSCLongConds.crossUnderSCSlow = scs[0].slow; xmaSCLongConds.scFastCrossUnderSlowTime = barTime; return; } // if ( isSCFastCrossOverSlow && xmaSCLongConds.scFastCrossUnderSlowTime > 0 && xmaSCLongConds.scFastCrossOverSlowTime == 0 ) { // xmaSCLongConds.crossOverSCFast = scs[0].fast; xmaSCLongConds.crossOverSCSlow = scs[0].slow; xmaSCLongConds.scFastCrossOverSlowTime = barTime; return; } // if ( xmaSCLongConds.scFastCrossUnderSlowTime > 0 && xmaSCLongConds.scFastCrossOverSlowTime > 0 && scs[0].fast > xmaSCLongConds.crossUnderSCSlow && xmaSCLongConds.scFastBiggerThanCrossUnderSlowTime == 0 ) { // xmaSCLongConds.scFastBiggerThanCrossUnderSlowTime = barTime; return; } // if ( isSCFastCrossUnderSlow && xmaSCLongConds.scFastCrossUnderSlowTime > 0 && xmaSCLongConds.scFastCrossOverSlowTime > 0 ) { // ClearXMASCLongSignalConditions(); return; } } // // Convert XMA Long Signal Conditions to XSignal ... XSignalRequest GenerateXMASCLongSignal( const int bar_index, // Bar Index ... const int marketLen, // MarketLength for TP and SL ... const double r2r // Risk to Reward ratio ... // // const double shpDetectMultiplier ) { // XSignalRequest result = {}; // result.hasSignal = false; result.type = X_SIGNAL_NONE; result.provider = X_UNKNOWN_PROVIDER; // if (!ValidateXMASCLongConditions()) { 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 + 1 ); // double closePrice = iClose( _Symbol, _Period, bar_index + 1 ); // // // double sharpDetectValue = shpDetectMultiplier * _Point; // double lowPrice = iLow( // _Symbol, // _Period, // bar_index + 1 // ); // double risk = MathMin(openPrice, closePrice) - ll; double reward = risk * r2r; // double sl = 0; 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_XMA_PROVIDER; result.signal.time = barTime; // result.hasSignal = true; result.type = X_SIGNAL_LONG; result.provider = X_XMA_PROVIDER; // return result; } // // Validate XMA Signal Conditions ... bool ValidateXMASCLongConditions() { // bool isConditionsFilled = xmaSCLongConds.crossOverSCSlow > 0 && xmaSCLongConds.crossOverSCFast > 0 && xmaSCLongConds.crossUnderSCFast > 0 && xmaSCLongConds.crossUnderSCSlow > 0 && xmaSCLongConds.scFastCrossOverSlowTime != 0 && xmaSCLongConds.scFastCrossUnderSlowTime != 0 && xmaSCLongConds.scFastBiggerThanCrossUnderSlowTime !=0 ; // bool isBLFilled = false; if (isConditionsFilled) { // isBLFilled = xmaSCLongConds.crossOverSCFast > xmaSCLongConds.crossUnderSCSlow && xmaSCLongConds.scFastCrossUnderSlowTime < xmaSCLongConds.scFastCrossOverSlowTime ; } // 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 ) { ClearXMASCLongSignalConditions(); } // return result; } // // Clear Long Signal Conditions for New One ... void ClearXMASCLongSignalConditions() { // xmaSCLongConds.crossUnderSCFast = 0; xmaSCLongConds.crossUnderSCSlow = 0; xmaSCLongConds.scFastCrossUnderSlowTime = 0; // xmaSCLongConds.crossOverSCFast = 0; xmaSCLongConds.crossOverSCSlow = 0; xmaSCLongConds.scFastCrossOverSlowTime = 0; // xmaSCLongConds.scFastBiggerThanCrossUnderSlowTime = 0; } // // Check XMA State for Long Signals ... bool IsReadyForXMASCLongSignals( const XSignal &signal, const XState &states[], const int marketLen ) { // bool result = false; // result = // true // && states[0].sc.fast > states[0].sc.slow && states[1].sc.fast > states[1].sc.slow ; // return result; } // // END Functions ... //