From 4a69e7edf872ff82e509d78058f773cbbbad2111 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Wed, 22 May 2024 13:15:20 +0330 Subject: [PATCH] last works ... --- Classes/x-saherelm.x121.provider.class.mq5 | 2144 ++++++++++++ Classes/x-saherelm.x121.xea.class.mq5 | 329 ++ Classes/x-saherelm.x121.xmcycle.class.mq5 | 3399 ++++++++++++++++++++ Classes/x-saherelm.x5.provider.class.mq5 | 185 +- Classes/x-saherelm.x5.xea.class.mq5 | 3 + Classes/x-saherelm.xea.class.mq5 | 20 + Experts/x-test.x121ea.mq5 | 420 +++ Experts/x-test.x5121ea.mq5 | 251 ++ Experts/x-test.x5ea.mq5 | 25 +- Helpers/x-saherelm.xchlh.helper.mq5 | 12 +- Helpers/x-saherelm.xchma.helper.mq5 | 12 +- Helpers/x-saherelm.xobd.helper.mq5 | 8 +- Helpers/x-saherelm.xpv.helper.mq5 | 7 +- Helpers/x-saherelm.xtd.helper.mq5 | 4 +- Indicators/x-saherelm.xobd.mq5 | 8 + Libraries/x-saherelm.common.lib.mq5 | 28 +- Libraries/x-saherelm.xtrade.lib.mq5 | 38 +- 17 files changed, 6815 insertions(+), 78 deletions(-) create mode 100644 Classes/x-saherelm.x121.provider.class.mq5 create mode 100644 Classes/x-saherelm.x121.xea.class.mq5 create mode 100644 Classes/x-saherelm.x121.xmcycle.class.mq5 create mode 100644 Experts/x-test.x121ea.mq5 create mode 100644 Experts/x-test.x5121ea.mq5 diff --git a/Classes/x-saherelm.x121.provider.class.mq5 b/Classes/x-saherelm.x121.provider.class.mq5 new file mode 100644 index 00000000..795427cb --- /dev/null +++ b/Classes/x-saherelm.x121.provider.class.mq5 @@ -0,0 +1,2144 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSC121Provider +// Description: provides all Base Provider +// requirements For X121 ... +// +// +// 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 + +// +// Imports ... + +// +#include "../Helpers/x-saherelm.xcc.helper.mq5" +#include "../Helpers/x-saherelm.xct.helper.mq5" +#include "../Helpers/x-saherelm.xmc.helper.mq5" +#include "../Helpers/x-saherelm.xdon.helper.mq5" +#include "../Helpers/x-saherelm.xzg.helper.mq5" +#include "../Helpers/x-saherelm.xpv.helper.mq5" +#include "../Helpers/x-saherelm.xstr.helper.mq5" +#include "../Helpers/x-saherelm.xche.helper.mq5" +#include "../Helpers/x-saherelm.xosc.helper.mq5" + +// +#include "../Classes/x-saherelm.xprovider.class.mq5" +#include "../Classes/x-saherelm.x121.xmcycle.class.mq5" + +// +// Definitions ... + +// +// Signallers ... +enum ENUM_X121_SIGNAL_PROVIDERS +{ + // + NONE, + XSP, + XTEST, + X786, + X121, + X110, + X92, +}; + +// +// X121 Provider Inputs ... +class X121ProviderInputs : public XSCBaseProviderInpts +{ + // + // Public ... +public: + // + // Props ... + + // + string symbol; + ENUM_TIMEFRAMES period; + + // + // S Market ... + ENUM_TIMEFRAMES sMarketPeriod; // Short Market Period + ENUM_X_PERIOD_METHOD sMarketMethod; // Short Market Period Method + string sMarketPrefix; // Short Market Prefix + + // + // MEDIUM Market ... + ENUM_TIMEFRAMES mMarketPeriod; // Medium Market Period + ENUM_X_PERIOD_METHOD mMarketMethod; // Medium Market Period Method + string mMarketPrefix; // Medium Market Prefix + + // + // LONG Market ... + ENUM_TIMEFRAMES lMarketPeriod; // Long Market Period + ENUM_X_PERIOD_METHOD lMarketMethod; // Long Market Period Method + string lMarketPrefix; // Long Market Prefix + + // + // HIND Market ... + ENUM_TIMEFRAMES hMarketPeriod; // Hind Market Period + ENUM_X_PERIOD_METHOD hMarketMethod; // Hind Market Period Method + string hMarketPrefix; // Hind Market Prefix + + // + // Indicators ... + XCCInputs ccInputs; + XCTInputs ctInputs; + XZGInputs zgInputs; + XPVInputs pvInputs; + XMCInputs mcInputs; + 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 + + // + // Tools ... + + // + // Initialize Input ... + bool Init() + { + // + bool result = false; + + // + // Validate Base Requirements ... + result = + // + IsSpecifiedValid(symbol) && + IsSpecifiedValid(period) && + IsSpecifiedValid(sMarketMethod, sMarketPeriod) && + IsSpecifiedValid(mMarketMethod, mMarketPeriod) && + IsSpecifiedValid(lMarketMethod, lMarketPeriod) && + IsSpecifiedValid(hMarketMethod, hMarketPeriod) + // + ; + if (!result) + { + return result; + } + + // + if (!zgInputs.IsValid()) + { + zgInputs.Default(); + } + if (!pvInputs.IsValid()) + { + pvInputs.Default(); + } + if (!mcInputs.IsValid()) + { + mcInputs.Default(); + } + if (!cheInputs.IsValid()) + { + cheInputs.Default(); + } + if (!strInputs.IsValid()) + { + strInputs.Default(); + } + if (!donInputs.IsValid()) + { + donInputs.Default(); + } + if (!oscInputs.IsValid()) + { + oscInputs.Default(); + } + if (!ichInputs.IsValid()) + { + ichInputs.Default(); + } + + // // + // if (!cMarketInputs.IsValid()) + // { + // cMarketInputs.Default(); + // } + // if (!sMarketInputs.IsValid()) + // { + // sMarketInputs.Default(); + // } + // if (!mMarketInputs.IsValid()) + // { + // mMarketInputs.Default(); + // } + // if (!lMarketInputs.IsValid()) + // { + // lMarketInputs.Default(); + // } + // if (!hMarketInputs.IsValid()) + // { + // hMarketInputs.Default(); + // } + + // + // Initialize Market Inputs ... + + // + // Current ... + cMarketInputs.mcInputs = this.mcInputs; + cMarketInputs.strInputs = this.strInputs; + cMarketInputs.oscInputs = this.oscInputs; + cMarketInputs.cheInputs = this.cheInputs; + cMarketInputs.ichInputs = this.ichInputs; + result = cMarketInputs.Init( + this.symbol, + this.period, + X_MARKET_CYCLE_SHORT, + this.period, + X_PERIOD_MANUALLY, + "HOST", + false // + ); + if (!result) + { + return result; + } + + // + // Short ... + sMarketInputs.mcInputs = this.mcInputs; + sMarketInputs.strInputs = this.strInputs; + sMarketInputs.oscInputs = this.oscInputs; + sMarketInputs.cheInputs = this.cheInputs; + sMarketInputs.ichInputs = this.ichInputs; + result = sMarketInputs.Init( + this.symbol, + this.period, + X_MARKET_CYCLE_SHORT, + this.sMarketPeriod, + this.sMarketMethod, + this.sMarketPrefix, + false // + ); + if (!result) + { + return result; + } + + // + // Medium ... + mMarketInputs.mcInputs = this.mcInputs; + mMarketInputs.strInputs = this.strInputs; + mMarketInputs.oscInputs = this.oscInputs; + mMarketInputs.cheInputs = this.cheInputs; + mMarketInputs.ichInputs = this.ichInputs; + result = mMarketInputs.Init( + this.symbol, + this.period, + X_MARKET_CYCLE_MEDIUM, + this.mMarketPeriod, + this.mMarketMethod, + this.mMarketPrefix, + false // + ); + if (!result) + { + return result; + } + + // + // Long ... + lMarketInputs.mcInputs = this.mcInputs; + lMarketInputs.strInputs = this.strInputs; + lMarketInputs.oscInputs = this.oscInputs; + lMarketInputs.cheInputs = this.cheInputs; + lMarketInputs.ichInputs = this.ichInputs; + result = lMarketInputs.Init( + this.symbol, + this.period, + X_MARKET_CYCLE_LONG, + this.lMarketPeriod, + this.lMarketMethod, + this.lMarketPrefix, + false // + ); + if (!result) + { + return result; + } + + // + // Hind ... + hMarketInputs.mcInputs = this.mcInputs; + hMarketInputs.strInputs = this.strInputs; + hMarketInputs.oscInputs = this.oscInputs; + hMarketInputs.cheInputs = this.cheInputs; + hMarketInputs.ichInputs = this.ichInputs; + result = hMarketInputs.Init( + this.symbol, + this.period, + X_MARKET_CYCLE_HIND, + this.hMarketPeriod, + this.hMarketMethod, + this.hMarketPrefix, + false // + ); + if (!result) + { + return result; + } + + // + result = IsValid(); + + // + return result; + } + + // + // Validate Input ... + bool IsValid() override + { + // + bool result = false; + + // + result = + // + // + IsSpecifiedValid(symbol) && + IsSpecifiedValid(period) && + IsSpecifiedValid(sMarketMethod, sMarketPeriod) && + IsSpecifiedValid(mMarketMethod, mMarketPeriod) && + IsSpecifiedValid(lMarketMethod, lMarketPeriod) && + IsSpecifiedValid(hMarketMethod, hMarketPeriod) && + // + ccInputs.IsValid() && + ctInputs.IsValid() && + zgInputs.IsValid() && + pvInputs.IsValid() && + mcInputs.IsValid() && + cheInputs.IsValid() && + strInputs.IsValid() && + donInputs.IsValid() && + oscInputs.IsValid() && + ichInputs.IsValid() && + // + cMarketInputs.IsValid() && + sMarketInputs.IsValid() && + mMarketInputs.IsValid() && + lMarketInputs.IsValid() && + hMarketInputs.IsValid() + // + ; + + // + return result; + } + + // + // Cleanup ... + void Clean() override + { + // + symbol = NULL; + period = NULL; + + // + sMarketPeriod = NULL; + sMarketMethod = X_PERIOD_NOTHING; + sMarketPrefix = NULL; + + // + mMarketPeriod = NULL; + mMarketMethod = X_PERIOD_NOTHING; + mMarketPrefix = NULL; + + // + lMarketPeriod = NULL; + lMarketMethod = X_PERIOD_NOTHING; + lMarketPrefix = NULL; + + // + hMarketPeriod = NULL; + hMarketMethod = X_PERIOD_NOTHING; + hMarketPrefix = NULL; + + // + ccInputs.Clean(); + ctInputs.Clean(); + zgInputs.Clean(); + pvInputs.Clean(); + mcInputs.Clean(); + cheInputs.Clean(); + strInputs.Clean(); + donInputs.Clean(); + oscInputs.Clean(); + ichInputs.Clean(); + // + cMarketInputs.Clean(); + sMarketInputs.Clean(); + mMarketInputs.Clean(); + lMarketInputs.Clean(); + hMarketInputs.Clean(); + } + + // + // Default ... + void Default() override + { + // + symbol = NULL; + period = NULL; + + // + sMarketPeriod = NULL; + sMarketMethod = X_PERIOD_AUTO; + sMarketPrefix = NULL; + + // + mMarketPeriod = NULL; + mMarketMethod = X_PERIOD_AUTO; + mMarketPrefix = NULL; + + // + lMarketPeriod = NULL; + lMarketMethod = X_PERIOD_AUTO; + lMarketPrefix = NULL; + + // + hMarketPeriod = NULL; + hMarketMethod = X_PERIOD_AUTO; + hMarketPrefix = NULL; + + // + ccInputs.Default(); + ctInputs.Default(); + zgInputs.Default(); + pvInputs.Default(); + mcInputs.Default(); + cheInputs.Default(); + strInputs.Default(); + donInputs.Default(); + oscInputs.Default(); + ichInputs.Default(); + cMarketInputs.Default(); + sMarketInputs.Default(); + mMarketInputs.Default(); + lMarketInputs.Default(); + hMarketInputs.Default(); + } + + // + // Max ... + int Max() override + { + // + int result = 0; + + // + return result; + } + + // + // Set Symbol ... + bool SetSymbol(string value) + { + // + bool result = false; + + // + result = IsSpecifiedValid(value); + if (!result) + { + return result; + } + + // + symbol = value; + cMarketInputs.cycle.symbol = value; + sMarketInputs.cycle.symbol = value; + mMarketInputs.cycle.symbol = value; + lMarketInputs.cycle.symbol = value; + hMarketInputs.cycle.symbol = value; + + // + return result; + } + + // + // Set Period ... + bool SetPeriod(ENUM_TIMEFRAMES value) + { + // + bool result = false; + + // + result = IsSpecifiedValid(value); + if (!result) + { + return result; + } + + // + period = value; + cMarketInputs.cycle.period = value; + sMarketInputs.cycle.period = value; + mMarketInputs.cycle.period = value; + lMarketInputs.cycle.period = value; + hMarketInputs.cycle.period = value; + + // + return result; + } + + // +}; + +// +// X121 Provider Market Conditions ... +class X121MarketConditions : public XSCBaseProviderMarketConditions +{ + // + // Public ... +public: + // + string symbol; // Symbol + ENUM_TIMEFRAMES period; // Period + datetime time; // Time + + // + X121MCycleConditions cMarketConditions; // Current Market Conditions + X121MCycleConditions sMarketConditions; // Short Market Conditions + X121MCycleConditions mMarketConditions; // Medium Market Conditions + X121MCycleConditions lMarketConditions; // Long Market Conditions + X121MCycleConditions hMarketConditions; // Hind Market Conditions + + // + // Tools ... + + // + // Cleanup ... + void Clear() + { + // + symbol = NULL; + period = NULL; + + // + cMarketConditions.Clear(); + sMarketConditions.Clear(); + mMarketConditions.Clear(); + lMarketConditions.Clear(); + hMarketConditions.Clear(); + } + + // + void GenerateScore( + double &bullishScore, // Bullish Score + double &bearishScore, // Bearish Score + double cMarketMultiplier = 1, // Current Market Score Multiplier + double sMarketMultiplier = 1.1, // Short Market Score Multiplier + double mMarketMultiplier = 1.2, // Medium Market Score Multiplier + double lMarketMultiplier = 1.3, // Long Market Score Multiplier + double hMarketMultiplier = 1.4 // Hind Market Score Multiplier + ) + { + // + // Current Market ... + double cMarketBullScore = 0; + double cMarketBearScore = 0; + cMarketConditions.GenerateScore( + cMarketBullScore, + cMarketBearScore, + cMarketMultiplier // + ); + + // + // Short Market ... + double sMarketBullScore = 0; + double sMarketBearScore = 0; + sMarketConditions.GenerateScore( + sMarketBullScore, + sMarketBearScore, + sMarketMultiplier // + ); + + // + // Medium Market ... + double mMarketBullScore = 0; + double mMarketBearScore = 0; + mMarketConditions.GenerateScore( + mMarketBullScore, + mMarketBearScore, + mMarketMultiplier // + ); + + // + // Long Market ... + double lMarketBullScore = 0; + double lMarketBearScore = 0; + lMarketConditions.GenerateScore( + lMarketBullScore, + lMarketBearScore, + lMarketMultiplier // + ); + + // + // Hind Market ... + double hMarketBullScore = 0; + double hMarketBearScore = 0; + hMarketConditions.GenerateScore( + hMarketBullScore, + hMarketBearScore, + hMarketMultiplier // + ); + + // + // Calculate Summary Scores ... + + // + bullishScore = + // + cMarketBullScore + + sMarketBullScore + + mMarketBullScore + + lMarketBullScore + + hMarketBullScore + // + ; + + // + bearishScore = + // + cMarketBearScore + + sMarketBearScore + + mMarketBearScore + + lMarketBearScore + + hMarketBearScore + // + ; + } + + // + string GenerateSummary( + double cMarketMultiplier = 1, // Current Market Score Multiplier + double sMarketMultiplier = 1.1, // Short Market Score Multiplier + double mMarketMultiplier = 1.2, // Medium Market Score Multiplier + double lMarketMultiplier = 1.3, // Long Market Score Multiplier + double hMarketMultiplier = 1.4, // Hind Market Score Multiplier + const string separator = "\n", // Separator + string provided = NULL, // Additional Info about Type, Provider and Symbol + const bool ignoreFalseConditions = true // Ignore False Conditions + ) + { + // + string result = NULL; + + // + double bullScore = 0; + double bearScore = 0; + GenerateScore( + bullScore, + bearScore, + cMarketMultiplier, + sMarketMultiplier, + mMarketMultiplier, + lMarketMultiplier, + hMarketMultiplier // + ); + + // + string commonStr = + // + "Commons: " + separator + + "-----------------------------" + separator + + "Symbol: " + symbol + separator + + "Period: " + ToString(period) + separator + + "Time: " + ToString(TimeCurrent()) + separator + + "-----------" + separator + + "Cycles: " + separator + + "-----------" + separator + + sMarketConditions.GetTitle() + separator + + mMarketConditions.GetTitle() + separator + + lMarketConditions.GetTitle() + separator + + hMarketConditions.GetTitle() + separator + + "Scores: " + separator + + "-----------" + separator + + "Bullish: " + ToString(bullScore) + separator + + "Bearish: " + ToString(bearScore) + separator + + "-----------------------------" + separator + + // + // TODO: Add Scores Later ... + separator + + "" + // + ; + + // + result = + // + "[" + GetToken() + "]" + separator + + (IsSpecifiedValid(provided) ? provided + separator : "") + + "-----------------------------" + separator + + commonStr + + "" + // + ; + + // + return result; + } +}; + +// +// Class ... + +// +// X121 Provider Class ... +class XSCX121Provider : public XSCBaseProvider +{ + // + // Public ... +public: + // + // Props ... + + // + XSCXCCHelper *ccHelper; // Candle Clear + XSCXCTHelper *ctHelper; // Candle Timer + XSCXZGHelper *zgHelper; // ZigZag Helper + XSCXPVHelper *pvHelper; // Peaks and Vales Helper + XSCXDONHelper *donHelper; // Donchain Helper; + + // + XSCX121Market *cMarket; // Current Market + XSCX121Market *sMarket; // Short Market + XSCX121Market *mMarket; // Medium Market + XSCX121Market *lMarket; // Long Market + XSCX121Market *hMarket; // Hind Market + + // + // Constructor ... + XSCX121Provider( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading PEriod + ) : XSCBaseProvider(symbol, period) + { + // + ccHelper = new XSCXCCHelper(); + ctHelper = new XSCXCTHelper(); + + // + // Instantiate Helpers Classes ... + zgHelper = new XSCXZGHelper(); + pvHelper = new XSCXPVHelper(); + donHelper = new XSCXDONHelper(); + + // + // Instantiate X121 Market Cycles Classes ... + cMarket = new XSCX121Market(); + sMarket = new XSCX121Market(); + mMarket = new XSCX121Market(); + lMarket = new XSCX121Market(); + hMarket = new XSCX121Market(); + + // + mNumberOfItems = 15; + } + + // + // Properties Gettr(s) / Setter(s) ... + + // + // Overrides ... + + // + // DeInit all Requirements ... + void DeInit() override + { + // + delete ccHelper; + delete ctHelper; + + // + delete zgHelper; + delete pvHelper; + delete donHelper; + + // + delete cMarket; + delete sMarket; + delete mMarket; + delete lMarket; + delete hMarket; + } + + // + // Functions ... + + // + // Init all Requirements ... + bool Init(X121ProviderInputs &inputs) + { + // + bool result = false; + + // + // Validate ... + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + string mSymbol = GetSymbol(); + ENUM_TIMEFRAMES mPeriod = GetPeriod(); + + // + // Init Indicators Helpers ... + + // + // CT ... + result = ctHelper + .Init( + mSymbol, + mPeriod, + mInputs.ctInputs + // + ); + if (!result) + { + return result; + } + + // + // CC ... + result = ccHelper + .Init( + mSymbol, + mPeriod, + mInputs.ccInputs + // + ); + if (!result) + { + return result; + } + + // + // ZigZag ... + result = zgHelper + .Init( + mSymbol, + mPeriod, + mInputs.zgInputs + // + ); + if (!result) + { + return result; + } + + // + // PV ... + result = pvHelper + .Init( + mSymbol, + mPeriod, + mInputs.pvInputs + // + ); + if (!result) + { + return result; + } + + // + // DON ... + result = donHelper + .Init( + mSymbol, + mPeriod, + mInputs.donInputs + // + ); + if (!result) + { + return result; + } + + // + // Initialize X121 Market Cycles ... + + // + // Current Market ... + result = cMarket + .Init(mInputs.cMarketInputs); + if (!result) + { + return result; + } + + // + // Short Market ... + result = sMarket + .Init(mInputs.sMarketInputs); + if (!result) + { + return result; + } + + // + // Medium Market ... + result = mMarket + .Init(mInputs.mMarketInputs); + if (!result) + { + return result; + } + + // + // Long Market ... + result = lMarket + .Init(mInputs.lMarketInputs); + if (!result) + { + return result; + } + + // + // Hind Market ... + result = hMarket + .Init(mInputs.hMarketInputs); + if (!result) + { + return result; + } + + // + return result; + } + + // + // Set Default Position's Type ... + // Enable / Disable Long (Buy), Short (Sell) ... + void SetSignalTypeState( + ENUM_POSITION_TYPE type, // Which types are Signals be Targetted + bool state // Which State is going to Set + ) + { + // + if (IsLong(type)) + { + mIsLongEnable = state; + } + else + { + mIsShortEnable = state; + } + } + + // + // Set Signal Providers ... + void SetSignalProviderState( + ENUM_X121_SIGNAL_PROVIDERS provider, // Provider State + bool state // Which state is going to set ... + ) + { + // + if (provider == NONE) + { + return; + } + + // + switch (provider) + { + // + case XSP: + mIsXSPSignalProviderEnable = state; + break; + + // + case XTEST: + mIsXTESTSignalProviderEnable = state; + break; + + // + case X786: + mIsX786SignalProviderEnable = state; + break; + + // + case X121: + mIsX121SignalProviderEnable = state; + break; + + // + case X110: + mIsX110SignalProviderEnable = state; + break; + + // + case X92: + mIsX92SignalProviderEnable = state; + break; + } + } + + // + void SetSignalProviderStates( + ENUM_X121_SIGNAL_PROVIDERS &providers[], // Collection of Providers ... + bool state // Which state is going to set ... + ) + { + // + int providersCount = ArraySize(providers); + if (providersCount <= 0) + { + return; + } + + // + for (int i = 0; i < providersCount; i++) + { + SetSignalProviderState(providers[i], state); + } + } + + // + string GetTag() + { + // + string result = NULL; + + // + result = + // + GetToken() + + "[" + + GetSymbol() + + "," + + ToString(GetPeriod()) + + "]" + // + ; + + // + return result; + } + + // + void GetMarketConditions( + X121MarketConditions &mConditions, // Market Conditions Result + int barIndex = 0 // Specified Bar Index + ) + { + // + mConditions.Clear(); + + // + CalculateConditions(mConditions, barIndex); + } + + // + // Check Market For Signal ... + bool HasSignal( + int barIndex, + XSignal &mSignal, // Hold's Signal if Exists ... + X121MarketConditions &mConditions // Hold's Market Conditions ... + ) + { + // + bool result = false; + + // + // Validate Enable Process ... + result = !CanIgnoreProcess(); + if (!result) + { + return result; + } + + // + mWaitsUntilNewBar = false; + + // + // Validate Enable Type of Signalling ... + result = mIsLongEnable || mIsShortEnable; + if (!result) + { + return result; + } + + // + // Now we Have to Pass the Conditions to Each Signal Provider + // for Retrieving Signals Based On them ... + + // + // Reading Market Conditions ... + GetMarketConditions(mConditions, barIndex); + // string mConditionsStr = mConditions.GenerateSummary(); + // Print(mConditionsStr); + + // + int signalPusher = 0; + bool hasLong = false; + bool hasShort = false; + string provider = ""; + + // + // Long ... + if (mIsLongEnable) + { + // + signalPusher = 0; + + // + hasLong = HasSpecificSignal( + barIndex, + POSITION_TYPE_BUY, + provider, + signalPusher, + mConditions // + ); + } + + // + // Short ... + if (mIsShortEnable) + { + // + signalPusher = 0; + + // + hasShort = HasSpecificSignal( + barIndex, + POSITION_TYPE_SELL, + provider, + signalPusher, + mConditions // + ); + } + + // + result = hasLong || hasShort; + if (!result) + { + return result; + } + + // + // Prepare Signal ... + + // + if (result) + { + // + // Here We Have to Prepare Signal ... + + // + // TODO: Make this Configurable ... + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + double tpPoint = 30; + double volume = 0.01; + double tpPrice = PointToPrice( + tpPoint, + symbol // + ); + ENUM_POSITION_TYPE type = hasLong + ? POSITION_TYPE_BUY + : POSITION_TYPE_SELL; + ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET; + double entry = GetEntry( + symbol, + type // + ); + double tp = hasLong + ? entry + tpPrice + : entry - tpPrice; + double sl = 0; + ENUM_X_SIGNAL_MANAGING_ACTIONS action = X_SIGNAL_USE_NOTHING; + + // + result = mSignal.Prepare( + symbol, + provider, + period, + type, + mode, + entry, + volume, + action, + sl, + tp + // + ); + + // + if (result) + { + // + mWaitsUntilNewBar = true; + + // // + // TODO: + // string providerTypeStr = GetSymbol() + ", " + provider + "(" + (hasLong ? "Long" : "Short") + ")"; + // string mConditionsStr = mConditions.GenerateSummary(providerTypeStr, true); + // mConditionsCollector.Add(mConditionsStr); + // Print(mConditionsStr); + } + } + + // + return result; + } + + // + void Draw() + { + // + // ulong chID = 0; + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + ulong chID = FindChartID( + symbol, + period); + if (chID < 0) + { + return; + } + + // + int subWindow = 0; + + // + int offset = 0; + + // + cMarket.Draw(chID, subWindow, offset); + sMarket.Draw(chID, subWindow, offset); + mMarket.Draw(chID, subWindow, offset); + lMarket.Draw(chID, subWindow, offset); + hMarket.Draw(chID, subWindow, offset); + } + + // + // Protected ... +protected: + // + X121ProviderInputs mInputs; + + // + // Private ... +private: + // + // Props ... + + // + int mNumberOfItems; // Number of Buffer Ites Read in Conditions ... + + // + // Signallers ... + + // + bool mIsLongEnable; + bool mIsShortEnable; + + // + bool mIsXSPSignalProviderEnable; + bool mIsX92SignalProviderEnable; + bool mIsX786SignalProviderEnable; + bool mIsX121SignalProviderEnable; + bool mIsX110SignalProviderEnable; + bool mIsXTESTSignalProviderEnable; + + // + // + // Detect Signal ... + bool HasSpecificSignal( + int barIndex, // Specified Bar Index ... + ENUM_POSITION_TYPE mType, // Specific Signal Type ... + string &provider, // Signal Provider ... + int &signalPusher, // Number Of Same Time Signals ... + X121MarketConditions &mConditions // Specified Market Conition ... + ) + { + // + bool result = false; + + // + // Validate Signal Type is Enables ... + bool isLong = IsLong(mType); + result = + (isLong && mIsLongEnable) || + (!isLong && mIsShortEnable); + if (!result) + { + return result; + } + + // + // Now we have to Filter based on Enabled Signal Providers ... + + // + // Long ... + if (isLong && mIsLongEnable) + { + // + XSignal lSignal; + + // + signalPusher = 0; + + // + bool hasXSPSignal = false; + bool hasXTESTSignal = false; + bool hasX786Signal = false; + bool hasX121Signal = false; + bool hasX110Signal = false; + bool hasX92Signal = false; + + // + // XPS ... + if (mIsXSPSignalProviderEnable) + { + // + hasXSPSignal = XSPHasSpecifiedLongSignal( + mConditions // + ); + + // + if (hasXSPSignal) + { + // + if (!IsValid(provider)) + { + provider = ToString(XSP); + } + + // + signalPusher++; + } + } + + // + // XTEST ... + if (mIsXTESTSignalProviderEnable) + { + // + hasXTESTSignal = XTESTHasSpecifiedLongSignal( + mConditions // + ); + + // + if (hasXTESTSignal) + { + // + if (!IsValid(provider)) + { + provider = ToString(XTEST); + } + + // + signalPusher++; + } + } + + // + // X786 ... + if (mIsX786SignalProviderEnable) + { + // + hasX786Signal = X786HasSpecifiedLongSignal( + mConditions // + ); + + // + if (hasX786Signal) + { + // + if (!IsValid(provider)) + { + provider = ToString(X786); + } + + // + signalPusher++; + } + } + + // + // X121 ... + if (mIsX121SignalProviderEnable) + { + // + hasX121Signal = XSIHasSpecifiedLongSignal( + mConditions // + ); + + // + if (hasX121Signal) + { + // + if (!IsValid(provider)) + { + provider = ToString(X121); + } + + // + signalPusher++; + } + } + + // + // X110 ... + if (mIsX110SignalProviderEnable) + { + // + hasX110Signal = XTSFIHasSpecifiedLongSignal( + mConditions // + ); + + // + if (hasX110Signal) + { + // + if (!IsValid(provider)) + { + provider = ToString(X110); + } + + // + signalPusher++; + } + } + + // + // X92 ... + if (mIsX92SignalProviderEnable) + { + // + hasX92Signal = XOBDLHHasSpecifiedLongSignal( + mConditions // + ); + + // + if (hasX92Signal) + { + // + if (!IsValid(provider)) + { + provider = ToString(X92); + } + + // + signalPusher++; + } + } + + // + result = + // + hasXSPSignal + // + || + // + hasXTESTSignal + // + || + // + hasX786Signal + // + || + // + hasX121Signal + // + || + // + hasX110Signal + // + || + // + hasX92Signal + // + ; + + // + if (result) + { + return result; + } + } + + // + // Short ... + if (!isLong && mIsShortEnable) + { + // + XSignal sSignal; + + // + signalPusher = 0; + + // + bool hasXSPSignal = false; + bool hasXTESTSignal = false; + bool hasX786Signal = false; + bool hasX121Signal = false; + bool hasX110Signal = false; + bool hasX92Signal = false; + + // + // XSP ... + if (mIsXSPSignalProviderEnable) + { + // + hasXSPSignal = XSPHasSpecifiedShortSignal( + mConditions // + ); + + // + if (hasXSPSignal) + { + // + if (!IsValid(provider)) + { + provider = ToString(XSP); + } + + // + signalPusher++; + } + } + + // + // XTEST ... + if (mIsXTESTSignalProviderEnable) + { + // + hasXTESTSignal = XTESTHasSpecifiedShortSignal( + mConditions // + ); + + // + if (hasXTESTSignal) + { + // + if (!IsValid(provider)) + { + provider = ToString(XTEST); + } + + // + signalPusher++; + } + } + + // + // X786 ... + if (mIsX786SignalProviderEnable) + { + // + hasX786Signal = X786HasSpecifiedShortSignal( + mConditions // + ); + + // + if (hasX786Signal) + { + // + if (!IsValid(provider)) + { + provider = ToString(X786); + } + + // + signalPusher++; + } + } + + // + // X121 ... + if (mIsX121SignalProviderEnable) + { + // + hasX121Signal = XSIHasSpecifiedShortSignal( + mConditions // + ); + + // + if (hasX121Signal) + { + // + if (!IsValid(provider)) + { + provider = ToString(X121); + } + + // + signalPusher++; + } + } + + // + // X110 ... + if (mIsX110SignalProviderEnable) + { + // + hasX110Signal = XTSFIHasSpecifiedShortSignal( + mConditions // + ); + + // + if (hasX110Signal) + { + // + if (!IsValid(provider)) + { + provider = ToString(X110); + } + + // + signalPusher++; + } + } + + // + // X92 ... + if (mIsX92SignalProviderEnable) + { + // + hasX92Signal = X92HasSpecifiedShortSignal( + mConditions // + ); + + // + if (hasX92Signal) + { + // + if (!IsValid(provider)) + { + provider = ToString(X92); + } + + // + signalPusher++; + } + } + + // + result = + // + hasXSPSignal + // + || + // + hasXTESTSignal + // + || + // + hasX786Signal + // + || + // + hasX121Signal + // + || + // + hasX110Signal + // + || + // + hasX92Signal + // + ; + + // + if (result) + { + return result; + } + } + + // + return result; + } + + // + void CalculateConditions( + X121MarketConditions &mConditions, // Market Conditions Result + int barIndex = 0 // Specified Bar Index + ) { + // +// cMarket +// sMarket +// mMarket +// lMarket +// hMarket + } + + // + // Signalling based On Signallers ... + + // + // XSP ... + + // + bool XSPHasSpecifiedLongSignal( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + return result; + } + + // + bool XTESTHasSpecifiedLongSignal( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + return result; + } + + // + bool X786HasSpecifiedLongSignal( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + return result; + } + + // + bool XSIHasSpecifiedLongSignal( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + return result; + } + + // + bool XTSFIHasSpecifiedLongSignal( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + return result; + } + + // + bool XOBDLHHasSpecifiedLongSignal( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + return result; + } + + // + bool XSPHasSpecifiedShortSignal( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + return result; + } + + // + bool XTESTHasSpecifiedShortSignal( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + return result; + } + + // + bool X786HasSpecifiedShortSignal( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + return result; + } + + // + bool XSIHasSpecifiedShortSignal( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + return result; + } + + // + bool XTSFIHasSpecifiedShortSignal( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + return result; + } + + // + bool X92HasSpecifiedShortSignal( + X121MarketConditions &mConditions // + ) + { + // + bool result = false; + + // + return result; + } + + // +}; + +// +// Tools ... + +// +// Model Provider Descriptor ... +struct X121ProviderDescriptor +{ + // + string symbol; // Trading Symbol + ENUM_TIMEFRAMES period; // Trading Timeframe + bool allowLong; // Allow Long Signals + bool allowShort; // Allow Short Signals + ENUM_X121_SIGNAL_PROVIDERS signallers[]; // Allowed Signal Providers + + // + X121ProviderInputs inputs; + XSCX121Provider *provider; + + // + XSignal signal; + X121MarketConditions conditions; + + // + // Tools ... + + // + bool Init() + { + // + bool result = false; + + // + result = this.Init( + this.symbol, + this.period, + this.signallers, + this.allowLong, + this.allowShort // + ); + + // + return result; + } + + // + bool Init( + ENUM_X121_SIGNAL_PROVIDERS &mSignallers[], // Allowed Signal Providers + bool mAllowLong = true, // Allow Long Signals + bool mAllowShort = true // Allow Short Signals + ) + { + // + bool result = false; + + // + result = this.Init( + this.symbol, + this.period, + mSignallers, + mAllowLong, + mAllowShort // + ); + + // + return result; + } + + // + bool Init( + string mSymbol, // Trading Symbol + ENUM_TIMEFRAMES mPeriod, // Trading Timeframe + ENUM_X121_SIGNAL_PROVIDERS &mSignallers[], // Allowed Signal Providers + bool mAllowLong = true, // Allow Long Signals + bool mAllowShort = true // Allow Short Signals + ) + { + // + bool result = false; + + // + result = + // + inputs.IsValid() && + IsValid(mSymbol) && + IsValid(mPeriod) && + (allowLong || allowShort) && + ArraySize(mSignallers) > 0 + // + ; + if (!result) + { + return result; + } + + // + this.symbol = mSymbol; + this.period = mPeriod; + this.allowLong = mAllowLong; + this.allowShort = mAllowShort; + + // + ENUM_X121_SIGNAL_PROVIDERS tmp[]; + Copy( + mSignallers, + tmp // + ); + Copy( + tmp, + this.signallers // + ); + + // + // Instantiate Provider ... + provider = new XSCX121Provider( + this.symbol, + this.period // + ); + + // + // Set Long/Short State ... + + // + provider + .SetSignalTypeState( + POSITION_TYPE_BUY, + this.allowLong // + ); + + // + provider + .SetSignalTypeState( + POSITION_TYPE_SELL, + this.allowShort // + ); + + // + // Enable Required Signallers ... + provider + .SetSignalProviderStates( + this.signallers, + true // + ); + + // + // Now Must to Initialize Provider ... + result = provider.Init( + this.inputs // + ); + + // + return result; + } + + // + // Cleanup ... + void Clean() + { + // + signal.Clean(); + conditions.Clear(); + } + + // + // Validate ... + bool IsValid(bool validateInputs = true) + { + // + bool result = false; + + // + result = + // + IsValid(symbol) && + IsValid(period) && + (validateInputs + ? inputs.IsValid() + : true) && + (allowLong || allowShort) && + ArraySize(signallers) > 0 + // + ; + + // + return result; + } + + // + // Check Signal ... + bool HasSignal(int barIndex = 0) + { + // + bool result = false; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + // Clear Signal and Conditions ... + Clean(); + + // + result = provider.HasSignal( + barIndex, + signal, + conditions // + ); + + // + return result; + } +}; + +// +void GetAllX121SignalProviders(ENUM_X121_SIGNAL_PROVIDERS &result[]) +{ + // + Clean(result); + + // + Add(NONE, result); + Add(XSP, result); + Add(XTEST, result); + Add(X786, result); + Add(X121, result); + Add(X110, result); + Add(X92, result); +} + +// +string ToString(ENUM_X121_SIGNAL_PROVIDERS value) +{ + return EnumToString(value); +} + +// +ENUM_X121_SIGNAL_PROVIDERS ToX121SignalProvider(string content) +{ + // + ENUM_X121_SIGNAL_PROVIDERS result = NONE; + + // + if (!IsValid(content)) + { + return result; + } + + // + if (content == ToString(NONE)) + { + result = NONE; + } + else if (content == ToString(XSP)) + { + result = XSP; + } + else if (content == ToString(XTEST)) + { + result = XTEST; + } + else if (content == ToString(X786)) + { + result = X786; + } + else if (content == ToString(X121)) + { + result = X121; + } + else if (content == ToString(X110)) + { + result = X110; + } + else if (content == ToString(X92)) + { + result = X92; + } + + // + return result; +} + +// \ No newline at end of file diff --git a/Classes/x-saherelm.x121.xea.class.mq5 b/Classes/x-saherelm.x121.xea.class.mq5 new file mode 100644 index 00000000..dfffb7a9 --- /dev/null +++ b/Classes/x-saherelm.x121.xea.class.mq5 @@ -0,0 +1,329 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCX121EA +// Description: provides all X121 EA requirements ... +// - X5 Provider; +// +// +// 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 + +// +// Imports ... +#include "../Classes/x-saherelm.xea.class.mq5" +#include "../Classes/x-saherelm.x121.provider.class.mq5" + +// +// Define On Signal Event Handler Type Specified for X5 ... +typedef void (*TX121OnSignal)(X121ProviderDescriptor &descriptor); + +// +// Class Definition ... + +class XSCX121EA : public XSCBaseEA +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCX121EA( + // + // XTrade Class Requirements ... + int slippage, // Specify Slippage + ulong magicNumber, // Specify Magic Number + int manageInterval, // Manager Check Intervals Seconds + double maxAllowedSpread, // Max Allowed Spred for Opening Trades + int maxAllowedPositions, // Max Allowed Positions + double maxAllowedDrawdownFactor, // Max Allowed Drawdown Factor + // + // Position Management ... + bool allowLong = true, // Allow Long Trades + bool allowShort = true, // Allow Short Trades + double minProfitPerTrade = 0, // Min Profit Per Trade based On Volume Factor (Hedge) + double minProfitPerVolumeFactor = 0, // Min Volume Factor for Calculating Profit (Hedge) + // + // Event Handlers ... + TOnStopLoss onStopLossTriggered = NULL, // On StopLoass Triggered Event Handler + TOnTakeProfit onTakeProfitTriggered = NULL, // On TakeProfit Triggered Event Handler + TOnDealsChanged onDealsChangedHandler = NULL, // On Deals Changed Event Handler + TOnOrdersChanged onOrdersChangedHandler = NULL, // On Orders Changed Event Handler + TOnPositionsChanged onPositionsChangedHandler = NULL, // On Positions Changed Event Handler + TOnTradeStateChanged onTradeStateChangedHandler = NULL, // On Trade State Changed Event Handler + // + TOnSignal onSignalHandler = NULL, // On Signal Event Handler + // + // Log Handler ... + bool enableAlerts = true, // Enable Alerts + bool logAlerts = true, // Log Alerts + bool terminalAlerts = false, // Terminal Alerts + bool mailAlerts = false, // Mail Alerts + bool pushAlerts = false // Push Alerts + ) : XSCBaseEA(slippage, + magicNumber, + manageInterval, + maxAllowedSpread, + maxAllowedPositions, + maxAllowedDrawdownFactor, + allowLong, + allowShort, + minProfitPerTrade, + minProfitPerVolumeFactor, + onStopLossTriggered, + onTakeProfitTriggered, + onDealsChangedHandler, + onOrdersChangedHandler, + onPositionsChangedHandler, + onTradeStateChangedHandler, + enableAlerts, + logAlerts, + terminalAlerts, + mailAlerts, + pushAlerts // + ) + { + } + + // + // Deconstructor ... + ~XSCX121EA() {} + + // + // Properties Getter(s) / Setter(s) ... + + // + // Add X5 Specified Signal Event Handler ... + void AddOnSignalEventHandler(TX121OnSignal listener) + { + // + Add( + listener, + mX121OnSignalEventHandlers + // + ); + } + + // + // Add Specified X5 Provider ... + bool AddProvider(X121ProviderDescriptor &descriptor) + { + // + bool result = false; + + // + // Validate Inputs ... + result = descriptor.Init(); + if (!result) + { + return result; + } + + // + AddRef( + descriptor, + mDescriptors // + ); + + // + return result; + } + + // + // Overrides ... + + // + // Customize Token ... + string GetToken() override + { + return GetSpecificToken(this); + } + + // + string GetTag() override + { + return this.GetToken(); + } + + // + void Draw() override + { + // + int descriptorsCount = CountDescriptors(); + if (descriptorsCount <= 0) + { + return; + } + + // + for (int i = 0; i < descriptorsCount; i++) + { + // + X121ProviderDescriptor iDescriptor = mDescriptors[i]; + + // + iDescriptor.provider.Draw(); + } + } + + // + // Check Provider for any Guards ... + bool CheckForGuard(XGuard &guards[]) override + { + // + // TODO: Implement this ... + return false; + } + + // + // Request Provider to Collect all + // Potentially Signals and then + // filters theme here and passed them + // for Executing ... + int RequestForSignal( + XSignal &signals[] // Holds Signals ... + ) override + { + // + bool result = 0; + + // + Clean(signals); + + // + int descriptorsCount = CountDescriptors(); + if (descriptorsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < descriptorsCount; i++) + { + // + X121ProviderDescriptor iDescriptor = mDescriptors[i]; + + // + bool iHasSignal = iDescriptor.HasSignal(); + if (iHasSignal) + { + // + // Here we Can double check Signals by Conditions + // for Score Base Filtering ... + + // + AddRef( + iDescriptor.signal, + signals + // + ); + + // + NotifyX121OnSignalEventHandlers(iDescriptor); + } + } + + // + result = ArraySize(signals); + + // + return result; + } + + // + // Handl Management Actions ... + // if returns true, it is going to prevent for processing forward ... + bool HandleStateManagement() override + { + // + // TODO: Implement this ... + return false; + } + + // + // Request for Support Signals using Guard ... + bool RequestForSupport( + XSignal &support, // Holds Support Signal, if Provided + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period // Specified Time Frame + ) override + { + // + // TODO: Implement this ... + return false; + } + + // + // Tools ... + + // + // Protected ... +protected: + // + // Tools ... + + // + void NotifyX121OnSignalEventHandlers(X121ProviderDescriptor &descriptor) + { + // + int listenersCount = ArraySize(mX121OnSignalEventHandlers); + if (listenersCount <= 0) + { + return; + } + + // + for (int i = 0; i < listenersCount; i++) + { + // + TX121OnSignal iListener = mX121OnSignalEventHandlers[i]; + + // + iListener(descriptor); + } + } + + // + // Private ... +private: + // + // Props ... + + // + // Collection of Signal Event Listeners ... + TX121OnSignal mX121OnSignalEventHandlers[]; + + // + // a Collection of X5 Provider Descriptors ... + X121ProviderDescriptor mDescriptors[]; + + // + int CountDescriptors() + { + return ArraySize(mDescriptors); + } + + // + // Tools ... +}; + +// +// Tools ... + +// \ No newline at end of file diff --git a/Classes/x-saherelm.x121.xmcycle.class.mq5 b/Classes/x-saherelm.x121.xmcycle.class.mq5 new file mode 100644 index 00000000..b229a443 --- /dev/null +++ b/Classes/x-saherelm.x121.xmcycle.class.mq5 @@ -0,0 +1,3399 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSC121MCycle +// Description: provides all requirements for +// Handling Specified Market Cycle Analysis... +// +// +// 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 + +// +// Imports ... + +// +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +#include "../Helpers/x-saherelm.xmc.helper.mq5" +#include "../Helpers/x-saherelm.xche.helper.mq5" +#include "../Helpers/x-saherelm.xosc.helper.mq5" +#include "../Helpers/x-saherelm.xstr.helper.mq5" +#include "../Helpers/x-saherelm.xich.helper.mq5" + +// +#include "../Classes/x-saherelm.xprovider.class.mq5" + +// +// Definitions ... + +// +// X121 Specified Market Cycle Structure ... +class X121MCycleInputs : public XSCBaseProviderInpts +{ + // + // Public ... +public: + // + // Props ... + + // + XMarketCycle cycle; // Cycle Descriptor ... + + // + // Draw Props ... + + // + XDrawSpecifications cBarMidDrawSpecs; // Current Bar MidLine Draw Specifications + XOHCLDrawSpecification cBarDrawSpecs; // Current Bar Draw Specifications + + // + XDrawSpecifications pBarMidDrawSpecs; // Previous Bar MidLine Draw Specifications + XOHCLDrawSpecification pBarDrawSpecs; // Previous Bar Draw Specifications + + // + bool drawLabels; // Draw Labels + bool drawCBar; // Draw Current Bar + bool drawPBar; // Draw Previous Bar + bool drawCBarMid; // Draw Current Bar Mid Line + bool drawPBarMid; // Draw Previous Bar Mid Line + + // + XMCInputs mcInputs; // MC Inputs ... + XSTRInputs strInputs; // STR Inputs ... + XOSCInputs oscInputs; // OSC Inputs ... + XCHEInputs cheInputs; // CHE Inputs ... + XICHInputs ichInputs; // ICH Inputs ... + + // + // Constructor ... + + // + // Tools ... + + // + // Initialize Market Cycle ... + bool Init( + string mSymbol, // Trading Symbol + ENUM_TIMEFRAMES mHostPeriod, // Host Period + ENUM_X_MARKET_CYCLES mCycle, // Init Cycle + ENUM_TIMEFRAMES mPeriod, // Cycle Period + ENUM_X_PERIOD_METHOD mPeriodMethod, // Cycle Period Method + string mPrefix = "", // Prefix + bool useDefaults = true // Use Inputs Default Settings ... + ) + { + // + bool result = false; + + // + cycle.period = mPeriod; + cycle.method = mPeriodMethod; + + // + // Initial Cycle Model ... + result = cycle.Init( + mSymbol, + mHostPeriod, + mCycle, + mPrefix + // + ); + if (!result) + { + return result; + } + + // + if (useDefaults) + { + // + mcInputs.Default(); + strInputs.Default(); + oscInputs.Default(); + cheInputs.Default(); + ichInputs.Default(); + } + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + return result; + } + + // + // Initialize Market Cycle ... + bool Init( + string mSymbol, // Trading Symbol + ENUM_TIMEFRAMES mHostPeriod, // Host Period + ENUM_X_MARKET_CYCLES mCycle, // Init Cycle + XMCInputs &mMcInputs, // MC Inputs + XSTRInputs &mStrInputs, // STR Inputs + XOSCInputs &mOscInputs, // OSC Inputs + XCHEInputs &mCheInputs, // CHE Inputs + int mHostBarIndex = 0, // Specified Host Period Bar Index + string mPrefix = "" // Prefix + ) + { + // + bool result = false; + + // + // Initial Cycle Model ... + result = cycle.Init( + mSymbol, + mHostPeriod, + mCycle, + mPrefix + // + ); + if (!result) + { + return result; + } + + // + mcInputs = mMcInputs; + strInputs = mStrInputs; + oscInputs = mOscInputs; + cheInputs = mCheInputs; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + return result; + } + + // + // Cleanup ... + virtual void Clean() + { + // + cycle.Clean(); + + // + mcInputs.Clean(); + strInputs.Clean(); + oscInputs.Clean(); + cheInputs.Clean(); + ichInputs.Clean(); + + // + cBarDrawSpecs.Clean(); + pBarDrawSpecs.Clean(); + cBarMidDrawSpecs.Clean(); + pBarMidDrawSpecs.Clean(); + + // + drawLabels = false; + drawCBar = false; + drawPBar = false; + drawCBarMid = false; + drawPBarMid = false; + } + + // + // Default ... + virtual void Default() + { + // + mcInputs.Default(); + strInputs.Default(); + oscInputs.Default(); + cheInputs.Default(); + ichInputs.Default(); + + // + drawLabels = false; + drawCBar = false; + drawPBar = false; + drawCBarMid = false; + drawPBarMid = false; + } + + // + // Validation ... + virtual bool IsValid() + { + // + bool result = false; + + // + result = cycle.IsValid(); + if (!result) + { + return result; + } + + // + result = mcInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = strInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = oscInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = cheInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = ichInputs.IsValid(); + if (!result) + { + return result; + } + + // + return result; + } + + // + // Max ... + virtual int Max() + { + // + int result = 0; + + // + result = MathMax(mcInputs.Max(), strInputs.Max()); + + // + result = MathMax(result, oscInputs.Max()); + result = MathMax(result, cheInputs.Max()); + result = MathMax(result, ichInputs.Max()); + + // + return result; + } +}; + +// +// Specific Market Sense Based on Specified Bar Index on Host Period ... +class X121MCycleConditions : public XSCBaseProviderMarketConditions +{ + // + // Public ... +public: + // + // Props ... + + // + // Common ... + string prefix; // Cycle Prefix ... + string symbol; // Analysing Symbol ... + ENUM_TIMEFRAMES period; // Analysing Time Frame ... + ENUM_TIMEFRAMES hostPeriod; // Hosting Time Frame ... + ENUM_X_MARKET_CYCLES cycle; // Init Cycle ... + + // + datetime time; // Extracting Time ... + + // + // Candlestic Conditions ... + bool isLastBullish; + bool isLastBearish; + bool isCurrentBullish; + bool isCurrentBearish; + bool isCurrentMidLineOverLastHigh; + bool isCurrentMidLineUnderLastLow; + bool isCurrentMidLineOverLastUp; + bool isCurrentMidLineUnderLastDown; + bool isCurrentMidLineOverLastMidLine; + bool isCurrentMidLineUnderLastMidLine; + + // + // Buffers ... + + // + // XICH ... + double ichTenkanSens[]; + double ichKijunSens[]; + double ichChikouSpans[]; + double ichSenkouSpanAs[]; + double ichSenkouSpanBs[]; + + // + // XMC ... + double mcFasts[]; + double mcSlows[]; + double mcVerifiers[]; + + // + // XSTR ... + double strTrends[]; + double strStates[]; + + // + // XCHE ... + double cheLongExit1s[]; + double cheLongExit2s[]; + double cheShortExit1s[]; + double cheShortExit2s[]; + + // + // XOSC ... + double oscAtrs[]; + double oscRviMains[]; + double oscRviSignals[]; + double oscBullPs[]; + double oscBearPs[]; + double oscVolumes[]; + double oscRsis[]; + double oscCcis[]; + double oscMomentums[]; + double oscSars[]; + double oscMacdMains[]; + double oscMacdSignals[]; + double oscStochMains[]; + double oscStochSignals[]; + double oscStddevs[]; + + // + // XICH ... + // Ichimoku strategy + // Strategy one: Ichimoku trend identifier: + // According to this strategy, we need a trigger that can be used + // to inform us about the trend type, + // if it is an uptrend or downtrend. + // We will check three values to do that and these values are the: + // closing price, Senkou Span A, and Senkou Span B. + // If the closing price is greater than the Senkou Span B and at the same time + // the closing price is greater than Senkou Span A, + // this will be the trigger to know that the trend is up. + // Vice versa, if the closing price is lower than the Senkou Span B and at the same time + // the closing price is lower than the Senkou Span A, + // this will be the trigger to the downtrend. + // + // Closing price > Senkou Span B and closing price > Senkou Span A --> Uptrend + // Closing price < Senkou Span B and closing price < Senkou Span A --> Downtrend + // + // Strategy two: Ichimoku trend strength: + // Based on this strategy, we need a trigger that can inform us the current trend is strong. + // We will check three values to do that and these values are the: + // - current Senkou Span A, + // - the previous Senkou Span A, and + // - the Senkou Span B. + // If the current Senkou Span A is greater than the previous Senkous Span A and at the same time + // the current Senkou Span A is greater than the Senkou Span B, + // this is a trigger that the trend is up and strong. + // Vice versa, if the current Senkou Span A is lower than the previous Senkou Span A and at the + // same time, the current Senkou Span A is lower than the Senkou Span B, + // this will be a signal that the trend is down and strong. + // + // Current Senkou Span A > previous Senkou Span A and current Senkou Span A > Senkou Span B --> the uptrend is strong + // Current Senkou Span A < previous Senkou Span A and current Senkou Span A < Senkou Span B --> the downtrend is strong + bool isSenkouSpanAOverB; + bool isSenkouSpanAUnderB; + bool isSenkouSpanAOverLast; + bool isSenkouSpanAUnderLast; + bool isFutureSenkouSpanAOverB; + bool isFutureSenkouSpanAUnderB; + bool isFutureSenkouSpanAOverLast; + bool isFutureSenkouSpanAUnderLast; + // + // Strategy three: Ichimoku price-Ki signal: + // According to this strategy, during the uptrend, we need a trigger that can + // alert us about the bullish signal, and during the downtrend, we need a trigger than can alert us about the bearish signal. + // We will check based on this strategy two values, closing price, and Kijun-Sen. + // If the closing price is greater than the Kijun-sen value, + // this will be a trigger to a bullish signal. + // Vice versa, if the closing price is lower than the Kijun-sen value, + // this will be a bearish signal. + // + // During uptrend, closing price > Kijun -sen --> bullish signal + // Duuring downtrend, closing price < Kijun -sen --> bearish signal + bool isCloseOverKijunSen; + bool isCloseUnderKijunSen; + // + // Strategy four: Ichimoku ten-ki signal: + // According to this strategy, during the uptrend, we need another trigger or + // method to alert us when there is a bullish signal or + // during the downtrend, we need a signal of bearishness. + // We will check based on this strategy two values, Tenkan-sen and Kijum-sen. + // If the Tenkan-sen value is greater than the Kijun-sen, + // this will be a signal of bullishness. + // Vice versa, if the Tenkan-sen is lower than the Kijun-sen, + // this will be a signal of bearishness. + // + // Tenkan-sen > Kijun-sen --> bullish signal + // Tenkan-sen < Kijun-sen --> bearish signal + bool isTenkanSenOverKijunSen; + bool isTenkanSenUnderKijunSen; + + // + // XMC ... + // Three Moving Averages Crossover + // In this strategy, we will use three simple moving averages: + // the shorter simple moving average period is 10, the longer one period is 48, and in between a period of 24. + // + // According to the strategy, we need the three simple moving averages to be checked at every tick: + // + // If 10 SMA > 24 SMA, 10 SMA > 48 SMA, and 24 SMA > 48 SMA: the signal will be to buy and we need to be appeared as a comment on the chart. + // If 10 SMA < 24 SMA, 10 SMA < 48 SMA, and 24 SMA < 48 SMA: the signal will be to sell and we need to be appeared as a comment on the chart. + // If anything, else do nothing. + bool isFastOverSlow; + bool isFastUnderSlow; + bool isFastOverVerifier; + bool isFastUnderVerifier; + bool isSlowOverVerifier; + bool isSlowUnderVerifier; + bool isCloseOverFast; + bool isCloseUnderFast; + bool isCloseOverSlow; + bool isCloseUnderSlow; + bool isCloseOverVerifier; + bool isCloseUnderVerifier; + + // + // XSTR ... + bool isTrendBullish; + bool isTrendBearish; + + // + // XCHE ... + bool isCHEInLong; + bool isCHEInStrongLong; + bool isCHEInShort; + bool isCHEInStrongShort; + + // + // XOSC ... + + // + // RVI Signals ... + // Strategy one: RVI Crossover - Uptrend: + // Based on this strategy, we need to get buy and close signals during the uptrend by a specific condition. + // When the RVI current value and RVI signal current value are greater than the zero level at the same time + // that RVI current value is greater than the current value of the RVI signal, this will be a buy signal. + // Vice Versa, when the RVI current value and RVI signal current value is below zero level at + // the same time that the RVI current value is below the current value of the RVI signal, this will be a close signal. + // + // RVI value > 0 and RVI signal value > 0 and RVI value > RVI signal value --> buy + // RVI value < 0 and RVI signal value < 0 and RVI value < RVI signal value --> close + bool isRVILongStart; + bool isRVILongStop; + // + // Strategy two: RVI Crossover - Downtrend: + // Based on this strategy, we need to get the opposite signals of the previous RVI Crossover - + // Uptrend strategy as we need to get short and cover signals. + // When the RVI current value and RVI signal current value are lower than the zero level at + // the same time that RVI current value is lower than the current value of the RVI signal, this will be a short signal. + // Vice Versa, when the RVI current value and RVI signal current value is above the zero level + // at the same time that the RVI current value is above the current value of the RVI signal, this will be a cover signal. + // + // RVI value < 0 and RVI signal value < 0 and RVI value < RVI signal value --> short + // RVI value > 0 and RVI signal value > 0 and RVI value > RVI signal value --> cover + bool isRVIShortStart; + bool isRVIShortStop; + // + // Strategy three: RVI and MA Crossover + // Based on this strategy, we need to get buy and sell signals based on specific conditions + // as we need to get a + // buy signal + // when the closing price is greater than the 100 -period moving average + // at the same time that the current RVI value is greater than the current RVI signal value. + // In the other scenario, we need to get a + // sell signal + // when the closing price is lower than the 100 -period moving average + // at the same time that the current RVI value is lower than the current RVI signal value. + + // + // RSI strategy ... + // During Uptrend + // In this case, most of the time RSI values move between or moving between + // the mid range and level 70 (Overbought level). + // The trading strategy for the uptrend is: + // + // RSI Value < 50 = Buy + // RSI Value > 70 = Take Profit + bool isRSIUnder50; + bool isRSIOver70; + // + // During Downtrend + // During the downtrend, the RSI moves most of the time between + // the mid range and level 30 (Oversold level). + // The trading strategy will be as follows: + // + // RSI Value > 50 = Short + // RSI Value < 30 = Take Profit + bool isRSIOver50; + bool isRSIUnder30; + // + // During Sideways: + // RSI spends most of the time between levels 30 (Oversold level) and 70 (Oversbought level). + // The trading strategy will be as follows: + // RSI Value < 30 = Buy + // RSI Value > 50 = Take Profit + // RSI Value > 70 = Short + // RSI Value < 50 = Take Profit + + // + // Bull's Power strategy: + // In this part, we will learn how we can use Bull's Power through simple strategies + // that can be used based on the basic concept of this indicator. + // The following are for these strategies and their conditions. + // I need to confirm here, that these strategies for education only as the main objective + // is to understand the main concept behind the indicator and how we can use them in our favor, + // so you must test any of them before using them on your real account to make sure that + // it will be good for your trading as there is no strategy is suitable for everyone. + // + // Strategy one: Bull's Power Movement: + // Based on this strategy, we need to get signals based on the position of current and previous bull's power values. + // If the current bull's power value is greater than the previous one, + // we will consider it as a signal of the rising of the Bull's Power indicator. + // Vice versa, if the current value is lower than the previous one, we will consider that as a signal of + // declining Bull's Power. + // + // To simplify that, it will be the same as the following: + // + // Current Bull's Power > Previous Bull's Power --> Bull's Power is Rising + // Current Bull's Power < Previous Bull's Power --> Bull's Power is declining + bool isBullPowerOverLast; + bool isBullPoswerUnderLast; + // + // Strategy two: Bull's Power - Strong or Divergence + // Based on this strategy, we want to get a signal that informs us if there is a strong movement + // or there is a divergence by evaluating four values and these values are current high, + // the previous high, bull power, and previous bull power. + // If the current high is higher than the previous high and + // the current bull power value is higher than the previous one, + // we will consider that as a signal of a strong move. + // In the other case, if the current high is higher than the previous high and the current + // bull value is lower than the previous one, we will consider that as a signal of bearish divergence. + // + // To simplify that, it will be the same as the following: + // + // Current high > previous high and current bull's power > previous bull's power --> strong move + // Current high < previous high and current bull's power > previous bull's power --> bearish divergence + // + // Strategy three: Bull's Power signals + // Based on this strategy, we need a signal that can be used to get buy and sell signals and we will + // evaluate four values to do that based on this strategy. + // These four values are: + // - current bull's power, + // - zero level, + // - current close value, and + // - current exponential moving average. + // If the current bull's power is lower than the zero level and + // the current close is lower than the exponential moving average, + // we will consider it as a signal of selling. + // If the current bull's power is greater than the zero level and the current close is greater than + // the exponential moving average, this will be a signal of buying. + // + // To simplify that, it will be the same as the following: + // + // Current bull's power < zero level and current close < EMA --> sell + // Current bear's power > zero level and current close > EMA --> buy + bool isBullPowerOverZero; + bool isBullPoswerUnderZero; + + // + // Bear's Power strategy + // In this part, we will learn how we can use Bear's Power through simple strategies + // that can be used based on the basic concept of this indicator. + // The following are for these strategies and their conditions. + // I need to confirm here, that these strategies for education as the main objective + // is to understand the main concept behind the indicator and how we can use it, + // so you must test any of them before using them on your real account to + // make sure that it will be good for your trading. + // + // Strategy one: Bear's Power Movement + // According to this strategy, we need to get signals based on the position of current and previous + // bear's power values. + // If the current value is greater than the previous, this will be a signal of the rising of + // Bear's Power indicator. + // Vice versa, if the current value is lower than the previous value, + // this will be a signal of declining Bear's Power. + // + // Simply, + // + // Current Bear's Power > Previous Bear's Power --> Bear's Power is Rising + // Current Bear's Power < Previous Bear's Power --> Bear's Power is declining + bool isBearPowerOverLast; + bool isBearPoswerUnderLast; + // + // Strategy two: Bear's Power - Strong or Divergence + // According to this strategy, we need to get a signal that informs us if there are strong movements or + // there are divergences by evaluating four values and they are: + // -current low, + // - previous low, + // - bear power, and + // - previous bear power. + // If the current low is lower than the previous low and the current bear power value + // is lower than the previous one, this will be a signal of a strong move. + // In the other case, if the current low is lower than the previous low and the current + // bear value is greater than the previous one, this will be a signal of bullish divergence. + // + // Simply, + // + // Current low < previous low and current bear's power < previous bear's power --> strong move + // Current low < previous low and current bear's power > previous bear's power --> bullish divergence + // + // Strategy three + // According to this strategy, we need a trigger that can be used to get buy and sell signals and + // we will evaluate four values to do that based on this strategy. + // These four values are current: + // - bear's power, + // - zero level, + // - current close value, and + // - current exponential moving average. + // If the current bear's power is greater than the zero level and the current close is greater than + // the exponential moving average, this will be a signal of buy. + // If the current bear's power is lower than the zero level and the current close is lower than + // the exponential moving average, this will be a signal of selling. + // + // Simply, + // + // Current bear's power > zero level and current close > EMA --> buy + // Current bear's power < zero level and current close < EMA --> sell + bool isBearPowerOverZero; + bool isBearPoswerUnderZero; + + // + // CCI ... + bool isCCIPositive; + bool isCCINegative; + bool isCCIOverPositiveHundred; + bool isCCIUnderNegativeHundred; + + // + // STDDEV ... + // Based on this strategy, we need to measure the volatility based on the comparison between the + // current Std Dev and the average of the five previous Std values. + // If the current Std Dev is greater than the Std Dev 5-periods average, this will be a high volatility signal. + // If the current Std is lower than the Std Dev 5- period average, this will be low volatility. + // + // Based on this strategy, we need to get buy and sell signals based on specific conditions. + // If the current Std Dev is greater than the previous Std Dev and the Ask value is greater than the moving average, + // this will be a buy signal. + // If the current Std Dev is greater than the previous Std Dev and the Bid value is lower than the moving average, + // this will be a sell signal. + // + // Current Std > Prev. Std and Ask > MA --> Buy signal + // Current Std > Prev. Std and Bid < MA --> Sell signal + // + // Based on this strategy, we need to get buy and sell signals based on other conditions. + // If the current Std Dev is greater than Std Dev Avg and Ask is greater than the moving average, + // this will be a buy signal. + // If the current Std Dev is greater than Std Dev Avg and Bid is lower than the moving average, + // this will be a sell signal. + // + // Current Std > Std Avg and Ask > MA --> Buy signal + // Current Std > Std Avg and Bid < Ma --> Sell signal + bool isSTDDEVOverAVG; + bool isSTDDEVOverLast; + bool isSTDDEVUnderAVG; + bool isSTDDEVUnderLast; + + // + // MACD ... + // According to this strategy, we need to identify the market setup: + // is it buying setup or shorting setup. + // In other words we need to identify the market direction, if it is bullish or bearish market, + // and this will be identified by MACD. + // If the MACD main line breaks above zero level, this will be a buying setup or bullish setup and + // vice versa if MACD main line breaks below zero level, this will be a shorting setup or bearish. + // + // MACD main line > 0 = Bullish Setup + // MACD main line < 0 = Bearish Setup + // + // According to this strategy, we need to identify generated signals + // if there is a buy signal or a sell signal based on MACD main line and Signal line crossover. + // If MACD main line breaks above Signal line, this will be a buy signal and if MACD main line breaks + // below Signal line, this will be a short signal. + // + // MACD main line > MACD signal line = Buying Signal + // MACD main line < MACD signal line = Shorting signal + bool isMACDPositiove; + bool isMACDNegative; + bool isMACDOverSignal; + bool isMACDUnderSignal; + + // + // STOCHASTIC ... + // Stochastic strategy + // In this part, we will talk about how we can use this indicator through simple strategies. + // We can get signals from the stochastic indicator according to market trend and these strategies are + // uptrend strategy, downtrend strategy, and sideways strategy. + // + // Strategy one: Uptrend strategy + // According to this strategy, we need to check if the %K line and %D line are below the 50 level, + // then, the buy signal will be generated + // when the %K line crosses above the %D line. + // We can take profit according to another effective tool like price action by searching + // for a lower low for example. + // + // %K, %D < 50 --> %K > %D = buy signal + bool isStochKOverD; + bool isStochKDUnder50; + // + // Strategy two: downtrend strategy + // According to this strategy, we need to check if the %K line and %D line are above the 50 level, + // then, the sell signal will be generated + // when the %K line crosses below the %D line. + // We can take profit according to another effective tool like price action by searching + // for a higher high for example. + // + // %K, %D > 50 --> %K < %D = sell signal + bool isStochKUnderD; + bool isStochKDOver50; + // + // Strategy three: sideways strategy + // + // The buy signal: + // According to this strategy, we need to check if the %K line and %D line are below the 20 level, + // then, the buy signal will be generated + // when the %K line crosses above the %D line. + // When the %K line and %D line are above 80, then the take profit signal will be generated + // when the %K line crosses below the %D line. + // %K, %D < 20 --> %K > %D = buy signal + // %K, %D > 80 --> %K < %D = take profit + bool isStochKDUnder20; + // + // The sell signal + // According to this strategy, we need to check if the %K line and %D line are above the 80 level, + // then, the sell signal will be generated + // when the %K line crosses below the %D line. + // When the %K line and %D are below the 20 level, then, the take profit signal will be generated + // when the %K line crosses above the %D line. + // + // %K, %D > 80 --> %K < %D = sell signal + // %K, %D < 20 --> %K > %D = take profit + bool isStochKDOver80; + + // + // Tools ... + + // + void Clear() + { + // + // Commons ... + time = 0; + cycle = NULL; + prefix = NULL; + symbol = NULL; + period = NULL; + hostPeriod = NULL; + + // + Clean(bars); + + // + // Candlestic ... + isLastBullish = false; + isLastBearish = false; + isCurrentBullish = false; + isCurrentBearish = false; + isCurrentMidLineOverLastHigh = false; + isCurrentMidLineUnderLastLow = false; + isCurrentMidLineOverLastUp = false; + isCurrentMidLineUnderLastDown = false; + isCurrentMidLineOverLastMidLine = false; + isCurrentMidLineUnderLastMidLine = false; + + // + // Buffers ... + Clean(ichTenkanSens); + Clean(ichKijunSens); + Clean(ichChikouSpans); + Clean(ichSenkouSpanAs); + Clean(ichSenkouSpanBs); + Clean(mcFasts); + Clean(mcSlows); + Clean(mcVerifiers); + Clean(strTrends); + Clean(strStates); + Clean(cheLongExit1s); + Clean(cheLongExit2s); + Clean(cheShortExit1s); + Clean(cheShortExit2s); + Clean(oscAtrs); + Clean(oscRviMains); + Clean(oscRviSignals); + Clean(oscBullPs); + Clean(oscBearPs); + Clean(oscVolumes); + Clean(oscRsis); + Clean(oscCcis); + Clean(oscMomentums); + Clean(oscSars); + Clean(oscMacdMains); + Clean(oscMacdSignals); + Clean(oscStochMains); + Clean(oscStochSignals); + Clean(oscStddevs); + + // + // XTSR ... + isTrendBullish = false; + isTrendBearish = false; + + // + // XCHE ... + isCHEInLong = false; + isCHEInStrongLong = false; + isCHEInShort = false; + isCHEInStrongShort = false; + + // + // XICH ... + isSenkouSpanAOverB = false; + isSenkouSpanAUnderB = false; + isSenkouSpanAOverLast = false; + isSenkouSpanAUnderLast = false; + isFutureSenkouSpanAOverB = false; + isFutureSenkouSpanAUnderB = false; + isFutureSenkouSpanAOverLast = false; + isFutureSenkouSpanAUnderLast = false; + isCloseOverKijunSen = false; + isCloseUnderKijunSen = false; + isTenkanSenOverKijunSen = false; + isTenkanSenUnderKijunSen = false; + + // + // XMC ... + isFastOverSlow = false; + isFastUnderSlow = false; + isFastOverVerifier = false; + isFastUnderVerifier = false; + isSlowOverVerifier = false; + isSlowUnderVerifier = false; + isCloseOverFast = false; + isCloseUnderFast = false; + isCloseOverSlow = false; + isCloseUnderSlow = false; + isCloseOverVerifier = false; + isCloseUnderVerifier = false; + + // + // XOSC ... + + // + // STDDEV ... + isSTDDEVOverAVG = false; + isSTDDEVUnderAVG = false; + isSTDDEVOverLast = false; + isSTDDEVUnderLast = false; + + // + // RVI ... + isRVILongStart = false; + isRVILongStop = false; + isRVIShortStart = false; + isRVIShortStop = false; + + // + // RSI ... + isRSIUnder50 = false; + isRSIOver70 = false; + isRSIOver50 = false; + isRSIUnder30 = false; + + // + // BULLPOWER ... + isBullPowerOverLast = false; + isBullPoswerUnderLast = false; + isBullPowerOverZero = false; + isBullPoswerUnderZero = false; + + // + // BEARPOWER ... + isBearPowerOverLast = false; + isBearPoswerUnderLast = false; + isBearPowerOverZero = false; + isBearPoswerUnderZero = false; + + // + // CCI ... + isCCIPositive = false; + isCCINegative = false; + isCCIOverPositiveHundred = false; + isCCIUnderNegativeHundred = false; + + // + // MACD ... + isMACDPositiove = false; + isMACDNegative = false; + isMACDOverSignal = false; + isMACDUnderSignal = false; + + // + // STOCH ... + isStochKOverD = false; + isStochKDUnder50 = false; + isStochKUnderD = false; + isStochKDOver50 = false; + isStochKDUnder20 = false; + isStochKDOver80 = false; + } + + // + // Generate Score ... + virtual void GenerateScore( + double &bullishScore, // Holds Bullish Score ... + double &bearishScore, // Holds Bearish Score ... + double multiplier = 1 // Score Multiplier ... + ) + { + // + double bullScore = 0; + double bearScore = 0; + + // + if (multiplier <= 0) + { + multiplier = 1; + } + + // + // Candlestic ... + + // + // BULLISH ... + if (isLastBullish) + { + bullScore++; + } + if (isCurrentBullish) + { + bullScore++; + } + if (isCurrentMidLineOverLastUp) + { + bullScore++; + } + if (isCurrentMidLineOverLastHigh) + { + bullScore++; + } + if (isCurrentMidLineOverLastMidLine) + { + bullScore++; + } + + // + // BEARISH ... + if (isLastBearish) + { + bearScore++; + } + if (isCurrentBearish) + { + bearScore++; + } + if (isCurrentMidLineUnderLastLow) + { + bearScore++; + } + if (isCurrentMidLineUnderLastDown) + { + bearScore++; + } + if (isCurrentMidLineUnderLastMidLine) + { + bearScore++; + } + + // + // XSTR ... + if (isTrendBullish) + { + bullScore++; + } + if (isTrendBearish) + { + bearScore++; + } + + // + // XICH ... + + // + // BULLISH ... + if (isSenkouSpanAOverB) + { + bullScore++; + } + if (isSenkouSpanAOverLast) + { + bullScore++; + } + if (isCloseOverKijunSen) + { + bullScore++; + } + if (isTenkanSenOverKijunSen) + { + bullScore++; + } + if (isFutureSenkouSpanAOverB) + { + bullScore++; + } + if (isFutureSenkouSpanAOverLast) + { + bullScore++; + } + + // + // BEARISH ... + if (isSenkouSpanAUnderB) + { + bearScore++; + } + if (isSenkouSpanAUnderLast) + { + bearScore++; + } + if (isCloseUnderKijunSen) + { + bearScore++; + } + if (isTenkanSenUnderKijunSen) + { + bearScore++; + } + if (isFutureSenkouSpanAUnderB) + { + bearScore++; + } + if (isFutureSenkouSpanAUnderLast) + { + bearScore++; + } + + // + // XMC ... + + // + // BULLISH ... + if (isFastOverSlow) + { + bullScore++; + } + if (isFastOverVerifier) + { + bullScore++; + } + if (isSlowOverVerifier) + { + bullScore++; + } + if (isCloseOverFast) + { + bullScore++; + } + if (isCloseOverSlow) + { + bullScore++; + } + if (isCloseOverVerifier) + { + bullScore++; + } + + // + // BEARISH ... + if (isFastUnderSlow) + { + bearScore++; + } + if (isFastUnderVerifier) + { + bearScore++; + } + if (isSlowUnderVerifier) + { + bearScore++; + } + if (isCloseUnderFast) + { + bearScore++; + } + if (isCloseUnderSlow) + { + bearScore++; + } + if (isCloseUnderVerifier) + { + bearScore++; + } + + // + // XOSC ... + + // + // STDDEV ... + + // + // BULLISH ... + if (isSTDDEVOverAVG) + { + bullScore++; + } + if (isSTDDEVOverLast) + { + bullScore++; + } + + // + // BEARISH ... + if (isSTDDEVUnderAVG) + { + bearScore++; + } + if (isSTDDEVUnderLast) + { + bearScore++; + } + + // + // RVI ... + if (isRVILongStart && !isRVILongStop) + { + bullScore++; + } + if (isRVIShortStart && isRVIShortStop) + { + bearScore++; + } + + // + // RSI ... + + // + // BULLISH ... + if (isRSIUnder30 || (!isRSIUnder30 && isRSIOver50 && isRSIOver70)) + { + bullScore++; + } + + // + // BEARISH ... + if (isRSIOver70 || (!isRSIOver70 && !isRSIOver50 && isRSIUnder30)) + { + bearScore++; + } + + // + // BULLPOWER ... + + // + // BULLISH ... + if (isBullPowerOverLast) + { + bullScore++; + } + if (isBullPowerOverZero) + { + bullScore++; + } + + // + // BEARISH ... + if (isBullPoswerUnderLast) + { + bearScore++; + } + if (isBullPoswerUnderZero) + { + bearScore++; + } + + // + // BEARPOWER ... + + // + // BULLISH ... + if (isBearPoswerUnderLast) + { + bullScore++; + } + if (isBearPoswerUnderZero) + { + bullScore++; + } + + // + // BEARISH ... + if (isBearPowerOverLast) + { + bearScore++; + } + if (isBearPowerOverZero) + { + bearScore++; + } + + // + // CCI ... + + // + // BULLISH ... + if (isCCIPositive) + { + bullScore++; + } + if (isCCIOverPositiveHundred) + { + bullScore++; + } + + // + // BEARISH ... + if (isCCINegative) + { + bearScore++; + } + if (isCCIUnderNegativeHundred) + { + bearScore++; + } + + // + // MACD ... + + // + // BULLISH ... + if (isMACDPositiove) + { + bullScore++; + } + if (isMACDOverSignal) + { + bullScore++; + } + + // + // BEARISH ... + if (isMACDNegative) + { + bearScore++; + } + if (isMACDUnderSignal) + { + bearScore++; + } + + // + // STOCH ... + + // + // BULLISH ... + if (isStochKOverD) + { + bullScore++; + } + if (isStochKDUnder20) + { + bullScore++; + } + if (isStochKDUnder50) + { + bullScore++; + } + + // + // BEARISH ... + if (isStochKUnderD) + { + bearScore++; + } + if (isStochKDOver50) + { + bearScore++; + } + if (isStochKDOver80) + { + bearScore++; + } + + // + bullishScore = bullScore * multiplier; + bearishScore = bearScore * multiplier; + } + + // + // Generate Summary ... + virtual string GenerateSummary( + const bool onlySummary = false, // Only Generate Conditions Summary + double multiplier = 1, // Score Multiplier + const string separator = "\n", // Separator + const bool ignoreFalseConditions = true // Ignore False Conditions + ) + { + // + string result = NULL; + + // + result = GenerateSummaryBody( + onlySummary, + multiplier, + separator, + ignoreFalseConditions + // + ); + + // + // Generating Full Result by Combining parts ... + result = + // + "[" + GetToken() + "]" + separator + + "-----------------------------" + separator + + result + + "" + // + ; + + // + return result; + } + + // + string GenerateSummary( + string provided, // Additional Info about Type, Provider and Symbol + const bool onlySummary = false, // Only Generate Conditions Summary + double multiplier = 1, // Score Multiplier + const string separator = "\n", // Separator + const bool ignoreFalseConditions = true // Ignore False Conditions + ) + { + // + string result = NULL; + + // + result = GenerateSummaryBody( + onlySummary, + multiplier, + separator, + ignoreFalseConditions + // + ); + + // + // Generating Full Result by Combining parts ... + result = + // + "[" + GetToken() + "]" + separator + + provided + separator + + "-----------------------------" + separator + + result + + "" + // + ; + + // + return result; + } + + // + string GenerateSummaryBody( + const bool onlySummary = false, // Only Generate Conditions Summary + double multiplier = 1, // Score Multiplier + const string separator = "\n", // Separator + const bool ignoreFalseConditions = true // Ignore False Conditions + ) + { + // + string result = NULL; + + // + double bullScore = 0; + double bearScore = 0; + GenerateScore( + bullScore, + bearScore, + multiplier // + ); + + // + // Common ... + string commonStr = + // + "Commons: " + separator + + "-----------------------------" + separator + + "Time: " + ToString(TimeCurrent()) + separator + + "-----------" + separator + + "Scores: " + separator + + "-----------" + separator + + "Bullish: " + ToString(bullScore) + separator + + "Bearish: " + ToString(bearScore) + separator + + "-----------------------------" + separator + + // + // TODO: Add Scores Later ... + separator + + "" + // + ; + + // + // Candlestick ... + string candlesticStr = + // + ToString("isLastBullish", isLastBullish, ignoreFalseConditions) + + ToString("isLastBearish", isLastBearish, ignoreFalseConditions) + + ToString("isCurrentBullish", isCurrentBullish, ignoreFalseConditions) + + ToString("isCurrentBearish", isCurrentBearish, ignoreFalseConditions) + + ToString("isCurrentMidLineOverLastHigh", isCurrentMidLineOverLastHigh, ignoreFalseConditions) + + ToString("isCurrentMidLineUnderLastLow", isCurrentMidLineUnderLastLow, ignoreFalseConditions) + + ToString("isCurrentMidLineOverLastUp", isCurrentMidLineOverLastUp, ignoreFalseConditions) + + ToString("isCurrentMidLineUnderLastDown", isCurrentMidLineUnderLastDown, ignoreFalseConditions) + + ToString("isCurrentMidLineOverLastMidLine", isCurrentMidLineOverLastMidLine, ignoreFalseConditions) + + ToString("isCurrentMidLineUnderLastMidLine", isCurrentMidLineUnderLastMidLine, ignoreFalseConditions) + + "" + // + ; + candlesticStr = SetLabel("Candelstick: ", candlesticStr, separator); + + // + // XSTR ... + string strStr = + // + ToString("isTrendBullish", isTrendBullish, ignoreFalseConditions) + + ToString("isTrendBearish", isTrendBearish, ignoreFalseConditions) + + "" + // + ; + strStr = SetLabel("XSTR: ", strStr, separator); + + // + // XCHE ... + string cheStr = + // + ToString("isCHEInLong", isCHEInLong, ignoreFalseConditions) + + ToString("isCHEInStrongLong", isCHEInStrongLong, ignoreFalseConditions) + + ToString("isCHEInShort", isCHEInShort, ignoreFalseConditions) + + ToString("isCHEInStrongShort", isCHEInStrongShort, ignoreFalseConditions) + + "" + // + ; + cheStr = SetLabel("XCHE: ", cheStr, separator); + + // + // XICH ... + string ichStr = + // + ToString("isSenkouSpanAOverB", isSenkouSpanAOverB, ignoreFalseConditions) + + ToString("isSenkouSpanAUnderB", isSenkouSpanAUnderB, ignoreFalseConditions) + + ToString("isSenkouSpanAOverLast", isSenkouSpanAOverLast, ignoreFalseConditions) + + ToString("isSenkouSpanAUnderLast", isSenkouSpanAUnderLast, ignoreFalseConditions) + + ToString("isCloseOverKijunSen", isCloseOverKijunSen, ignoreFalseConditions) + + ToString("isCloseUnderKijunSen", isCloseUnderKijunSen, ignoreFalseConditions) + + ToString("isTenkanSenOverKijunSen", isTenkanSenOverKijunSen, ignoreFalseConditions) + + ToString("isTenkanSenUnderKijunSen", isTenkanSenUnderKijunSen, ignoreFalseConditions) + + ToString("isFutureSenkouSpanAOverB", isFutureSenkouSpanAOverB, ignoreFalseConditions) + + ToString("isFutureSenkouSpanAUnderB", isFutureSenkouSpanAUnderB, ignoreFalseConditions) + + ToString("isFutureSenkouSpanAOverLast", isFutureSenkouSpanAOverLast, ignoreFalseConditions) + + ToString("isFutureSenkouSpanAUnderLast", isFutureSenkouSpanAUnderLast, ignoreFalseConditions) + + "" + // + ; + ichStr = SetLabel("XICH: ", ichStr, separator); + + // + // XMC ... + string mcStr = + // + ToString("isFastOverSlow", isFastOverSlow, ignoreFalseConditions) + + ToString("isFastUnderSlow", isFastUnderSlow, ignoreFalseConditions) + + ToString("isFastOverVerifier", isFastOverVerifier, ignoreFalseConditions) + + ToString("isFastUnderVerifier", isFastUnderVerifier, ignoreFalseConditions) + + ToString("isSlowOverVerifier", isSlowOverVerifier, ignoreFalseConditions) + + ToString("isSlowUnderVerifier", isSlowUnderVerifier, ignoreFalseConditions) + + ToString("isCloseOverFast", isCloseOverFast, ignoreFalseConditions) + + ToString("isCloseUnderFast", isCloseUnderFast, ignoreFalseConditions) + + ToString("isCloseOverSlow", isCloseOverSlow, ignoreFalseConditions) + + ToString("isCloseUnderSlow", isCloseUnderSlow, ignoreFalseConditions) + + ToString("isCloseOverVerifier", isCloseOverVerifier, ignoreFalseConditions) + + ToString("isCloseUnderVerifier", isCloseUnderVerifier, ignoreFalseConditions) + + "" + // + ; + mcStr = SetLabel("XMC: ", mcStr, separator); + + // + // XOSC ... + + // + // STDDEV ... + string stddevStr = + // + ToString("isSTDDEVOverAVG", isSTDDEVOverAVG, ignoreFalseConditions) + + ToString("isSTDDEVUnderAVG", isSTDDEVUnderAVG, ignoreFalseConditions) + + ToString("isSTDDEVOverLast", isSTDDEVOverLast, ignoreFalseConditions) + + ToString("isSTDDEVUnderLast", isSTDDEVUnderLast, ignoreFalseConditions) + + "" + // + ; + stddevStr = SetLabel("STDDEV: ", stddevStr, separator); + + // + // RVI ... + string rviStr = + // + ToString("isRVILongStart", isRVILongStart, ignoreFalseConditions) + + ToString("isRVILongStop", isRVILongStop, ignoreFalseConditions) + + ToString("isRVIShortStart", isRVIShortStart, ignoreFalseConditions) + + ToString("isRVIShortStop", isRVIShortStop, ignoreFalseConditions) + + "" + // + ; + rviStr = SetLabel("RVI: ", rviStr, separator); + + // + // RSI ... + string rsiStr = + // + ToString("isRSIOver50", isRSIOver50, ignoreFalseConditions) + + ToString("isRSIUnder50", isRSIUnder50, ignoreFalseConditions) + + ToString("isRSIOver70", isRSIOver70, ignoreFalseConditions) + + ToString("isRSIUnder30", isRSIUnder30, ignoreFalseConditions) + + "" + // + ; + rsiStr = SetLabel("RSI: ", rsiStr, separator); + + // + // CCI ... + string cciStr = + // + ToString("isCCIPositive", isCCIPositive, ignoreFalseConditions) + + ToString("isCCINegative", isCCINegative, ignoreFalseConditions) + + ToString("isCCIOverPositiveHundred", isCCIOverPositiveHundred, ignoreFalseConditions) + + ToString("isCCIUnderNegativeHundred", isCCIUnderNegativeHundred, ignoreFalseConditions) + + "" + // + ; + cciStr = SetLabel("CCI: ", cciStr, separator); + + // + // MACD ... + string macdStr = + // + ToString("isMACDPositiove", isMACDPositiove, ignoreFalseConditions) + + ToString("isMACDNegative", isMACDNegative, ignoreFalseConditions) + + ToString("isMACDOverSignal", isMACDOverSignal, ignoreFalseConditions) + + ToString("isMACDUnderSignal", isMACDUnderSignal, ignoreFalseConditions) + + "" + // + ; + macdStr = SetLabel("MACD: ", macdStr, separator); + + // + // BULLP ... + string bullPStr = + // + ToString("isBullPowerOverLast", isBullPowerOverLast, ignoreFalseConditions) + + ToString("isBullPoswerUnderLast", isBullPoswerUnderLast, ignoreFalseConditions) + + ToString("isBullPowerOverZero", isBullPowerOverZero, ignoreFalseConditions) + + ToString("isBullPoswerUnderZero", isBullPoswerUnderZero, ignoreFalseConditions) + + "" + // + ; + bullPStr = SetLabel("BULLP: ", bullPStr, separator); + + // + // BEARP ... + string bearPStr = + // + ToString("isBearPowerOverLast", isBearPowerOverLast, ignoreFalseConditions) + + ToString("isBearPoswerUnderLast", isBearPoswerUnderLast, ignoreFalseConditions) + + ToString("isBearPowerOverZero", isBearPowerOverZero, ignoreFalseConditions) + + ToString("isBearPoswerUnderZero", isBearPoswerUnderZero, ignoreFalseConditions) + + "" + // + ; + bearPStr = SetLabel("BEARP: ", bearPStr, separator); + + // + // STOCH ... + string stochStr = + // + ToString("isStochKOverD", isStochKOverD, ignoreFalseConditions) + + ToString("isStochKUnderD", isStochKUnderD, ignoreFalseConditions) + + ToString("isStochKDOver50", isStochKDOver50, ignoreFalseConditions) + + ToString("isStochKDOver80", isStochKDOver80, ignoreFalseConditions) + + ToString("isStochKDUnder20", isStochKDUnder20, ignoreFalseConditions) + + ToString("isStochKDUnder50", isStochKDUnder50, ignoreFalseConditions) + + "" + // + ; + stochStr = SetLabel("STOCH: ", stochStr, separator); + + // + string oscStr = + // + stddevStr + + rviStr + + rsiStr + + cciStr + + macdStr + + bullPStr + + bearPStr + + stochStr + + "" + // + ; + oscStr = SetLabel("XOSC: ", oscStr, separator); + + // + result = + // + commonStr + + candlesticStr + + (onlySummary + ? "" + : strStr + + cheStr + + ichStr + + mcStr + + oscStr // + ) + + "" + // + ; + + // + return result; + } + + // + string GetTitle() + { + // + string result = NULL; + + // + result = + // + "[" + ToString(cycle) + "]: " + ToString(period) + // + ; + + // + return result; + } + + // + // For Data Collector ... + string GetToken() + { + return GetSpecificToken(this); + } + bool IsModelValid() + { + return false; + } + string ToModelString() + { + return NULL; + } + bool ParseModel(string content) + { + return false; + } + int FindIndex(X121MCycleConditions &items[]) + { + return -1; + } +}; + +// +// Market Class ... +class XSCX121Market : XSCBase +{ + // + // Public ... +public: + // + // Props ... + XSCXMCHelper mc; + XSCXSTRHelper str; + XSCXCHEHelper che; + XSCXOSCHelper osc; + XSCXICHHelper ich; + + // + // Properties ... + + // + // Retrieve Trading Symbol ... + string GetSymbol() + { + return mInputs.cycle.symbol; + } + + // + // Retrieve Cycle Time Frame ... + ENUM_TIMEFRAMES GetPeriod() + { + return mInputs.cycle.period; + } + + // + // Retrieve Market Host Time Frame ... + ENUM_TIMEFRAMES GetHostPeriod() + { + return mInputs.cycle.hostPeriod; + } + + // + // Count Total Available Bars in Market ... + int CountBars() + { + // + Update(0); + return mInputs.cycle.CountBars(); + } + + // + // Check Market is in new Bar ... + int IsNewBar() + { + // + Update(0); + return mInputs.cycle.IsNewBar(); + } + + // + // Retrieve Current Cycles Specific Bar ... + XOHCL GetBar(int barIndex) + { + // + Update(0); + return mInputs.cycle.GetBar(barIndex); + } + + // + // Retrieve Current Bar Index based on Host Period bar Index ... + int GetBarIndex(int barIndex) + { + // + Update(barIndex); + return mInputs.cycle.GetBarIndex(barIndex); + } + + // + // Retrieve Bar Time ... + datetime GetBarTime(int barIndex) + { + // + Update(0); + return mInputs.cycle.GetBarTime(barIndex); + } + + // + // Retrieve Current Market Config ... + bool GetInputs(X121MCycleInputs &inputs) + { + // + bool result = false; + + // + inputs = mInputs; + + // + result = inputs.IsValid(); + + // + return result; + } + + // + // Set Market Inputs and Re Initial ... + bool SetInputs( + X121MCycleInputs &inputs // Config + ) + { + // + return Init(inputs); + } + + // + // Tools ... + // + void GetMarketConditions( + X121MCycleConditions &conditions, // Market Conditions Result + int barIndex = 0, // Specified Bar Index + int mNumberOfItems = 15 // Number of Reading Items + ) + { + // + conditions.Clear(); + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (barIndex >= CountBars()) + { + barIndex = CountBars() + 2; + } + + // + // Here i Have to Calculate Market Conditions based on + // Several Indicator/Oscillator(s) ... + + // + // Set Commons ... + conditions.time = GetBarTime(barIndex); + conditions.cycle = mInputs.cycle.cycle; + conditions.prefix = mInputs.cycle.prefix; + conditions.symbol = mInputs.cycle.symbol; + conditions.period = mInputs.cycle.period; + conditions.hostPeriod = mInputs.cycle.hostPeriod; + + // + Clean(conditions.bars); + GetBars( + conditions.bars, + conditions.symbol, + conditions.period, + barIndex, + barIndex + 5); + + // + XOHCL cBar = GetBar(barIndex); + XOHCL pBar = GetBar(barIndex + 1); + + // + // CANDELSTICK ... + + // + bool isLastBullish = + // + pBar.IsBullish() + // + ; + + // + bool isLastBearish = + // + pBar.IsBearish() + // + ; + + // + bool isCurrentBullish = + // + cBar.IsBullish() + // + ; + + // + bool isCurrentBearish = + // + cBar.IsBearish() + // + ; + + // + bool isCurrentMidLineOverLastHigh = + // + cBar.GetMid() > pBar.high; + // + ; + + // + bool isCurrentMidLineUnderLastLow = + // + cBar.GetMid() < pBar.low + // + ; + + // + bool isCurrentMidLineOverLastUp = + // + cBar.GetMid() > pBar.GetUp() + // + ; + + // + bool isCurrentMidLineUnderLastDown = + // + cBar.GetMid() < pBar.GetDown() + // + ; + + // + bool isCurrentMidLineOverLastMidLine = + // + cBar.GetMid() > pBar.GetMid() + // + ; + + // + bool isCurrentMidLineUnderLastMidLine = + // + cBar.GetMid() < pBar.GetMid() + // + ; + + // + conditions.isLastBullish = isLastBullish; + conditions.isLastBearish = isLastBearish; + conditions.isCurrentBullish = isCurrentBullish; + conditions.isCurrentBearish = isCurrentBearish; + conditions.isCurrentMidLineOverLastHigh = isCurrentMidLineOverLastHigh; + conditions.isCurrentMidLineUnderLastLow = isCurrentMidLineUnderLastLow; + conditions.isCurrentMidLineOverLastUp = isCurrentMidLineOverLastUp; + conditions.isCurrentMidLineUnderLastDown = isCurrentMidLineUnderLastDown; + conditions.isCurrentMidLineOverLastMidLine = isCurrentMidLineOverLastMidLine; + conditions.isCurrentMidLineUnderLastMidLine = isCurrentMidLineUnderLastMidLine; + + // + // XSTR ... + + // + str.CopyTrend( + barIndex, + mNumberOfItems, + conditions.strTrends // + ); + str.CopyState( + barIndex, + mNumberOfItems, + conditions.strStates // + ); + + // + bool isTrendBullish = + // + str.IsBullish(str.GetState(barIndex)) + // + ; + bool isTrendBearish = + // + str.IsBearish(str.GetState(barIndex)) + // + ; + + // + conditions.isTrendBullish = isTrendBullish; + conditions.isTrendBearish = isTrendBearish; + + // + // XCHE ... + + // + che.CopyLongExit1( + barIndex, + mNumberOfItems, + conditions.cheLongExit1s // + ); + che.CopyLongExit2( + barIndex, + mNumberOfItems, + conditions.cheLongExit2s // + ); + che.CopyShortExit1( + barIndex, + mNumberOfItems, + conditions.cheShortExit1s // + ); + che.CopyShortExit2( + barIndex, + mNumberOfItems, + conditions.cheShortExit2s // + ); + + // + bool isCHEInLong = + // + NotEmpty(che.GetLongExit1(barIndex)) + // + ; + bool isCHEInStrongLong = + // + isCHEInLong && + NotEmpty(che.GetLongExit2(barIndex)) + // + ; + bool isCHEInShort = + // + NotEmpty(che.GetShortExit1(barIndex)) + // + ; + bool isCHEInStrongShort = + // + isCHEInShort && + NotEmpty(che.GetShortExit2(barIndex)) + // + ; + + // + conditions.isCHEInLong = isCHEInLong; + conditions.isCHEInShort = isCHEInShort; + conditions.isCHEInStrongLong = isCHEInStrongLong; + conditions.isCHEInStrongShort = isCHEInStrongShort; + + // + // XMC ... + + // + mc.CopyFast( + barIndex, + mNumberOfItems, + conditions.mcFasts // + ); + mc.CopySlow( + barIndex, + mNumberOfItems, + conditions.mcSlows // + ); + mc.CopyVerifier( + barIndex, + mNumberOfItems, + conditions.mcVerifiers // + ); + + // + bool isFastOverSlow = + // + conditions.mcFasts[0] > conditions.mcSlows[0] && + conditions.mcFasts[1] > conditions.mcSlows[1] + // + ; + bool isFastUnderSlow = + // + conditions.mcFasts[0] < conditions.mcSlows[0] && + conditions.mcFasts[1] < conditions.mcSlows[1] + // + ; + bool isFastOverVerifier = + // + conditions.mcFasts[0] > conditions.mcVerifiers[0] && + conditions.mcFasts[1] > conditions.mcVerifiers[1] + // + ; + bool isFastUnderVerifier = + // + conditions.mcFasts[0] < conditions.mcVerifiers[0] && + conditions.mcFasts[1] < conditions.mcVerifiers[1] + // + ; + bool isSlowOverVerifier = + // + conditions.mcSlows[0] > conditions.mcVerifiers[0] && + conditions.mcSlows[1] > conditions.mcVerifiers[1] + // + ; + bool isSlowUnderVerifier = + // + conditions.mcSlows[0] < conditions.mcVerifiers[0] && + conditions.mcSlows[1] < conditions.mcVerifiers[1] + // + ; + bool isCloseOverFast = + // + pBar.close > conditions.mcFasts[1] + // + ; + bool isCloseUnderFast = + // + pBar.close < conditions.mcFasts[1] + // + ; + bool isCloseOverSlow = + // + pBar.close > conditions.mcSlows[1] + // + ; + bool isCloseUnderSlow = + // + pBar.close < conditions.mcSlows[1] + // + ; + bool isCloseOverVerifier = + // + pBar.close > conditions.mcVerifiers[1] + // + ; + bool isCloseUnderVerifier = + // + pBar.close < conditions.mcVerifiers[1] + // + ; + + // + conditions.isFastOverSlow = isFastOverSlow; + conditions.isFastUnderSlow = isFastUnderSlow; + conditions.isFastOverVerifier = isFastOverVerifier; + conditions.isFastUnderVerifier = isFastUnderVerifier; + conditions.isSlowOverVerifier = isSlowOverVerifier; + conditions.isSlowUnderVerifier = isSlowUnderVerifier; + conditions.isCloseOverFast = isCloseOverFast; + conditions.isCloseUnderFast = isCloseUnderFast; + conditions.isCloseOverSlow = isCloseOverSlow; + conditions.isCloseUnderSlow = isCloseUnderSlow; + conditions.isCloseOverVerifier = isCloseOverVerifier; + conditions.isCloseUnderVerifier = isCloseUnderVerifier; + + // + // TODO: XICH ... + + // + // XOSC ... + + // + // ATR ... + osc.CopyATR( + barIndex, + mNumberOfItems, + conditions.oscAtrs // + ); + + // + // VOLUE ... + osc.CopyVolume( + barIndex, + mNumberOfItems, + conditions.oscVolumes // + ); + + // + // MOMENTUM ... + osc.CopyMomentum( + barIndex, + mNumberOfItems, + conditions.oscMomentums // + ); + + // + // SAR ... + osc.CopySAR( + barIndex, + mNumberOfItems, + conditions.oscSars // + ); + + // + // RVI ... + + // + osc.CopyRVI( + barIndex, + mNumberOfItems, + conditions.oscRviMains // + ); + osc.CopyRVISignal( + barIndex, + mNumberOfItems, + conditions.oscRviSignals // + ); + + // + double rvi = osc.GetRVI(barIndex); + double rviSignal = osc.GetRVISignal(barIndex); + + // + bool isRVILongStart = + // + rvi > 0 && + rviSignal > 0 && + rvi > rviSignal + // + ; + bool isRVILongStop = + // + rvi < 0 && + rviSignal < 0 && + rvi < rviSignal + // + ; + bool isRVIShortStart = + // + rvi < 0 && + rviSignal < 0 && + rvi < rviSignal + // + ; + bool isRVIShortStop = + // + rvi > 0 && + rviSignal > 0 && + rvi > rviSignal + // + ; + + // + conditions.isRVILongStart = isRVILongStart; + conditions.isRVILongStop = isRVILongStop; + conditions.isRVIShortStart = isRVIShortStart; + conditions.isRVIShortStop = isRVIShortStop; + + // + // RSI ... + + // + osc.CopyRSI( + barIndex, + mNumberOfItems, + conditions.oscRsis // + ); + + // + double rsi = osc.GetRSI(barIndex); + + // + bool isRSIUnder50 = + // + rsi < 50 + // + ; + bool isRSIOver70 = + // + rsi > 70 + // + ; + bool isRSIOver50 = + // + rsi > 50 + // + ; + bool isRSIUnder30 = + // + rsi < 30 + // + ; + + // + conditions.isRSIUnder50 = isRSIUnder50; + conditions.isRSIOver70 = isRSIOver70; + conditions.isRSIOver50 = isRSIOver50; + conditions.isRSIUnder30 = isRSIUnder30; + + // + // BULLPOWER ... + + // + osc.CopyBullPower( + barIndex, + mNumberOfItems, + conditions.oscBullPs // + ); + + // + double bullp = osc.GetBullPower(barIndex); + double bullpLast = osc.GetBullPower(barIndex + 1); + + // + bool isBullPowerOverLast = + // + bullp > bullpLast + // + ; + bool isBullPoswerUnderLast = + // + bullp < bullpLast + // + ; + bool isBullPowerOverZero = + // + bullp > 0 + // + ; + bool isBullPoswerUnderZero = + // + bullp < 0 + // + ; + + // + conditions.isBullPowerOverLast = isBullPowerOverLast; + conditions.isBullPoswerUnderLast = isBullPoswerUnderLast; + conditions.isBullPowerOverZero = isBullPowerOverZero; + conditions.isBullPoswerUnderZero = isBullPoswerUnderZero; + + // + // BEARPOWER ... + + // + osc.CopyBearPower( + barIndex, + mNumberOfItems, + conditions.oscBearPs // + ); + + // + double bearp = osc.GetBearPower(barIndex); + double bearpLast = osc.GetBearPower(barIndex + 1); + + // + bool isBearPowerOverLast = + // + bearp > bearpLast + // + ; + bool isBearPoswerUnderLast = + // + bearp < bearpLast + // + ; + bool isBearPowerOverZero = + // + bearp > 0 + // + ; + bool isBearPoswerUnderZero = + // + bearp < 0 + // + ; + + // + conditions.isBearPowerOverLast = isBearPowerOverLast; + conditions.isBearPoswerUnderLast = isBearPoswerUnderLast; + conditions.isBearPowerOverZero = isBearPowerOverZero; + conditions.isBearPoswerUnderZero = isBearPoswerUnderZero; + + // + // CCI ... + + // + osc.CopyCCI( + barIndex, + mNumberOfItems, + conditions.oscCcis // + ); + + // + double cci = osc.GetCCI(barIndex); + + // + bool isCCIPositive = + // + cci > 0 + // + ; + bool isCCINegative = + // + cci < 0 + // + ; + bool isCCIOverPositiveHundred = + // + cci > 100 + // + ; + bool isCCIUnderNegativeHundred = + // + cci < -100 + // + ; + + // + conditions.isCCIPositive = isCCIPositive; + conditions.isCCINegative = isCCINegative; + conditions.isCCIOverPositiveHundred = isCCIOverPositiveHundred; + conditions.isCCIUnderNegativeHundred = isCCIUnderNegativeHundred; + + // + // MACD ... + + // + osc.CopyMACD( + barIndex, + mNumberOfItems, + conditions.oscMacdMains // + ); + osc.CopyMACDSignal( + barIndex, + mNumberOfItems, + conditions.oscMacdSignals // + ); + + // + double macd = osc.GetMACD(barIndex); + double macdSignal = osc.GetMACDSignal(barIndex); + + // + bool isMACDPositiove = + // + macd > 0 + // + ; + bool isMACDNegative = + // + macd < 0 + // + ; + bool isMACDOverSignal = + // + macd > macdSignal + // + ; + bool isMACDUnderSignal = + // + macd < macdSignal + // + ; + + // + conditions.isMACDPositiove = isMACDPositiove; + conditions.isMACDNegative = isMACDNegative; + conditions.isMACDOverSignal = isMACDOverSignal; + conditions.isMACDUnderSignal = isMACDUnderSignal; + + // + // STOCH ... + + // + osc.CopySTOCH( + barIndex, + mNumberOfItems, + conditions.oscStochMains // + ); + osc.CopySTOCHSignal( + barIndex, + mNumberOfItems, + conditions.oscStochSignals // + ); + + // + double stoch = osc.GetSTOCH(barIndex); + double stochSignal = osc.GetSTOCHSignal(barIndex); + + // + bool isStochKOverD = + // + stoch > stochSignal + // + ; + bool isStochKDUnder50 = + // + stoch < 50 && + stochSignal < 50 + // + ; + bool isStochKUnderD = + // + stoch < stochSignal + // + ; + bool isStochKDOver50 = + // + stoch > 50 && + stochSignal > 50 + // + ; + bool isStochKDUnder20 = + // + stoch < 20 && + stochSignal < 20 + // + ; + bool isStochKDOver80 = + // + stoch > 80 && + stochSignal > 80 + // + ; + + // + conditions.isStochKOverD = isStochKOverD; + conditions.isStochKDUnder50 = isStochKDUnder50; + conditions.isStochKUnderD = isStochKUnderD; + conditions.isStochKDOver50 = isStochKDOver50; + conditions.isStochKDUnder20 = isStochKDUnder20; + conditions.isStochKDOver80 = isStochKDOver80; + + // + // STDDEV ... + + // + osc.CopySTDDEV( + barIndex, + mNumberOfItems, + conditions.oscStddevs // + ); + + // + double stdDevs[]; + osc.CopySTDDEV( + barIndex + 1, + 5, + stdDevs // + ); + double stdDevAVG = GetAverage(stdDevs); + + // + double stdDev = osc.GetSTDDEV(barIndex); + double stdDevLast = osc.GetSTDDEV(barIndex + 1); + + // + bool isSTDDEVOverAVG = + // + stdDev > stdDevAVG + // + ; + bool isSTDDEVUnderAVG = + // + stdDev < stdDevAVG + // + ; + bool isSTDDEVOverLast = + // + stdDev > stdDevLast + // + ; + bool isSTDDEVUnderLast = + // + stdDev < stdDevLast + // + ; + + // + conditions.isSTDDEVOverAVG = isSTDDEVOverAVG; + conditions.isSTDDEVUnderAVG = isSTDDEVUnderAVG; + conditions.isSTDDEVOverLast = isSTDDEVOverLast; + conditions.isSTDDEVUnderLast = isSTDDEVUnderLast; + } + + // + // Initial Market Cycle ... + bool Init( + X121MCycleInputs &inputs // Inputs for Initialization + ) + { + // + bool result = false; + + // + // Validate Input ... + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + string symbol = mInputs.cycle.symbol; + ENUM_TIMEFRAMES period = mInputs.cycle.period; + + // + // Init Helpers ... + + // + // XMC ... + result = mc.Init( + symbol, + period, + mInputs.mcInputs + // + ); + if (!result) + { + return result; + } + + // + // XSTR ... + result = str.Init( + symbol, + period, + mInputs.strInputs + // + ); + if (!result) + { + return result; + } + + // + // XCHE ... + result = che.Init( + symbol, + period, + mInputs.cheInputs + // + ); + if (!result) + { + return result; + } + + // + // XOSC ... + result = osc.Init( + symbol, + period, + mInputs.oscInputs + // + ); + if (!result) + { + return result; + } + + // + // XICH ... + result = ich.Init( + symbol, + period, + mInputs.ichInputs + // + ); + if (!result) + { + return result; + } + + // + return result; + } + + // + // Draw Tools ... + // + // Completely Draw Bars ... + void Draw( + long chartID, // Chart ID ... + int subWindow, // Chart Sub Window ... + int &offset // Distance used for Labels ... + ) + { + // + if (mInputs.drawCBar || mInputs.drawPBar) + { + // + DrawOHCL( + chartID, + subWindow, + mInputs.drawLabels, + !mInputs.drawCBar && mInputs.drawPBar, + !mInputs.drawPBar && mInputs.drawCBar, + offset + // + ); + + // + if (mInputs.drawLabels) + { + offset += 3; + } + } + + // + if (mInputs.drawCBarMid || mInputs.drawPBarMid) + { + // + DrawMidLine( + chartID, + subWindow, + mInputs.drawLabels, + !mInputs.drawCBarMid && mInputs.drawPBarMid, + !mInputs.drawPBarMid && mInputs.drawCBarMid, + offset + // + ); + + // + if (mInputs.drawLabels) + { + // + if (mInputs.drawCBarMid) + { + offset++; + } + + // + if (mInputs.drawPBarMid) + { + offset++; + } + } + } + } + + // + // Draw Functions ... + // + // Draw Middle Line of Cycle ... + void DrawOHCL( + long chartID, + int subWindow, + bool drawLabel = false, // Specify Draw Label of Mid Line or not ... + bool drawOnlyPrev = false, // Specify Draw Only Prev Bar of Cycle ... + bool drawOnlyCurrent = false, // Specify Draw Only Current Bar of Cycle ... + int offset = 0 // Distance used for Labels ... + ) + { + // + if (offset < 0) + { + offset = 0; + } + + // + string baseTag = ToString(mInputs.cycle.cycle); + + // + XOHCL cBar = GetBar(0); + XOHCL pBar = GetBar(1); + + // + datetime fromCDate = GetBarTime(0); + datetime fromPDate = GetBarTime(1); + + // + datetime cTime = TimeCurrent(); + + // + // Try to Draw ... + + // + bool canDrawPrev = !drawOnlyCurrent; + bool canDrawCurrent = !drawOnlyPrev; + + // + // Set Cycles Color based on Current Candle ... + + // + bool isCBarBullish = + cBar.IsBullish(); + + // + bool isPBarBullish = + pBar.IsBearish(); + + // + color clrTemoBullishColor = mInputs.cBarDrawSpecs.openStyle.clr; + color clrTemoBearishColor = mInputs.cBarDrawSpecs.closeStyle.clr; + + // + color cBarSelectedColor = isCBarBullish ? clrTemoBullishColor : clrTemoBearishColor; + color pBarSelectedColor = isPBarBullish ? clrTemoBullishColor : clrTemoBearishColor; + + // + mInputs.cBarDrawSpecs.openStyle.clr = cBarSelectedColor; + mInputs.cBarDrawSpecs.openStyle.labelColor = cBarSelectedColor; + + // + mInputs.cBarDrawSpecs.closeStyle.clr = cBarSelectedColor; + mInputs.cBarDrawSpecs.closeStyle.labelColor = cBarSelectedColor; + + // + mInputs.pBarDrawSpecs.openStyle.clr = pBarSelectedColor; + mInputs.pBarDrawSpecs.openStyle.labelColor = pBarSelectedColor; + + // + mInputs.pBarDrawSpecs.closeStyle.clr = pBarSelectedColor; + mInputs.pBarDrawSpecs.closeStyle.labelColor = pBarSelectedColor; + + // + if (canDrawPrev) + { + offset++; + } + + // + // Label ... + if (drawLabel) + { + // + if (canDrawPrev) + { + // + // Draw Prev Bar Lables ... + + // + DrawXOHCLLabel( + chartID, + subWindow, + pBar, + mInputs.pBarDrawSpecs, + "P", + cTime, + offset - 1 + // + ); + + // + offset += 3; + } + + // + if (canDrawCurrent) + { + // + // Draw Current Bar Lables ... + + // + DrawXOHCLLabel( + chartID, + subWindow, + cBar, + mInputs.cBarDrawSpecs, + "C", + cTime, + offset + // + ); + } + } + + // + // Line ... + + // + if (canDrawPrev) + { + // + // Draw Cycle Prev Bar ... + DrawXOHCLContent( + chartID, + subWindow, + pBar, + mInputs.pBarDrawSpecs, + "P", + fromPDate + // + ); + } + + // + if (canDrawCurrent) + { + // + // Draw Cycle Current Bar ... + DrawXOHCLContent( + chartID, + subWindow, + cBar, + mInputs.cBarDrawSpecs, + "C", + fromCDate + // + ); + } + } + + // + // Draw Middle Line of Cycle ... + void DrawMidLine( + long chartID, + int subWindow, + bool drawLabel = false, // Specify Draw Label of Mid Line or not ... + bool drawOnlyPrev = false, // Specify Draw Only Prev Bar of Cycle ... + bool drawOnlyCurrent = false, // Specify Draw Only Current Bar of Cycle ... + int offset = 0 // Distance used for Labels ... + ) + { + // + if (offset < 0) + { + offset = 0; + } + + // + // Calculate Mid Line ... + XOHCL cBar = GetBar(0); + double cMidLine = cBar.GetMid(); + + // + XOHCL pBar = GetBar(1); + double pMidLine = pBar.GetMid(); + + // + string baseTag = ToString(mInputs.cycle.cycle); + + // + string midCTag = baseTag + "|MID|C|"; + string midPTag = baseTag + "|MID|P|"; + + // + string midCLblTag = midCTag + "lbl"; + string midPLblTag = midPTag + "lbl"; + + // + datetime fromCDate = GetBarTime(0); + datetime fromPDate = GetBarTime(1); + + // + datetime cTime = TimeCurrent(); + + // + // Try to Draw ... + + // + bool canDrawPrev = !drawOnlyCurrent; + bool canDrawCurrent = !drawOnlyPrev; + + // + if (canDrawPrev) + { + offset++; + } + + // + // Label ... + if (drawLabel) + { + // + if (canDrawPrev) + { + // + // Draw Prev Candle MidLine Lable ... + DrawLabel( + chartID, + subWindow, + mInputs.pBarMidDrawSpecs, + midPLblTag, + cTime, + pMidLine, + offset // + ); + } + + // + if (canDrawCurrent) + { + // + // Draw Current Candle MidLine Label ... + DrawLabel( + chartID, + subWindow, + mInputs.cBarMidDrawSpecs, + midCLblTag, + cTime, + cMidLine, + offset - 1 // + ); + } + } + + // + // Line ... + + // + if (canDrawPrev) + { + // + // Draw Prev Candle MidLine ... + DrawLine( + chartID, + subWindow, + mInputs.pBarMidDrawSpecs, + midPTag, + fromPDate, + pMidLine // + ); + } + + // + if (canDrawCurrent) + { + // + // Draw Current Candle MidLine ... + DrawLine( + chartID, + subWindow, + mInputs.cBarMidDrawSpecs, + midCTag, + fromCDate, + cMidLine // + ); + } + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + + // + X121MCycleInputs mInputs; + + // + // Tools ... + + // + bool Update(int hostBarIndex = 0) + { + return mInputs.cycle.Update(hostBarIndex); + } + + // + // Draw Functions ... + + // + // Draw OHCL Labels ... + void DrawXOHCLLabel( + long chartID, + int subWindow, + XOHCL &bar, // Specify Cycle XOHCL Model to Draw ... + XOHCLDrawSpecification &specs, // Specify Cycle XOHCL Draw Specifications ... + string baseTag, // Specify a Unique Tag ... + datetime time, // Draw Time ... + int offset = 0 // + ) + { + // + // Open ... + string openTag = mInputs.cycle.prefix + "_" + baseTag + "_O_lbl"; + DrawLabel( + chartID, + subWindow, + specs.openStyle, + openTag, + time, + bar.open, + offset + // + ); + + // + // High ... + string highTag = mInputs.cycle.prefix + "_" + baseTag + "_H_lbl"; + DrawLabel( + chartID, + subWindow, + specs.highStyle, + highTag, + time, + bar.high, + offset + 1 + // + ); + + // + // Close ... + string closeTag = mInputs.cycle.prefix + "_" + baseTag + "_C_lbl"; + DrawLabel( + chartID, + subWindow, + specs.closeStyle, + closeTag, + time, + bar.close, + offset + 2 + // + ); + + // + // Low ... + string lowTag = mInputs.cycle.prefix + "_" + baseTag + "_L_lbl"; + DrawLabel( + chartID, + subWindow, + specs.lowStyle, + lowTag, + time, + bar.low, + offset + 3 + // + ); + } + + // + // Draw XOHCL Content ... + void DrawXOHCLContent( + long chartID, + int subWindow, + XOHCL &bar, // Specify Cycle XOHCL Model to Draw ... + XOHCLDrawSpecification &specs, // Specify Cycle XOHCL Draw Specifications ... + string baseTag, // Specify a Unique Tag ... + datetime time // Draw Time ... + ) + { + // + // Open ... + string openTag = mInputs.cycle.prefix + "_" + baseTag + "_O"; + DrawLine( + chartID, + subWindow, + specs.openStyle, + openTag, + time, + bar.open + // + ); + + // + // High ... + string highTag = mInputs.cycle.prefix + "_" + baseTag + "_H"; + DrawLine( + chartID, + subWindow, + specs.highStyle, + highTag, + time, + bar.high + // + ); + + // + // Close ... + string closeTag = mInputs.cycle.prefix + "_" + baseTag + "_C"; + DrawLine( + chartID, + subWindow, + specs.closeStyle, + closeTag, + time, + bar.close + // + ); + + // + // Low ... + string lowTag = mInputs.cycle.prefix + "_" + baseTag + "_L"; + DrawLine( + chartID, + subWindow, + specs.lowStyle, + lowTag, + time, + bar.low + // + ); + } + + // + // Draw Label Using Specifications ... + void DrawLabel( + long chartID, + int subWindow, + XDrawSpecifications &specs, + string tag, + datetime time, + double price, + int offset = 0 // + ) + { + // + if (offset < 0) + { + offset = 0; + } + + // + int offsetSeconds = PeriodSeconds(mInputs.cycle.hostPeriod) * offset; + + // + string value = specs.label; + + // + DrawText( + chartID, + tag, + subWindow, + time - offsetSeconds, + price, + specs.label, + specs.labelFont, + specs.labelFontSize, + specs.labelColor, + specs.labelAngel, + specs.labelAnchor, + specs.back, + specs.selection, + specs.hidden, + specs.zOrder // + ); + } + + // + // Draw TrendLine Using Specifications ... + void DrawLine( + long chartID, + int subWindow, + XDrawSpecifications &specs, + string tag, + datetime fromDate, + double fromPrice, + datetime toDate = NULL, + double toPrice = 0 // + ) + { + // + if (toPrice <= 0) + { + toPrice = fromPrice; + } + + // + if (toDate == 0 || toDate == NULL) + { + toDate = TimeCurrent(); + } + + // + DrawTrendLine( + chartID, + tag, + subWindow, + fromDate, + fromPrice, + toDate, + toPrice, + specs.clr, + specs.style, + specs.width, + specs.back, + specs.selection, + specs.rayRight, + specs.hidden, + specs.zOrder // + ); + } +}; + +// +// Tools ... + +// +struct X121MarketCycleDescriptor +{ + // + string symbol; // Trading Symbol + ENUM_TIMEFRAMES hostPeriod; // Host Period + ENUM_X_MARKET_CYCLES cycle; // Init Cycle + ENUM_TIMEFRAMES period; // Cycle Period + ENUM_X_PERIOD_METHOD periodMethod; // Cycle Period Method + string prefix; // Prefix + bool useDefaults; // Use Inputs Default Settings ... + + // + X121MCycleInputs inputs; // Inputs + + // + XSCX121Market *market; // Market + + // + X121MCycleConditions conditions; // Market Conditions + + // + // Tools ... + + // + bool Init() + { + // + bool result = false; + + // + result = inputs.Init( + symbol, + hostPeriod, + cycle, + period, + periodMethod, + prefix, + useDefaults // + ); + if (!result) + { + return result; + } + + // + + // + // Instantiate Market ... + market = new XSCX121Market(); + + // + // Initialize Market ... + result = market.Init(inputs); + + // + return result; + } + + // + bool Init( + string mSymbol, // Trading Symbol + ENUM_TIMEFRAMES mHostPeriod, // Host Period + ENUM_X_MARKET_CYCLES mCycle, // Init Cycle + ENUM_TIMEFRAMES mPeriod, // Cycle Period + ENUM_X_PERIOD_METHOD mPeriodMethod, // Cycle Period Method + string mPrefix = "", // Prefix + bool mUseDefaults = true // Use Inputs Default Settings ... + ) + { + // + bool result = false; + + // + result = + // + IsValid(mSymbol) && + IsValid(mHostPeriod) && + IsValid(mPeriodMethod, mPeriod) + // + ; + if (!result) + { + return result; + } + + // + this.cycle = mCycle; + this.symbol = mSymbol; + this.period = mPeriod; + this.prefix = mPrefix; + this.hostPeriod = mHostPeriod; + this.useDefaults = mUseDefaults; + this.periodMethod = mPeriodMethod; + + // + result = this.Init(); + + // + return result; + } +}; + +// \ No newline at end of file diff --git a/Classes/x-saherelm.x5.provider.class.mq5 b/Classes/x-saherelm.x5.provider.class.mq5 index 1601cf60..8b5a7748 100644 --- a/Classes/x-saherelm.x5.provider.class.mq5 +++ b/Classes/x-saherelm.x5.provider.class.mq5 @@ -2,7 +2,7 @@ // // SaherElm IT Center MQL5 Class Library // ---------------------------------------------- -// Name: XSCBaseX5Provider +// Name: XSCX5Provider // Description: provides all Base Provider // requirements For X5 ... // @@ -547,6 +547,7 @@ public: bool isXCHMALCFastCrossedUnderSlow; // + // Tools ... // // Conditions ... @@ -1757,6 +1758,41 @@ public: // string result = NULL; + // + result = GenerateSummaryBody( + onlySummary, + multiplier, + separator, + ignoreFalseConditions + // + ); + + // + // Generating Full Result by Combining parts ... + result = + // + "[" + GetToken() + "]" + separator + + "-----------------------------" + separator + + result + + "" + // + ; + + // + return result; + } + + // + string GenerateSummaryBody( + const bool onlySummary = false, // Only Generate Conditions Summary + double multiplier = 1, // Score Multiplier + const string separator = "\n", // Separator + const bool ignoreFalseConditions = true // Ignore False Conditions + ) + { + // + string result = NULL; + // double bullScore = 0; double bearScore = 0; @@ -2007,8 +2043,6 @@ public: // Generating Full Result by Combining parts ... result = // - "[" + GetToken() + "]" + separator + - "-----------------------------" + separator + commonStr + (onlySummary ? "" @@ -2031,6 +2065,43 @@ public: return result; } + // + string GenerateSummary( + string provided, // Additional Info about Type, Provider and Symbol + const bool onlySummary = false, // Only Generate Conditions Summary + double multiplier = 1, // Score Multiplier + const string separator = "\n", // Separator + const bool ignoreFalseConditions = true // Ignore False Conditions + ) + { + // + string result = NULL; + + // + result = GenerateSummaryBody( + onlySummary, + multiplier, + separator, + ignoreFalseConditions + // + ); + + // + // Generating Full Result by Combining parts ... + result = + // + "[" + GetToken() + "]" + separator + + provided + separator + + "-----------------------------" + separator + + result + + "" + // + ; + + // + return result; + } + // // For Data Collector ... string GetToken() @@ -2109,11 +2180,33 @@ public: // Properties Gettr(s) / Setter(s) ... // - // Inheritance ... + // Overrides ... + + // + // DeInit all Requirements ... + void DeInit() override + { + // + delete tsHelper; + delete fiHelper; + delete tdHelper; + delete lhHelper; + delete tmHelper; + delete ccHelper; + delete ctHelper; + delete obdHelper; + delete rsiHelper; + delete amaHelper; + delete chmaHelper; + delete chlhHelper; + } + + // + // Functions ... // // Init all Requirements ... - virtual bool Init(X5ProviderInputs &inputs) + bool Init(X5ProviderInputs &inputs) { // bool result = false; @@ -2289,28 +2382,6 @@ public: return result; } - // - // DeInit all Requirements ... - virtual void DeInit() - { - // - delete tsHelper; - delete fiHelper; - delete tdHelper; - delete lhHelper; - delete tmHelper; - delete ccHelper; - delete ctHelper; - delete obdHelper; - delete rsiHelper; - delete amaHelper; - delete chmaHelper; - delete chlhHelper; - } - - // - // Functions ... - // // Set Default Position's Type ... // Enable / Disable Long (Buy), Short (Sell) ... @@ -2783,16 +2854,59 @@ public: if (result) { // - mWaitsUntilNewBar = true; + // Here We Have to Prepare Signal ... // - string mConditionsStr = mConditions.GenerateSummary(true); + // TODO: Make this Configurable ... + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + double tpPoint = 30; + double volume = 0.01; + double tpPrice = PointToPrice( + tpPoint, + symbol // + ); + ENUM_POSITION_TYPE type = hasLong + ? POSITION_TYPE_BUY + : POSITION_TYPE_SELL; + ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET; + double entry = GetEntry( + symbol, + type // + ); + double tp = hasLong + ? entry + tpPrice + : entry - tpPrice; + double sl = 0; + ENUM_X_SIGNAL_MANAGING_ACTIONS action = X_SIGNAL_USE_NOTHING; // - string providerTypeStr = GetSymbol() + ", " + provider + "(" + (hasLong ? "Long" : "Short") + ")"; - mConditionsStr = providerTypeStr + "\n" + mConditionsStr; - mConditionsCollector.Add(mConditionsStr); - Print(mConditionsStr); + result = mSignal.Prepare( + symbol, + provider, + period, + type, + mode, + entry, + volume, + action, + sl, + tp + // + ); + + // + if (result) + { + // + mWaitsUntilNewBar = true; + + // + string providerTypeStr = GetSymbol() + ", " + provider + "(" + (hasLong ? "Long" : "Short") + ")"; + string mConditionsStr = mConditions.GenerateSummary(providerTypeStr, true); + mConditionsCollector.Add(mConditionsStr); + Print(mConditionsStr); + } } // @@ -95066,7 +95180,7 @@ struct X5ProviderDescriptor // ENUM_X5_SIGNAL_PROVIDERS tmp[]; Copy( - mSignallers, + mSignallers, tmp // ); Copy( @@ -95171,7 +95285,8 @@ struct X5ProviderDescriptor result = provider.HasSignal( barIndex, signal, - conditions); + conditions // + ); // return result; diff --git a/Classes/x-saherelm.x5.xea.class.mq5 b/Classes/x-saherelm.x5.xea.class.mq5 index 7dfcf066..938cae7f 100644 --- a/Classes/x-saherelm.x5.xea.class.mq5 +++ b/Classes/x-saherelm.x5.xea.class.mq5 @@ -210,6 +210,9 @@ public: signals // ); + + // + NotifyX5OnSignalEventHandlers(iDescriptor); } } diff --git a/Classes/x-saherelm.xea.class.mq5 b/Classes/x-saherelm.xea.class.mq5 index ed72ec57..f6bfa815 100644 --- a/Classes/x-saherelm.xea.class.mq5 +++ b/Classes/x-saherelm.xea.class.mq5 @@ -385,6 +385,10 @@ public: // OnTick Handler ... virtual void OnTick() { + // + // Draw ... + Draw(); + // // Check Trade Events ... OnTrade(); @@ -528,6 +532,10 @@ public: // TODO: Implement this ... } + // + // Draw On Chart if anything is required ... + virtual void Draw() {} + // // Check For any Guard Actions ... virtual bool CheckForGuard(XGuard &guards[]) @@ -628,7 +636,19 @@ public: string message = NULL; if (executedSignalsCount == 0) { + // message = "(" + ToString(filteredSignalsCount) + ") Signals Execution Failed ..."; + + // + for (int j = 0; j < ArraySize(reasons); j++) + { + // + string iReason = ToString(reasons[j]); + + // + // ToString(GetSpread(filteredSignals[j].symbol)) + "," + message += "\n" + ToString(j) + ": " + iReason; + } } else if (executedSignalsCount < filteredSignalsCount) { diff --git a/Experts/x-test.x121ea.mq5 b/Experts/x-test.x121ea.mq5 new file mode 100644 index 00000000..8c1e8c44 --- /dev/null +++ b/Experts/x-test.x121ea.mq5 @@ -0,0 +1,420 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center X121EA MQL5 Expert Advisor +// ------------------------------------------------- +// Name: X121EA +// 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 X121EA" +#property strict + +// +#define ShortName "X121EA" + +// +#include "../Classes/x-saherelm.x121.xea.class.mq5" + +// +// "EURUSDb,USDCHFb,USDJPYb,XAUUSDb" + +// +// Inputs ... +long x121EAMagicNumber = 78692110; // Magic Number +int x121EASlippage = 10; // Slippgae +string x121EASymbols = "EURUSDb,USDCHFb"; // Symbols +// +bool x121EAAllowLong = true; // Allow Long Trades +bool x121EAAllowShort = true; // Allow Short Trades +int x121EAManageInterval = 5; // Manager Check Intervals Seconds +int x121EAMaxAllowedPositions = 15; // Max Allowed Positions +double x121EAMaxAllowedSpread = 0; // Max Allowed Spred for Opening Trades +double x121EAMinProfitPerTrade = 0; // Min Profit Per Trade based On Volume Factor (Hedge) +double x121EAMinProfitPerVolumeFactor = 0; // Min Volume Factor for Calculating Profit (Hedge) +double x121EAMaxAllowedDrawdownFactor = 0; // Max Allowed Drawdown Factor +// +double x121EAVolume = 0.01; + +// +// Vars ... +string x121EASymbol; +ENUM_TIMEFRAMES x121EAPeriod; + +// +MqlTick x121EATick; + +// +// X121EA ... +XSCX121EA *mX121EA; + +// +// Event Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + if (x121EASymbol == NULL || StringLen(x121EASymbol) <= 0) + { + x121EASymbol = _Symbol; + } + + // + if (x121EAPeriod == NULL) + { + x121EAPeriod = _Period; + } + + // + // Validate Inputs ... + if (!X121EAValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Initial EA ... + if (!InitialEA()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // TesterHideIndicators(true); + + // + // 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 X121EA Providers ... +} + +// +// On Tick Handler ... +void OnTick() +{ + // + // Reading Tick ... + if (!SymbolInfoTick(x121EASymbol, x121EATick)) + { + return; + } + + // + mX121EA.OnTick(); +} + +// +// Custom Functions ... + +// +// Validate Variables nd Inputs ... +bool X121EAValidateInputs() +{ + // + bool result = false; + + // + result = + // + x121EASlippage > 0 && + x121EAMagicNumber > 0 + // + ; + + // + return result; +} + +// +// Initialize Specific Providers ... +bool InitialEA() +{ + // + bool result = false; + + // + // Here We Have to Initial 4 instance of X5Provider ... + // - EURUSD/M5; + // - USDCHF/M5; + // - USDJPY/M5; + // - XAUUSD/M5; + + // + result = IsValid(x121EASymbols); + if (!result) + { + return result; + } + + // + string symbols[]; + int symbolsCount = SplitContent( + symbols, + x121EASymbols); + result = symbolsCount > 0; + if (!result) + { + return result; + } + + // + // Define Signallers ... + ENUM_X121_SIGNAL_PROVIDERS signallers[]; + GetAllX121SignalProviders(signallers); + + // + // Instantiate X121EA Class ... + mX121EA = new XSCX121EA( + x121EASlippage, // Slippgae + x121EAMagicNumber, // Magic Number + x121EAManageInterval, // Manager Check Intervals Seconds + x121EAMaxAllowedSpread, // Max Allowed Spred for Opening Trades + x121EAMaxAllowedPositions, // Max Allowed Positions + x121EAMaxAllowedDrawdownFactor, // Max Allowed Drawdown Factor + x121EAAllowLong, // Allow Long Trades + x121EAAllowShort, // Allow Short Trades + x121EAMinProfitPerTrade, // Min Profit Per Trade based On Volume Factor (Hedge) + x121EAMinProfitPerVolumeFactor // Min Volume Factor for Calculating Profit (Hedge) + ); + + // + // Prepare Providers and Add them into mX121EA class ... + for (int i = 0; i < symbolsCount; i++) + { + // + // Requirements ... + string iSymbol = symbols[i]; + ENUM_TIMEFRAMES iPeriod = PERIOD_M5; + + // + // Define Structure ... + X121ProviderDescriptor iDescriptor; + + // + iDescriptor.symbol = iSymbol; + iDescriptor.period = iPeriod; + iDescriptor.allowLong = x121EAAllowLong; + iDescriptor.allowShort = x121EAAllowShort; + Copy( + signallers, + iDescriptor.signallers); + + // + // Set Inputs to Default ... + iDescriptor.inputs.Default(); + + // + // Prepare Input Requirements ... + + // + // XMC ... + iDescriptor.inputs.mcInputs.showFastMa = false; + iDescriptor.inputs.mcInputs.showSlowMa = false; + iDescriptor.inputs.mcInputs.showVerifierMa = false; + + // + // XICH ... + iDescriptor.inputs.ichInputs.showKumo = false; + iDescriptor.inputs.ichInputs.showKijunSen = false; + iDescriptor.inputs.ichInputs.showTenkanSen = false; + iDescriptor.inputs.ichInputs.showChikouSpan = false; + iDescriptor.inputs.ichInputs.showSenkouSpanA = false; + iDescriptor.inputs.ichInputs.showSenkouSpanB = false; + iDescriptor.inputs.ichInputs.showKijunSenPlus = false; + iDescriptor.inputs.ichInputs.showKijunSenNegative = false; + + // + // XSTR ... + iDescriptor.inputs.cheInputs.showLongExit1Line = false; + iDescriptor.inputs.cheInputs.showShortExit1Line = false; + iDescriptor.inputs.cheInputs.showLongExit2Line = false; + iDescriptor.inputs.cheInputs.showShortExit2Line = false; + + // + // XSTR ... + iDescriptor.inputs.strInputs.showTrends = false; + iDescriptor.inputs.strInputs.fillTrends = false; + + // + iDescriptor.inputs.symbol = iSymbol; + iDescriptor.inputs.period = iPeriod; + + // + // Short MArket ... + iDescriptor.inputs.sMarketPeriod = NULL; + iDescriptor.inputs.sMarketMethod = X_PERIOD_AUTO; + + // + // Medium Market ... + iDescriptor.inputs.mMarketPeriod = NULL; + iDescriptor.inputs.mMarketMethod = X_PERIOD_AUTO; + + // + // Long Market ... + iDescriptor.inputs.lMarketPeriod = NULL; + iDescriptor.inputs.lMarketMethod = X_PERIOD_AUTO; + + // + int fontSize = 12; + double fontAngel = 90; + string fontName = "Arial"; + ENUM_ANCHOR_POINT fontAnchor = ANCHOR_LEFT_UPPER; + + // + // Hind Market ... + iDescriptor.inputs.hMarketPeriod = NULL; + iDescriptor.inputs.hMarketMethod = X_PERIOD_AUTO; + iDescriptor.inputs.hMarketInputs.drawLabels = true; + iDescriptor.inputs.hMarketInputs.drawCBar = true; + iDescriptor.inputs.hMarketInputs.drawPBar = true; + iDescriptor.inputs.hMarketInputs.drawCBarMid = true; + iDescriptor.inputs.hMarketInputs.drawPBarMid = true; + iDescriptor.inputs.hMarketInputs.cBarDrawSpecs.Default(); + iDescriptor.inputs.hMarketInputs.pBarDrawSpecs.Default(); + + // + iDescriptor.inputs.hMarketInputs.cBarDrawSpecs.openStyle.Label( + "C Hind Open", + iDescriptor.inputs.hMarketInputs.cBarDrawSpecs.openStyle.clr, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + iDescriptor.inputs.hMarketInputs.cBarDrawSpecs.highStyle.Label( + "C Hind High", + iDescriptor.inputs.hMarketInputs.cBarDrawSpecs.highStyle.clr, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + iDescriptor.inputs.hMarketInputs.cBarDrawSpecs.closeStyle.Label( + "C Hind Close", + iDescriptor.inputs.hMarketInputs.cBarDrawSpecs.closeStyle.clr, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + iDescriptor.inputs.hMarketInputs.cBarDrawSpecs.lowStyle.Label( + "C Hind Low", + iDescriptor.inputs.hMarketInputs.cBarDrawSpecs.lowStyle.clr, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + + // + iDescriptor.inputs.hMarketInputs.pBarDrawSpecs.openStyle.Label( + "P Hind Open", + iDescriptor.inputs.hMarketInputs.pBarDrawSpecs.openStyle.clr, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + iDescriptor.inputs.hMarketInputs.pBarDrawSpecs.highStyle.Label( + "P Hind High", + iDescriptor.inputs.hMarketInputs.pBarDrawSpecs.highStyle.clr, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + iDescriptor.inputs.hMarketInputs.pBarDrawSpecs.closeStyle.Label( + "P Hind Close", + iDescriptor.inputs.hMarketInputs.pBarDrawSpecs.closeStyle.clr, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + iDescriptor.inputs.hMarketInputs.pBarDrawSpecs.lowStyle.Label( + "P Hind Low", + iDescriptor.inputs.hMarketInputs.pBarDrawSpecs.lowStyle.clr, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + + iDescriptor.inputs.hMarketInputs.cBarMidDrawSpecs.clr = clrYellow; + iDescriptor.inputs.hMarketInputs.cBarMidDrawSpecs.Label( + "C Hind Mid", + clrYellow, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + iDescriptor.inputs.hMarketInputs.pBarMidDrawSpecs.clr = clrYellow; + iDescriptor.inputs.hMarketInputs.pBarMidDrawSpecs.Label( + "P Hind Mid", + clrYellow, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + + // + // Init Inputs ... + result = iDescriptor.inputs.Init(); + if (!result) + { + return result; + } + + // + // Validate Inputs ... + bool isInputsValid = iDescriptor.inputs.IsValid(); + if (!isInputsValid) + { + continue; + } + + // + result = mX121EA.AddProvider(iDescriptor); + if (!result) + { + break; + } + } + + // + return result; +} + +// \ No newline at end of file diff --git a/Experts/x-test.x5121ea.mq5 b/Experts/x-test.x5121ea.mq5 new file mode 100644 index 00000000..8c37492c --- /dev/null +++ b/Experts/x-test.x5121ea.mq5 @@ -0,0 +1,251 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center X5121EA MQL5 Expert Advisor +// ------------------------------------------------- +// Name: X5121EA and X121EA +// 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 X5121EA" +#property strict + +// +#define ShortName "X5121EA" + +// +#include "../Classes/x-saherelm.x5.xea.class.mq5" + +// +// "EURUSDb,USDCHFb,USDJPYb,XAUUSDb" + +// +// Inputs ... +long x5EAMagicNumber = 78692110; // Magic Number +int x5EASlippage = 10; // Slippgae +string x5EASymbols = "EURUSDb,USDCHFb,USDJPYb,XAUUSDb"; // Symbols +// +bool x5EAAllowLong = true; // Allow Long Trades +bool x5EAAllowShort = true; // Allow Short Trades +int x5EAManageInterval = 5; // Manager Check Intervals Seconds +int x5EAMaxAllowedPositions = 15; // Max Allowed Positions +double x5EAMaxAllowedSpread = 0; // Max Allowed Spred for Opening Trades +double x5EAMinProfitPerTrade = 0; // Min Profit Per Trade based On Volume Factor (Hedge) +double x5EAMinProfitPerVolumeFactor = 0; // Min Volume Factor for Calculating Profit (Hedge) +double x5EAMaxAllowedDrawdownFactor = 0; // Max Allowed Drawdown Factor +// +double x5EAVolume = 0.01; + +// +// Vars ... +string x5EASymbol; +ENUM_TIMEFRAMES x5EAPeriod; + +// +MqlTick x5EATick; + +// +// X5121EA ... +XSCX5121EA *mX5121EA; + +// +// Event Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + if (x5EASymbol == NULL || StringLen(x5EASymbol) <= 0) + { + x5EASymbol = _Symbol; + } + + // + if (x5EAPeriod == NULL) + { + x5EAPeriod = _Period; + } + + // + // Validate Inputs ... + if (!X5121EAValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Initial EA ... + if (!InitialX5EA()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + TesterHideIndicators(true); + + // + // 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 X5121EA Providers ... +} + +// +// On Tick Handler ... +void OnTick() +{ + // + // Reading Tick ... + if (!SymbolInfoTick(x5EASymbol, x5EATick)) + { + return; + } + + // + mX5121EA.OnTick(); +} + +// +// Custom Functions ... + +// +// Validate Variables nd Inputs ... +bool X5121EAValidateInputs() +{ + // + bool result = false; + + // + result = + // + x5EASlippage > 0 && + x5EAMagicNumber > 0 + // + ; + + // + return result; +} + +// +// Initialize Specific Providers ... +bool InitialX5EA() +{ + // + bool result = false; + + // + // Here We Have to Initial 4 instance of X5Provider ... + // - EURUSD/M5; + // - USDCHF/M5; + // - USDJPY/M5; + // - XAUUSD/M5; + + // + result = IsValid(x5EASymbols); + if (!result) + { + return result; + } + + // + string symbols[]; + int symbolsCount = SplitContent( + symbols, + x5EASymbols); + result = symbolsCount > 0; + if (!result) + { + return result; + } + + // + // Define Signallers ... + ENUM_X5_SIGNAL_PROVIDERS signallers[]; + GetAllX5SignalProviders(signallers); + + // + // Instantiate X5121EA Class ... + mX5121EA = new XSCX5121EA( + x5EASlippage, // Slippgae + x5EAMagicNumber, // Magic Number + x5EAManageInterval, // Manager Check Intervals Seconds + x5EAMaxAllowedSpread, // Max Allowed Spred for Opening Trades + x5EAMaxAllowedPositions, // Max Allowed Positions + x5EAMaxAllowedDrawdownFactor, // Max Allowed Drawdown Factor + x5EAAllowLong, // Allow Long Trades + x5EAAllowShort, // Allow Short Trades + x5EAMinProfitPerTrade, // Min Profit Per Trade based On Volume Factor (Hedge) + x5EAMinProfitPerVolumeFactor // Min Volume Factor for Calculating Profit (Hedge) + ); + + // + // Prepare Providers and Add them into mX5121EA class ... + for (int i = 0; i < symbolsCount; i++) + { + // + // Define Structure ... + X5ProviderDescriptor iDescriptor; + + // + iDescriptor.symbol = symbols[i]; + iDescriptor.period = PERIOD_M5; + iDescriptor.allowLong = x5EAAllowLong; + iDescriptor.allowShort = x5EAAllowShort; + Copy( + signallers, + iDescriptor.signallers); + + // + // Set Inputs to Default ... + iDescriptor.inputs.Default(); + + // + // Validate Inputs ... + bool isInputsValid = iDescriptor.inputs.IsValid(); + if (!isInputsValid) + { + continue; + } + + // + result = mX5121EA.AddProvider(iDescriptor); + if (!result) + { + break; + } + } + + // + return result; +} + +// \ No newline at end of file diff --git a/Experts/x-test.x5ea.mq5 b/Experts/x-test.x5ea.mq5 index 3526ba53..a2fcc378 100644 --- a/Experts/x-test.x5ea.mq5 +++ b/Experts/x-test.x5ea.mq5 @@ -30,18 +30,18 @@ // // Inputs ... -long x5EAMagicNumber = 78692110; // Magic Number -int x5EASlippage = 10; // Slippgae -string x5EASymbols = "EURUSDb"; // Symbols +long x5EAMagicNumber = 78692110; // Magic Number +int x5EASlippage = 10; // Slippgae +string x5EASymbols = "EURUSDb,USDCHFb,USDJPYb,XAUUSDb"; // Symbols // -bool x5EAAllowLong = true; // Allow Long Trades -bool x5EAAllowShort = true; // Allow Short Trades -int x5EAManageInterval = 5; // Manager Check Intervals Seconds -int x5EAMaxAllowedPositions = 15; // Max Allowed Positions -double x5EAMaxAllowedSpread = 15; // Max Allowed Spred for Opening Trades -double x5EAMinProfitPerTrade = 0; // Min Profit Per Trade based On Volume Factor (Hedge) -double x5EAMinProfitPerVolumeFactor = 0; // Min Volume Factor for Calculating Profit (Hedge) -double x5EAMaxAllowedDrawdownFactor = 0.015; // Max Allowed Drawdown Factor +bool x5EAAllowLong = true; // Allow Long Trades +bool x5EAAllowShort = true; // Allow Short Trades +int x5EAManageInterval = 5; // Manager Check Intervals Seconds +int x5EAMaxAllowedPositions = 15; // Max Allowed Positions +double x5EAMaxAllowedSpread = 0; // Max Allowed Spred for Opening Trades +double x5EAMinProfitPerTrade = 0; // Min Profit Per Trade based On Volume Factor (Hedge) +double x5EAMinProfitPerVolumeFactor = 0; // Min Volume Factor for Calculating Profit (Hedge) +double x5EAMaxAllowedDrawdownFactor = 0; // Max Allowed Drawdown Factor // double x5EAVolume = 0.01; @@ -90,6 +90,9 @@ int OnInit() return INIT_PARAMETERS_INCORRECT; } + // + TesterHideIndicators(true); + // // Init Succeed ... return INIT_SUCCEEDED; diff --git a/Helpers/x-saherelm.xchlh.helper.mq5 b/Helpers/x-saherelm.xchlh.helper.mq5 index 487f5bc6..f67f9022 100644 --- a/Helpers/x-saherelm.xchlh.helper.mq5 +++ b/Helpers/x-saherelm.xchlh.helper.mq5 @@ -217,8 +217,8 @@ struct XCHLHInputs lcHHColor = clrAqua; lcLLColor = clrFuchsia; // LC Drawings ... - lcDrawHH = true; - lcDrawLL = true; + lcDrawHH = false; + lcDrawLL = false; // // Medium Cycle ... @@ -234,8 +234,8 @@ struct XCHLHInputs mcHHColor = clrLime; mcLLColor = clrRed; // MC Drawings ... - mcDrawHH = true; - mcDrawLL = true; + mcDrawHH = false; + mcDrawLL = false; // // Short Cycle ... @@ -251,8 +251,8 @@ struct XCHLHInputs scHHColor = clrLightBlue; scLLColor = clrLightSalmon; // SC Drawings ... - scDrawHH = true; - scDrawLL = true; + scDrawHH = false; + scDrawLL = false; } // diff --git a/Helpers/x-saherelm.xchma.helper.mq5 b/Helpers/x-saherelm.xchma.helper.mq5 index a0a6c5d5..b18120a5 100644 --- a/Helpers/x-saherelm.xchma.helper.mq5 +++ b/Helpers/x-saherelm.xchma.helper.mq5 @@ -218,8 +218,8 @@ struct XCHMAInputs lcFastColor = clrAqua; lcSlowColor = clrFuchsia; // LC Drawings ... - lcDrawFast = true; - lcDrawSlow = true; + lcDrawFast = false; + lcDrawSlow = false; lcDrawCrosses = false; // @@ -236,8 +236,8 @@ struct XCHMAInputs mcFastColor = clrLime; mcSlowColor = clrRed; // MC Drawings ... - mcDrawFast = true; - mcDrawSlow = true; + mcDrawFast = false; + mcDrawSlow = false; mcDrawCrosses = false; // @@ -254,8 +254,8 @@ struct XCHMAInputs scFastColor = clrLightBlue; scSlowColor = clrLightSalmon; // SC Drawings ... - scDrawFast = true; - scDrawSlow = true; + scDrawFast = false; + scDrawSlow = false; scDrawCrosses = false; } diff --git a/Helpers/x-saherelm.xobd.helper.mq5 b/Helpers/x-saherelm.xobd.helper.mq5 index 968e9524..03957cb5 100644 --- a/Helpers/x-saherelm.xobd.helper.mq5 +++ b/Helpers/x-saherelm.xobd.helper.mq5 @@ -68,9 +68,9 @@ struct XOBDInputs { // length = 0; - swingHighArrowCode = 108; + swingHighArrowCode = 0; swingHighArrowColor = CLR_NONE; - swingLowArrowCode = 108; + swingLowArrowCode = 0; swingLowArrowColor = CLR_NONE; } @@ -80,9 +80,9 @@ struct XOBDInputs { // length = 5; - swingHighArrowCode = 108; + swingHighArrowCode = 0; swingHighArrowColor = CLR_NONE; - swingLowArrowCode = 108; + swingLowArrowCode = 0; swingLowArrowColor = CLR_NONE; } diff --git a/Helpers/x-saherelm.xpv.helper.mq5 b/Helpers/x-saherelm.xpv.helper.mq5 index 8045a2e4..3e4ce052 100644 --- a/Helpers/x-saherelm.xpv.helper.mq5 +++ b/Helpers/x-saherelm.xpv.helper.mq5 @@ -242,7 +242,10 @@ struct XPVInputs // result = // - false + IsValid(scMethod, scPeriod) && + IsValid(mcMethod, mcPeriod) && + IsValid(lcMethod, lcPeriod) && + IsValid(hcMethod, hcPeriod) // ; @@ -290,7 +293,7 @@ public: bool Init( string symbol, // Trading Symbol ENUM_TIMEFRAMES period, // Trading Period - XPVInputs &inputs // Inputs + XPVInputs &inputs // Inputs ) { // diff --git a/Helpers/x-saherelm.xtd.helper.mq5 b/Helpers/x-saherelm.xtd.helper.mq5 index 19fb46dc..488e7d67 100644 --- a/Helpers/x-saherelm.xtd.helper.mq5 +++ b/Helpers/x-saherelm.xtd.helper.mq5 @@ -72,7 +72,7 @@ struct XTDInputs { // length = 0; - drawCrosses = true; + drawCrosses = false; // // Bullish ... @@ -91,7 +91,7 @@ struct XTDInputs { // length = 14; - drawCrosses = true; + drawCrosses = false; // // Bullish ... diff --git a/Indicators/x-saherelm.xobd.mq5 b/Indicators/x-saherelm.xobd.mq5 index d1ca9ed4..2865679a 100644 --- a/Indicators/x-saherelm.xobd.mq5 +++ b/Indicators/x-saherelm.xobd.mq5 @@ -350,6 +350,14 @@ void DrawSwingArrow( { // bool isSwingHigh = type == 1; + + // + if ((isSwingHigh && swingHighArrowCode == 0) || + (!isSwingHigh && swingLowArrowCode == 0)) + { + return; + } + XOHCL candle; candle.Init( _Symbol, diff --git a/Libraries/x-saherelm.common.lib.mq5 b/Libraries/x-saherelm.common.lib.mq5 index 136d32b3..5146afbc 100644 --- a/Libraries/x-saherelm.common.lib.mq5 +++ b/Libraries/x-saherelm.common.lib.mq5 @@ -2477,6 +2477,11 @@ bool IsValid(string value) // return result; } +bool IsSpecifiedValid(string value) +{ + return IsValid(value); +} + // // Validate a Date ... @@ -2509,6 +2514,11 @@ bool IsValid(ENUM_TIMEFRAMES value) // return result; } +bool IsSpecifiedValid(ENUM_TIMEFRAMES value) +{ + // + return IsValid(value); +} // // Validate Specified Cycle ... @@ -2556,6 +2566,17 @@ bool IsValid( return result; } +// +bool IsSpecifiedValid( + ENUM_X_PERIOD_METHOD mMethod, // Period Select Method + ENUM_TIMEFRAMES mPeriod // Selected Period +) +{ + return IsValid(mMethod, + mPeriod // + ); +} + // // Validate Swing Mode ... bool IsValid(ENUM_X_SWING_TYPE value) @@ -2633,16 +2654,17 @@ bool IsRunningOnTestMode() // // Find Chart ID ... -ulong FindChartID( +long FindChartID( string mSymbol = NULL, // Trading Symbol ENUM_TIMEFRAMES mPeriod = NULL // Trading Period ) { // - ulong result = ChartFirst(); + long result = ChartFirst(); + long first = result; // - while (result >= 0) + while (result > 0) { // string chSymbol = ChartSymbol(result); diff --git a/Libraries/x-saherelm.xtrade.lib.mq5 b/Libraries/x-saherelm.xtrade.lib.mq5 index caead5c8..4c0d1c0e 100644 --- a/Libraries/x-saherelm.xtrade.lib.mq5 +++ b/Libraries/x-saherelm.xtrade.lib.mq5 @@ -218,15 +218,16 @@ struct XSignal // bool Prepare( - string mSymbol, // Trading Symbol - string mProvider, // Signal Provider - ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame - ENUM_POSITION_TYPE mType, // Long (Buy) or Short (Sell) - ENUM_X_ORDER_MODES mMode, // Execution Mode - double mEntry, // Entry Price - double mVolume, // Volume - double sl = 0, // Stop Loss - double tp = 0 // Take Profit + string mSymbol, // Trading Symbol + string mProvider, // Signal Provider + ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame + ENUM_POSITION_TYPE mType, // Long (Buy) or Short (Sell) + ENUM_X_ORDER_MODES mMode, // Execution Mode + double mEntry, // Entry Price + double mVolume, // Volume + ENUM_X_SIGNAL_MANAGING_ACTIONS mAction = X_SIGNAL_USE_NOTHING, // Signal Management Action + double sl = 0, // Stop Loss + double tp = 0 // Take Profit ) { // @@ -284,6 +285,9 @@ struct XSignal entry = mEntry; volume = mVolume; + // + action = mAction; + // Add( sl, @@ -313,6 +317,7 @@ struct XSignal ENUM_X_ORDER_MODES mMode, // Execution Mode double mEntry, // Entry Price double mVolume, // Volume + ENUM_X_SIGNAL_MANAGING_ACTIONS mAction = X_SIGNAL_USE_NOTHING, // Signal Management Action double sl = 0, // Stop Loss double tp = 0 // Take Profit ) @@ -326,6 +331,7 @@ struct XSignal mMode, mEntry, mVolume, + mAction, sl, tp // @@ -340,6 +346,7 @@ struct XSignal ENUM_X_ORDER_MODES mMode, // Execution Mode double mEntry, // Entry Price double mVolume, // Volume + ENUM_X_SIGNAL_MANAGING_ACTIONS mAction = X_SIGNAL_USE_NOTHING, // Signal Management Action double sl = 0, // Stop Loss double tp = 0 // Take Profit ) @@ -353,6 +360,7 @@ struct XSignal mMode, mEntry, mVolume, + mAction, sl, tp // @@ -369,6 +377,7 @@ struct XSignal ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame double mEntry, // Entry Price double mVolume, // Volume + ENUM_X_SIGNAL_MANAGING_ACTIONS mAction = X_SIGNAL_USE_NOTHING, // Signal Management Action double sl = 0, // Stop Loss double tp = 0 // Take Profit ) @@ -381,6 +390,7 @@ struct XSignal X_ORDER_MODE_MARKET, mEntry, mVolume, + mAction, sl, tp // @@ -394,6 +404,7 @@ struct XSignal ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame double mEntry, // Entry Price double mVolume, // Volume + ENUM_X_SIGNAL_MANAGING_ACTIONS mAction = X_SIGNAL_USE_NOTHING, // Signal Management Action double sl = 0, // Stop Loss double tp = 0 // Take Profit ) @@ -406,6 +417,7 @@ struct XSignal X_ORDER_MODE_MARKET, mEntry, mVolume, + mAction, sl, tp // @@ -422,6 +434,7 @@ struct XSignal ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame double mEntry, // Entry Price double mVolume, // Volume + ENUM_X_SIGNAL_MANAGING_ACTIONS mAction = X_SIGNAL_USE_NOTHING, // Signal Management Action double sl = 0, // Stop Loss double tp = 0 // Take Profit ) @@ -434,6 +447,7 @@ struct XSignal X_ORDER_MODE_STOP, mEntry, mVolume, + mAction, sl, tp // @@ -447,6 +461,7 @@ struct XSignal ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame double mEntry, // Entry Price double mVolume, // Volume + ENUM_X_SIGNAL_MANAGING_ACTIONS mAction = X_SIGNAL_USE_NOTHING, // Signal Management Action double sl = 0, // Stop Loss double tp = 0 // Take Profit ) @@ -459,6 +474,7 @@ struct XSignal X_ORDER_MODE_STOP, mEntry, mVolume, + mAction, sl, tp // @@ -475,6 +491,7 @@ struct XSignal ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame double mEntry, // Entry Price double mVolume, // Volume + ENUM_X_SIGNAL_MANAGING_ACTIONS mAction = X_SIGNAL_USE_NOTHING, // Signal Management Action double sl = 0, // Stop Loss double tp = 0 // Take Profit ) @@ -487,6 +504,7 @@ struct XSignal X_ORDER_MODE_LIMIT, mEntry, mVolume, + mAction, sl, tp // @@ -500,6 +518,7 @@ struct XSignal ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame double mEntry, // Entry Price double mVolume, // Volume + ENUM_X_SIGNAL_MANAGING_ACTIONS mAction = X_SIGNAL_USE_NOTHING, // Signal Management Action double sl = 0, // Stop Loss double tp = 0 // Take Profit ) @@ -512,6 +531,7 @@ struct XSignal X_ORDER_MODE_LIMIT, mEntry, mVolume, + mAction, sl, tp //