/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Seriallize Library // --------------------------------------- // Name: XSupportSignal // Description: provides Seriallizing EA abilities ... // // // 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 // #include "../Libraries/x-saherelm.models.lib.mq5" #include "../Libraries/x-saherelm.common.lib.mq5" #include "../Classes/x-saherelm.xtrade.class.mq5" #include "../Libraries/x-saherelm.seriallizer.lib.mq5" #include "../Classes/x-saherelm.x121.provider.class.mq5" // // TODO: add this to Configurations ... double supportVolumeMultiplier = 2; int oldAgeSupportForReNewFactor = 35; int oldAgePositionForSupportFactor = 17; // // Required Variables ... double minProfitPerTrade = 0.15; double minProfitPerVolumeFactor = 0.01; // double supportsSginalTpPoint = 30; // // NOTE: // Define some tokens to Specify types of Supports ... string XEQMSupportToken = "XEQM"; // // Define Two Main Support Types of EQM ... enum ENUM_X121EQM_SUPPORT_TYPES { // XEQM_UNBOUND = 0, // Without TP ... XEQM_INBOUND = 1, // With TP ... }; // // Generate Signal Period Comment Part ... string GeneratePeriodComment( ENUM_TIMEFRAMES period = NULL // Time Frame ... ) { // string result = ""; // if (period == NULL) { return result; } // result = XPeriodToken + "(" + ToString(period) + ")"; // return result; } // // Generate String Tag for EQM Support Signals ... string GenerateXEQMSupportComment( ENUM_TIMEFRAMES period = NULL // Time Frame ... ) { // string result = XEQMSupportToken; // return result; } // // Check a Comment belongs to a EQM Support or not ... bool IsEQMSupport(string comment) { // bool result = false; // if (StringLen(comment) <= 0) { return result; } // int tokenPosition = StringFind( comment, XEQMSupportToken); result = tokenPosition >= 0; // return result; } // // Select EQM Support Orders ... int GetEQMSupportOrders( XOrder &supports[], // Hold Result ... XOrder &orders[], // List of All Orders ... ENUM_TIMEFRAMES period = NULL // Specified Period ... ) { // int result = 0; // Clean(supports); // int ordersCount = ArraySize(orders); if (ordersCount <= 0) { return result; } // // Loop through Orders ... for (int i = 0; i < ordersCount; i++) { // XOrder iOrder = orders[i]; // // Check Order is Support or not ... bool isSupport = IsEQMSupport(iOrder.comment); if (!isSupport) { continue; } // // Check Order is not Triggered ... if (iOrder.state != ORDER_STATE_PLACED) { continue; } // // Check Period ... if (period != NULL && iOrder.period != period) { continue; } // // we now sure this order is EQM Support ... Add( iOrder, supports); } // // Count Result ... result = ArraySize(supports); // return result; } // // Select EQM Support Orders by Type ... int GetEQMSupportsByType( XOrder &supports[], // Hold Result ... XOrder &orders[], // List of All Orders ... ENUM_TIMEFRAMES period = NULL, // Specified Period ... ENUM_X121EQM_SUPPORT_TYPES type = NULL // EQM Support Type ... ) { // int result = 0; // XOrder mOrders[]; result = GetEQMSupportOrders(mOrders, orders, period); if (result <= 0) { return result; } // if (type == NULL) { // Copy( mOrders, supports); } else { // for (int i = 0; i < result; i++) { // XOrder iOrder = mOrders[i]; // if (iOrder.tp > 0 && type == XEQM_INBOUND) { // Add( iOrder, supports); } else if (iOrder.tp == 0 && type == XEQM_UNBOUND) { // Add( iOrder, supports); } } } // result = ArraySize(supports); // return result; } // // NOTE: // here we add all Supporting Signals preparations ... // 1- must have at least TWO Support Signal without tp ... // 2- there are some signals by providing tp ... // 3- Trend base and Conditional Supports by tp ... // // UNBOUND Support => Support Signals with TP ... // INBOUND Support => Support Signals without TP ... // // in each time when there are an open positions in DrawDown and it's passed // a certain candles ... // we Have to Placed atleast 2 UNBOUND Support Signals ... // // LIFETIME of Supports ... // Each Support Signal must be Cancel if their doesn't triggered // for an specific Number of Candels ... // // SUPPORT GENERATORs ... // // Generate Supports Signal For Market ... int GenerateMarketSupports( XSignal &supports[], // Hold Result string symbol, // Trading Symbol ENUM_TIMEFRAMES period, // Trading Timeframe XSCX121Provider *analyzer, // Market Analizer double volume = 0.01 // Provided Volume ) { // int result = 0; // // TODO: Variable ... int numberOfItems = 10; // Clean(supports); // // Calculate Lng Exit Price ... double longExit = GetExit(symbol, POSITION_TYPE_BUY); // // Generate Support and Resistances ... XOHCLSupRes longSupRes = analyzer.GenerateSupportAndResistance( longExit, numberOfItems); // // Calculate Short Exit Price ... double shortExit = GetExit(symbol, POSITION_TYPE_SELL); // // Generate Support and Resistances ... XOHCLSupRes shortSupRes = analyzer.GenerateSupportAndResistance( shortExit, numberOfItems); // X121MarketConditions mConditions = analyzer.GetMarketConditions(1); // double tp = 0; double sl = 0; double max = 0; double med = 0; double min = 0; double entry = 0; double tpPointPrice = PointToPrice( symbol, supportsSginalTpPoint); // XSignal mSignal; Clean(mSignal); // // 1- Breakout PEAK to UP ... // 2- Breakout PEAK to Down ... // 3- Breakeout VALE Down ... // mSignal.ignoreTP = false; mSignal.ignoreSL = false; mSignal.calculateTP = false; mSignal.useRiskAmountAsVolume = true; // mSignal.symbol = symbol; mSignal.period = period; mSignal.riskAmount = volume; // // 1 // mSignal.mode = X_ORDER_MODE_LIMIT; mSignal.type = POSITION_TYPE_SELL; // entry = mConditions.xpvInfo.peak; tp = entry - tpPointPrice; // mSignal.tp = tp; mSignal.entry = entry; // Add( mSignal, supports); // Clean(mSignal); // mSignal.ignoreTP = false; mSignal.ignoreSL = false; mSignal.calculateTP = false; mSignal.useRiskAmountAsVolume = true; // mSignal.symbol = symbol; mSignal.period = period; mSignal.riskAmount = volume; // // 2 // mSignal.mode = X_ORDER_MODE_STOP; mSignal.type = POSITION_TYPE_BUY; // entry = mConditions.xpvInfo.peak; tp = entry + tpPointPrice; // mSignal.tp = tp; mSignal.entry = entry; // Add( mSignal, supports); // Clean(mSignal); // mSignal.ignoreTP = false; mSignal.ignoreSL = false; mSignal.calculateTP = false; mSignal.useRiskAmountAsVolume = true; // mSignal.symbol = symbol; mSignal.period = period; mSignal.riskAmount = volume; // // 3 // mSignal.mode = X_ORDER_MODE_STOP; mSignal.type = POSITION_TYPE_SELL; // entry = mConditions.xpvInfo.vale; tp = entry + tpPointPrice; // mSignal.tp = tp; mSignal.entry = entry; // Add( mSignal, supports); // Clean(mSignal); // result = ArraySize(supports); // return result; } // // Generate Support Signal for Specific Signal ... bool GenerateSignalSupports( XSignal &signal, // Source Signal XSCX121Provider *analyzer // Market Analizer ) { // bool result = false; // Clean(signal.supports); // string providerStr = signal.providers[0]; if (StringLen(providerStr) == 0) { return result; } // ENUM_X121_SIGNAL_PROVIDERS provider = ToProvider(providerStr); bool isAllowed = analyzer.IsAllowdSignaller(provider); if (!isAllowed) { return result; } // bool isLong = IsLong( signal.type); bool isLongSupport = !isLong; // ENUM_POSITION_TYPE type = isLong ? POSITION_TYPE_SELL : POSITION_TYPE_BUY; // double tp = 0; double sl = 0; double volume = signal.volume * 2; double entry = GetEntry( type); // double tpPriceDistance = MathAbs(signal.entry - signal.tp); double tpPoint = PriceToPoint( signal.symbol, tpPriceDistance); // double ll3 = GetLowestLow( signal.symbol, signal.period, 3, 0); // double hh3 = GetHighestHigh( signal.symbol, signal.period, 3, 0); // // XPV ... double fl1 = analyzer.mXPVHelper.fl1Buffer[0]; double fl2 = analyzer.mXPVHelper.fl2Buffer[0]; double fl3 = analyzer.mXPVHelper.fl3Buffer[0]; double peak = analyzer.mXPVHelper.peaksBuffer[0]; double vales = analyzer.mXPVHelper.valesBuffer[0]; // double distancePrice = isLong ? MathAbs(signal.entry - ll3) : MathAbs(signal.entry - hh3); double distancePoint = PriceToPoint( signal.symbol, distancePrice); double supportTpPrice = PointToPrice( signal.symbol, distancePoint + tpPoint); entry = isLongSupport ? hh3 : ll3; tp = isLongSupport ? entry + supportTpPrice : entry - supportTpPrice; // XSignal tmpSignal; Clean(tmpSignal); // tmpSignal.r2r = 0; tmpSignal.volume = volume; tmpSignal.ignoreTP = false; tmpSignal.ignoreSL = false; tmpSignal.riskAmount = volume; tmpSignal.calculateTP = false; tmpSignal.symbol = signal.symbol; tmpSignal.period = signal.period; tmpSignal.useRiskAmountAsVolume = true; tmpSignal.useSupportAndResistance = false; // tmpSignal.type = type; // Add( providerStr, tmpSignal.providers); // switch (provider) { // // X92 ... case X92: // tmpSignal.tp = tp; tmpSignal.sl = sl; tmpSignal.entry = entry; tmpSignal.mode = X_ORDER_MODE_STOP; // Add( tmpSignal, signal.supports); // break; } // result = ArraySize(signal.supports) > 0; // return result; }