Files
xMQL5/MQLTestWorkspace/BKPS/Old/Classes/x-saherelm.x121.xmcycle.class.mq5
T
2024-06-01 19:37:54 +03:30

3087 lines
83 KiB
Plaintext

///////////////////////////////////////////////////////
//
// 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 //
);
}
};