Files
MQL5Data/Classes/x-saherelm.x121.xmcycle.class.mq5
T
2024-05-23 07:46:43 +03:30

3588 lines
95 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.xmc.helper.mq5"
#include "../Helpers/x-saherelm.xche.helper.mq5"
#include "../Helpers/x-saherelm.xosc.helper.mq5"
#include "../Helpers/x-saherelm.xstr.helper.mq5"
#include "../Helpers/x-saherelm.xich.helper.mq5"
//
#include "../Classes/x-saherelm.xprovider.class.mq5"
//
// Definitions ...
//
// X121 Specified Market Cycle Structure ...
class X121MCycleInputs : public XSCBaseProviderInpts
{
//
// Public ...
public:
//
// Props ...
//
XMarketCycle cycle; // Cycle Descriptor ...
//
// Draw Props ...
//
XDrawSpecifications cBarMidDrawSpecs; // Current Bar MidLine Draw Specifications
XOHCLDrawSpecification cBarDrawSpecs; // Current Bar Draw Specifications
//
XDrawSpecifications pBarMidDrawSpecs; // Previous Bar MidLine Draw Specifications
XOHCLDrawSpecification pBarDrawSpecs; // Previous Bar Draw Specifications
//
bool drawLabels; // Draw Labels
bool drawCBar; // Draw Current Bar
bool drawPBar; // Draw Previous Bar
bool drawCBarMid; // Draw Current Bar Mid Line
bool drawPBarMid; // Draw Previous Bar Mid Line
//
XMCInputs mcInputs; // MC Inputs ...
XSTRInputs strInputs; // STR Inputs ...
XOSCInputs oscInputs; // OSC Inputs ...
XCHEInputs cheInputs; // CHE Inputs ...
XICHInputs ichInputs; // ICH Inputs ...
//
// Constructor ...
//
// Tools ...
//
// Initialize Market Cycle ...
bool Init(
string mSymbol, // Trading Symbol
ENUM_TIMEFRAMES mHostPeriod, // Host Period
ENUM_X_MARKET_CYCLES mCycle, // Init Cycle
ENUM_TIMEFRAMES mPeriod, // Cycle Period
ENUM_X_PERIOD_METHOD mPeriodMethod, // Cycle Period Method
string mPrefix = "", // Prefix
bool useDefaults = true // Use Inputs Default Settings ...
)
{
//
bool result = false;
//
cycle.period = mPeriod;
cycle.method = mPeriodMethod;
//
// Initial Cycle Model ...
result = cycle.Init(
mSymbol,
mHostPeriod,
mCycle,
mPrefix
//
);
if (!result)
{
return result;
}
//
if (useDefaults)
{
//
mcInputs.Default();
strInputs.Default();
oscInputs.Default();
cheInputs.Default();
ichInputs.Default();
}
//
result = IsValid();
if (!result)
{
return result;
}
//
return result;
}
//
// Initialize Market Cycle ...
bool Init(
string mSymbol, // Trading Symbol
ENUM_TIMEFRAMES mHostPeriod, // Host Period
ENUM_X_MARKET_CYCLES mCycle, // Init Cycle
XMCInputs &mMcInputs, // MC Inputs
XSTRInputs &mStrInputs, // STR Inputs
XOSCInputs &mOscInputs, // OSC Inputs
XCHEInputs &mCheInputs, // CHE Inputs
int mHostBarIndex = 0, // Specified Host Period Bar Index
string mPrefix = "" // Prefix
)
{
//
bool result = false;
//
// Initial Cycle Model ...
result = cycle.Init(
mSymbol,
mHostPeriod,
mCycle,
mPrefix
//
);
if (!result)
{
return result;
}
//
mcInputs = mMcInputs;
strInputs = mStrInputs;
oscInputs = mOscInputs;
cheInputs = mCheInputs;
//
result = IsValid();
if (!result)
{
return result;
}
//
return result;
}
//
// Cleanup ...
virtual void Clean()
{
//
cycle.Clean();
//
mcInputs.Clean();
strInputs.Clean();
oscInputs.Clean();
cheInputs.Clean();
ichInputs.Clean();
//
cBarDrawSpecs.Clean();
pBarDrawSpecs.Clean();
cBarMidDrawSpecs.Clean();
pBarMidDrawSpecs.Clean();
//
drawLabels = false;
drawCBar = false;
drawPBar = false;
drawCBarMid = false;
drawPBarMid = false;
}
//
// Default ...
virtual void Default()
{
//
mcInputs.Default();
strInputs.Default();
oscInputs.Default();
cheInputs.Default();
ichInputs.Default();
//
drawLabels = false;
drawCBar = false;
drawPBar = false;
drawCBarMid = false;
drawPBarMid = false;
}
//
// Validation ...
virtual bool IsValid()
{
//
bool result = false;
//
result = cycle.IsValid();
if (!result)
{
return result;
}
//
result = mcInputs.IsValid();
if (!result)
{
return result;
}
//
result = strInputs.IsValid();
if (!result)
{
return result;
}
//
result = oscInputs.IsValid();
if (!result)
{
return result;
}
//
result = cheInputs.IsValid();
if (!result)
{
return result;
}
//
result = ichInputs.IsValid();
if (!result)
{
return result;
}
//
return result;
}
//
// Max ...
virtual int Max()
{
//
int result = 0;
//
result = MathMax(mcInputs.Max(), strInputs.Max());
//
result = MathMax(result, oscInputs.Max());
result = MathMax(result, cheInputs.Max());
result = MathMax(result, ichInputs.Max());
//
return result;
}
};
//
// Specific Market Sense Based on Specified Bar Index on Host Period ...
class X121MCycleConditions : public XSCBaseProviderMarketConditions
{
//
// Public ...
public:
//
// Props ...
//
// Common ...
string prefix; // Cycle Prefix ...
string symbol; // Analysing Symbol ...
ENUM_TIMEFRAMES period; // Analysing Time Frame ...
ENUM_TIMEFRAMES hostPeriod; // Hosting Time Frame ...
ENUM_X_MARKET_CYCLES cycle; // Init Cycle ...
//
datetime time; // Extracting Time ...
//
// Candlestic Conditions ...
bool isLastBullish;
bool isLastBearish;
bool isCurrentBullish;
bool isCurrentBearish;
bool isCurrentMidLineOverLastHigh;
bool isCurrentMidLineUnderLastLow;
bool isCurrentMidLineOverLastUp;
bool isCurrentMidLineUnderLastDown;
bool isCurrentMidLineOverLastMidLine;
bool isCurrentMidLineUnderLastMidLine;
//
// Buffers ...
//
// XICH ...
double ichTenkanSens[];
double ichKijunSens[];
double ichChikouSpans[];
double ichSenkouSpanAs[];
double ichSenkouSpanBs[];
//
// XMC ...
double mcFasts[];
double mcSlows[];
double mcVerifiers[];
//
// XSTR ...
double strTrends[];
double strStates[];
//
// XCHE ...
double cheLongExit1s[];
double cheLongExit2s[];
double cheShortExit1s[];
double cheShortExit2s[];
//
// XOSC ...
double oscAtrs[];
double oscRviMains[];
double oscRviSignals[];
double oscBullPs[];
double oscBearPs[];
double oscVolumes[];
double oscRsis[];
double oscCcis[];
double oscMomentums[];
double oscSars[];
double oscMacdMains[];
double oscMacdSignals[];
double oscStochMains[];
double oscStochSignals[];
double oscStddevs[];
//
// XICH ...
// Ichimoku strategy
// Strategy one: Ichimoku trend identifier:
// According to this strategy, we need a trigger that can be used
// to inform us about the trend type,
// if it is an uptrend or downtrend.
// We will check three values to do that and these values are the:
// closing price, Senkou Span A, and Senkou Span B.
// If the closing price is greater than the Senkou Span B and at the same time
// the closing price is greater than Senkou Span A,
// this will be the trigger to know that the trend is up.
// Vice versa, if the closing price is lower than the Senkou Span B and at the same time
// the closing price is lower than the Senkou Span A,
// this will be the trigger to the downtrend.
//
// Closing price > Senkou Span B and closing price > Senkou Span A --> Uptrend
// Closing price < Senkou Span B and closing price < Senkou Span A --> Downtrend
//
// Strategy two: Ichimoku trend strength:
// Based on this strategy, we need a trigger that can inform us the current trend is strong.
// We will check three values to do that and these values are the:
// - current Senkou Span A,
// - the previous Senkou Span A, and
// - the Senkou Span B.
// If the current Senkou Span A is greater than the previous Senkous Span A and at the same time
// the current Senkou Span A is greater than the Senkou Span B,
// this is a trigger that the trend is up and strong.
// Vice versa, if the current Senkou Span A is lower than the previous Senkou Span A and at the
// same time, the current Senkou Span A is lower than the Senkou Span B,
// this will be a signal that the trend is down and strong.
//
// Current Senkou Span A > previous Senkou Span A and current Senkou Span A > Senkou Span B --> the uptrend is strong
// Current Senkou Span A < previous Senkou Span A and current Senkou Span A < Senkou Span B --> the downtrend is strong
bool isSenkouSpanAOverB;
bool isSenkouSpanAUnderB;
bool isSenkouSpanAOverLast;
bool isSenkouSpanAUnderLast;
bool isFutureSenkouSpanAOverB;
bool isFutureSenkouSpanAUnderB;
bool isFutureSenkouSpanAOverLast;
bool isFutureSenkouSpanAUnderLast;
//
// Strategy three: Ichimoku price-Ki signal:
// According to this strategy, during the uptrend, we need a trigger that can
// alert us about the bullish signal, and during the downtrend, we need a trigger than can alert us about the bearish signal.
// We will check based on this strategy two values, closing price, and Kijun-Sen.
// If the closing price is greater than the Kijun-sen value,
// this will be a trigger to a bullish signal.
// Vice versa, if the closing price is lower than the Kijun-sen value,
// this will be a bearish signal.
//
// During uptrend, closing price > Kijun -sen --> bullish signal
// Duuring downtrend, closing price < Kijun -sen --> bearish signal
bool isCloseOverKijunSen;
bool isCloseUnderKijunSen;
//
// Strategy four: Ichimoku ten-ki signal:
// According to this strategy, during the uptrend, we need another trigger or
// method to alert us when there is a bullish signal or
// during the downtrend, we need a signal of bearishness.
// We will check based on this strategy two values, Tenkan-sen and Kijum-sen.
// If the Tenkan-sen value is greater than the Kijun-sen,
// this will be a signal of bullishness.
// Vice versa, if the Tenkan-sen is lower than the Kijun-sen,
// this will be a signal of bearishness.
//
// Tenkan-sen > Kijun-sen --> bullish signal
// Tenkan-sen < Kijun-sen --> bearish signal
bool isTenkanSenOverKijunSen;
bool isTenkanSenUnderKijunSen;
bool isTenkanSenCrossedOverKijunSen;
bool isTenkanSenCrossedUnderKijunSen;
//
// XMC ...
// Three Moving Averages Crossover
// In this strategy, we will use three simple moving averages:
// the shorter simple moving average period is 10, the longer one period is 48, and in between a period of 24.
//
// According to the strategy, we need the three simple moving averages to be checked at every tick:
//
// If 10 SMA > 24 SMA, 10 SMA > 48 SMA, and 24 SMA > 48 SMA: the signal will be to buy and we need to be appeared as a comment on the chart.
// If 10 SMA < 24 SMA, 10 SMA < 48 SMA, and 24 SMA < 48 SMA: the signal will be to sell and we need to be appeared as a comment on the chart.
// If anything, else do nothing.
bool isFastOverSlow;
bool isFastUnderSlow;
bool isFastOverVerifier;
bool isFastUnderVerifier;
bool isSlowOverVerifier;
bool isSlowUnderVerifier;
bool isCloseOverFast;
bool isCloseUnderFast;
bool isCloseOverSlow;
bool isCloseUnderSlow;
bool isCloseOverVerifier;
bool isCloseUnderVerifier;
//
// XSTR ...
bool isTrendBullish;
bool isTrendSwitchedToBullish;
bool isTrendBearish;
bool isTrendSwitchedToBearish;
//
// XCHE ...
bool isCHEInLong;
bool isCHEInStrongLong;
bool isCHEInShort;
bool isCHEInStrongShort;
//
// XOSC ...
//
// RVI Signals ...
// Strategy one: RVI Crossover - Uptrend:
// Based on this strategy, we need to get buy and close signals during the uptrend by a specific condition.
// When the RVI current value and RVI signal current value are greater than the zero level at the same time
// that RVI current value is greater than the current value of the RVI signal, this will be a buy signal.
// Vice Versa, when the RVI current value and RVI signal current value is below zero level at
// the same time that the RVI current value is below the current value of the RVI signal, this will be a close signal.
//
// RVI value > 0 and RVI signal value > 0 and RVI value > RVI signal value --> buy
// RVI value < 0 and RVI signal value < 0 and RVI value < RVI signal value --> close
bool isRVILongStart;
bool isRVILongStop;
//
// Strategy two: RVI Crossover - Downtrend:
// Based on this strategy, we need to get the opposite signals of the previous RVI Crossover -
// Uptrend strategy as we need to get short and cover signals.
// When the RVI current value and RVI signal current value are lower than the zero level at
// the same time that RVI current value is lower than the current value of the RVI signal, this will be a short signal.
// Vice Versa, when the RVI current value and RVI signal current value is above the zero level
// at the same time that the RVI current value is above the current value of the RVI signal, this will be a cover signal.
//
// RVI value < 0 and RVI signal value < 0 and RVI value < RVI signal value --> short
// RVI value > 0 and RVI signal value > 0 and RVI value > RVI signal value --> cover
bool isRVIShortStart;
bool isRVIShortStop;
//
// Strategy three: RVI and MA Crossover
// Based on this strategy, we need to get buy and sell signals based on specific conditions
// as we need to get a
// buy signal
// when the closing price is greater than the 100 -period moving average
// at the same time that the current RVI value is greater than the current RVI signal value.
// In the other scenario, we need to get a
// sell signal
// when the closing price is lower than the 100 -period moving average
// at the same time that the current RVI value is lower than the current RVI signal value.
//
// RSI strategy ...
// During Uptrend
// In this case, most of the time RSI values move between or moving between
// the mid range and level 70 (Overbought level).
// The trading strategy for the uptrend is:
//
// RSI Value < 50 = Buy
// RSI Value > 70 = Take Profit
bool isRSIUnder50;
bool isRSIOver70;
//
// During Downtrend
// During the downtrend, the RSI moves most of the time between
// the mid range and level 30 (Oversold level).
// The trading strategy will be as follows:
//
// RSI Value > 50 = Short
// RSI Value < 30 = Take Profit
bool isRSIOver50;
bool isRSIUnder30;
//
// During Sideways:
// RSI spends most of the time between levels 30 (Oversold level) and 70 (Oversbought level).
// The trading strategy will be as follows:
// RSI Value < 30 = Buy
// RSI Value > 50 = Take Profit
// RSI Value > 70 = Short
// RSI Value < 50 = Take Profit
//
// Bull's Power strategy:
// In this part, we will learn how we can use Bull's Power through simple strategies
// that can be used based on the basic concept of this indicator.
// The following are for these strategies and their conditions.
// I need to confirm here, that these strategies for education only as the main objective
// is to understand the main concept behind the indicator and how we can use them in our favor,
// so you must test any of them before using them on your real account to make sure that
// it will be good for your trading as there is no strategy is suitable for everyone.
//
// Strategy one: Bull's Power Movement:
// Based on this strategy, we need to get signals based on the position of current and previous bull's power values.
// If the current bull's power value is greater than the previous one,
// we will consider it as a signal of the rising of the Bull's Power indicator.
// Vice versa, if the current value is lower than the previous one, we will consider that as a signal of
// declining Bull's Power.
//
// To simplify that, it will be the same as the following:
//
// Current Bull's Power > Previous Bull's Power --> Bull's Power is Rising
// Current Bull's Power < Previous Bull's Power --> Bull's Power is declining
bool isBullPowerOverLast;
bool isBullPoswerUnderLast;
//
// Strategy two: Bull's Power - Strong or Divergence
// Based on this strategy, we want to get a signal that informs us if there is a strong movement
// or there is a divergence by evaluating four values and these values are current high,
// the previous high, bull power, and previous bull power.
// If the current high is higher than the previous high and
// the current bull power value is higher than the previous one,
// we will consider that as a signal of a strong move.
// In the other case, if the current high is higher than the previous high and the current
// bull value is lower than the previous one, we will consider that as a signal of bearish divergence.
//
// To simplify that, it will be the same as the following:
//
// Current high > previous high and current bull's power > previous bull's power --> strong move
// Current high < previous high and current bull's power > previous bull's power --> bearish divergence
//
// Strategy three: Bull's Power signals
// Based on this strategy, we need a signal that can be used to get buy and sell signals and we will
// evaluate four values to do that based on this strategy.
// These four values are:
// - current bull's power,
// - zero level,
// - current close value, and
// - current exponential moving average.
// If the current bull's power is lower than the zero level and
// the current close is lower than the exponential moving average,
// we will consider it as a signal of selling.
// If the current bull's power is greater than the zero level and the current close is greater than
// the exponential moving average, this will be a signal of buying.
//
// To simplify that, it will be the same as the following:
//
// Current bull's power < zero level and current close < EMA --> sell
// Current bear's power > zero level and current close > EMA --> buy
bool isBullPowerOverZero;
bool isBullPoswerUnderZero;
//
// Bear's Power strategy
// In this part, we will learn how we can use Bear's Power through simple strategies
// that can be used based on the basic concept of this indicator.
// The following are for these strategies and their conditions.
// I need to confirm here, that these strategies for education as the main objective
// is to understand the main concept behind the indicator and how we can use it,
// so you must test any of them before using them on your real account to
// make sure that it will be good for your trading.
//
// Strategy one: Bear's Power Movement
// According to this strategy, we need to get signals based on the position of current and previous
// bear's power values.
// If the current value is greater than the previous, this will be a signal of the rising of
// Bear's Power indicator.
// Vice versa, if the current value is lower than the previous value,
// this will be a signal of declining Bear's Power.
//
// Simply,
//
// Current Bear's Power > Previous Bear's Power --> Bear's Power is Rising
// Current Bear's Power < Previous Bear's Power --> Bear's Power is declining
bool isBearPowerOverLast;
bool isBearPoswerUnderLast;
//
// Strategy two: Bear's Power - Strong or Divergence
// According to this strategy, we need to get a signal that informs us if there are strong movements or
// there are divergences by evaluating four values and they are:
// -current low,
// - previous low,
// - bear power, and
// - previous bear power.
// If the current low is lower than the previous low and the current bear power value
// is lower than the previous one, this will be a signal of a strong move.
// In the other case, if the current low is lower than the previous low and the current
// bear value is greater than the previous one, this will be a signal of bullish divergence.
//
// Simply,
//
// Current low < previous low and current bear's power < previous bear's power --> strong move
// Current low < previous low and current bear's power > previous bear's power --> bullish divergence
//
// Strategy three
// According to this strategy, we need a trigger that can be used to get buy and sell signals and
// we will evaluate four values to do that based on this strategy.
// These four values are current:
// - bear's power,
// - zero level,
// - current close value, and
// - current exponential moving average.
// If the current bear's power is greater than the zero level and the current close is greater than
// the exponential moving average, this will be a signal of buy.
// If the current bear's power is lower than the zero level and the current close is lower than
// the exponential moving average, this will be a signal of selling.
//
// Simply,
//
// Current bear's power > zero level and current close > EMA --> buy
// Current bear's power < zero level and current close < EMA --> sell
bool isBearPowerOverZero;
bool isBearPoswerUnderZero;
//
// CCI ...
bool isCCIPositive;
bool isCCINegative;
bool isCCIOverPositiveHundred;
bool isCCIUnderNegativeHundred;
//
// STDDEV ...
// Based on this strategy, we need to measure the volatility based on the comparison between the
// current Std Dev and the average of the five previous Std values.
// If the current Std Dev is greater than the Std Dev 5-periods average, this will be a high volatility signal.
// If the current Std is lower than the Std Dev 5- period average, this will be low volatility.
//
// Based on this strategy, we need to get buy and sell signals based on specific conditions.
// If the current Std Dev is greater than the previous Std Dev and the Ask value is greater than the moving average,
// this will be a buy signal.
// If the current Std Dev is greater than the previous Std Dev and the Bid value is lower than the moving average,
// this will be a sell signal.
//
// Current Std > Prev. Std and Ask > MA --> Buy signal
// Current Std > Prev. Std and Bid < MA --> Sell signal
//
// Based on this strategy, we need to get buy and sell signals based on other conditions.
// If the current Std Dev is greater than Std Dev Avg and Ask is greater than the moving average,
// this will be a buy signal.
// If the current Std Dev is greater than Std Dev Avg and Bid is lower than the moving average,
// this will be a sell signal.
//
// Current Std > Std Avg and Ask > MA --> Buy signal
// Current Std > Std Avg and Bid < Ma --> Sell signal
bool isSTDDEVOverAVG;
bool isSTDDEVOverLast;
bool isSTDDEVUnderAVG;
bool isSTDDEVUnderLast;
//
// MACD ...
// According to this strategy, we need to identify the market setup:
// is it buying setup or shorting setup.
// In other words we need to identify the market direction, if it is bullish or bearish market,
// and this will be identified by MACD.
// If the MACD main line breaks above zero level, this will be a buying setup or bullish setup and
// vice versa if MACD main line breaks below zero level, this will be a shorting setup or bearish.
//
// MACD main line > 0 = Bullish Setup
// MACD main line < 0 = Bearish Setup
//
// According to this strategy, we need to identify generated signals
// if there is a buy signal or a sell signal based on MACD main line and Signal line crossover.
// If MACD main line breaks above Signal line, this will be a buy signal and if MACD main line breaks
// below Signal line, this will be a short signal.
//
// MACD main line > MACD signal line = Buying Signal
// MACD main line < MACD signal line = Shorting signal
bool isMACDPositiove;
bool isMACDNegative;
bool isMACDOverSignal;
bool isMACDUnderSignal;
//
// STOCHASTIC ...
// Stochastic strategy
// In this part, we will talk about how we can use this indicator through simple strategies.
// We can get signals from the stochastic indicator according to market trend and these strategies are
// uptrend strategy, downtrend strategy, and sideways strategy.
//
// Strategy one: Uptrend strategy
// According to this strategy, we need to check if the %K line and %D line are below the 50 level,
// then, the buy signal will be generated
// when the %K line crosses above the %D line.
// We can take profit according to another effective tool like price action by searching
// for a lower low for example.
//
// %K, %D < 50 --> %K > %D = buy signal
bool isStochKOverD;
bool isStochKDUnder50;
//
// Strategy two: downtrend strategy
// According to this strategy, we need to check if the %K line and %D line are above the 50 level,
// then, the sell signal will be generated
// when the %K line crosses below the %D line.
// We can take profit according to another effective tool like price action by searching
// for a higher high for example.
//
// %K, %D > 50 --> %K < %D = sell signal
bool isStochKUnderD;
bool isStochKDOver50;
//
// Strategy three: sideways strategy
//
// The buy signal:
// According to this strategy, we need to check if the %K line and %D line are below the 20 level,
// then, the buy signal will be generated
// when the %K line crosses above the %D line.
// When the %K line and %D line are above 80, then the take profit signal will be generated
// when the %K line crosses below the %D line.
// %K, %D < 20 --> %K > %D = buy signal
// %K, %D > 80 --> %K < %D = take profit
bool isStochKDUnder20;
//
// The sell signal
// According to this strategy, we need to check if the %K line and %D line are above the 80 level,
// then, the sell signal will be generated
// when the %K line crosses below the %D line.
// When the %K line and %D are below the 20 level, then, the take profit signal will be generated
// when the %K line crosses above the %D line.
//
// %K, %D > 80 --> %K < %D = sell signal
// %K, %D < 20 --> %K > %D = take profit
bool isStochKDOver80;
//
// Tools ...
//
void Clear()
{
//
// Commons ...
time = 0;
cycle = NULL;
prefix = NULL;
symbol = NULL;
period = NULL;
hostPeriod = NULL;
//
Clean(bars);
//
// Candlestic ...
isLastBullish = false;
isLastBearish = false;
isCurrentBullish = false;
isCurrentBearish = false;
isCurrentMidLineOverLastHigh = false;
isCurrentMidLineUnderLastLow = false;
isCurrentMidLineOverLastUp = false;
isCurrentMidLineUnderLastDown = false;
isCurrentMidLineOverLastMidLine = false;
isCurrentMidLineUnderLastMidLine = false;
//
// Buffers ...
Clean(bars);
Clean(ichTenkanSens);
Clean(ichKijunSens);
Clean(ichChikouSpans);
Clean(ichSenkouSpanAs);
Clean(ichSenkouSpanBs);
Clean(mcFasts);
Clean(mcSlows);
Clean(mcVerifiers);
Clean(strTrends);
Clean(strStates);
Clean(cheLongExit1s);
Clean(cheLongExit2s);
Clean(cheShortExit1s);
Clean(cheShortExit2s);
Clean(oscAtrs);
Clean(oscRviMains);
Clean(oscRviSignals);
Clean(oscBullPs);
Clean(oscBearPs);
Clean(oscVolumes);
Clean(oscRsis);
Clean(oscCcis);
Clean(oscMomentums);
Clean(oscSars);
Clean(oscMacdMains);
Clean(oscMacdSignals);
Clean(oscStochMains);
Clean(oscStochSignals);
Clean(oscStddevs);
//
// Buffers ...
ArraySetAsSeries(bars, true);
ArraySetAsSeries(ichTenkanSens, true);
ArraySetAsSeries(ichKijunSens, true);
ArraySetAsSeries(ichChikouSpans, true);
ArraySetAsSeries(ichSenkouSpanAs, true);
ArraySetAsSeries(ichSenkouSpanBs, true);
ArraySetAsSeries(mcFasts, true);
ArraySetAsSeries(mcSlows, true);
ArraySetAsSeries(mcVerifiers, true);
ArraySetAsSeries(strTrends, true);
ArraySetAsSeries(strStates, true);
ArraySetAsSeries(cheLongExit1s, true);
ArraySetAsSeries(cheLongExit2s, true);
ArraySetAsSeries(cheShortExit1s, true);
ArraySetAsSeries(cheShortExit2s, true);
ArraySetAsSeries(oscAtrs, true);
ArraySetAsSeries(oscRviMains, true);
ArraySetAsSeries(oscRviSignals, true);
ArraySetAsSeries(oscBullPs, true);
ArraySetAsSeries(oscBearPs, true);
ArraySetAsSeries(oscVolumes, true);
ArraySetAsSeries(oscRsis, true);
ArraySetAsSeries(oscCcis, true);
ArraySetAsSeries(oscMomentums, true);
ArraySetAsSeries(oscSars, true);
ArraySetAsSeries(oscMacdMains, true);
ArraySetAsSeries(oscMacdSignals, true);
ArraySetAsSeries(oscStochMains, true);
ArraySetAsSeries(oscStochSignals, true);
ArraySetAsSeries(oscStddevs, true);
//
// XTSR ...
isTrendBullish = false;
isTrendBearish = false;
isTrendSwitchedToBullish = false;
isTrendSwitchedToBearish = false;
//
// XCHE ...
isCHEInLong = false;
isCHEInStrongLong = false;
isCHEInShort = false;
isCHEInStrongShort = false;
//
// XICH ...
isSenkouSpanAOverB = false;
isSenkouSpanAUnderB = false;
isSenkouSpanAOverLast = false;
isSenkouSpanAUnderLast = false;
isFutureSenkouSpanAOverB = false;
isFutureSenkouSpanAUnderB = false;
isFutureSenkouSpanAOverLast = false;
isFutureSenkouSpanAUnderLast = false;
isCloseOverKijunSen = false;
isCloseUnderKijunSen = false;
isTenkanSenOverKijunSen = false;
isTenkanSenUnderKijunSen = false;
//
// XMC ...
isFastOverSlow = false;
isFastUnderSlow = false;
isFastOverVerifier = false;
isFastUnderVerifier = false;
isSlowOverVerifier = false;
isSlowUnderVerifier = false;
isCloseOverFast = false;
isCloseUnderFast = false;
isCloseOverSlow = false;
isCloseUnderSlow = false;
isCloseOverVerifier = false;
isCloseUnderVerifier = false;
//
// XOSC ...
//
// STDDEV ...
isSTDDEVOverAVG = false;
isSTDDEVUnderAVG = false;
isSTDDEVOverLast = false;
isSTDDEVUnderLast = false;
//
// RVI ...
isRVILongStart = false;
isRVILongStop = false;
isRVIShortStart = false;
isRVIShortStop = false;
//
// RSI ...
isRSIUnder50 = false;
isRSIOver70 = false;
isRSIOver50 = false;
isRSIUnder30 = false;
//
// BULLPOWER ...
isBullPowerOverLast = false;
isBullPoswerUnderLast = false;
isBullPowerOverZero = false;
isBullPoswerUnderZero = false;
//
// BEARPOWER ...
isBearPowerOverLast = false;
isBearPoswerUnderLast = false;
isBearPowerOverZero = false;
isBearPoswerUnderZero = false;
//
// CCI ...
isCCIPositive = false;
isCCINegative = false;
isCCIOverPositiveHundred = false;
isCCIUnderNegativeHundred = false;
//
// MACD ...
isMACDPositiove = false;
isMACDNegative = false;
isMACDOverSignal = false;
isMACDUnderSignal = false;
//
// STOCH ...
isStochKOverD = false;
isStochKDUnder50 = false;
isStochKUnderD = false;
isStochKDOver50 = false;
isStochKDUnder20 = false;
isStochKDOver80 = false;
}
//
// Generate Score ...
virtual void GenerateScore(
double &bullishScore, // Holds Bullish Score ...
double &bearishScore, // Holds Bearish Score ...
double multiplier = 1 // Score Multiplier ...
)
{
//
double bullScore = 0;
double bearScore = 0;
//
if (multiplier <= 0)
{
multiplier = 1;
}
//
// Candlestic ...
//
// BULLISH ...
if (isLastBullish)
{
bullScore++;
}
if (isCurrentBullish)
{
bullScore++;
}
if (isCurrentMidLineOverLastUp)
{
bullScore++;
}
if (isCurrentMidLineOverLastHigh)
{
bullScore++;
}
if (isCurrentMidLineOverLastMidLine)
{
bullScore++;
}
//
// BEARISH ...
if (isLastBearish)
{
bearScore++;
}
if (isCurrentBearish)
{
bearScore++;
}
if (isCurrentMidLineUnderLastLow)
{
bearScore++;
}
if (isCurrentMidLineUnderLastDown)
{
bearScore++;
}
if (isCurrentMidLineUnderLastMidLine)
{
bearScore++;
}
//
// XSTR ...
if (isTrendBullish)
{
bullScore++;
}
if (isTrendBearish)
{
bearScore++;
}
if (isTrendSwitchedToBullish)
{
//
bullScore++;
bearScore--:
}
if (isTrendSwitchedToBearish)
{
//
bullScore--;
bearScore++:
}
//
// XICH ...
//
// BULLISH ...
if (isSenkouSpanAOverB)
{
bullScore++;
}
if (isSenkouSpanAOverLast)
{
bullScore++;
}
if (isCloseOverKijunSen)
{
bullScore++;
}
if (isTenkanSenOverKijunSen)
{
bullScore++;
}
if (isFutureSenkouSpanAOverB)
{
bullScore++;
}
if (isFutureSenkouSpanAOverLast)
{
bullScore++;
}
if (isTenkanSenCrossedOverKijunSen)
{
//
bullScore++;
bearScore--;
}
//
// BEARISH ...
if (isSenkouSpanAUnderB)
{
bearScore++;
}
if (isSenkouSpanAUnderLast)
{
bearScore++;
}
if (isCloseUnderKijunSen)
{
bearScore++;
}
if (isTenkanSenUnderKijunSen)
{
bearScore++;
}
if (isFutureSenkouSpanAUnderB)
{
bearScore++;
}
if (isFutureSenkouSpanAUnderLast)
{
bearScore++;
}
if (isTenkanSenCrossedUnderKijunSen)
{
//
bullScore--;
bearScore++;
}
//
// XMC ...
//
// BULLISH ...
if (isFastOverSlow)
{
bullScore++;
}
if (isFastOverVerifier)
{
bullScore++;
}
if (isSlowOverVerifier)
{
bullScore++;
}
if (isCloseOverFast)
{
bullScore++;
}
if (isCloseOverSlow)
{
bullScore++;
}
if (isCloseOverVerifier)
{
bullScore++;
}
//
// BEARISH ...
if (isFastUnderSlow)
{
bearScore++;
}
if (isFastUnderVerifier)
{
bearScore++;
}
if (isSlowUnderVerifier)
{
bearScore++;
}
if (isCloseUnderFast)
{
bearScore++;
}
if (isCloseUnderSlow)
{
bearScore++;
}
if (isCloseUnderVerifier)
{
bearScore++;
}
//
// XOSC ...
//
// STDDEV ...
//
// BULLISH ...
if (isSTDDEVOverAVG)
{
bullScore++;
}
if (isSTDDEVOverLast)
{
bullScore++;
}
//
// BEARISH ...
if (isSTDDEVUnderAVG)
{
bearScore++;
}
if (isSTDDEVUnderLast)
{
bearScore++;
}
//
// RVI ...
if (isRVILongStart && !isRVILongStop)
{
bullScore++;
}
if (isRVIShortStart && isRVIShortStop)
{
bearScore++;
}
//
// RSI ...
//
// BULLISH ...
if (isRSIUnder30 || (!isRSIUnder30 && isRSIOver50 && isRSIOver70))
{
bullScore++;
}
//
// BEARISH ...
if (isRSIOver70 || (!isRSIOver70 && !isRSIOver50 && isRSIUnder30))
{
bearScore++;
}
//
// BULLPOWER ...
//
// BULLISH ...
if (isBullPowerOverLast)
{
bullScore++;
}
if (isBullPowerOverZero)
{
bullScore++;
}
//
// BEARISH ...
if (isBullPoswerUnderLast)
{
bearScore++;
}
if (isBullPoswerUnderZero)
{
bearScore++;
}
//
// BEARPOWER ...
//
// BULLISH ...
if (isBearPoswerUnderLast)
{
bullScore++;
}
if (isBearPoswerUnderZero)
{
bullScore++;
}
//
// BEARISH ...
if (isBearPowerOverLast)
{
bearScore++;
}
if (isBearPowerOverZero)
{
bearScore++;
}
//
// CCI ...
//
// BULLISH ...
if (isCCIPositive)
{
bullScore++;
}
if (isCCIOverPositiveHundred)
{
bullScore++;
}
//
// BEARISH ...
if (isCCINegative)
{
bearScore++;
}
if (isCCIUnderNegativeHundred)
{
bearScore++;
}
//
// MACD ...
//
// BULLISH ...
if (isMACDPositiove)
{
bullScore++;
}
if (isMACDOverSignal)
{
bullScore++;
}
//
// BEARISH ...
if (isMACDNegative)
{
bearScore++;
}
if (isMACDUnderSignal)
{
bearScore++;
}
//
// STOCH ...
//
// BULLISH ...
if (isStochKOverD)
{
bullScore++;
}
if (isStochKDUnder20)
{
bullScore++;
}
if (isStochKDUnder50)
{
bullScore++;
}
//
// BEARISH ...
if (isStochKUnderD)
{
bearScore++;
}
if (isStochKDOver50)
{
bearScore++;
}
if (isStochKDOver80)
{
bearScore++;
}
//
bullishScore = bullScore * multiplier;
bearishScore = bearScore * multiplier;
}
//
// Generate Summary ...
virtual string GenerateSummary(
const bool onlySummary = false, // Only Generate Conditions Summary
double multiplier = 1, // Score Multiplier
const string separator = "\n", // Separator
const bool ignoreFalseConditions = true // Ignore False Conditions
)
{
//
string result = NULL;
//
result = GenerateSummaryBody(
onlySummary,
multiplier,
separator,
ignoreFalseConditions
//
);
//
// Generating Full Result by Combining parts ...
result =
//
"[" + GetToken() + "]" + separator +
"-----------------------------" + separator +
result +
""
//
;
//
return result;
}
//
string GenerateSummary(
string provided, // Additional Info about Type, Provider and Symbol
const bool onlySummary = false, // Only Generate Conditions Summary
double multiplier = 1, // Score Multiplier
const string separator = "\n", // Separator
const bool ignoreFalseConditions = true // Ignore False Conditions
)
{
//
string result = NULL;
//
result = GenerateSummaryBody(
onlySummary,
multiplier,
separator,
ignoreFalseConditions
//
);
//
// Generating Full Result by Combining parts ...
result =
//
"[" + GetToken() + "]" + separator +
provided + separator +
"-----------------------------" + separator +
result +
""
//
;
//
return result;
}
//
string GenerateSummaryBody(
const bool onlySummary = false, // Only Generate Conditions Summary
double multiplier = 1, // Score Multiplier
const string separator = "\n", // Separator
const bool ignoreFalseConditions = true // Ignore False Conditions
)
{
//
string result = NULL;
//
double bullScore = 0;
double bearScore = 0;
GenerateScore(
bullScore,
bearScore,
multiplier //
);
//
// Common ...
string commonStr =
//
"Commons: " + separator +
"-----------------------------" + separator +
"Time: " + ToString(TimeCurrent()) + separator +
"-----------" + separator +
"Scores: " + separator +
"-----------" + separator +
"Bullish: " + ToString(bullScore) + separator +
"Bearish: " + ToString(bearScore) + separator +
"-----------------------------" + separator +
//
// TODO: Add Scores Later ...
separator +
""
//
;
//
// Candlestick ...
string candlesticStr =
//
ToString("isLastBullish", isLastBullish, ignoreFalseConditions) +
ToString("isLastBearish", isLastBearish, ignoreFalseConditions) +
ToString("isCurrentBullish", isCurrentBullish, ignoreFalseConditions) +
ToString("isCurrentBearish", isCurrentBearish, ignoreFalseConditions) +
ToString("isCurrentMidLineOverLastHigh", isCurrentMidLineOverLastHigh, ignoreFalseConditions) +
ToString("isCurrentMidLineUnderLastLow", isCurrentMidLineUnderLastLow, ignoreFalseConditions) +
ToString("isCurrentMidLineOverLastUp", isCurrentMidLineOverLastUp, ignoreFalseConditions) +
ToString("isCurrentMidLineUnderLastDown", isCurrentMidLineUnderLastDown, ignoreFalseConditions) +
ToString("isCurrentMidLineOverLastMidLine", isCurrentMidLineOverLastMidLine, ignoreFalseConditions) +
ToString("isCurrentMidLineUnderLastMidLine", isCurrentMidLineUnderLastMidLine, ignoreFalseConditions) +
""
//
;
candlesticStr = SetLabel("Candelstick: ", candlesticStr, separator);
//
// XSTR ...
string strStr =
//
ToString("isTrendBullish", isTrendBullish, ignoreFalseConditions) +
ToString("isTrendBearish", isTrendBearish, ignoreFalseConditions) +
ToString("isTrendSwitchedToBullish", isTrendSwitchedToBullish, ignoreFalseConditions) +
ToString("isTrendSwitchedToBearish", isTrendSwitchedToBearish, ignoreFalseConditions) +
""
//
;
strStr = SetLabel("XSTR: ", strStr, separator);
//
// XCHE ...
string cheStr =
//
ToString("isCHEInLong", isCHEInLong, ignoreFalseConditions) +
ToString("isCHEInStrongLong", isCHEInStrongLong, ignoreFalseConditions) +
ToString("isCHEInShort", isCHEInShort, ignoreFalseConditions) +
ToString("isCHEInStrongShort", isCHEInStrongShort, ignoreFalseConditions) +
""
//
;
cheStr = SetLabel("XCHE: ", cheStr, separator);
//
// XICH ...
string ichStr =
//
ToString("isSenkouSpanAOverB", isSenkouSpanAOverB, ignoreFalseConditions) +
ToString("isSenkouSpanAUnderB", isSenkouSpanAUnderB, ignoreFalseConditions) +
ToString("isSenkouSpanAOverLast", isSenkouSpanAOverLast, ignoreFalseConditions) +
ToString("isSenkouSpanAUnderLast", isSenkouSpanAUnderLast, ignoreFalseConditions) +
ToString("isCloseOverKijunSen", isCloseOverKijunSen, ignoreFalseConditions) +
ToString("isCloseUnderKijunSen", isCloseUnderKijunSen, ignoreFalseConditions) +
ToString("isTenkanSenOverKijunSen", isTenkanSenOverKijunSen, ignoreFalseConditions) +
ToString("isTenkanSenUnderKijunSen", isTenkanSenUnderKijunSen, ignoreFalseConditions) +
ToString("isFutureSenkouSpanAOverB", isFutureSenkouSpanAOverB, ignoreFalseConditions) +
ToString("isFutureSenkouSpanAUnderB", isFutureSenkouSpanAUnderB, ignoreFalseConditions) +
ToString("isFutureSenkouSpanAOverLast", isFutureSenkouSpanAOverLast, ignoreFalseConditions) +
ToString("isFutureSenkouSpanAUnderLast", isFutureSenkouSpanAUnderLast, ignoreFalseConditions) +
""
//
;
ichStr = SetLabel("XICH: ", ichStr, separator);
//
// XMC ...
string mcStr =
//
ToString("isFastOverSlow", isFastOverSlow, ignoreFalseConditions) +
ToString("isFastUnderSlow", isFastUnderSlow, ignoreFalseConditions) +
ToString("isFastOverVerifier", isFastOverVerifier, ignoreFalseConditions) +
ToString("isFastUnderVerifier", isFastUnderVerifier, ignoreFalseConditions) +
ToString("isSlowOverVerifier", isSlowOverVerifier, ignoreFalseConditions) +
ToString("isSlowUnderVerifier", isSlowUnderVerifier, ignoreFalseConditions) +
ToString("isCloseOverFast", isCloseOverFast, ignoreFalseConditions) +
ToString("isCloseUnderFast", isCloseUnderFast, ignoreFalseConditions) +
ToString("isCloseOverSlow", isCloseOverSlow, ignoreFalseConditions) +
ToString("isCloseUnderSlow", isCloseUnderSlow, ignoreFalseConditions) +
ToString("isCloseOverVerifier", isCloseOverVerifier, ignoreFalseConditions) +
ToString("isCloseUnderVerifier", isCloseUnderVerifier, ignoreFalseConditions) +
""
//
;
mcStr = SetLabel("XMC: ", mcStr, separator);
//
// XOSC ...
//
// STDDEV ...
string stddevStr =
//
ToString("isSTDDEVOverAVG", isSTDDEVOverAVG, ignoreFalseConditions) +
ToString("isSTDDEVUnderAVG", isSTDDEVUnderAVG, ignoreFalseConditions) +
ToString("isSTDDEVOverLast", isSTDDEVOverLast, ignoreFalseConditions) +
ToString("isSTDDEVUnderLast", isSTDDEVUnderLast, ignoreFalseConditions) +
""
//
;
stddevStr = SetLabel("STDDEV: ", stddevStr, separator);
//
// RVI ...
string rviStr =
//
ToString("isRVILongStart", isRVILongStart, ignoreFalseConditions) +
ToString("isRVILongStop", isRVILongStop, ignoreFalseConditions) +
ToString("isRVIShortStart", isRVIShortStart, ignoreFalseConditions) +
ToString("isRVIShortStop", isRVIShortStop, ignoreFalseConditions) +
""
//
;
rviStr = SetLabel("RVI: ", rviStr, separator);
//
// RSI ...
string rsiStr =
//
ToString("isRSIOver50", isRSIOver50, ignoreFalseConditions) +
ToString("isRSIUnder50", isRSIUnder50, ignoreFalseConditions) +
ToString("isRSIOver70", isRSIOver70, ignoreFalseConditions) +
ToString("isRSIUnder30", isRSIUnder30, ignoreFalseConditions) +
""
//
;
rsiStr = SetLabel("RSI: ", rsiStr, separator);
//
// CCI ...
string cciStr =
//
ToString("isCCIPositive", isCCIPositive, ignoreFalseConditions) +
ToString("isCCINegative", isCCINegative, ignoreFalseConditions) +
ToString("isCCIOverPositiveHundred", isCCIOverPositiveHundred, ignoreFalseConditions) +
ToString("isCCIUnderNegativeHundred", isCCIUnderNegativeHundred, ignoreFalseConditions) +
""
//
;
cciStr = SetLabel("CCI: ", cciStr, separator);
//
// MACD ...
string macdStr =
//
ToString("isMACDPositiove", isMACDPositiove, ignoreFalseConditions) +
ToString("isMACDNegative", isMACDNegative, ignoreFalseConditions) +
ToString("isMACDOverSignal", isMACDOverSignal, ignoreFalseConditions) +
ToString("isMACDUnderSignal", isMACDUnderSignal, ignoreFalseConditions) +
""
//
;
macdStr = SetLabel("MACD: ", macdStr, separator);
//
// BULLP ...
string bullPStr =
//
ToString("isBullPowerOverLast", isBullPowerOverLast, ignoreFalseConditions) +
ToString("isBullPoswerUnderLast", isBullPoswerUnderLast, ignoreFalseConditions) +
ToString("isBullPowerOverZero", isBullPowerOverZero, ignoreFalseConditions) +
ToString("isBullPoswerUnderZero", isBullPoswerUnderZero, ignoreFalseConditions) +
""
//
;
bullPStr = SetLabel("BULLP: ", bullPStr, separator);
//
// BEARP ...
string bearPStr =
//
ToString("isBearPowerOverLast", isBearPowerOverLast, ignoreFalseConditions) +
ToString("isBearPoswerUnderLast", isBearPoswerUnderLast, ignoreFalseConditions) +
ToString("isBearPowerOverZero", isBearPowerOverZero, ignoreFalseConditions) +
ToString("isBearPoswerUnderZero", isBearPoswerUnderZero, ignoreFalseConditions) +
""
//
;
bearPStr = SetLabel("BEARP: ", bearPStr, separator);
//
// STOCH ...
string stochStr =
//
ToString("isStochKOverD", isStochKOverD, ignoreFalseConditions) +
ToString("isStochKUnderD", isStochKUnderD, ignoreFalseConditions) +
ToString("isStochKDOver50", isStochKDOver50, ignoreFalseConditions) +
ToString("isStochKDOver80", isStochKDOver80, ignoreFalseConditions) +
ToString("isStochKDUnder20", isStochKDUnder20, ignoreFalseConditions) +
ToString("isStochKDUnder50", isStochKDUnder50, ignoreFalseConditions) +
""
//
;
stochStr = SetLabel("STOCH: ", stochStr, separator);
//
string oscStr =
//
stddevStr +
rviStr +
rsiStr +
cciStr +
macdStr +
bullPStr +
bearPStr +
stochStr +
""
//
;
oscStr = SetLabel("XOSC: ", oscStr, separator);
//
result =
//
commonStr +
candlesticStr +
(onlySummary
? ""
: strStr +
cheStr +
ichStr +
mcStr +
oscStr //
) +
""
//
;
//
return result;
}
//
string GetTitle()
{
//
string result = NULL;
//
result =
//
"[" + ToString(cycle) + "]: " + ToString(period)
//
;
//
return result;
}
//
// For Data Collector ...
string GetToken()
{
return GetSpecificToken(this);
}
bool IsModelValid()
{
return false;
}
string ToModelString()
{
return NULL;
}
bool ParseModel(string content)
{
return false;
}
int FindIndex(X121MCycleConditions &items[])
{
return -1;
}
};
//
// Market Class ...
class XSCX121Market : XSCBase
{
//
// Public ...
public:
//
// Props ...
XSCXMCHelper mc;
XSCXSTRHelper str;
XSCXCHEHelper che;
XSCXOSCHelper osc;
XSCXICHHelper ich;
//
// Properties ...
//
// Retrieve Trading Symbol ...
string GetSymbol()
{
return mInputs.cycle.symbol;
}
//
// Retrieve Cycle Time Frame ...
ENUM_TIMEFRAMES GetPeriod()
{
return mInputs.cycle.period;
}
//
// Retrieve Market Host Time Frame ...
ENUM_TIMEFRAMES GetHostPeriod()
{
return mInputs.cycle.hostPeriod;
}
//
// Count Total Available Bars in Market ...
int CountBars()
{
//
Update(0);
return mInputs.cycle.CountBars();
}
//
// Check Market is in new Bar ...
int IsNewBar()
{
//
Update(0);
return mInputs.cycle.IsNewBar();
}
//
// Retrieve Current Cycles Specific Bar ...
XOHCL GetBar(int barIndex)
{
//
Update(0);
return mInputs.cycle.GetBar(barIndex);
}
//
// Retrieve Current Bar Index based on Host Period bar Index ...
int GetBarIndex(int barIndex)
{
//
Update(barIndex);
return mInputs.cycle.GetBarIndex(barIndex);
}
//
// Retrieve Bar Time ...
datetime GetBarTime(int barIndex)
{
//
Update(0);
return mInputs.cycle.GetBarTime(barIndex);
}
//
// Retrieve Current Market Config ...
bool GetInputs(X121MCycleInputs &inputs)
{
//
bool result = false;
//
inputs = mInputs;
//
result = inputs.IsValid();
//
return result;
}
//
// Set Market Inputs and Re Initial ...
bool SetInputs(
X121MCycleInputs &inputs // Config
)
{
//
return Init(inputs);
}
//
// Tools ...
//
void GetMarketConditions(
X121MCycleConditions &conditions, // Market Conditions Result
int barIndex = 0, // Specified Bar Index
int mNumberOfItems = 15 // Number of Reading Items
)
{
//
conditions.Clear();
//
if (barIndex < 0)
{
barIndex = 0;
}
//
if (barIndex >= CountBars())
{
barIndex = CountBars() + 2;
}
//
int curr = barIndex + 1;
int prev = curr + 1;
//
// Here i Have to Calculate Market Conditions based on
// Several Indicator/Oscillator(s) ...
//
// Set Commons ...
conditions.time = GetBarTime(barIndex);
conditions.cycle = mInputs.cycle.cycle;
conditions.prefix = mInputs.cycle.prefix;
conditions.symbol = mInputs.cycle.symbol;
conditions.period = mInputs.cycle.period;
conditions.hostPeriod = mInputs.cycle.hostPeriod;
//
Clean(conditions.bars);
GetBars(
conditions.bars,
conditions.symbol,
conditions.period,
barIndex,
barIndex + 5);
//
XOHCL cBar = GetBar(barIndex);
XOHCL pBar = GetBar(barIndex + 1);
//
// CANDELSTICK ...
//
bool isLastBullish =
//
pBar.IsBullish()
//
;
//
bool isLastBearish =
//
pBar.IsBearish()
//
;
//
bool isCurrentBullish =
//
cBar.IsBullish()
//
;
//
bool isCurrentBearish =
//
cBar.IsBearish()
//
;
//
bool isCurrentMidLineOverLastHigh =
//
cBar.GetMid() > pBar.high;
//
;
//
bool isCurrentMidLineUnderLastLow =
//
cBar.GetMid() < pBar.low
//
;
//
bool isCurrentMidLineOverLastUp =
//
cBar.GetMid() > pBar.GetUp()
//
;
//
bool isCurrentMidLineUnderLastDown =
//
cBar.GetMid() < pBar.GetDown()
//
;
//
bool isCurrentMidLineOverLastMidLine =
//
cBar.GetMid() > pBar.GetMid()
//
;
//
bool isCurrentMidLineUnderLastMidLine =
//
cBar.GetMid() < pBar.GetMid()
//
;
//
conditions.isLastBullish = isLastBullish;
conditions.isLastBearish = isLastBearish;
conditions.isCurrentBullish = isCurrentBullish;
conditions.isCurrentBearish = isCurrentBearish;
conditions.isCurrentMidLineOverLastHigh = isCurrentMidLineOverLastHigh;
conditions.isCurrentMidLineUnderLastLow = isCurrentMidLineUnderLastLow;
conditions.isCurrentMidLineOverLastUp = isCurrentMidLineOverLastUp;
conditions.isCurrentMidLineUnderLastDown = isCurrentMidLineUnderLastDown;
conditions.isCurrentMidLineOverLastMidLine = isCurrentMidLineOverLastMidLine;
conditions.isCurrentMidLineUnderLastMidLine = isCurrentMidLineUnderLastMidLine;
//
// XSTR ...
//
str.CopyTrend(
barIndex,
mNumberOfItems,
conditions.strTrends //
);
str.CopyState(
barIndex,
mNumberOfItems,
conditions.strStates //
);
//
bool isTrendBullish =
//
str.IsBullish(str.GetState(curr))
//
;
bool isTrendBearish =
//
str.IsBearish(str.GetState(curr))
//
;
//
bool isTrendBullishPrev =
//
str.IsBullish(str.GetState(prev))
//
;
bool isTrendBearishPrev =
//
str.IsBearish(str.GetState(prev))
//
;
//
conditions.isTrendBullish = isTrendBullish;
conditions.isTrendBearish = isTrendBearish;
conditions.isTrendSwitchedToBullish =
//
isTrendBullish &&
!isTrendBullishPrev
//
;
conditions.isTrendSwitchedToBearish =
//
isTrendBearish &&
!isTrendBearishPrev
//
;
//
// XCHE ...
//
che.CopyLongExit1(
barIndex,
mNumberOfItems,
conditions.cheLongExit1s //
);
che.CopyLongExit2(
barIndex,
mNumberOfItems,
conditions.cheLongExit2s //
);
che.CopyShortExit1(
barIndex,
mNumberOfItems,
conditions.cheShortExit1s //
);
che.CopyShortExit2(
barIndex,
mNumberOfItems,
conditions.cheShortExit2s //
);
//
bool isCHEInLong =
//
NotEmpty(che.GetLongExit1(curr))
//
;
bool isCHEInStrongLong =
//
isCHEInLong &&
NotEmpty(che.GetLongExit2(curr))
//
;
bool isCHEInShort =
//
NotEmpty(che.GetShortExit1(curr))
//
;
bool isCHEInStrongShort =
//
isCHEInShort &&
NotEmpty(che.GetShortExit2(curr))
//
;
//
conditions.isCHEInLong = isCHEInLong;
conditions.isCHEInShort = isCHEInShort;
conditions.isCHEInStrongLong = isCHEInStrongLong;
conditions.isCHEInStrongShort = isCHEInStrongShort;
//
// XMC ...
//
mc.CopyFast(
barIndex,
mNumberOfItems,
conditions.mcFasts //
);
mc.CopySlow(
barIndex,
mNumberOfItems,
conditions.mcSlows //
);
mc.CopyVerifier(
barIndex,
mNumberOfItems,
conditions.mcVerifiers //
);
//
bool isFastOverSlow =
//
conditions.mcFasts[curr] > conditions.mcSlows[curr] &&
conditions.mcFasts[prev] > conditions.mcSlows[prev]
//
;
bool isFastUnderSlow =
//
conditions.mcFasts[curr] < conditions.mcSlows[curr] &&
conditions.mcFasts[prev] < conditions.mcSlows[prev]
//
;
bool isFastOverVerifier =
//
conditions.mcFasts[curr] > conditions.mcVerifiers[curr] &&
conditions.mcFasts[prev] > conditions.mcVerifiers[prev]
//
;
bool isFastUnderVerifier =
//
conditions.mcFasts[curr] < conditions.mcVerifiers[curr] &&
conditions.mcFasts[prev] < conditions.mcVerifiers[prev]
//
;
bool isSlowOverVerifier =
//
conditions.mcSlows[curr] > conditions.mcVerifiers[curr] &&
conditions.mcSlows[prev] > conditions.mcVerifiers[prev]
//
;
bool isSlowUnderVerifier =
//
conditions.mcSlows[curr] < conditions.mcVerifiers[curr] &&
conditions.mcSlows[prev] < conditions.mcVerifiers[prev]
//
;
bool isCloseOverFast =
//
pBar.close > conditions.mcFasts[prev]
//
;
bool isCloseUnderFast =
//
pBar.close < conditions.mcFasts[prev]
//
;
bool isCloseOverSlow =
//
pBar.close > conditions.mcSlows[prev]
//
;
bool isCloseUnderSlow =
//
pBar.close < conditions.mcSlows[prev]
//
;
bool isCloseOverVerifier =
//
pBar.close > conditions.mcVerifiers[prev]
//
;
bool isCloseUnderVerifier =
//
pBar.close < conditions.mcVerifiers[prev]
//
;
//
conditions.isFastOverSlow = isFastOverSlow;
conditions.isFastUnderSlow = isFastUnderSlow;
conditions.isFastOverVerifier = isFastOverVerifier;
conditions.isFastUnderVerifier = isFastUnderVerifier;
conditions.isSlowOverVerifier = isSlowOverVerifier;
conditions.isSlowUnderVerifier = isSlowUnderVerifier;
conditions.isCloseOverFast = isCloseOverFast;
conditions.isCloseUnderFast = isCloseUnderFast;
conditions.isCloseOverSlow = isCloseOverSlow;
conditions.isCloseUnderSlow = isCloseUnderSlow;
conditions.isCloseOverVerifier = isCloseOverVerifier;
conditions.isCloseUnderVerifier = isCloseUnderVerifier;
//
// XICH ...
//
ich.CopyTenkanSen(
barIndex,
mNumberOfItems,
conditions.ichTenkanSens //
);
ich.CopyKijunSen(
barIndex,
mNumberOfItems,
conditions.ichKijunSens //
);
ich.CopyChikouSpan(
barIndex,
mNumberOfItems,
conditions.ichChikouSpans //
);
ich.CopySenkouSpanA(
barIndex,
mNumberOfItems,
conditions.ichSenkouSpanBs //
);
ich.CopySenkouSpanB(
barIndex,
mNumberOfItems,
conditions.ichSenkouSpanAs //
);
//
double tenkanSen = ich.GetTenkanSen(curr);
double tenkanSenPrev = ich.GetTenkanSen(prev);
//
double kijunSen = ich.GetKijunSen(curr);
double kijunSenPrev = ich.GetKijunSen(prev);
//
double senkouSpanA = ich.GetSenkouSpanA(curr);
double senkouSpanAPrev = ich.GetSenkouSpanA(prev);
//
double senkouSpanB = ich.GetSenkouSpanB(curr);
double senkouSpanBPrev = ich.GetSenkouSpanB(prev);
//
double futureSenkouSpanA = ich.GetFutureSenkouSpanA(curr);
double futureSenkouSpanAPrev = ich.GetFutureSenkouSpanA(prev);
//
double futureSenkouSpanB = ich.GetFutureSenkouSpanB(curr);
double futureSenkouSpanBPrev = ich.GetFutureSenkouSpanB(prev);
//
bool isSenkouSpanAOverB = senkouSpanA > senkouSpanB;
bool isSenkouSpanAUnderB = senkouSpanA < senkouSpanB;
bool isSenkouSpanAOverLast = senkouSpanA > senkouSpanAPrev;
bool isSenkouSpanAUnderLast = senkouSpanA < senkouSpanAPrev;
bool isFutureSenkouSpanAOverB = futureSenkouSpanA > futureSenkouSpanB;
bool isFutureSenkouSpanAUnderB = futureSenkouSpanA < futureSenkouSpanB;
bool isFutureSenkouSpanAOverLast = futureSenkouSpanA > futureSenkouSpanAPrev;
bool isFutureSenkouSpanAUnderLast = futureSenkouSpanA < futureSenkouSpanAPrev;
bool isCloseOverKijunSen = pBar.close > kijunSenPrev;
bool isCloseUnderKijunSen = pBar.close < kijunSenPrev;
bool isTenkanSenOverKijunSen = tenkanSen > kijunSen;
bool isTenkanSenUnderKijunSen = tenkanSen < kijunSen;
bool isTenkanSenPrevOverKijunSen = tenkanSenPrev > kijunSenPrev;
bool isTenkanSenPrevUnderKijunSen = tenkanSenPrev < kijunSenPrev;
bool isTenkanSenCrossedOverKijunSen =
//
isTenkanSenOverKijunSen &&
!isTenkanSenPrevOverKijunSen
//
;
bool isTenkanSenCrossedUnderKijunSen =
//
isTenkanSenUnderKijunSen &&
!isTenkanSenPrevUnderKijunSen
//
;
//
conditions.isSenkouSpanAOverB = isSenkouSpanAOverB;
conditions.isSenkouSpanAUnderB = isSenkouSpanAUnderB;
conditions.isSenkouSpanAOverLast = isSenkouSpanAOverLast;
conditions.isSenkouSpanAUnderLast = isSenkouSpanAUnderLast;
conditions.isFutureSenkouSpanAOverB = isFutureSenkouSpanAOverB;
conditions.isFutureSenkouSpanAUnderB = isFutureSenkouSpanAUnderB;
conditions.isFutureSenkouSpanAOverLast = isFutureSenkouSpanAOverLast;
conditions.isFutureSenkouSpanAUnderLast = isFutureSenkouSpanAUnderLast;
conditions.isCloseOverKijunSen = isCloseOverKijunSen;
conditions.isCloseUnderKijunSen = isCloseUnderKijunSen;
conditions.isTenkanSenOverKijunSen = isTenkanSenOverKijunSen;
conditions.isTenkanSenUnderKijunSen = isTenkanSenUnderKijunSen;
conditions.isTenkanSenCrossedOverKijunSen = isTenkanSenCrossedOverKijunSen;
conditions.isTenkanSenCrossedUnderKijunSen = isTenkanSenCrossedUnderKijunSen;
//
// XOSC ...
//
// ATR ...
osc.CopyATR(
barIndex,
mNumberOfItems,
conditions.oscAtrs //
);
//
// VOLUE ...
osc.CopyVolume(
barIndex,
mNumberOfItems,
conditions.oscVolumes //
);
//
// MOMENTUM ...
osc.CopyMomentum(
barIndex,
mNumberOfItems,
conditions.oscMomentums //
);
//
// SAR ...
osc.CopySAR(
barIndex,
mNumberOfItems,
conditions.oscSars //
);
//
// RVI ...
//
osc.CopyRVI(
barIndex,
mNumberOfItems,
conditions.oscRviMains //
);
osc.CopyRVISignal(
barIndex,
mNumberOfItems,
conditions.oscRviSignals //
);
//
double rvi = osc.GetRVI(curr);
double rviSignal = osc.GetRVISignal(curr);
//
bool isRVILongStart =
//
rvi > 0 &&
rviSignal > 0 &&
rvi > rviSignal
//
;
bool isRVILongStop =
//
rvi < 0 &&
rviSignal < 0 &&
rvi < rviSignal
//
;
bool isRVIShortStart =
//
rvi < 0 &&
rviSignal < 0 &&
rvi < rviSignal
//
;
bool isRVIShortStop =
//
rvi > 0 &&
rviSignal > 0 &&
rvi > rviSignal
//
;
//
conditions.isRVILongStart = isRVILongStart;
conditions.isRVILongStop = isRVILongStop;
conditions.isRVIShortStart = isRVIShortStart;
conditions.isRVIShortStop = isRVIShortStop;
//
// RSI ...
//
osc.CopyRSI(
barIndex,
mNumberOfItems,
conditions.oscRsis //
);
//
double rsi = osc.GetRSI(curr);
//
bool isRSIUnder50 =
//
rsi < 50
//
;
bool isRSIOver70 =
//
rsi > 70
//
;
bool isRSIOver50 =
//
rsi > 50
//
;
bool isRSIUnder30 =
//
rsi < 30
//
;
//
conditions.isRSIUnder50 = isRSIUnder50;
conditions.isRSIOver70 = isRSIOver70;
conditions.isRSIOver50 = isRSIOver50;
conditions.isRSIUnder30 = isRSIUnder30;
//
// BULLPOWER ...
//
osc.CopyBullPower(
barIndex,
mNumberOfItems,
conditions.oscBullPs //
);
//
double bullp = osc.GetBullPower(curr);
double bullpLast = osc.GetBullPower(prev);
//
bool isBullPowerOverLast =
//
bullp > bullpLast
//
;
bool isBullPoswerUnderLast =
//
bullp < bullpLast
//
;
bool isBullPowerOverZero =
//
bullp > 0
//
;
bool isBullPoswerUnderZero =
//
bullp < 0
//
;
//
conditions.isBullPowerOverLast = isBullPowerOverLast;
conditions.isBullPoswerUnderLast = isBullPoswerUnderLast;
conditions.isBullPowerOverZero = isBullPowerOverZero;
conditions.isBullPoswerUnderZero = isBullPoswerUnderZero;
//
// BEARPOWER ...
//
osc.CopyBearPower(
barIndex,
mNumberOfItems,
conditions.oscBearPs //
);
//
double bearp = osc.GetBearPower(curr);
double bearpLast = osc.GetBearPower(prev);
//
bool isBearPowerOverLast =
//
bearp > bearpLast
//
;
bool isBearPoswerUnderLast =
//
bearp < bearpLast
//
;
bool isBearPowerOverZero =
//
bearp > 0
//
;
bool isBearPoswerUnderZero =
//
bearp < 0
//
;
//
conditions.isBearPowerOverLast = isBearPowerOverLast;
conditions.isBearPoswerUnderLast = isBearPoswerUnderLast;
conditions.isBearPowerOverZero = isBearPowerOverZero;
conditions.isBearPoswerUnderZero = isBearPoswerUnderZero;
//
// CCI ...
//
osc.CopyCCI(
barIndex,
mNumberOfItems,
conditions.oscCcis //
);
//
double cci = osc.GetCCI(curr);
//
bool isCCIPositive =
//
cci > 0
//
;
bool isCCINegative =
//
cci < 0
//
;
bool isCCIOverPositiveHundred =
//
cci > 100
//
;
bool isCCIUnderNegativeHundred =
//
cci < -100
//
;
//
conditions.isCCIPositive = isCCIPositive;
conditions.isCCINegative = isCCINegative;
conditions.isCCIOverPositiveHundred = isCCIOverPositiveHundred;
conditions.isCCIUnderNegativeHundred = isCCIUnderNegativeHundred;
//
// MACD ...
//
osc.CopyMACD(
barIndex,
mNumberOfItems,
conditions.oscMacdMains //
);
osc.CopyMACDSignal(
barIndex,
mNumberOfItems,
conditions.oscMacdSignals //
);
//
double macd = osc.GetMACD(curr);
double macdSignal = osc.GetMACDSignal(curr);
//
bool isMACDPositiove =
//
macd > 0
//
;
bool isMACDNegative =
//
macd < 0
//
;
bool isMACDOverSignal =
//
macd > macdSignal
//
;
bool isMACDUnderSignal =
//
macd < macdSignal
//
;
//
conditions.isMACDPositiove = isMACDPositiove;
conditions.isMACDNegative = isMACDNegative;
conditions.isMACDOverSignal = isMACDOverSignal;
conditions.isMACDUnderSignal = isMACDUnderSignal;
//
// STOCH ...
//
osc.CopySTOCH(
barIndex,
mNumberOfItems,
conditions.oscStochMains //
);
osc.CopySTOCHSignal(
barIndex,
mNumberOfItems,
conditions.oscStochSignals //
);
//
double stoch = osc.GetSTOCH(curr);
double stochSignal = osc.GetSTOCHSignal(curr);
//
bool isStochKOverD =
//
stoch > stochSignal
//
;
bool isStochKDUnder50 =
//
stoch < 50 &&
stochSignal < 50
//
;
bool isStochKUnderD =
//
stoch < stochSignal
//
;
bool isStochKDOver50 =
//
stoch > 50 &&
stochSignal > 50
//
;
bool isStochKDUnder20 =
//
stoch < 20 &&
stochSignal < 20
//
;
bool isStochKDOver80 =
//
stoch > 80 &&
stochSignal > 80
//
;
//
conditions.isStochKOverD = isStochKOverD;
conditions.isStochKDUnder50 = isStochKDUnder50;
conditions.isStochKUnderD = isStochKUnderD;
conditions.isStochKDOver50 = isStochKDOver50;
conditions.isStochKDUnder20 = isStochKDUnder20;
conditions.isStochKDOver80 = isStochKDOver80;
//
// STDDEV ...
//
osc.CopySTDDEV(
barIndex,
mNumberOfItems,
conditions.oscStddevs //
);
//
double stdDevs[];
osc.CopySTDDEV(
barIndex + 1,
5,
stdDevs //
);
double stdDevAVG = GetAverage(stdDevs);
//
double stdDev = osc.GetSTDDEV(curr);
double stdDevLast = osc.GetSTDDEV(prev);
//
bool isSTDDEVOverAVG =
//
stdDev > stdDevAVG
//
;
bool isSTDDEVUnderAVG =
//
stdDev < stdDevAVG
//
;
bool isSTDDEVOverLast =
//
stdDev > stdDevLast
//
;
bool isSTDDEVUnderLast =
//
stdDev < stdDevLast
//
;
//
conditions.isSTDDEVOverAVG = isSTDDEVOverAVG;
conditions.isSTDDEVUnderAVG = isSTDDEVUnderAVG;
conditions.isSTDDEVOverLast = isSTDDEVOverLast;
conditions.isSTDDEVUnderLast = isSTDDEVUnderLast;
}
//
// Initial Market Cycle ...
bool Init(
X121MCycleInputs &inputs // Inputs for Initialization
)
{
//
bool result = false;
//
// Validate Input ...
result = inputs.IsValid();
if (!result)
{
return result;
}
//
mInputs = inputs;
//
string symbol = mInputs.cycle.symbol;
ENUM_TIMEFRAMES period = mInputs.cycle.period;
//
// Init Helpers ...
//
// XMC ...
result = mc.Init(
symbol,
period,
mInputs.mcInputs
//
);
if (!result)
{
return result;
}
//
// XSTR ...
result = str.Init(
symbol,
period,
mInputs.strInputs
//
);
if (!result)
{
return result;
}
//
// XCHE ...
result = che.Init(
symbol,
period,
mInputs.cheInputs
//
);
if (!result)
{
return result;
}
//
// XOSC ...
result = osc.Init(
symbol,
period,
mInputs.oscInputs
//
);
if (!result)
{
return result;
}
//
// XICH ...
result = ich.Init(
symbol,
period,
mInputs.ichInputs
//
);
if (!result)
{
return result;
}
//
return result;
}
//
// Draw Tools ...
//
// Completely Draw Bars ...
void Draw(
long chartID, // Chart ID ...
int subWindow, // Chart Sub Window ...
int &offset // Distance used for Labels ...
)
{
//
if (mInputs.drawCBar || mInputs.drawPBar)
{
//
DrawOHCL(
chartID,
subWindow,
mInputs.drawLabels,
!mInputs.drawCBar && mInputs.drawPBar,
!mInputs.drawPBar && mInputs.drawCBar,
offset
//
);
//
if (mInputs.drawLabels)
{
offset += 3;
}
}
//
if (mInputs.drawCBarMid || mInputs.drawPBarMid)
{
//
DrawMidLine(
chartID,
subWindow,
mInputs.drawLabels,
!mInputs.drawCBarMid && mInputs.drawPBarMid,
!mInputs.drawPBarMid && mInputs.drawCBarMid,
offset
//
);
//
if (mInputs.drawLabels)
{
//
if (mInputs.drawCBarMid)
{
offset++;
}
//
if (mInputs.drawPBarMid)
{
offset++;
}
}
}
}
//
// Draw Functions ...
//
// Draw Middle Line of Cycle ...
void DrawOHCL(
long chartID,
int subWindow,
bool drawLabel = false, // Specify Draw Label of Mid Line or not ...
bool drawOnlyPrev = false, // Specify Draw Only Prev Bar of Cycle ...
bool drawOnlyCurrent = false, // Specify Draw Only Current Bar of Cycle ...
int offset = 0 // Distance used for Labels ...
)
{
//
if (offset < 0)
{
offset = 0;
}
//
string baseTag = ToString(mInputs.cycle.cycle);
//
XOHCL cBar = GetBar(0);
XOHCL pBar = GetBar(1);
//
datetime fromCDate = GetBarTime(0);
datetime fromPDate = GetBarTime(1);
//
datetime cTime = TimeCurrent();
//
// Try to Draw ...
//
bool canDrawPrev = !drawOnlyCurrent;
bool canDrawCurrent = !drawOnlyPrev;
//
// Set Cycles Color based on Current Candle ...
//
bool isCBarBullish =
cBar.IsBullish();
//
bool isPBarBullish =
pBar.IsBearish();
//
color clrTemoBullishColor = mInputs.cBarDrawSpecs.openStyle.clr;
color clrTemoBearishColor = mInputs.cBarDrawSpecs.closeStyle.clr;
//
color cBarSelectedColor = isCBarBullish ? clrTemoBullishColor : clrTemoBearishColor;
color pBarSelectedColor = isPBarBullish ? clrTemoBullishColor : clrTemoBearishColor;
//
mInputs.cBarDrawSpecs.openStyle.clr = cBarSelectedColor;
mInputs.cBarDrawSpecs.openStyle.labelColor = cBarSelectedColor;
//
mInputs.cBarDrawSpecs.closeStyle.clr = cBarSelectedColor;
mInputs.cBarDrawSpecs.closeStyle.labelColor = cBarSelectedColor;
//
mInputs.pBarDrawSpecs.openStyle.clr = pBarSelectedColor;
mInputs.pBarDrawSpecs.openStyle.labelColor = pBarSelectedColor;
//
mInputs.pBarDrawSpecs.closeStyle.clr = pBarSelectedColor;
mInputs.pBarDrawSpecs.closeStyle.labelColor = pBarSelectedColor;
//
if (canDrawPrev)
{
offset++;
}
//
// Label ...
if (drawLabel)
{
//
if (canDrawPrev)
{
//
// Draw Prev Bar Lables ...
//
DrawXOHCLLabel(
chartID,
subWindow,
pBar,
mInputs.pBarDrawSpecs,
"P",
cTime,
offset - 1
//
);
//
offset += 3;
}
//
if (canDrawCurrent)
{
//
// Draw Current Bar Lables ...
//
DrawXOHCLLabel(
chartID,
subWindow,
cBar,
mInputs.cBarDrawSpecs,
"C",
cTime,
offset
//
);
}
}
//
// Line ...
//
if (canDrawPrev)
{
//
// Draw Cycle Prev Bar ...
DrawXOHCLContent(
chartID,
subWindow,
pBar,
mInputs.pBarDrawSpecs,
"P",
fromPDate
//
);
}
//
if (canDrawCurrent)
{
//
// Draw Cycle Current Bar ...
DrawXOHCLContent(
chartID,
subWindow,
cBar,
mInputs.cBarDrawSpecs,
"C",
fromCDate
//
);
}
}
//
// Draw Middle Line of Cycle ...
void DrawMidLine(
long chartID,
int subWindow,
bool drawLabel = false, // Specify Draw Label of Mid Line or not ...
bool drawOnlyPrev = false, // Specify Draw Only Prev Bar of Cycle ...
bool drawOnlyCurrent = false, // Specify Draw Only Current Bar of Cycle ...
int offset = 0 // Distance used for Labels ...
)
{
//
if (offset < 0)
{
offset = 0;
}
//
// Calculate Mid Line ...
XOHCL cBar = GetBar(0);
double cMidLine = cBar.GetMid();
//
XOHCL pBar = GetBar(1);
double pMidLine = pBar.GetMid();
//
string baseTag = ToString(mInputs.cycle.cycle);
//
string midCTag = baseTag + "|MID|C|";
string midPTag = baseTag + "|MID|P|";
//
string midCLblTag = midCTag + "lbl";
string midPLblTag = midPTag + "lbl";
//
datetime fromCDate = GetBarTime(0);
datetime fromPDate = GetBarTime(1);
//
datetime cTime = TimeCurrent();
//
// Try to Draw ...
//
bool canDrawPrev = !drawOnlyCurrent;
bool canDrawCurrent = !drawOnlyPrev;
//
if (canDrawPrev)
{
offset++;
}
//
// Label ...
if (drawLabel)
{
//
if (canDrawPrev)
{
//
// Draw Prev Candle MidLine Lable ...
DrawLabel(
chartID,
subWindow,
mInputs.pBarMidDrawSpecs,
midPLblTag,
cTime,
pMidLine,
offset //
);
}
//
if (canDrawCurrent)
{
//
// Draw Current Candle MidLine Label ...
DrawLabel(
chartID,
subWindow,
mInputs.cBarMidDrawSpecs,
midCLblTag,
cTime,
cMidLine,
offset - 1 //
);
}
}
//
// Line ...
//
if (canDrawPrev)
{
//
// Draw Prev Candle MidLine ...
DrawLine(
chartID,
subWindow,
mInputs.pBarMidDrawSpecs,
midPTag,
fromPDate,
pMidLine //
);
}
//
if (canDrawCurrent)
{
//
// Draw Current Candle MidLine ...
DrawLine(
chartID,
subWindow,
mInputs.cBarMidDrawSpecs,
midCTag,
fromCDate,
cMidLine //
);
}
}
//
// Protected ...
protected:
//
// Private ...
private:
//
// Props ...
//
X121MCycleInputs mInputs;
//
// Tools ...
//
bool Update(int hostBarIndex = 0)
{
return mInputs.cycle.Update(hostBarIndex);
}
//
// Draw Functions ...
//
// Draw OHCL Labels ...
void DrawXOHCLLabel(
long chartID,
int subWindow,
XOHCL &bar, // Specify Cycle XOHCL Model to Draw ...
XOHCLDrawSpecification &specs, // Specify Cycle XOHCL Draw Specifications ...
string baseTag, // Specify a Unique Tag ...
datetime time, // Draw Time ...
int offset = 0 //
)
{
//
// Open ...
string openTag = mInputs.cycle.prefix + "_" + baseTag + "_O_lbl";
DrawLabel(
chartID,
subWindow,
specs.openStyle,
openTag,
time,
bar.open,
offset
//
);
//
// High ...
string highTag = mInputs.cycle.prefix + "_" + baseTag + "_H_lbl";
DrawLabel(
chartID,
subWindow,
specs.highStyle,
highTag,
time,
bar.high,
offset + 1
//
);
//
// Close ...
string closeTag = mInputs.cycle.prefix + "_" + baseTag + "_C_lbl";
DrawLabel(
chartID,
subWindow,
specs.closeStyle,
closeTag,
time,
bar.close,
offset + 2
//
);
//
// Low ...
string lowTag = mInputs.cycle.prefix + "_" + baseTag + "_L_lbl";
DrawLabel(
chartID,
subWindow,
specs.lowStyle,
lowTag,
time,
bar.low,
offset + 3
//
);
}
//
// Draw XOHCL Content ...
void DrawXOHCLContent(
long chartID,
int subWindow,
XOHCL &bar, // Specify Cycle XOHCL Model to Draw ...
XOHCLDrawSpecification &specs, // Specify Cycle XOHCL Draw Specifications ...
string baseTag, // Specify a Unique Tag ...
datetime time // Draw Time ...
)
{
//
// Open ...
string openTag = mInputs.cycle.prefix + "_" + baseTag + "_O";
DrawLine(
chartID,
subWindow,
specs.openStyle,
openTag,
time,
bar.open
//
);
//
// High ...
string highTag = mInputs.cycle.prefix + "_" + baseTag + "_H";
DrawLine(
chartID,
subWindow,
specs.highStyle,
highTag,
time,
bar.high
//
);
//
// Close ...
string closeTag = mInputs.cycle.prefix + "_" + baseTag + "_C";
DrawLine(
chartID,
subWindow,
specs.closeStyle,
closeTag,
time,
bar.close
//
);
//
// Low ...
string lowTag = mInputs.cycle.prefix + "_" + baseTag + "_L";
DrawLine(
chartID,
subWindow,
specs.lowStyle,
lowTag,
time,
bar.low
//
);
}
//
// Draw Label Using Specifications ...
void DrawLabel(
long chartID,
int subWindow,
XDrawSpecifications &specs,
string tag,
datetime time,
double price,
int offset = 0 //
)
{
//
if (offset < 0)
{
offset = 0;
}
//
int offsetSeconds = PeriodSeconds(mInputs.cycle.hostPeriod) * offset;
//
string value = specs.label;
//
DrawText(
chartID,
tag,
subWindow,
time - offsetSeconds,
price,
specs.label,
specs.labelFont,
specs.labelFontSize,
specs.labelColor,
specs.labelAngel,
specs.labelAnchor,
specs.back,
specs.selection,
specs.hidden,
specs.zOrder //
);
}
//
// Draw TrendLine Using Specifications ...
void DrawLine(
long chartID,
int subWindow,
XDrawSpecifications &specs,
string tag,
datetime fromDate,
double fromPrice,
datetime toDate = NULL,
double toPrice = 0 //
)
{
//
if (toPrice <= 0)
{
toPrice = fromPrice;
}
//
if (toDate == 0 || toDate == NULL)
{
toDate = TimeCurrent();
}
//
DrawTrendLine(
chartID,
tag,
subWindow,
fromDate,
fromPrice,
toDate,
toPrice,
specs.clr,
specs.style,
specs.width,
specs.back,
specs.selection,
specs.rayRight,
specs.hidden,
specs.zOrder //
);
}
};
//
// Tools ...
//
struct X121MarketCycleDescriptor
{
//
string symbol; // Trading Symbol
ENUM_TIMEFRAMES hostPeriod; // Host Period
ENUM_X_MARKET_CYCLES cycle; // Init Cycle
ENUM_TIMEFRAMES period; // Cycle Period
ENUM_X_PERIOD_METHOD periodMethod; // Cycle Period Method
string prefix; // Prefix
bool useDefaults; // Use Inputs Default Settings ...
//
X121MCycleInputs inputs; // Inputs
//
XSCX121Market *market; // Market
//
X121MCycleConditions conditions; // Market Conditions
//
// Tools ...
//
bool Init()
{
//
bool result = false;
//
result = inputs.Init(
symbol,
hostPeriod,
cycle,
period,
periodMethod,
prefix,
useDefaults //
);
if (!result)
{
return result;
}
//
//
// Instantiate Market ...
market = new XSCX121Market();
//
// Initialize Market ...
result = market.Init(inputs);
//
return result;
}
//
bool Init(
string mSymbol, // Trading Symbol
ENUM_TIMEFRAMES mHostPeriod, // Host Period
ENUM_X_MARKET_CYCLES mCycle, // Init Cycle
ENUM_TIMEFRAMES mPeriod, // Cycle Period
ENUM_X_PERIOD_METHOD mPeriodMethod, // Cycle Period Method
string mPrefix = "", // Prefix
bool mUseDefaults = true // Use Inputs Default Settings ...
)
{
//
bool result = false;
//
result =
//
IsValid(mSymbol) &&
IsValid(mHostPeriod) &&
IsValid(mPeriodMethod, mPeriod)
//
;
if (!result)
{
return result;
}
//
this.cycle = mCycle;
this.symbol = mSymbol;
this.period = mPeriod;
this.prefix = mPrefix;
this.hostPeriod = mHostPeriod;
this.useDefaults = mUseDefaults;
this.periodMethod = mPeriodMethod;
//
result = this.Init();
//
return result;
}
};
//