/////////////////////////////////////////////////////// // // SaherElm IT Center MQL4 XTPW Signal Global Library // --------------------------------------------------- // XSaherElm EA Signal Provider based on // XTPow Indicator... // // // 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 Inputs ... // // input string xTPWStarter = "- XTPW Signal Provider -"; // ---> XTPW Signal Provider <--- // input bool enableXTPWSignalling = true; // XTPW Signalling Enable // input double xTPWR2R = 2.5; // XTPW Risk To Reward Ratio input int xTPWMaximumCandlesPerTrade = 206; // XTPW Maximum Candles which a Trade can open // input double xTPWPSarStep = 0.02; // XTPW Parabolic Sar Step input double xTPWPSarMaximum = 0.2; // XTPW Parabolic Sar Maximum // input int xTPWSwingLength = 7; // XTPW Signal Swing Length // // END Inputs ... // // // START Global Requirement Functions ... // // // XTPW Based Signal Conditions ... struct XTPWSignalConditions { datetime startTime; datetime signalTime; datetime entryTime; }; // struct XTPWMarketState { double psar; double fast; double slow; double verifier; }; // static XTPWSignalConditions xTPWLongConds; static bool xTPWCloseLongTrades = false; static bool xTPWWaitForLongSignals = true; // static XTPWSignalConditions xTPWShortConds; static bool xTPWCloseShortTrades = false; static bool xTPWWaitForShortSignals = true; // // END Global Requirement Functions ... // // // START Functions ... // // // Check and Fill Long and Short Signal Handlers ... void CheckXTPWSignalHandler( const int bar_index ) { // // Check Market For Enable/Disable Signal Handlers ... // Checking Market for Long Signals ... // if (!enableXTPWSignalling) { return; } // datetime barTime = iTime( _Symbol, _Period, bar_index ); // XOHCL candle = GetCandleModel(bar_index); XOHCL pCandle = GetCandleModel(bar_index + 1); } // // Check and Fill Long Signal Conditions ... void CheckXTPWLongSignalConditions( const int bar_index ) { // if ( !enableXTPWSignalling || !xTPWWaitForLongSignals ) { return; } // datetime barTime = iTime( _Symbol, _Period, bar_index ); // bool startCondition = false; bool signalCondition = false; // if ( startCondition && xTPWLongConds.startTime == 0 ) { // xTPWLongConds.startTime = barTime; return; } // if ( signalCondition && xTPWLongConds.startTime > 0 && xTPWLongConds.signalTime == 0 ) { // xTPWLongConds.signalTime = barTime; xTPWLongConds.entryTime = barTime; return; } } // // Check and Fill Short Signal Conditions ... void CheckXShortSignalConditions( const int bar_index ) { // if ( !enableXTPWSignalling || !xTPWWaitForShortSignals ) { return; } // datetime barTime = iTime( _Symbol, _Period, bar_index ); // bool startCondition = false; bool signalCondition = false; // if ( startCondition && xTPWShortConds.startTime == 0 ) { // xTPWShortConds.startTime = barTime; return; } // if ( signalCondition && xTPWShortConds.startTime > 0 && xTPWShortConds.signalTime == 0 ) { // xTPWShortConds.signalTime = barTime; xTPWShortConds.entryTime = barTime; return; } } // // Convert Long Signal Conditions to XSignal ... XSignalRequest GenerateXTPWSignal( const ENUM_X_SIGNAL_TYPE type, // Signal Type ... const string signalTag , // Signal Tag ... const int bar_index ) { // XSignalRequest result = {}; // result.hasSignal = false; result.type = X_SIGNAL_NONE; result.provider = X_UNKNOWN_PROVIDER; // if (!enableXTPWSignalling) { return result; } // bool requestLong = type == X_SIGNAL_LONG; // if (requestLong) { // if ( !ValidateXTPWLongConditions() ) { return result; } } else { // if ( !ValidateXTPWShortConditions() ) { return result; } } // // Price Calculations ... // RefreshRates(); // double askPrice = SymbolInfoDouble( _Symbol, SYMBOL_ASK ); // double bidPrice = SymbolInfoDouble( _Symbol, SYMBOL_BID ); // double entryPrice = requestLong ? askPrice : bidPrice; // double exitPrice = requestLong ? bidPrice : askPrice; // double priceGap = MathAbs(entryPrice - exitPrice); // double ll = // GetMarketLowestLow( bar_index, xTPWSwingLength ) ; // double hh = // GetMarketHighestHigh( bar_index, xTPWSwingLength ) ; // double openPrice = iOpen( _Symbol, _Period, bar_index ); // double closePrice = iClose( _Symbol, _Period, bar_index ); // double risk = requestLong ? MathMin(openPrice, closePrice) - ll : hh - MathMax(openPrice, closePrice); // double reward = risk * xTPWR2R; // double sl = requestLong ? 0 : 0; double tp = requestLong ? entryPrice + reward : entryPrice - reward ; // datetime barTime = iTime( _Symbol, _Period, bar_index ); // result.signal.tp = tp; result.signal.sl = sl; result.signal.type = type; result.signal.time = barTime; result.signal.tag = signalTag; result.signal.symbol = _Symbol; result.signal.entry = entryPrice; result.signal.id = totalSignals + 1; result.signal.provider = X_XXX_PROVIDER; // result.hasSignal = true; result.type = type; result.provider = X_XXX_PROVIDER; // return result; } // // Validate Signal Conditions ... bool ValidateXTPWLongConditions() { // if (!enableXTPWSignalling) { return false; } // bool isConditionsFilled = xTPWLongConds.startTime > 0 && xTPWLongConds.signalTime > 0 && xTPWLongConds.entryTime > 0 ; // bool isBLFilled = false; if (isConditionsFilled) { // int startBarIndex = iBarShift( _Symbol, _Period, xTPWLongConds.startTime ); // int signalBarIndex = iBarShift( _Symbol, _Period, xTPWLongConds.signalTime ); // int entryBarIndex = iBarShift( _Symbol, _Period, xTPWLongConds.entryTime ); // isBLFilled = // xTPWLongConds.signalTime > xTPWLongConds.startTime && xTPWLongConds.entryTime >= xTPWLongConds.signalTime ; } // bool result = isBLFilled && isConditionsFilled && xTPWWaitForLongSignals ; // // 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 ) { ClearXTPWLongSignalConditions(); } // return result; } // // Validate Signal Conditions ... bool ValidateXTPWShortConditions() { // if (!enableXTPWSignalling) { return false; } // bool isConditionsFilled = xTPWShortConds.startTime > 0 && xTPWShortConds.signalTime > 0 && xTPWShortConds.entryTime > 0 ; // bool isBLFilled = false; if (isConditionsFilled) { // int startBarIndex = iBarShift( _Symbol, _Period, xTPWShortConds.startTime ); // int signalBarIndex = iBarShift( _Symbol, _Period, xTPWShortConds.signalTime ); // int entryBarIndex = iBarShift( _Symbol, _Period, xTPWShortConds.entryTime ); // isBLFilled = // xTPWShortConds.signalTime > xTPWShortConds.startTime && xTPWShortConds.entryTime >= xTPWShortConds.signalTime ; } // bool result = isBLFilled && isConditionsFilled && xTPWWaitForShortSignals ; // // 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 ) { ClearXTPWShortSignalConditions(); } // return result; } // // Clear Long Signal Conditions for New One ... void ClearXTPWLongSignalConditions() { // xTPWLongConds.startTime = 0; xTPWLongConds.entryTime = 0; xTPWLongConds.signalTime = 0; } // // Clear Short Signal Conditions for New One ... void ClearXTPWShortSignalConditions() { // xTPWShortConds.startTime = 0; xTPWShortConds.entryTime = 0; xTPWShortConds.signalTime = 0; } // // Check State for Long Signals ... bool IsReadyForXTPWSignals( const XSignal &signal ) { // bool result = false; // if (!enableXTPWSignalling) { return result; } // int signalBarIndex = iBarShift( _Symbol, _Period, signal.time ); // // XOHCL candle = GetCandleModel(0); XOHCL candle = GetCandleModel(signalBarIndex); XOHCL pCandle = GetCandleModel(signalBarIndex + 1); // // Retrive XMarket States ... // double hh = GetMarketHighestHigh( signalBarIndex, xTPWSwingLength ); double ll = GetMarketLowestLow( signalBarIndex, xTPWSwingLength ); double diffChange = (hh - ll); bool isBigSharpOccured = diffChange > (600 * _Point) ; // bool isPSarVerified = false; bool isTPowVerified = false; bool isStateVerified = false; bool isPriceVerified = false; // // Verify Long Signals ... if (signal.type == X_SIGNAL_LONG) { // // Get Price Verification for Long ... isPriceVerified = // // Starter ... true ; // isTPowVerified = // // Starter ... true ; // isPSarVerified = // // Starter ... true ; // isStateVerified = // // Start ... true ; // result = // // Starter ... true // && isPSarVerified // && isTPowVerified // && isStateVerified // && isPriceVerified ; } else // // Verify Short Signals ... if (signal.type == X_SIGNAL_SHORT) { // isPSarVerified = // // Starter ... true ; // // Get Price Verification for Short ... isPriceVerified = // // Starter ... true ; // isTPowVerified = // // Starter ... true ; // isStateVerified = // // Start ... true ; // result = // // Starter Condition ... true // && isPSarVerified // && isTPowVerified // && isStateVerified // && isPriceVerified ; } // return result; } // // END Functions ... // // // START Data Provider ... // XTPWMarketState GetXMTPWarketState( const int bar_index ) { // XTPWMarketState result = {}; // double fast = GetMA( bar_index, xTPWSwingLength, 0, MODE_SMA, PRICE_CLOSE ); // double slow = GetMA( bar_index, xTPWSwingLength * 2, 0, MODE_SMA, PRICE_CLOSE ); // int dailyCount = GetDailyCandleCount(); double verifier = GetMA( bar_index, dailyCount, 0, MODE_EMA, PRICE_MEDIAN ); // double psar = iSAR( _Symbol, _Period, xTPWPSarStep, xTPWPSarMaximum, bar_index ); // result.psar = psar; result.fast = fast; result.slow = slow; result.verifier = verifier; // return result; } // // END Data Provider ... //