/////////////////////////////////////////////////////// // // SaherElm IT Center MQL4 RMA 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 ... // // // RMA Based Signal Conditions ... struct XRMALongSignalConditions { // datetime crossUnderTime; // datetime crossOverTime; }; // static XRMALongSignalConditions xrmaLongConds; // // END Global Requirement Functions ... // // // START Functions ... // // // Check and Fill CC Signal Conditions ... void CheckXRMALongSignalConditions( const int bar_index, const int marketLen, // const double smoother = 5 ) { // datetime barTime = iTime( _Symbol, _Period, bar_index ); // XCycleState states[]; ArrayResize( states, marketLen ); // int index = 0; for (int i = bar_index; i < marketLen; i++) { // XCycleState state = GetXMANN(i); // states[index] = state; // index++; } // bool isCrossUnder = states[1].fast < states[1].slow && !(states[2].fast < states[2].slow) ; // bool isCrossOver = states[1].fast > states[1].slow && !(states[2].fast > states[2].slow) ; // if ( isCrossUnder && xrmaLongConds.crossUnderTime == 0 ) { // xrmaLongConds.crossUnderTime = barTime; return; } // if ( isCrossOver && xrmaLongConds.crossUnderTime > 0 && xrmaLongConds.crossOverTime == 0 ) { // xrmaLongConds.crossOverTime = barTime; return; } } // // Convert XMA Long Signal Conditions to XSignal ... XSignalRequest GenerateXRMALongSignal( const int bar_index, // Bar Index ... const int marketLen, // MarketLength for TP and SL ... const double r2r // Risk to Reward ratio ... ) { // XSignalRequest result = {}; // result.hasSignal = false; result.type = X_SIGNAL_NONE; result.provider = X_UNKNOWN_PROVIDER; // if (!ValidateXRMALongConditions(marketLen)) { 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 = risk * r2r; // 300 * _Point; // double sl = 0; // entryPrice - (300 * _Point); // ll; 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_RMA_PROVIDER; result.signal.time = barTime; // result.hasSignal = true; result.type = X_SIGNAL_LONG; result.provider = X_RMA_PROVIDER; // return result; } // // Validate XMA Signal Conditions ... bool ValidateXRMALongConditions( const int marketLen ) { // bool isConditionsFilled = true && xrmaLongConds.crossOverTime > 0 && xrmaLongConds.crossUnderTime > 0 ; // bool isBLFilled = false; if (isConditionsFilled) { // int crossOverBarIndex = iBarShift( _Symbol, _Period, xrmaLongConds.crossOverTime ); // int crossUnderBarIndex = iBarShift( _Symbol, _Period, xrmaLongConds.crossUnderTime ); // XCycleState stateOnCrossUnder = GetXMANN( crossUnderBarIndex ); // XCycleState stateOnCrossOver = GetXMANN( crossOverBarIndex ); // double maC = iMA( _Symbol, _Period, 14, 0, MODE_SMA, PRICE_CLOSE, crossOverBarIndex ); // // // double rmaOnCrossOver = GetRMA( // crossOverBarIndex, // 10 // ); // // // double rmaOnMarketLength = GetRMA( // crossOverBarIndex + marketLen, // 10 // ); // // // double prevCandleHigh = iHigh( // _Symbol, // _Period, // crossOverBarIndex // ); // // // PrepareZigZagState(crossOverBarIndex); // double zigZagDelta = zigZags[1] - zigZags[2]; // bool isZigZagWaitForHigh = zigZagDelta < 0; // isBLFilled = true // && (crossUnderBarIndex - crossOverBarIndex) > 5 // && xrmaLongConds.crossOverTime > xrmaLongConds.crossUnderTime // && stateOnCrossOver.slow < stateOnCrossUnder.slow // && MathAbs(stateOnCrossOver.fast - stateOnCrossOver.slow) > (70 * _Point) // && maC >= stateOnCrossOver.slow // // // && !(rmaOnCrossOver < stateOnCrossOver.slow) // // // && MathAbs(rmaOnCrossOver - rmaOnMarketLength) < (600 * _Point) // // // && !isZigZagWaitForHigh ; } // 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 ) { ClearXRMALongSignalConditions(); } // return result; } // // Clear Long Signal Conditions for New One ... void ClearXRMALongSignalConditions() { // xrmaLongConds.crossOverTime = 0; xrmaLongConds.crossUnderTime = 0; } // // Check XMA State for Long Signals ... bool IsReadyForXRMALongSignals( const XSignal &signal, const XState &states[], const int marketLen ) { // bool result = false; // result = // true ; // return result; } // // END Functions ... //