/////////////////////////////////////////////////////// // // 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.x121.xmc.helper.mq5" #include "../Helpers/x-saherelm.x121.xche.helper.mq5" #include "../Helpers/x-saherelm.x121.xosc.helper.mq5" #include "../Helpers/x-saherelm.x121.xstr.helper.mq5" #include "../Helpers/x-saherelm.x121.xich.helper.mq5" // // Definitions ... // struct X121MCycleInputs { // // 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 // X121MCInputs mcInputs; // MC Inputs ... X121STRInputs strInputs; // STR Inputs ... X121OSCInputs oscInputs; // OSC Inputs ... X121CHEInputs cheInputs; // CHE Inputs ... X121ICHInputs ichInputs; // ICH Inputs ... // // Constructor ... X121MCycleInputs() { Clean(); } // // Tools ... // 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; } // bool Init( string mSymbol, // Trading Symbol ENUM_TIMEFRAMES mHostPeriod, // Host Period ENUM_X_MARKET_CYCLES mCycle, // Init Cycle X121MCInputs &mMcInputs, // MC Inputs X121STRInputs &mStrInputs, // STR Inputs X121OSCInputs &mOscInputs, // OSC Inputs X121CHEInputs &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; } // 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; } // void Default() { // mcInputs.Default(); strInputs.Default(); oscInputs.Default(); cheInputs.Default(); ichInputs.Default(); // drawLabels = false; drawCBar = false; drawPBar = false; drawCBarMid = false; drawPBarMid = false; } // 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; } }; // // Specific Market Sense Based on Specified Bar Index on Host Period ... struct X121MCycleConditions { // // 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 ... // // Bars ... XOHCL bars[]; // Some Bars ... 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; // // 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; // // Constructor(s) ... X121MCycleConditions() { Clean(); } // void Clean() { // // 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; // // 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; } // // Tools ... // // Generate Score ... 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 ... string GenerateSummary( double multiplier = 1, // Score Multiplier bool ignoreFalseConditions = true // Ignore False Conditions ) { // string result = ""; // double bullScore = 0; double bearScore = 0; GenerateScore( bullScore, bearScore, multiplier // ); // // Commons ... string commons = // ToString(cycle) + "[" + prefix + "]" + "\n" + "-------------" + "\n" + "Time: " + ToString(time) + "\n" + "\n" + "Scores:" + "\n" + "-------------" + "\n" + "Bullish: " + ToString(bullScore) + "\n" + "Bearish: " + ToString(bearScore) + "\n" + "\n" // ; // string candlestic = // ((isLastBullish || !ignoreFalseConditions) ? "isLastBullish: " + ToString(isLastBullish) + "\n" : "") + ((isLastBearish || !ignoreFalseConditions) ? "isLastBearish: " + ToString(isLastBearish) + "\n" : "") + ((isCurrentBullish || !ignoreFalseConditions) ? "isCurrentBullish: " + ToString(isCurrentBullish) + "\n" : "") + ((isCurrentBearish || !ignoreFalseConditions) ? "isCurrentBearish: " + ToString(isCurrentBearish) + "\n" : "") + ((isCurrentMidLineOverLastHigh || !ignoreFalseConditions) ? "isCurrentMidLineOverLastHigh: " + ToString(isCurrentMidLineOverLastHigh) + "\n" : "") + ((isCurrentMidLineUnderLastLow || !ignoreFalseConditions) ? "isCurrentMidLineUnderLastLow: " + ToString(isCurrentMidLineUnderLastLow) + "\n" : "") + ((isCurrentMidLineOverLastUp || !ignoreFalseConditions) ? "isCurrentMidLineOverLastUp: " + ToString(isCurrentMidLineOverLastUp) + "\n" : "") + ((isCurrentMidLineUnderLastDown || !ignoreFalseConditions) ? "isCurrentMidLineUnderLastDown: " + ToString(isCurrentMidLineUnderLastDown) + "\n" : "") + ((isCurrentMidLineOverLastMidLine || !ignoreFalseConditions) ? "isCurrentMidLineOverLastMidLine: " + ToString(isCurrentMidLineOverLastMidLine) + "\n" : "") + ((isCurrentMidLineUnderLastMidLine || !ignoreFalseConditions) ? "isCurrentMidLineUnderLastMidLine: " + ToString(isCurrentMidLineUnderLastMidLine) + "\n" : "") + "" // ; if (StringLen(candlestic) > 0) { // candlestic = // "XOHCL(s):" + "\n" + "-------------" + "\n" + candlestic + "\n" // ; } // // XSTR ... string str = // ((isTrendBullish || !ignoreFalseConditions) ? "isTrendBullish: " + ToString(isTrendBullish) + "\n" : "") + ((isTrendBearish || !ignoreFalseConditions) ? "isTrendBearish: " + ToString(isTrendBearish) + "\n" : "") + "" // ; if (StringLen(str) > 0) { // str = // "XSTR:" + "\n" + "-------------" + "\n" + str + "\n" // ; } // // XCHE ... string che = // ((isCHEInLong || !ignoreFalseConditions) ? "isCHEInLong: " + ToString(isCHEInLong) + "\n" : "") + ((isCHEInStrongLong || !ignoreFalseConditions) ? "isCHEInStrongLong: " + ToString(isCHEInStrongLong) + "\n" : "") + ((isCHEInShort || !ignoreFalseConditions) ? "isCHEInShort: " + ToString(isCHEInShort) + "\n" : "") + ((isCHEInStrongShort || !ignoreFalseConditions) ? "isCHEInStrongShort: " + ToString(isCHEInStrongShort) + "\n" : "") + "" // ; if (StringLen(che) > 0) { // che = // "XCHE:" + "\n" + "-------------" + "\n" + che + "\n" // ; } // // XICH ... string ich = // ((isSenkouSpanAOverB || !ignoreFalseConditions) ? "isSenkouSpanAOverB: " + ToString(isSenkouSpanAOverB) + "\n" : "") + ((isSenkouSpanAUnderB || !ignoreFalseConditions) ? "isSenkouSpanAUnderB: " + ToString(isSenkouSpanAUnderB) + "\n" : "") + ((isSenkouSpanAOverLast || !ignoreFalseConditions) ? "isSenkouSpanAOverLast: " + ToString(isSenkouSpanAOverLast) + "\n" : "") + ((isSenkouSpanAUnderLast || !ignoreFalseConditions) ? "isSenkouSpanAUnderLast: " + ToString(isSenkouSpanAUnderLast) + "\n" : "") + ((isCloseOverKijunSen || !ignoreFalseConditions) ? "isCloseOverKijunSen: " + ToString(isCloseOverKijunSen) + "\n" : "") + ((isCloseUnderKijunSen || !ignoreFalseConditions) ? "isCloseUnderKijunSen: " + ToString(isCloseUnderKijunSen) + "\n" : "") + ((isTenkanSenOverKijunSen || !ignoreFalseConditions) ? "isTenkanSenOverKijunSen: " + ToString(isTenkanSenOverKijunSen) + "\n" : "") + ((isTenkanSenUnderKijunSen || !ignoreFalseConditions) ? "isTenkanSenUnderKijunSen: " + ToString(isTenkanSenUnderKijunSen) + "\n" : "") + ((isFutureSenkouSpanAOverB || !ignoreFalseConditions) ? "isFutureSenkouSpanAOverB: " + ToString(isFutureSenkouSpanAOverB) + "\n" : "") + ((isFutureSenkouSpanAUnderB || !ignoreFalseConditions) ? "isFutureSenkouSpanAUnderB: " + ToString(isFutureSenkouSpanAUnderB) + "\n" : "") + ((isFutureSenkouSpanAOverLast || !ignoreFalseConditions) ? "isFutureSenkouSpanAOverLast: " + ToString(isFutureSenkouSpanAOverLast) + "\n" : "") + ((isFutureSenkouSpanAUnderLast || !ignoreFalseConditions) ? "isFutureSenkouSpanAUnderLast: " + ToString(isFutureSenkouSpanAUnderLast) + "\n" : "") + "" // ; if (StringLen(ich) > 0) { // ich = // "XICH:" + "\n" + "-------------" + "\n" + ich + "\n" // ; } // // XMC ... string mc = // ((isFastOverSlow || !ignoreFalseConditions) ? "isFastOverSlow: " + ToString(isFastOverSlow) + "\n" : "") + ((isFastUnderSlow || !ignoreFalseConditions) ? "isFastUnderSlow: " + ToString(isFastUnderSlow) + "\n" : "") + ((isFastOverVerifier || !ignoreFalseConditions) ? "isFastOverVerifier: " + ToString(isFastOverVerifier) + "\n" : "") + ((isFastUnderVerifier || !ignoreFalseConditions) ? "isFastUnderVerifier: " + ToString(isFastUnderVerifier) + "\n" : "") + ((isSlowOverVerifier || !ignoreFalseConditions) ? "isSlowOverVerifier: " + ToString(isSlowOverVerifier) + "\n" : "") + ((isSlowUnderVerifier || !ignoreFalseConditions) ? "isSlowUnderVerifier: " + ToString(isSlowUnderVerifier) + "\n" : "") + ((isCloseOverFast || !ignoreFalseConditions) ? "isCloseOverFast: " + ToString(isCloseOverFast) + "\n" : "") + ((isCloseUnderFast || !ignoreFalseConditions) ? "isCloseUnderFast: " + ToString(isCloseUnderFast) + "\n" : "") + ((isCloseOverSlow || !ignoreFalseConditions) ? "isCloseOverSlow: " + ToString(isCloseOverSlow) + "\n" : "") + ((isCloseUnderSlow || !ignoreFalseConditions) ? "isCloseUnderSlow: " + ToString(isCloseUnderSlow) + "\n" : "") + ((isCloseOverVerifier || !ignoreFalseConditions) ? "isCloseOverVerifier: " + ToString(isCloseOverVerifier) + "\n" : "") + ((isCloseUnderVerifier || !ignoreFalseConditions) ? "isCloseUnderVerifier: " + ToString(isCloseUnderVerifier) + "\n" : "") + "" // ; if (StringLen(mc) > 0) { // mc = // "XMC:" + "\n" + "-------------" + "\n" + mc + "\n" // ; } // // XOSC ... // // STDDEV ... string stddev = // ((isSTDDEVOverAVG || !ignoreFalseConditions) ? "isSTDDEVOverAVG: " + ToString(isSTDDEVOverAVG) + "\n" : "") + ((isSTDDEVUnderAVG || !ignoreFalseConditions) ? "isSTDDEVUnderAVG: " + ToString(isSTDDEVUnderAVG) + "\n" : "") + ((isSTDDEVOverLast || !ignoreFalseConditions) ? "isSTDDEVOverLast: " + ToString(isSTDDEVOverLast) + "\n" : "") + ((isSTDDEVUnderLast || !ignoreFalseConditions) ? "isSTDDEVUnderLast: " + ToString(isSTDDEVUnderLast) + "\n" : "") + "" // ; if (StringLen(stddev) > 0) { // stddev = // "STDDev:" + "\n" + "-------------" + "\n" + stddev + "\n" // ; } // // RVI ... string rvi = // ((isRVILongStart || !ignoreFalseConditions) ? "isRVILongStart: " + ToString(isRVILongStart) + "\n" : "") + ((isRVILongStop || !ignoreFalseConditions) ? "isRVILongStop: " + ToString(isRVILongStop) + "\n" : "") + ((isRVIShortStart || !ignoreFalseConditions) ? "isRVIShortStart: " + ToString(isRVIShortStart) + "\n" : "") + ((isRVIShortStop || !ignoreFalseConditions) ? "isRVIShortStop: " + ToString(isRVIShortStop) + "\n" : "") + "" // ; if (StringLen(rvi) > 0) { // rvi = // "RVI:" + "\n" + "-------------" + "\n" + rvi + "\n" // ; } // // RSI ... string rsi = // ((isRSIOver50 || !ignoreFalseConditions) ? "isRSIOver50: " + ToString(isRSIOver50) + "\n" : "") + ((isRSIUnder50 || !ignoreFalseConditions) ? "isRSIUnder50: " + ToString(isRSIUnder50) + "\n" : "") + ((isRSIOver70 || !ignoreFalseConditions) ? "isRSIOver70: " + ToString(isRSIOver70) + "\n" : "") + ((isRSIUnder30 || !ignoreFalseConditions) ? "isRSIUnder30: " + ToString(isRSIUnder30) + "\n" : "") + "" // ; if (StringLen(rsi) > 0) { // rsi = // "RSI:" + "\n" + "-------------" + "\n" + rsi + "\n" // ; } // // XCCI ... string cci = // ((isCCIPositive || !ignoreFalseConditions) ? "isCCIPositive: " + ToString(isCCIPositive) + "\n" : "") + ((isCCINegative || !ignoreFalseConditions) ? "isCCINegative: " + ToString(isCCINegative) + "\n" : "") + ((isCCIOverPositiveHundred || !ignoreFalseConditions) ? "isCCIOverPositiveHundred: " + ToString(isCCIOverPositiveHundred) + "\n" : "") + ((isCCIUnderNegativeHundred || !ignoreFalseConditions) ? "isCCIUnderNegativeHundred: " + ToString(isCCIUnderNegativeHundred) + "\n" : "") + "" // ; if (StringLen(cci) > 0) { // cci = // "CCI:" + "\n" + "-------------" + "\n" + cci + "\n" // ; } // // MACD ... string macd = // ((isMACDPositiove || !ignoreFalseConditions) ? "isMACDPositiove: " + ToString(isMACDPositiove) + "\n" : "") + ((isMACDNegative || !ignoreFalseConditions) ? "isMACDNegative: " + ToString(isMACDNegative) + "\n" : "") + ((isMACDOverSignal || !ignoreFalseConditions) ? "isMACDOverSignal: " + ToString(isMACDOverSignal) + "\n" : "") + ((isMACDUnderSignal || !ignoreFalseConditions) ? "isMACDUnderSignal: " + ToString(isMACDUnderSignal) + "\n" : "") + "" // ; if (StringLen(macd) > 0) { // macd = // "MACD:" + "\n" + "-------------" + "\n" + macd + "\n" // ; } // // BULLP ... string bullp = // ((isBullPowerOverLast || !ignoreFalseConditions) ? "isBullPowerOverLast: " + ToString(isBullPowerOverLast) + "\n" : "") + ((isBullPoswerUnderLast || !ignoreFalseConditions) ? "isBullPoswerUnderLast: " + ToString(isBullPoswerUnderLast) + "\n" : "") + ((isBullPowerOverZero || !ignoreFalseConditions) ? "isBullPowerOverZero: " + ToString(isBullPowerOverZero) + "\n" : "") + ((isBullPoswerUnderZero || !ignoreFalseConditions) ? "isBullPoswerUnderZero: " + ToString(isBullPoswerUnderZero) + "\n" : "") + "" // ; if (StringLen(bullp) > 0) { // bullp = // "BullPower:" + "\n" + "-------------" + "\n" + bullp + "\n" // ; } // // BEARP ... string bearp = // ((isBearPowerOverLast || !ignoreFalseConditions) ? "isBearPowerOverLast: " + ToString(isBearPowerOverLast) + "\n" : "") + ((isBearPoswerUnderLast || !ignoreFalseConditions) ? "isBearPoswerUnderLast: " + ToString(isBearPoswerUnderLast) + "\n" : "") + ((isBearPowerOverZero || !ignoreFalseConditions) ? "isBearPowerOverZero: " + ToString(isBearPowerOverZero) + "\n" : "") + ((isBearPoswerUnderZero || !ignoreFalseConditions) ? "isBearPoswerUnderZero: " + ToString(isBearPoswerUnderZero) + "\n" : "") + "" // ; if (StringLen(bearp) > 0) { // bearp = // "BearPower:" + "\n" + "-------------" + "\n" + bearp + "\n" // ; } // // STOCH ... string stoch = // ((isStochKOverD || !ignoreFalseConditions) ? "isStochKOverD: " + ToString(isStochKOverD) + "\n" : "") + ((isStochKUnderD || !ignoreFalseConditions) ? "isStochKUnderD: " + ToString(isStochKUnderD) + "\n" : "") + ((isStochKDOver50 || !ignoreFalseConditions) ? "isStochKDOver50: " + ToString(isStochKDOver50) + "\n" : "") + ((isStochKDOver80 || !ignoreFalseConditions) ? "isStochKDOver80: " + ToString(isStochKDOver80) + "\n" : "") + ((isStochKDUnder20 || !ignoreFalseConditions) ? "isStochKDUnder20: " + ToString(isStochKDUnder20) + "\n" : "") + ((isStochKDUnder50 || !ignoreFalseConditions) ? "isStochKDUnder50: " + ToString(isStochKDUnder50) + "\n" : "") + "" // ; if (StringLen(stoch) > 0) { // stoch = // "Stoch:" + "\n" + "-------------" + "\n" + stoch + "\n" // ; } string osc = // stddev + rvi + rsi + cci + macd + bullp + bearp + stoch + "" // ; if (StringLen(osc) > 0) { // osc = // "XOSC:" + "\n" + "-------------" + "\n" + osc + "\n" // ; } // result = // commons + candlestic + str + che + ich + mc + osc + "" // ; // return result; } }; // // Class ... // class XSC121Market { // // Public ... public: // // Props ... XSCX121MCHelper mc; XSCX121STRHelper str; XSCX121CHEHelper che; XSCX121OSCHelper osc; XSCX121ICHHelper ich; // // Constructors ... XSC121Market() {} // // Deconstructors ... ~XSC121Market() {} // // Props ... // // 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; } // // Retrieve Current Market Config ... X121MCycleInputs GetInputs() { return mInputs; } // // 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); } // // Set Market Inputs and Re Initial ... bool SetInputs( X121MCycleInputs &inputs // Config ) { // return Init(inputs); } // // Tools ... // // 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; } // // Retrieve Current Market Conditions ... X121MCycleConditions GetMarketConditions( int barIndex // Specified Bar Index ) { // X121MCycleConditions result; // 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 ... result.time = GetBarTime(barIndex); result.cycle = mInputs.cycle.cycle; result.prefix = mInputs.cycle.prefix; result.symbol = mInputs.cycle.symbol; result.period = mInputs.cycle.period; result.hostPeriod = mInputs.cycle.hostPeriod; // Clean(result.bars); GetBars( result.bars, result.symbol, result.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() // ; // result.isLastBullish = isLastBullish; result.isLastBearish = isLastBearish; result.isCurrentBullish = isCurrentBullish; result.isCurrentBearish = isCurrentBearish; result.isCurrentMidLineOverLastHigh = isCurrentMidLineOverLastHigh; result.isCurrentMidLineUnderLastLow = isCurrentMidLineUnderLastLow; result.isCurrentMidLineOverLastUp = isCurrentMidLineOverLastUp; result.isCurrentMidLineUnderLastDown = isCurrentMidLineUnderLastDown; result.isCurrentMidLineOverLastMidLine = isCurrentMidLineOverLastMidLine; result.isCurrentMidLineUnderLastMidLine = isCurrentMidLineUnderLastMidLine; // // XSTR ... bool isTrendBullish = // str.IsBullish(str.GetState(barIndex)) // ; bool isTrendBearish = // str.IsBearish(str.GetState(barIndex)) // ; // result.isTrendBullish = isTrendBullish; result.isTrendBearish = isTrendBearish; // // XCHE ... 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)) // ; // result.isCHEInLong = isCHEInLong; result.isCHEInShort = isCHEInShort; result.isCHEInStrongLong = isCHEInStrongLong; result.isCHEInStrongShort = isCHEInStrongShort; // // XMC ... // double fasts[]; mc.CopyFast( barIndex, 2, fasts // ); // double slows[]; mc.CopySlow( barIndex, 2, slows // ); // double verifiers[]; mc.CopyVerifier( barIndex, 2, verifiers // ); // bool isFastOverSlow = // fasts[0] > slows[0] && fasts[1] > slows[1] // ; bool isFastUnderSlow = // fasts[0] < slows[0] && fasts[1] < slows[1] // ; bool isFastOverVerifier = // fasts[0] > verifiers[0] && fasts[1] > verifiers[1] // ; bool isFastUnderVerifier = // fasts[0] < verifiers[0] && fasts[1] < verifiers[1] // ; bool isSlowOverVerifier = // slows[0] > verifiers[0] && slows[1] > verifiers[1] // ; bool isSlowUnderVerifier = // slows[0] < verifiers[0] && slows[1] < verifiers[1] // ; bool isCloseOverFast = // pBar.close > fasts[1] // ; bool isCloseUnderFast = // pBar.close < fasts[1] // ; bool isCloseOverSlow = // pBar.close > slows[1] // ; bool isCloseUnderSlow = // pBar.close < slows[1] // ; bool isCloseOverVerifier = // pBar.close > verifiers[1] // ; bool isCloseUnderVerifier = // pBar.close < verifiers[1] // ; // result.isFastOverSlow = isFastOverSlow; result.isFastUnderSlow = isFastUnderSlow; result.isFastOverVerifier = isFastOverVerifier; result.isFastUnderVerifier = isFastUnderVerifier; result.isSlowOverVerifier = isSlowOverVerifier; result.isSlowUnderVerifier = isSlowUnderVerifier; result.isCloseOverFast = isCloseOverFast; result.isCloseUnderFast = isCloseUnderFast; result.isCloseOverSlow = isCloseOverSlow; result.isCloseUnderSlow = isCloseUnderSlow; result.isCloseOverVerifier = isCloseOverVerifier; result.isCloseUnderVerifier = isCloseUnderVerifier; // // XICH ... // // XOSC ... // // STDDEV ... // double stdDev = osc.GetSTDDEV(barIndex); double stdDevLast = osc.GetSTDDEV(barIndex + 1); double stdDevs[]; osc.CopySTDDEV( barIndex + 1, 5, stdDevs // ); double stdDevAVG = GetAverage(stdDevs); // bool isSTDDEVOverAVG = // stdDev > stdDevAVG // ; bool isSTDDEVUnderAVG = // stdDev < stdDevAVG // ; bool isSTDDEVOverLast = // stdDev > stdDevLast // ; bool isSTDDEVUnderLast = // stdDev < stdDevLast // ; // result.isSTDDEVOverAVG = isSTDDEVOverAVG; result.isSTDDEVUnderAVG = isSTDDEVUnderAVG; result.isSTDDEVOverLast = isSTDDEVOverLast; result.isSTDDEVUnderLast = isSTDDEVUnderLast; // // RVI ... // 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 // ; // result.isRVILongStart = isRVILongStart; result.isRVILongStop = isRVILongStop; result.isRVIShortStart = isRVIShortStart; result.isRVIShortStop = isRVIShortStop; // // RSI ... double rsi = osc.GetRSI(barIndex); // bool isRSIUnder50 = // rsi < 50 // ; bool isRSIOver70 = // rsi > 70 // ; bool isRSIOver50 = // rsi > 50 // ; bool isRSIUnder30 = // rsi < 30 // ; // result.isRSIUnder50 = isRSIUnder50; result.isRSIOver70 = isRSIOver70; result.isRSIOver50 = isRSIOver50; result.isRSIUnder30 = isRSIUnder30; // // BULLPOWER ... // 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 // ; // result.isBullPowerOverLast = isBullPowerOverLast; result.isBullPoswerUnderLast = isBullPoswerUnderLast; result.isBullPowerOverZero = isBullPowerOverZero; result.isBullPoswerUnderZero = isBullPoswerUnderZero; // // BEARPOWER ... // 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 // ; // result.isBearPowerOverLast = isBearPowerOverLast; result.isBearPoswerUnderLast = isBearPoswerUnderLast; result.isBearPowerOverZero = isBearPowerOverZero; result.isBearPoswerUnderZero = isBearPoswerUnderZero; // // CCI ... // double cci = osc.GetCCI(barIndex); // bool isCCIPositive = // cci > 0 // ; bool isCCINegative = // cci < 0 // ; bool isCCIOverPositiveHundred = // cci > 100 // ; bool isCCIUnderNegativeHundred = // cci < -100 // ; // result.isCCIPositive = isCCIPositive; result.isCCINegative = isCCINegative; result.isCCIOverPositiveHundred = isCCIOverPositiveHundred; result.isCCIUnderNegativeHundred = isCCIUnderNegativeHundred; // // MACD ... // 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 // ; // result.isMACDPositiove = isMACDPositiove; result.isMACDNegative = isMACDNegative; result.isMACDOverSignal = isMACDOverSignal; result.isMACDUnderSignal = isMACDUnderSignal; // // STOCH ... // 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 // ; // result.isStochKOverD = isStochKOverD; result.isStochKDUnder50 = isStochKDUnder50; result.isStochKUnderD = isStochKUnderD; result.isStochKDOver50 = isStochKDOver50; result.isStochKDUnder20 = isStochKDUnder20; result.isStochKDOver80 = isStochKDOver80; // return result; } // // 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 // ); } };