diff --git a/Experts/x-sample.ea.mq5 b/Experts/x-sample.ea.mq5 new file mode 100644 index 00000000..5090242d --- /dev/null +++ b/Experts/x-sample.ea.mq5 @@ -0,0 +1,2453 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center XSAMPLE MQL5 Expert Advisor +// ------------------------------------------------- +// Name: XSAMPLE +// Description: an Exper Advisor which used RSI and MA +// to Analyse Market ... +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +//////////////////////////////////////////////////////x +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XSAMPLE" +#property strict + +// +#define ShortName "XSAMPLE" + +// +#include "../Libraries/x-saherelm.draw.lib.mq5" +#include "../Helpers/x-saherelm.xcc.helper.mq5" +#include "../Helpers/x-saherelm.xct.helper.mq5" +#include "../Classes/x-saherelm.xtrade.class.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xalert.class.mq5" +#include "../Classes/x-saherelm.x121.xmcycle.class.mq5" +#include "../Classes/x-saherelm.x121.xmcycle.class.mq5" + +// +// Inputs ... + +// +input group "Market"; + +// +input group "Short"; +input ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // Method +input ENUM_TIMEFRAMES scPeriod = NULL; // Period + +// +input group "Medium"; +input ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // Method +input ENUM_TIMEFRAMES mcPeriod = NULL; // Period + +// +input group "Long"; +input ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // Method +input ENUM_TIMEFRAMES lcPeriod = NULL; // Period + +// +input group "Hind"; +input ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // Method +input ENUM_TIMEFRAMES hcPeriod = NULL; // Period + +// +long xSampleEAMagicNumber = 78692110; // Magic Number +int xSampleEASlippage = 10; // Slippgae + +// +double xSampleEAVolume = 0.01; + +// +// Vars ... +string xSampleEASymbol; +ENUM_TIMEFRAMES xSampleEAPeriod; + +// +int maxBuys = 1; +int maxSells = 1; +int buyCount = 0; +int sellCount = 0; + +// +double _tp = 0; +double _sl = 0; +double _entry = 0; +ENUM_POSITION_TYPE _type = NULL; + +// +MqlTick xSampleEATick; + +// +XBarTracker xSamplEABarTracker; + +// +// Cycles ... + +// +double bullishBuffer[]; +double bearishBuffer[]; +double nBullishBuffer[]; +double nBearishBuffer[]; +double longVFBuffer[]; +double shortVFBuffer[]; + +// +double lastVale = 0; +double lastPeak = 0; +double lastSupport = 0; +double lastResistance = 0; + +// +double xBullishScore = 0; +double xBearishScore = 0; + +// +double normalizeBullishScore = 0; +double normalizeBearishScore = 0; + +// +double xLongVerifications = 0; +double xShortVerifications = 0; +bool isScoreBalanced = false; + +// +double lastBullishPivot = 0; +double lastBearishPivot = 0; + +// +int normalizationLength = 15; + +// +datetime lastTradeOn = NULL; + +// +// Indicators ... +XCCInputs ccInputs; +XCTInputs ctInputs; + +// +XZGInputs zgInputs; +XPVInputs pvInputs; +XHKInputs hkInputs; +XMCInputs mcInputs; +XTDInputs tdInputs; +XMRBInputs mrbInputs; +XICHInputs ichInputs; +XCHEInputs cheInputs; +XSTRInputs strInputs; +XDONInputs donInputs; +XOSCInputs oscInputs; + +// +X121MCycleInputs cMarketInputs; // Curent Market Inputs +X121MCycleInputs sMarketInputs; // Short Market Inputs +X121MCycleInputs mMarketInputs; // Medium Market Inputs +X121MCycleInputs lMarketInputs; // Long Market Inputs +X121MCycleInputs hMarketInputs; // Hind Market Inputs + +// +XSCX121Market *cMarket; +XSCX121Market *sMarket; +XSCX121Market *mMarket; +XSCX121Market *lMarket; +XSCX121Market *hMarket; + +// +X121MCycleConditions cConditions; +X121MCycleConditions sConditions; +X121MCycleConditions mConditions; +X121MCycleConditions lConditions; +X121MCycleConditions hConditions; + +// +XSCTrade *mTrader; +XSCAlert *mAlert; + +// +XPivotTracker mPivotTracker; +XSignal mSignals[]; + +// +// Event Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + if (xSampleEASymbol == NULL || StringLen(xSampleEASymbol) <= 0) + { + xSampleEASymbol = _Symbol; + } + + // + if (xSampleEAPeriod == NULL) + { + xSampleEAPeriod = _Period; + } + + // + // Validate Inputs ... + if (!XSampleEAValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + if (!InitialTrader()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Initial Cycles ... + if (!InitCycles()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + drawPrefix = ShortName; + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // De Initialize XSampleEA Providers ... + + // + delete mAlert; + delete mTrader; + + // + delete cMarket; + delete sMarket; + delete mMarket; + delete lMarket; + delete hMarket; +} + +// +// On Tick Handler ... +void OnTick() +{ + // + if (!xSamplEABarTracker.IsNewBar()) + { + return; + } + + // + // Reading Tick ... + if (!GetTick( + xSampleEASymbol, + xSampleEATick // + )) + { + return; + } + + // + Analyze(); + + // + Manage(); +} + +// +// Custom Functions ... + +// +// Validate Variables nd Inputs ... +bool XSampleEAValidateInputs() +{ + // + bool result = false; + + // + result = + // + xSampleEASlippage > 0 && + xSampleEAMagicNumber > 0 && + IsValid(scMethod, scPeriod) && + IsValid(mcMethod, mcPeriod) && + IsValid(lcMethod, lcPeriod) && + IsValid(hcMethod, hcPeriod) + // + ; + + // + return result; +} + +// +// Tools ... + +// +// Do Market Analyziation ... +void Analyze() +{ + // + GenerateMarketConditions(); + + // + xBullishScore = 0; + xBearishScore = 0; + CalculateScores( + xBullishScore, + xBearishScore // + ); + + // + normalizeBullishScore = 0; + normalizeBearishScore = 0; + CalculateNormalizedScores( + normalizeBullishScore, + normalizeBearishScore // + ); + + // + xLongVerifications = 0; + xShortVerifications = 0; + CalculateVerifications( + xLongVerifications, + xShortVerifications // + ); + + // + // Check Conditions on Pivots ... + HandleSignalDetection(); + + // + // Execute Signals ... + HandleSignalExecution(); + + // + // SUMMARY ... + + // + string strSuumarry = + "[XTEA]" + "\n" + + "---------------------" + "\n" + + ToString(cMarketInputs.cycle.cycle) + ": " + ToString(cMarket.GetPeriod()) + "\n" + + ToString(sMarketInputs.cycle.cycle) + ": " + ToString(sMarket.GetPeriod()) + "\n" + + ToString(mMarketInputs.cycle.cycle) + ": " + ToString(mMarket.GetPeriod()) + "\n" + + ToString(lMarketInputs.cycle.cycle) + ": " + ToString(lMarket.GetPeriod()) + "\n" + + ToString(hMarketInputs.cycle.cycle) + ": " + ToString(hMarket.GetPeriod()) + "\n" + + "---------------------" + "\n" + + "Scores:" + "\n" + + "---------------------" + "\n" + + "Bullish: " + ToString(xBullishScore) + ", " + ToString(normalizeBullishScore) + ", " + ToString(xLongVerifications) + "\n" + + "Bearish: " + ToString(xBearishScore) + ", " + ToString(normalizeBearishScore) + ", " + ToString(xShortVerifications) + "\n" + + ""; + + // + Comment(strSuumarry); + + // +} + +// +void Manage() +{ +} + +// +// Inbitial Classes ... +bool InitialTrader() +{ + // + bool result = true; + + // + mAlert = new XSCAlert(); + mAlert.SetLogAlerts(true); + mAlert.SetPrefix(ShortName); + mAlert.SetEnableAlerts(true); + mAlert.SetPushAlerts(false); + mAlert.SetMailAlerts(false); + mAlert.SetTerminalAlerts(false); + + // + mTrader = new XSCTrade( + xSampleEASlippage, + xSampleEAMagicNumber, + 0, + 0, + 0, + 0 // + ); + + // + return result; +} + +// +// Initial Market Conditions ... +bool InitCycles() +{ + // + bool result = false; + + // + // Define an Input Object and Configure it ... + // then use same Input for Separate Markets ... + + // + string symbol = _Symbol; + ENUM_TIMEFRAMES period = _Period; + + // + // Set Inputs to Default ... + ccInputs.Default(); + ctInputs.Default(); + zgInputs.Default(); + pvInputs.Default(); + hkInputs.Default(); + mcInputs.Default(); + tdInputs.Default(); + mrbInputs.Default(); + ichInputs.Default(); + cheInputs.Default(); + strInputs.Default(); + donInputs.Default(); + oscInputs.Default(); + + // + cMarketInputs.Default(); + sMarketInputs.Default(); + mMarketInputs.Default(); + lMarketInputs.Default(); + hMarketInputs.Default(); + + // + // XHK ... + hkInputs.drawHikenAshi = false; + hkInputs.drawSmoothedHikenAshi = false; + + // + // XMRB ... + mrbInputs.showFastMa = false; + mrbInputs.showSlowMa = false; + mrbInputs.showRibbon = false; + + // + // XMC ... + mcInputs.showFastMa = false; + mcInputs.showSlowMa = false; + mcInputs.showVerifierMa = false; + + // + // XICH ... + ichInputs.showKumo = false; + ichInputs.showKijunSen = false; + ichInputs.showTenkanSen = false; + ichInputs.showChikouSpan = false; + ichInputs.showSenkouSpanA = false; + ichInputs.showSenkouSpanB = false; + ichInputs.showKijunSenPlus = false; + ichInputs.showKijunSenNegative = false; + + // + // XCHE ... + cheInputs.showLongExit1Line = false; + cheInputs.showShortExit1Line = false; + cheInputs.showLongExit2Line = false; + cheInputs.showShortExit2Line = false; + + // + // XPV ... + pvInputs.showPeaksAndVales = false; + pvInputs.showLevels = false; + pvInputs.showConsolidations = false; + pvInputs.showFibo1Levels = false; + pvInputs.showFibo2Levels = false; + pvInputs.showFibo3Levels = false; + pvInputs.showFibo4Levels = false; + pvInputs.showFibo5Levels = false; + + // + // XZG ... + zgInputs.showZigZag = false; + zgInputs.showPeaksAndVales = false; + + // + // XDON ... + donInputs.showOpen = false; + donInputs.showHigh = false; + donInputs.showClose = false; + donInputs.showLow = false; + + // + // XSTR ... + strInputs.showTrends = false; + strInputs.fillTrends = false; + + // + // Current Cycle ... + + // + ConfigureCurrentCycles(); + + // + cMarketInputs.cycle.symbol = symbol; + cMarketInputs.cycle.period = period; + + // + cMarketInputs.pvInputs = pvInputs; + cMarketInputs.zgInputs = zgInputs; + cMarketInputs.tdInputs = tdInputs; + cMarketInputs.mcInputs = mcInputs; + cMarketInputs.hkInputs = hkInputs; + cMarketInputs.mrbInputs = mrbInputs; + cMarketInputs.strInputs = strInputs; + cMarketInputs.oscInputs = oscInputs; + cMarketInputs.cheInputs = cheInputs; + cMarketInputs.ichInputs = ichInputs; + cMarketInputs.donInputs = donInputs; + + // + result = cMarketInputs.Init( + symbol, + period, + X_MARKET_CYCLE_SHORT, + period, + X_PERIOD_MANUALLY, + "HOST", + false // + ); + if (!result) + { + return result; + } + + // + cMarket = new XSCX121Market(); + result = cMarket.Init(cMarketInputs); + if (!result) + { + return result; + } + + // + // Short Cycle ... + + // + ConfigureShortCycles(); + + // + sMarketInputs.cycle.symbol = symbol; + sMarketInputs.cycle.period = period; + + // + sMarketInputs.pvInputs = pvInputs; + sMarketInputs.zgInputs = zgInputs; + sMarketInputs.tdInputs = tdInputs; + sMarketInputs.mcInputs = mcInputs; + sMarketInputs.hkInputs = hkInputs; + sMarketInputs.mrbInputs = mrbInputs; + sMarketInputs.strInputs = strInputs; + sMarketInputs.oscInputs = oscInputs; + sMarketInputs.cheInputs = cheInputs; + sMarketInputs.ichInputs = ichInputs; + sMarketInputs.donInputs = donInputs; + + // + result = sMarketInputs.Init( + symbol, + period, + X_MARKET_CYCLE_SHORT, + scPeriod, + scMethod, + NULL, + false // + ); + if (!result) + { + return result; + } + + // + sMarket = new XSCX121Market(); + result = sMarket.Init(sMarketInputs); + if (!result) + { + return result; + } + + // + // Medium Cycle ... + + // + ConfigureMediumCycles(); + + // + mMarketInputs.cycle.symbol = symbol; + mMarketInputs.cycle.period = period; + + // + mMarketInputs.pvInputs = pvInputs; + mMarketInputs.zgInputs = zgInputs; + mMarketInputs.tdInputs = tdInputs; + mMarketInputs.mcInputs = mcInputs; + mMarketInputs.hkInputs = hkInputs; + mMarketInputs.mrbInputs = mrbInputs; + mMarketInputs.strInputs = strInputs; + mMarketInputs.oscInputs = oscInputs; + mMarketInputs.cheInputs = cheInputs; + mMarketInputs.ichInputs = ichInputs; + mMarketInputs.donInputs = donInputs; + + // + result = mMarketInputs.Init( + symbol, + period, + X_MARKET_CYCLE_MEDIUM, + mcPeriod, + mcMethod, + NULL, + false // + ); + if (!result) + { + return result; + } + + // + mMarket = new XSCX121Market(); + result = mMarket.Init(mMarketInputs); + if (!result) + { + return result; + } + + // + // Long Cycle ... + + // + ConfigureLongCycles(); + + // + lMarketInputs.cycle.symbol = symbol; + lMarketInputs.cycle.period = period; + + // + lMarketInputs.pvInputs = pvInputs; + lMarketInputs.zgInputs = zgInputs; + lMarketInputs.tdInputs = tdInputs; + lMarketInputs.mcInputs = mcInputs; + lMarketInputs.hkInputs = hkInputs; + lMarketInputs.mrbInputs = mrbInputs; + lMarketInputs.strInputs = strInputs; + lMarketInputs.oscInputs = oscInputs; + lMarketInputs.cheInputs = cheInputs; + lMarketInputs.ichInputs = ichInputs; + lMarketInputs.donInputs = donInputs; + + // + result = lMarketInputs.Init( + symbol, + period, + X_MARKET_CYCLE_LONG, + lcPeriod, + lcMethod, + NULL, + false // + ); + if (!result) + { + return result; + } + + // + lMarket = new XSCX121Market(); + result = lMarket.Init(lMarketInputs); + if (!result) + { + return result; + } + + // + // Hind Cycle ... + + // + ConfigureHindCycles(); + + // + hMarketInputs.cycle.symbol = symbol; + hMarketInputs.cycle.period = period; + + // + hMarketInputs.pvInputs = pvInputs; + hMarketInputs.zgInputs = zgInputs; + hMarketInputs.tdInputs = tdInputs; + hMarketInputs.mcInputs = mcInputs; + hMarketInputs.hkInputs = hkInputs; + hMarketInputs.mrbInputs = mrbInputs; + hMarketInputs.strInputs = strInputs; + hMarketInputs.oscInputs = oscInputs; + hMarketInputs.cheInputs = cheInputs; + hMarketInputs.ichInputs = ichInputs; + hMarketInputs.donInputs = donInputs; + + // + result = hMarketInputs.Init( + symbol, + period, + X_MARKET_CYCLE_HIND, + hcPeriod, + hcMethod, + NULL, + false // + ); + if (!result) + { + return result; + } + + // + hMarket = new XSCX121Market(); + result = hMarket.Init(hMarketInputs); + if (!result) + { + return result; + } + + // + return result; +} + +// +// Generate and Update Market Conditions ... +void GenerateMarketConditions() +{ + // + cConditions.Clear(); + cMarket.GetMarketConditions(cConditions); + + // + sConditions.Clear(); + sMarket.GetMarketConditions(sConditions); + + // + mConditions.Clear(); + mMarket.GetMarketConditions(mConditions); + + // + lConditions.Clear(); + lMarket.GetMarketConditions(lConditions); + + // + hConditions.Clear(); + hMarket.GetMarketConditions(hConditions); +} + +// +// Calculate Markets Score Summary ... +void CalculateScores( + double &mBullishScore, + double &mBearishScore // +) +{ + // + // Current Market ... + + // + double cBullScore = 0; + double cBearScore = 0; + double cScoreMultiplier = 1; + + // + cConditions.GenerateScore( + cBullScore, + cBearScore, + cScoreMultiplier // + ); + + // + // Short Market ... + + // + double sBullScore = 0; + double sBearScore = 0; + double sScoreMultiplier = 1.25; + + // + sConditions.GenerateScore( + sBullScore, + sBearScore, + sScoreMultiplier // + ); + + // + // Medium Market ... + + // + double mBullScore = 0; + double mBearScore = 0; + double mScoreMultiplier = 1.5; + + // + mConditions.GenerateScore( + mBullScore, + mBearScore, + mScoreMultiplier // + ); + + // + // Long Market ... + + // + double lBullScore = 0; + double lBearScore = 0; + double lScoreMultiplier = 2; + + // + lConditions.GenerateScore( + lBullScore, + lBearScore, + lScoreMultiplier // + ); + + // + // Hind Market ... + + // + double hBullScore = 0; + double hBearScore = 0; + double hScoreMultiplier = 2.5; + + // + hConditions.GenerateScore( + hBullScore, + hBearScore, + hScoreMultiplier // + ); + + // + mBullishScore = cBullScore + + sBullScore + + mBullScore + + lBullScore + + hBullScore; + + // + mBearishScore = cBearScore + + sBearScore + + mBearScore + + lBearScore + + hBearScore; + + // + Add( + mBullishScore, + bullishBuffer + // + ); + + // + Add( + mBearishScore, + bearishBuffer + // + ); +} + +// +// Calculate Market Normalized Scores ... +void CalculateNormalizedScores( + double &mBullishScore, + double &mBearishScore // +) +{ + // + CalculateNormalization( + mBullishScore, + mBearishScore + // + ); + + Add( + mBullishScore, + nBullishBuffer // + ); + + Add( + mBearishScore, + nBearishBuffer // + ); +} + +// +// Calculate Normalization Value ... +void CalculateNormalization( + double &normalBullish, + double &normalBearish // +) +{ + // + normalBullish = GetNormalizedValueMethod2( + bullishBuffer, + ArraySize(bullishBuffer), + 1, + -1, + 0 // + ); + + // + normalBearish = GetNormalizedValueMethod2( + bearishBuffer, + ArraySize(bearishBuffer), + 1, + -1, + 0 // + ); +} + +// +// Calculate Market Verifications ... +void CalculateVerifications( + double &longVerifications, + double &shortVerifications // +) +{ + // + // Generate Long ans Short Verifiers ... + + // + // XSTR ... + + // + bool isTrendBullish = + // + hConditions.isTrendBullish && + lConditions.isTrendBullish && + mConditions.isTrendBullish && + sConditions.isTrendBullish && + cConditions.isTrendBullish + // + ; + + // + if (isTrendBullish) + { + longVerifications++; + } + + // + bool isTrendBearish = + // + hConditions.isTrendBearish && + lConditions.isTrendBearish && + mConditions.isTrendBearish && + sConditions.isTrendBearish && + cConditions.isTrendBearish + // + ; + + // + if (isTrendBearish) + { + shortVerifications++; + } + + // + // XTD ... + + // + bool isTDBullish = + // + hConditions.isTDBullish && + lConditions.isTDBullish && + mConditions.isTDBullish && + sConditions.isTDBullish && + cConditions.isTDBullish + // + ; + + // + if (isTDBullish) + { + longVerifications++; + } + + // + bool isTDBearish = + // + hConditions.isTDBearish && + lConditions.isTDBearish && + mConditions.isTDBearish && + sConditions.isTDBearish && + cConditions.isTDBearish + // + ; + + // + if (isTDBearish) + { + shortVerifications++; + } + + // + // XCHE ... + + // + bool isCHEBullish = + // + hConditions.isCHEBullish && + lConditions.isCHEBullish && + mConditions.isCHEBullish && + sConditions.isCHEBullish && + cConditions.isCHEBullish + // + ; + + // + if (isCHEBullish) + { + longVerifications++; + } + + // + bool isCHEBearish = + // + hConditions.isCHEBearish && + lConditions.isCHEBearish && + mConditions.isCHEBearish && + sConditions.isCHEBearish && + cConditions.isCHEBearish + // + ; + + // + if (isCHEBearish) + { + shortVerifications++; + } + + // + // XHK ... + + // + bool isHKBullish = + // + (hConditions.isHKBullish && + lConditions.isHKBullish && + mConditions.isHKBullish && + sConditions.isHKBullish && + cConditions.isHKBullish) + // + || + // + (hConditions.isSMHKBullish && + lConditions.isSMHKBullish && + mConditions.isSMHKBullish && + sConditions.isSMHKBullish && + cConditions.isSMHKBullish) + // + ; + + // + if (isHKBullish) + { + longVerifications++; + } + + // + bool isHKBearish = + // + (hConditions.isHKBearish && + lConditions.isHKBearish && + mConditions.isHKBearish && + sConditions.isHKBearish && + cConditions.isHKBearish) + // + || + // + (hConditions.isSMHKBearish && + lConditions.isSMHKBearish && + mConditions.isSMHKBearish && + sConditions.isSMHKBearish && + cConditions.isSMHKBearish) + // + ; + + // + if (isHKBearish) + { + shortVerifications++; + } + + // + // XMC ... + + // + bool isMCBullish = + // + (hConditions.isMCFastOverSlow && + lConditions.isMCFastOverSlow && + mConditions.isMCFastOverSlow && + sConditions.isMCFastOverSlow && + cConditions.isMCFastOverSlow) + // + || + // + (hConditions.isMCFastOverVerifier && + lConditions.isMCFastOverVerifier && + mConditions.isMCFastOverVerifier && + sConditions.isMCFastOverVerifier && + cConditions.isMCFastOverVerifier) + // + ; + + // + if (isMCBullish) + { + longVerifications++; + } + + // + bool isMCBearish = + // + (hConditions.isMCFastUnderSlow && + lConditions.isMCFastUnderSlow && + mConditions.isMCFastUnderSlow && + sConditions.isMCFastUnderSlow && + cConditions.isMCFastUnderSlow) + // + || + // + (hConditions.isMCFastUnderVerifier && + lConditions.isMCFastUnderVerifier && + mConditions.isMCFastUnderVerifier && + sConditions.isMCFastUnderVerifier && + cConditions.isMCFastUnderVerifier) + // + ; + + // + if (isMCBearish) + { + shortVerifications++; + } + + // + // XMRB ... + + // + bool isMRBBullish = + // + (hConditions.isMRBFastOverSlow && + lConditions.isMRBFastOverSlow && + mConditions.isMRBFastOverSlow && + sConditions.isMRBFastOverSlow && + cConditions.isMRBFastOverSlow) + // + || + // + (hConditions.isMRBFastOverVerifier && + lConditions.isMRBFastOverVerifier && + mConditions.isMRBFastOverVerifier && + sConditions.isMRBFastOverVerifier && + cConditions.isMRBFastOverVerifier) + // + || + // + (hConditions.isMRBSlowOverVerifier && + lConditions.isMRBSlowOverVerifier && + mConditions.isMRBSlowOverVerifier && + sConditions.isMRBSlowOverVerifier && + cConditions.isMRBSlowOverVerifier) + // + ; + + // + if (isMRBBullish) + { + longVerifications++; + } + + // + bool isMRBBearish = + // + (hConditions.isMRBFastUnderSlow && + lConditions.isMRBFastUnderSlow && + mConditions.isMRBFastUnderSlow && + sConditions.isMRBFastUnderSlow && + cConditions.isMRBFastUnderSlow) + // + || + // + (hConditions.isMRBFastUnderVerifier && + lConditions.isMRBFastUnderVerifier && + mConditions.isMRBFastUnderVerifier && + sConditions.isMRBFastUnderVerifier && + cConditions.isMRBFastUnderVerifier) + // + || + // + (hConditions.isMRBSlowUnderVerifier && + lConditions.isMRBSlowUnderVerifier && + mConditions.isMRBSlowUnderVerifier && + sConditions.isMRBSlowUnderVerifier && + cConditions.isMRBSlowUnderVerifier) + // + ; + + // + if (isMRBBearish) + { + shortVerifications++; + } + + // + // X786 ... + + // + bool isX786CLong = + // + (cConditions.isSMHKSwitchedToBullish && + (cConditions.isTDBullish && + cConditions.isCHEBullish && + cConditions.isTrendBullish)) + // + || + // + (cConditions.isTDSwitchedToBullish && + (cConditions.isSMHKBullish && + cConditions.isCHEBullish && + cConditions.isTrendBullish)) + // + || + // + (cConditions.isCHESwitchedToBullish && + (cConditions.isTDBullish && + cConditions.isSMHKBullish && + cConditions.isTrendBullish)) + // + || + // + (cConditions.isTrendSwitchedToBullish && + (cConditions.isTDBullish && + cConditions.isCHEBullish && + cConditions.isSMHKBullish)) + // + ; + + // + if (isX786CLong) + { + xLongVerifications++; + } + + // + bool isX786SLong = + // + (sConditions.isSMHKSwitchedToBullish && + (sConditions.isTDBullish && + sConditions.isCHEBullish && + sConditions.isTrendBullish)) + // + || + // + (sConditions.isTDSwitchedToBullish && + (sConditions.isSMHKBullish && + sConditions.isCHEBullish && + sConditions.isTrendBullish)) + // + || + // + (sConditions.isCHESwitchedToBullish && + (sConditions.isTDBullish && + sConditions.isSMHKBullish && + sConditions.isTrendBullish)) + // + || + // + (sConditions.isTrendSwitchedToBullish && + (sConditions.isTDBullish && + sConditions.isCHEBullish && + sConditions.isSMHKBullish)) + // + ; + + // + if (isX786SLong) + { + xLongVerifications++; + } + + // + bool isX786MLong = + // + (mConditions.isSMHKSwitchedToBullish && + (mConditions.isTDBullish && + mConditions.isCHEBullish && + mConditions.isTrendBullish)) + // + || + // + (mConditions.isTDSwitchedToBullish && + (mConditions.isSMHKBullish && + mConditions.isCHEBullish && + mConditions.isTrendBullish)) + // + || + // + (mConditions.isCHESwitchedToBullish && + (mConditions.isTDBullish && + mConditions.isSMHKBullish && + mConditions.isTrendBullish)) + // + || + // + (mConditions.isTrendSwitchedToBullish && + (mConditions.isTDBullish && + mConditions.isCHEBullish && + mConditions.isSMHKBullish)) + // + ; + + // + if (isX786MLong) + { + xLongVerifications++; + } + + // + bool isX786LLong = + // + (lConditions.isSMHKSwitchedToBullish && + (lConditions.isTDBullish && + lConditions.isCHEBullish && + lConditions.isTrendBullish)) + // + || + // + (lConditions.isTDSwitchedToBullish && + (lConditions.isSMHKBullish && + lConditions.isCHEBullish && + lConditions.isTrendBullish)) + // + || + // + (lConditions.isCHESwitchedToBullish && + (lConditions.isTDBullish && + lConditions.isSMHKBullish && + lConditions.isTrendBullish)) + // + || + // + (lConditions.isTrendSwitchedToBullish && + (lConditions.isTDBullish && + lConditions.isCHEBullish && + lConditions.isSMHKBullish)) + // + ; + + // + if (isX786LLong) + { + xLongVerifications++; + } + + // + bool isX786HLong = + // + (hConditions.isSMHKSwitchedToBullish && + (hConditions.isTDBullish && + hConditions.isCHEBullish && + hConditions.isTrendBullish)) + // + || + // + (hConditions.isTDSwitchedToBullish && + (hConditions.isSMHKBullish && + hConditions.isCHEBullish && + hConditions.isTrendBullish)) + // + || + // + (hConditions.isCHESwitchedToBullish && + (hConditions.isTDBullish && + hConditions.isSMHKBullish && + hConditions.isTrendBullish)) + // + || + // + (hConditions.isTrendSwitchedToBullish && + (hConditions.isTDBullish && + hConditions.isCHEBullish && + hConditions.isSMHKBullish)) + // + ; + + // + if (isX786HLong) + { + xLongVerifications++; + } + + // + bool isX786CShort = + // + (cConditions.isSMHKSwitchedToBearish && + (cConditions.isTDBearish && + cConditions.isCHEBearish && + cConditions.isTrendBearish)) + // + || + // + (cConditions.isTDSwitchedToBearish && + (cConditions.isSMHKBearish && + cConditions.isCHEBearish && + cConditions.isTrendBearish)) + // + || + // + (cConditions.isCHESwitchedToBearish && + (cConditions.isTDBearish && + cConditions.isSMHKBearish && + cConditions.isTrendBearish)) + // + || + // + (cConditions.isTrendSwitchedToBearish && + (cConditions.isTDBearish && + cConditions.isCHEBearish && + cConditions.isSMHKBearish)) + // + ; + + // + if (isX786CShort) + { + xShortVerifications++; + } + + // + bool isX786SShort = + // + (sConditions.isSMHKSwitchedToBearish && + (sConditions.isTDBearish && + sConditions.isCHEBearish && + sConditions.isTrendBearish)) + // + || + // + (sConditions.isTDSwitchedToBearish && + (sConditions.isSMHKBearish && + sConditions.isCHEBearish && + sConditions.isTrendBearish)) + // + || + // + (sConditions.isCHESwitchedToBearish && + (sConditions.isTDBearish && + sConditions.isSMHKBearish && + sConditions.isTrendBearish)) + // + || + // + (sConditions.isTrendSwitchedToBearish && + (sConditions.isTDBearish && + sConditions.isCHEBearish && + sConditions.isSMHKBearish)) + // + ; + + // + if (isX786SShort) + { + xShortVerifications++; + } + + // + bool isX786MShort = + // + (mConditions.isSMHKSwitchedToBearish && + (mConditions.isTDBearish && + mConditions.isCHEBearish && + mConditions.isTrendBearish)) + // + || + // + (mConditions.isTDSwitchedToBearish && + (mConditions.isSMHKBearish && + mConditions.isCHEBearish && + mConditions.isTrendBearish)) + // + || + // + (mConditions.isCHESwitchedToBearish && + (mConditions.isTDBearish && + mConditions.isSMHKBearish && + mConditions.isTrendBearish)) + // + || + // + (mConditions.isTrendSwitchedToBearish && + (mConditions.isTDBearish && + mConditions.isCHEBearish && + mConditions.isSMHKBearish)) + // + ; + + // + if (isX786MShort) + { + xShortVerifications++; + } + + // + bool isX786LShort = + // + (lConditions.isSMHKSwitchedToBearish && + (lConditions.isTDBearish && + lConditions.isCHEBearish && + lConditions.isTrendBearish)) + // + || + // + (lConditions.isTDSwitchedToBearish && + (lConditions.isSMHKBearish && + lConditions.isCHEBearish && + lConditions.isTrendBearish)) + // + || + // + (lConditions.isCHESwitchedToBearish && + (lConditions.isTDBearish && + lConditions.isSMHKBearish && + lConditions.isTrendBearish)) + // + || + // + (lConditions.isTrendSwitchedToBearish && + (lConditions.isTDBearish && + lConditions.isCHEBearish && + lConditions.isSMHKBearish)) + // + ; + + // + if (isX786LShort) + { + xShortVerifications++; + } + + // + bool isX786HShort = + // + (hConditions.isSMHKSwitchedToBearish && + (hConditions.isTDBearish && + hConditions.isCHEBearish && + hConditions.isTrendBearish)) + // + || + // + (hConditions.isTDSwitchedToBearish && + (hConditions.isSMHKBearish && + hConditions.isCHEBearish && + hConditions.isTrendBearish)) + // + || + // + (hConditions.isCHESwitchedToBearish && + (hConditions.isTDBearish && + hConditions.isSMHKBearish && + hConditions.isTrendBearish)) + // + || + // + (hConditions.isTrendSwitchedToBearish && + (hConditions.isTDBearish && + hConditions.isCHEBearish && + hConditions.isSMHKBearish)) + // + ; + + // + if (isX786HShort) + { + xShortVerifications++; + } + + // + Add( + xLongVerifications, + longVFBuffer // + ); + + // + Add( + xShortVerifications, + shortVFBuffer // + ); +} + +// +void HandleSignalDetection() +{ + // + // Define Using Variables ... + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + + // + // Define Global Variables ... + double r2r = 1.5; + double tpPrice = 0; + double slPrice = 0; + bool hasLong = false; + bool hasShort = false; + bool hasSignal = false; + + // + double scroeDetectionMultiplier = 2; + double verificationDetectionCount = 4; + + // + if (ArraySize(bullishBuffer) < 3) + { + return; + } + + // + // Set Arrays As Series ... + ArraySetAsSeries(bullishBuffer, true); + ArraySetAsSeries(bearishBuffer, true); + ArraySetAsSeries(longVFBuffer, true); + ArraySetAsSeries(shortVFBuffer, true); + + // + bool isZScoreBullish = bullishBuffer[zIndex] > + bearishBuffer[zIndex] * scroeDetectionMultiplier; + // + bool isCScoreBullish = bullishBuffer[cIndex] > + bearishBuffer[cIndex] * scroeDetectionMultiplier; + // + bool isPScoreBullish = bullishBuffer[pIndex] > + bearishBuffer[pIndex] * scroeDetectionMultiplier; + + // + bool isZScoreBearish = bearishBuffer[zIndex] > + bullishBuffer[zIndex] * scroeDetectionMultiplier; + // + bool isCScoreBearish = bearishBuffer[cIndex] > + bullishBuffer[cIndex] * scroeDetectionMultiplier; + // + bool isPScoreBearish = bearishBuffer[pIndex] > + bullishBuffer[pIndex] * scroeDetectionMultiplier; + + // + bool isZLongVerificationsBullish = longVFBuffer[zIndex] > longVFBuffer[cIndex] && + longVFBuffer[zIndex] > shortVFBuffer[cIndex] && + longVFBuffer[cIndex] >= verificationDetectionCount; + + // + bool isCLongVerificationsBullish = longVFBuffer[cIndex] > longVFBuffer[pIndex] && + longVFBuffer[cIndex] > shortVFBuffer[pIndex] && + longVFBuffer[pIndex] >= verificationDetectionCount; + + // + bool isZShortVerificationsBearish = shortVFBuffer[zIndex] > shortVFBuffer[cIndex] && + shortVFBuffer[zIndex] > longVFBuffer[cIndex] && + shortVFBuffer[cIndex] >= verificationDetectionCount; + + // + bool isCShortVerificationsBearish = shortVFBuffer[cIndex] > shortVFBuffer[pIndex] && + shortVFBuffer[cIndex] > longVFBuffer[pIndex] && + shortVFBuffer[pIndex] >= verificationDetectionCount; + + // + bool lookingLong = + // + isZScoreBullish + // + || + // + (isZLongVerificationsBullish && + !isCLongVerificationsBullish) + // + ; + + // + bool lookingShort = + // + isZScoreBearish + // + || + // + (isZShortVerificationsBearish && + !isCShortVerificationsBearish) + // + ; + + // + if (lookingLong) + { + // + bool cHasX786 = cMarket.HasX786LongConditions(); + bool sHasX786 = sMarket.HasX786LongConditions(); + bool mHasX786 = mMarket.HasX786LongConditions(); + bool lHasX786 = lMarket.HasX786LongConditions(); + bool hHasX786 = hMarket.HasX786LongConditions(); + + // + double cMarketSL = cMarket.don.GetLowerH(cIndex); + double sMarketSL = sMarket.don.GetLowerH(cIndex); + double mMarketSL = mMarket.don.GetLowerH(cIndex); + double lMarketSL = lMarket.don.GetLowerH(cIndex); + double hMarketSL = hMarket.don.GetLowerH(cIndex); + + // + bool condition1 = + // + ((cHasX786 && + sHasX786 && + mHasX786) + // + || + // + (cHasX786 && + mHasX786 && + lHasX786)) + // + ; + + // + bool condition2 = + // + ((sHasX786 && + mHasX786 && + lHasX786) + // + || + // + (sHasX786 && + lHasX786 && + hHasX786)) + // + ; + + // + bool condition3 = + // + ((mHasX786 && + lHasX786 && + hHasX786) + // + || + // + (mHasX786 && + hHasX786 && + sHasX786)) + // + ; + + // + bool condition4 = + // + (lHasX786 && + hHasX786 && + mHasX786) + // + ; + + // + bool condition5 = (isZLongVerificationsBullish && + !isCLongVerificationsBullish); + + // + if (condition1) + { + // + double sls[] = { + cMarketSL, + sMarketSL, + mMarketSL // + }; + + // + slPrice = GetAverage(sls); + } + else if (condition2) + { + // + double sls[] = { + sMarketSL, + mMarketSL, + lMarketSL // + }; + + // + slPrice = GetAverage(sls); + } + else if (condition3) + { + // + double sls[] = { + mMarketSL, + lMarketSL, + hMarketSL // + }; + + // + slPrice = GetAverage(sls); + } + else if (condition4) + { + // + double sls[] = { + lMarketSL, + hMarketSL // + }; + + // + slPrice = GetAverage(sls); + } + else if (condition5) + { + slPrice = sMarketSL; + } + + // + hasLong = + // + condition1 + // + || + // + condition2 + // + || + // + condition3 + // + || + // + condition4 + // + || + // + condition5 + // + ; + } + else if (lookingShort) + { + // + bool cHasX786 = cMarket.HasX786ShortConditions(); + bool sHasX786 = sMarket.HasX786ShortConditions(); + bool mHasX786 = mMarket.HasX786ShortConditions(); + bool lHasX786 = lMarket.HasX786ShortConditions(); + bool hHasX786 = hMarket.HasX786ShortConditions(); + + // + double cMarketSL = cMarket.don.GetUpperL(cIndex); + double sMarketSL = sMarket.don.GetUpperL(cIndex); + double mMarketSL = mMarket.don.GetUpperL(cIndex); + double lMarketSL = lMarket.don.GetUpperL(cIndex); + double hMarketSL = hMarket.don.GetUpperL(cIndex); + + // + bool condition1 = + // + ((cHasX786 && + sHasX786) + // + || + // + (cHasX786 && + mHasX786)) + // + ; + + // + bool condition2 = + // + ((sHasX786 && + mHasX786) + // + || + // + (sHasX786 && + lHasX786)) + // + ; + + // + bool condition3 = + // + ((mHasX786 && + lHasX786) + // + || + // + (mHasX786 && + hHasX786)) + // + ; + + // + bool condition4 = + // + (lHasX786 && + hHasX786) + // + ; + + // + bool condition5 = (isZShortVerificationsBearish && + !isCShortVerificationsBearish); + + // + if (condition1) + { + // + double sls[] = { + cMarketSL, + sMarketSL, + mMarketSL // + }; + + // + slPrice = GetAverage(sls); + } + else if (condition2) + { + // + double sls[] = { + sMarketSL, + mMarketSL, + lMarketSL // + }; + + // + slPrice = GetAverage(sls); + } + else if (condition3) + { + // + double sls[] = { + mMarketSL, + lMarketSL, + hMarketSL // + }; + + // + slPrice = GetAverage(sls); + } + else if (condition4) + { + // + double sls[] = { + lMarketSL, + hMarketSL // + }; + + // + slPrice = GetAverage(sls); + } + else if (condition5) + { + slPrice = sMarketSL; + } + + // + hasShort = + // + condition1 + // + || + // + condition2 + // + || + // + condition3 + // + || + // + condition4 + // + || + // + condition5 + // + ; + + // // + // XPivot pivot; + // pivot.pivot = pivotPrice; + + // // + // DrawPivot( + // pivot, + // clrOrange // + // ); + } + + // + // Set Arrays As Series ... + ArraySetAsSeries(bullishBuffer, false); + ArraySetAsSeries(bearishBuffer, false); + ArraySetAsSeries(longVFBuffer, false); + ArraySetAsSeries(shortVFBuffer, false); + + // + // Handle Signal Generating ... + hasSignal = hasLong || hasShort; + if (!hasSignal) + { + return; + } + + // + // Generate Signal ... + + // + ENUM_POSITION_TYPE mType = + hasLong + ? POSITION_TYPE_BUY + : POSITION_TYPE_SELL; + + // + double mEntry = GetEntry( + xSampleEASymbol, + mType // + ); + + // + double mSL = 0; + double mTP = 0; + CalculateTPSL( + mSL, + mTP, + mType, + mEntry, + r2r, + slPrice // + ); + + // + if (mTP == 0 && mSL == 0) + { + Print("Zero"); + } + + // + lastBullishPivot = + hasLong + ? slPrice + : lastBullishPivot; + lastBearishPivot = + hasShort + ? slPrice + : lastBearishPivot; + // + XSignal signal; + bool isPrepared = signal.Prepare( + xSampleEASymbol, + "X92", + xSampleEAPeriod, + mType, + X_ORDER_MODE_MARKET, + mEntry, + 0.01, + mSL, + mTP // + ); + + // + if (isPrepared) + { + // + AddRef( + signal, + mSignals // + ); + } +} + +// +// Execute Signals ... +void HandleSignalExecution() +{ + // + int signalsCount = ArraySize(mSignals); + if (!IsValidSize(signalsCount)) + { + return; + } + + // + XSignal tmp[]; + Copy( + mSignals, + tmp // + ); + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = tmp[i]; + + // + if (!iSignal.IsValid()) + { + continue; + } + + // + // TODO: + // Validate Signal Execution based on lastTradeOn ... + + // + ENUM_X_SIGNAL_EXECUTION_RESULT state; + bool isExecuted = mTrader.ExecuteSignal( + iSignal, + state // + ); + if (isExecuted) + { + // + // Remove Signal from mSignals ... + + // + bool isRemoved = ArrayRemove( + mSignals, + i, + 1 // + ); + + // + if (isRemoved) + { + // + string message = "Signal Executed Successfully ..."; + + // + mAlert.Alert(message); + + // + long chartID = ChartID(); + + // + iSignal.Draw( + chartID // + ); + + // + // Remove Drawn Pivot ... + RemovePivotDraw(lastPeak); + RemovePivotDraw(lastVale); + RemovePivotDraw(lastSupport); + RemovePivotDraw(lastResistance); + + // + lastPeak = 0; + lastVale = 0; + lastSupport = 0; + lastResistance = 0; + mPivotTracker.Clean(); + + // + // Check Last Trade ON ... + lastTradeOn = + // + TimeCurrent() + // + ; + + // + // Detect All In Profit Positions and Trail their Stops ... + XPosition positions[]; + int positionsCount = mTrader.GetInProfitPositions( + positions, + iSignal.symbol, + iSignal.provider, + iSignal.period, + iSignal.type // + ); + if (IsValidSize(positionsCount)) + { + // + // Trial Stops ... + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + if (iPosition.ticket == iSignal.positionId) + { + continue; + } + + // + string comment = "Modify SL ..."; + + // + bool isLong = IsLong(iPosition.type); + double slDiff = PointToPrice(30, iPosition.symbol); + double sl = iSignal.entry + (isLong + ? -1 * slDiff + : slDiff); + sl = MathMin(sl, iPosition.sl); + // XPivot slPivot; + // slPivot.pivot = sl; + // DrawPivot( + // slPivot, + // clrAqua // + // ); + + // + bool isModified = mTrader.Modify( + iPosition.ticket, + sl, + iPosition.tp, + comment // + ); + + // + if (isModified) + { + mAlert.Alert(comment); + } + } + } + } + } + } +} + +// +void HandleDrawPivots() +{ + // + // return; + bool hasChild = mPivotTracker.HasChild(); + if (!hasChild) + { + return; + } + + // + int pivotsCount = mPivotTracker.Count(); + + // + for (int i = 0; i < pivotsCount; i++) + { + // + XPivot iPivot = mPivotTracker.GetPivot(i); + if (!iPivot.IsValid()) + { + continue; + } + + // + DrawPivot(iPivot); + } +} + +// +void RemovePivotDraw(double pivot) +{ + // + if (pivot <= 0) + { + return; + } + + // + long chartID = ChartID(); + + // + string pPrefix = "P_" + + ToString(pivot); + + // + if (!IsDrawExists(pPrefix)) + { + return; + } + + // + RemoveDraw(pPrefix); +} + +// +void DrawPivot( + XPivot &pivot, + color crl = clrLime // +) +{ + // + if (!pivot.IsValid()) + { + return; + } + + // + long chartID = ChartID(); + datetime time1 = iTime( + xSampleEASymbol, + xSampleEAPeriod, + 2 // + ); + datetime time = iTime( + xSampleEASymbol, + xSampleEAPeriod, + 0 // + ); + + // + bool currentPrice = MathMax(xSampleEATick.ask, xSampleEATick.bid); + + // + string pPrefix = "P_" + + ToString(pivot.pivot); + + // + // RemoveDraws(pPrefix); + + // + if (IsDrawExists(pPrefix)) + { + return; + } + + // + DrawTrendLine( + chartID, + pPrefix, + 0, + time1, + pivot.pivot, + time, + pivot.pivot, + crl, + STYLE_SOLID, + 2, + false, + false, + true // + ); +} + +// +void ConfigureCurrentCycles() +{ + + // + // XHK ... + hkInputs.drawHikenAshi = false; + hkInputs.drawSmoothedHikenAshi = false; + + // + // XMRB ... + mrbInputs.showFastMa = false; + mrbInputs.showSlowMa = false; + mrbInputs.showRibbon = false; + + // + // XMC ... + mcInputs.showFastMa = false; + mcInputs.showSlowMa = false; + mcInputs.showVerifierMa = false; + + // + // XICH ... + ichInputs.showKumo = false; + ichInputs.showKijunSen = false; + ichInputs.showTenkanSen = false; + ichInputs.showChikouSpan = false; + ichInputs.showSenkouSpanA = false; + ichInputs.showSenkouSpanB = false; + ichInputs.showKijunSenPlus = false; + ichInputs.showKijunSenNegative = false; + + // + // XCHE ... + cheInputs.showLongExit1Line = true; + cheInputs.showShortExit1Line = true; + cheInputs.showLongExit2Line = true; + cheInputs.showShortExit2Line = true; + + // + // XPV ... + pvInputs.showPeaksAndVales = true; + pvInputs.showLevels = false; + pvInputs.showConsolidations = false; + pvInputs.showFibo1Levels = false; + pvInputs.showFibo2Levels = false; + pvInputs.showFibo3Levels = false; + pvInputs.showFibo4Levels = false; + pvInputs.showFibo5Levels = false; + + // + // XZG ... + zgInputs.showZigZag = false; + zgInputs.showPeaksAndVales = true; + + // + // XDON ... + donInputs.showOpen = false; + donInputs.showHigh = false; + donInputs.showClose = false; + donInputs.showLow = false; + + // + // XSTR ... + strInputs.showTrends = false; + strInputs.fillTrends = false; +} + +// +void ConfigureShortCycles() {} + +// +void ConfigureMediumCycles() {} + +// +void ConfigureLongCycles() {} + +// +void ConfigureHindCycles() {} + +// +// Add Score ... +void AddBullishScroe() +{ + // +} + +// \ No newline at end of file diff --git a/Libraries/x-saherelm.common.lib.mq5 b/Libraries/x-saherelm.common.lib.mq5 index 3c76e9d9..25684519 100644 --- a/Libraries/x-saherelm.common.lib.mq5 +++ b/Libraries/x-saherelm.common.lib.mq5 @@ -1040,6 +1040,7 @@ struct XOHCL // also zBar Open must be Above Price Line ... result = // + pBar.high > price && pBar.low < price && cBar.close > price && this.close > price && @@ -1088,6 +1089,7 @@ struct XOHCL // also zBar Open must be Below Price Line ... result = // + pBar.high > price && pBar.low < price && cBar.close < price && this.close < price && @@ -1137,6 +1139,7 @@ struct XOHCL result = // pBar.high > price && + pBar.low < price && cBar.close < price && this.close < price && this.open < price @@ -1184,6 +1187,7 @@ struct XOHCL // also zBar Open must be Pver Price Line ... result = // + pBar.low < price && pBar.high > price && cBar.close > price && this.close > price && @@ -1238,7 +1242,7 @@ struct XOHCL // // Check Bar has Strongest Body in a Range ... bool HasStrongestBody( - int loopback = 3 // loopback candles to compare it ... + int mLoopback = 3 // loopback candles to compare it ... ) { // @@ -1254,7 +1258,7 @@ struct XOHCL // double body = GetBody(); XOHCL prev = this; - for (int i = 0; i < loopback; i++) + for (int i = 0; i < mLoopback; i++) { // bool isValid = prev.GetPreviousBar(prev); @@ -1285,7 +1289,7 @@ struct XOHCL // // Check Bar has Weakest Body in a Range ... bool HasWeakestBody( - int loopback = 3 // loopback candles to compare it ... + int mLoopback = 3 // loopback candles to compare it ... ) { // @@ -1301,7 +1305,7 @@ struct XOHCL // double body = GetBody(); XOHCL prev = this; - for (int i = 0; i < loopback; i++) + for (int i = 0; i < mLoopback; i++) { // bool isValid = prev.GetPreviousBar(prev); @@ -1696,6 +1700,312 @@ struct XOHCL } }; +// +struct XPivot +{ + // + double pivot; // Pivot Price ... + int breaks; // Number of Breaks ... + int rejects; // Number of Rejects ... + + // + void XPivot() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + pivot = 0; + breaks = 0; + rejects = 0; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = pivot > 0; + + // + return result; + } +}; + +// +struct XPivotTracker +{ + // + XPivot pivots[]; + + // + // Constructor ... + void XPivotTracker() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + Clean(pivots); + } + + // + int Count() + { + return ArraySize(pivots); + } + + // + double Get(int index) + { + // + double result = 0; + + // + NormalizeIndex(index, pivots); + + // + XPivot iPivot = pivots[index]; + + // + result = iPivot.pivot; + + // + return result; + } + + // + XPivot GetPivot(int index) + { + // + XPivot result; + + // + NormalizeIndex(index, pivots); + + // + result = pivots[index]; + + // + return result; + } + + // + bool Add(double mPivot) + { + // + bool result = false; + + // + result = mPivot > 0 && !Has(mPivot); + if (!result) + { + return result; + } + + // + XPivot pivot; + pivot.pivot = mPivot; + + // + AddRef( + pivot, + pivots // + ); + + // + result = true; + + // + return result; + } + + // + int Adds(double &mPivots[]) + { + // + int result = 0; + + // + int pivotsCount = ArraySize(mPivots); + if (!IsValidSize(pivotsCount)) + { + return result; + } + + // + for (int i = 0; i < pivotsCount; i++) + { + // + double iPivot = mPivots[i]; + + // + bool isAdded = Add(iPivot); + if (isAdded) + { + result++; + } + } + + // + return result; + } + + // + int FindIndex(double mPivot) + { + // + int result = -1; + + // + if (mPivot <= 0) + { + return result; + } + + // + int count = Count(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + XPivot iPivot = pivots[i]; + + // + if (iPivot.pivot == mPivot) + { + // + result = i; + break; + } + } + + // + return result; + } + + // + double Has(double mPivot) + { + // + bool result = false; + + // + int pivotIDX = FindIndex(mPivot); + result = pivotIDX >= 0; + + // + return result; + } + + // + int Reject(double mPivot) + { + // + int result = 0; + + // + int pivotIDX = FindIndex(mPivot); + if (pivotIDX < 0) + { + return result; + } + + // + pivots[pivotIDX].rejects++; + + // + result = pivots[pivotIDX].rejects; + + // + return result; + } + + // + int Break(double mPivot) + { + // + int result = 0; + + // + int pivotIDX = FindIndex(mPivot); + if (pivotIDX < 0) + { + return result; + } + + // + pivots[pivotIDX].breaks++; + + // + result = pivots[pivotIDX].breaks; + + // + return result; + } + + // + bool Remove(double mPivot) + { + // + bool result = false; + + // + int pivotIDX = FindIndex(mPivot); + result = pivotIDX >= 0; + if (!result) + { + return result; + } + + // + result = ArrayRemove( + pivots, + pivotIDX, + 1 // + ); + + // + return result; + } + + // + bool HasChild() + { + // + bool result = false; + + // + int count = Count(); + result = IsValidSize(count); + + // + return result; + } +}; + // // Model Support and Resistance // for Specific Bar ... @@ -3553,6 +3863,52 @@ void NormalizeIndex( } } +// +// Normalize Start and Count based on Specified Buffer ... +template +void NormalizeCount( + int &start, + int &count, + T &buffer[] // +) +{ + // + // Validate Buffer Size ... + int bufferSize = ArraySize(buffer); + if (!IsValidSize(bufferSize)) + { + return; + } + + // + // Normalization Start ... + NormalizeIndex( + start, + buffer // + ); + + // + if (count < start) + { + count = (start - count); + } + + // + // Normalization Count ... + + // + if (count < 0) + { + count = start; + } + + // + if (count > bufferSize) + { + count = bufferSize; + } +} + // // Normalize a give Volume ... double NormalizeVolume( @@ -4051,8 +4407,8 @@ void CalculateTPSL( // mSL = isLong - ? mEntry - reward - : mEntry + reward; + ? mEntry - risk + : mEntry + risk; } // @@ -4939,6 +5295,177 @@ double GetFibonacciLevel( return result; } +// +// Method 1 +// Normalize between 1 and 0 ... +template +double GetNormalizedValueMethod1( + T &buffer[], // Array which required to Normalize + int mLength, // Length of Normalization + int mStart = 0, // start index + int digits = 5 // Normalization Digits +) +{ + // + double result = 0; + + // + if (digits <= 5) + { + digits = 5; + } + + // + int bufferSize = ArraySize(buffer); + if (!IsValidSize(bufferSize)) + { + return result; + } + + // + // Normalize Count ... + NormalizeCount( + mStart, + mLength, + buffer // + ); + + // + T max = 0; + T min = 0; + + // + if (bufferSize != mLength) + { + // + T tmp[]; + Copy( + mStart, + mLength, + buffer, + tmp // + ); + + // + max = GetMax(tmp); + min = GetMin(tmp); + } + + // + if (bufferSize == mLength) + { + // + max = GetMax(buffer); + min = GetMin(buffer); + } + + // + T iValue = buffer[mStart]; + + // + double minMaxDiff = (max - min); + if (minMaxDiff <= 0) + { + return result; + } + + // + result = (iValue - min) / minMaxDiff; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} + +// +// Method 2 +// Normalize Between Specified Upper and Lower ... +template +double GetNormalizedValueMethod2( + T &buffer[], // Array which required to Normalize + int mLength, // Length of Normalization + int mUpper, // Specified Upper Value + int mLower, // Specified Lower Value + int mStart = 0, // start index + int digits = 5 // Normalization Digits +) +{ + // + double result = 0; + + // + if (digits <= 5) + { + digits = 5; + } + + // + int bufferSize = ArraySize(buffer); + if (!IsValidSize(bufferSize)) + { + return result; + } + + // + // Normalize Count ... + NormalizeCount( + mStart, + mLength, + buffer // + ); + + // + T max = 0; + T min = 0; + + // + if (bufferSize != mLength) + { + // + T tmp[]; + Copy( + mStart, + mLength, + buffer, + tmp // + ); + + // + max = GetMax(tmp); + min = GetMin(tmp); + } + + // + if (bufferSize == mLength) + { + // + max = GetMax(buffer); + min = GetMin(buffer); + } + + // + T iValue = buffer[mStart]; + + // + double minMaxDiff = (max - min); + double boundaryDiff = (mUpper - mLower); + if (minMaxDiff <= 0 || boundaryDiff <= 0) + { + return result; + } + + // + result = boundaryDiff / (minMaxDiff * (iValue - max) + max); + + // + result = NormalizeDouble(result, digits); + + // + return result; +} + // // Templates ... diff --git a/Libraries/x-saherelm.xtrade.lib.mq5 b/Libraries/x-saherelm.xtrade.lib.mq5 index c721199d..0ed75682 100644 --- a/Libraries/x-saherelm.xtrade.lib.mq5 +++ b/Libraries/x-saherelm.xtrade.lib.mq5 @@ -22,6 +22,7 @@ // // Imports ... #include +#include "../Libraries/x-saherelm.draw.lib.mq5" #include "../Libraries/x-saherelm.common.lib.mq5" #include "../Classes/x-saherelm.xdata-collector.class.mq5" @@ -1015,7 +1016,7 @@ struct XSignal IsValid(period) && IsValid(symbol) && NotEmpty(volume) && - NotEmpty(entry) + NotEmpty(entry) // ; @@ -1109,6 +1110,16 @@ struct XSignal return result; } + // + int GetAge() + { + // + return GetAge( + this, + this.period // + ); + } + // // Retrieve Entry Price ... double GetEntry() @@ -1480,6 +1491,162 @@ struct XSignal // return result; } + + // + // Draw Signal on Chart ... + bool Draw( + long chartID, + int subWindow = 0, + string prefix = NULL, + color entryColor = clrGold, + color bullishColor = clrSpringGreen, + color bearishColor = clrTomato // + ) + { + // + bool result = false; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + bool isLong = IsLong(this.type); + + // + prefix = + // + (!IsValid(prefix) ? "" : prefix) + + this.symbol + "_" + + ToString(this.period) + "_" + + this.provider + // + ; + + // + int age = this.GetAge(); + + // + // Retrieve Time ... + datetime time0 = iTime( + this.symbol, + this.period, + age // + ); + + // + // Retrieve 3 Time ... + datetime time3 = iTime( + this.symbol, + this.period, + age + 3 // + ); + + // + color posColor = isLong + ? bullishColor + : bearishColor; + color tpColor = bullishColor; + color slColor = bearishColor; + + // + ENUM_LINE_STYLE vLineStyle = STYLE_DOT; + ENUM_LINE_STYLE tpLineStyle = STYLE_SOLID; + ENUM_LINE_STYLE slLineStyle = STYLE_SOLID; + ENUM_LINE_STYLE entryLineStyle = STYLE_SOLID; + + // + int lineWidth = 2; + + // + // Vertical Line ... + string vlName = prefix + "_" + (string)time; + + // + result = DrawVerticalLine( + chartID, + vlName, + subWindow, + time0, + posColor, + vLineStyle, + lineWidth // + ); + if (!result) + { + return result; + } + + // + // TP ... + double profit = (MathAbs(this.tp - this.entry)) * this.volume; + string tpName = prefix + "_TP_" + (string)profit; + + // + result = DrawTrendLine( + chartID, + tpName, + subWindow, + time3, + this.tp, + time0, + this.tp, + tpColor, + tpLineStyle, + lineWidth // + ); + if (!result) + { + return result; + } + + // + // SL ... + double lost = (MathAbs(this.sl - this.entry)) * this.volume; + string slName = prefix + "_SL_" + (string)lost; + + // + result = DrawTrendLine( + chartID, + slName, + subWindow, + time3, + this.sl, + time0, + this.sl, + slColor, + slLineStyle, + lineWidth // + ); + if (!result) + { + return result; + } + + // + // ENTRY ... + string entryName = prefix + "_ENTRY_" + (string)lost; + + // + result = DrawTrendLine( + chartID, + entryName, + subWindow, + time3, + this.entry, + time, + this.entry, + entryColor, + entryLineStyle, + lineWidth // + ); + + // + return result; + } }; // @@ -2888,6 +3055,32 @@ bool IsValid(ENUM_X_ORDER_MODES value) // // Ages ... +// +// Retrieve a Position Age ... +int GetAge( + XSignal &signal, // Selected Signal ... + ENUM_TIMEFRAMES period = NULL // Dest Time Frame ... +) +{ + // + int result = -1; + + // + if (period == NULL) + { + period = _Period; + } + + // + result = iBarShift( + signal.symbol, + period, + signal.time); + + // + return result; +} + // // Retrieve a Position Age ... int GetAge( @@ -3917,7 +4110,7 @@ int GenerateEQMOrders( XEQMSupportToken, position.period, iEntry, - position.volume, + position.volume, iSL, iTP // );