3087 lines
83 KiB
Plaintext
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 //
|
|
);
|
|
}
|
|
};
|