/////////////////////////////////////////////////////// // // 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; bool isTenkanSenCrossedOverKijunSen; bool isTenkanSenCrossedUnderKijunSen; // // 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++; } if (isTenkanSenCrossedOverKijunSen) { // bullScore++; bearScore--; } // // BEARISH ... if (isSenkouSpanAUnderB) { bearScore++; } if (isSenkouSpanAUnderLast) { bearScore++; } if (isCloseUnderKijunSen) { bearScore++; } if (isTenkanSenUnderKijunSen) { bearScore++; } if (isFutureSenkouSpanAUnderB) { bearScore++; } if (isFutureSenkouSpanAUnderLast) { bearScore++; } if (isTenkanSenCrossedUnderKijunSen) { // bullScore--; 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; // // XICH ... // ich.CopyTenkanSen( barIndex, mNumberOfItems, conditions.ichTenkanSens // ); ich.CopyKijunSen( barIndex, mNumberOfItems, conditions.ichKijunSens // ); ich.CopyChikouSpan( barIndex, mNumberOfItems, conditions.ichChikouSpans // ); ich.CopySenkouSpanA( barIndex, mNumberOfItems, conditions.ichSenkouSpanBs // ); ich.CopySenkouSpanB( barIndex, mNumberOfItems, conditions.ichSenkouSpanAs // ); // double tenkanSen = ich.GetTenkanSen(barIndex); double tenkanSenPrev = ich.GetTenkanSen(barIndex + 1); // double kijunSen = ich.GetKijunSen(barIndex); double kijunSenPrev = ich.GetKijunSen(barIndex + 1); // double senkouSpanA = ich.GetSenkouSpanA(barIndex); double senkouSpanAPrev = ich.GetSenkouSpanA(barIndex + 1); // double senkouSpanB = ich.GetSenkouSpanB(barIndex); double senkouSpanBPrev = ich.GetSenkouSpanB(barIndex + 1); // double futureSenkouSpanA = ich.GetFutureSenkouSpanA(barIndex); double futureSenkouSpanAPrev = ich.GetFutureSenkouSpanA(barIndex + 1); // double futureSenkouSpanB = ich.GetFutureSenkouSpanB(barIndex); double futureSenkouSpanBPrev = ich.GetFutureSenkouSpanB(barIndex + 1); // bool isSenkouSpanAOverB = senkouSpanA > senkouSpanB; bool isSenkouSpanAUnderB = senkouSpanA < senkouSpanB; bool isSenkouSpanAOverLast = senkouSpanA > senkouSpanAPrev; bool isSenkouSpanAUnderLast = senkouSpanA < senkouSpanAPrev; bool isFutureSenkouSpanAOverB = futureSenkouSpanA > futureSenkouSpanB; bool isFutureSenkouSpanAUnderB = futureSenkouSpanA < futureSenkouSpanB; bool isFutureSenkouSpanAOverLast = futureSenkouSpanA > futureSenkouSpanAPrev; bool isFutureSenkouSpanAUnderLast = futureSenkouSpanA < futureSenkouSpanAPrev; bool isCloseOverKijunSen = pBar.close > kijunSenPrev; bool isCloseUnderKijunSen = pBar.close < kijunSenPrev; bool isTenkanSenOverKijunSen = tenkanSen > kijunSen; bool isTenkanSenUnderKijunSen = tenkanSen < kijunSen; bool isTenkanSenPrevOverKijunSen = tenkanSenPrev > kijunSenPrev; bool isTenkanSenPrevUnderKijunSen = tenkanSenPrev < kijunSenPrev; bool isTenkanSenCrossedOverKijunSen = // isTenkanSenOverKijunSen && !isTenkanSenPrevOverKijunSen // ; bool isTenkanSenCrossedUnderKijunSen = // isTenkanSenUnderKijunSen && !isTenkanSenPrevUnderKijunSen // ; // conditions.isSenkouSpanAOverB = isSenkouSpanAOverB; conditions.isSenkouSpanAUnderB = isSenkouSpanAUnderB; conditions.isSenkouSpanAOverLast = isSenkouSpanAOverLast; conditions.isSenkouSpanAUnderLast = isSenkouSpanAUnderLast; conditions.isFutureSenkouSpanAOverB = isFutureSenkouSpanAOverB; conditions.isFutureSenkouSpanAUnderB = isFutureSenkouSpanAUnderB; conditions.isFutureSenkouSpanAOverLast = isFutureSenkouSpanAOverLast; conditions.isFutureSenkouSpanAUnderLast = isFutureSenkouSpanAUnderLast; conditions.isCloseOverKijunSen = isCloseOverKijunSen; conditions.isCloseUnderKijunSen = isCloseUnderKijunSen; conditions.isTenkanSenOverKijunSen = isTenkanSenOverKijunSen; conditions.isTenkanSenUnderKijunSen = isTenkanSenUnderKijunSen; conditions.isTenkanSenCrossedOverKijunSen = isTenkanSenCrossedOverKijunSen; conditions.isTenkanSenCrossedUnderKijunSen = isTenkanSenCrossedUnderKijunSen; // // 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; } }; //