Files
MQL5Data/Documents/BKP/sample.mq5
T
2025-05-25 21:24:50 +03:30

2525 lines
58 KiB
Plaintext

// //
// // Now we Have to Detect Spike Breake Ruls ...
// // for Bullish: bar.low goes Below of pBar.low ...
// // for Bearish: bar.high goes Above of pBar.high ...
// for (int i = toIDX; i > pBarIndex; i--)
// {
// //
// // Initialize iBar ...
// result = iBar.Init(
// bar.symbol,
// bar.period,
// i //
// );
// result =
// result &&
// iBar.GetPreviousBar(iPBar);
// if (result)
// {
// //
// if (isBullish)
// {
// result = iBar.low < iPBar.low;
// }
// else if (isBearish)
// {
// result = iBar.high > iPBar.high;
// }
// //
// if (result)
// {
// break;
// }
// }
// //
// iBar.Clean();
// iPBar.Clean();
// }
// if (!result)
// {
// //
// ob.Clean();
// fvg.Clean();
// box.Clean();
// pBar.Clean();
// iBar.Clean();
// iPBar.Clean();
// swingBar.Clean();
// liquidity.Clean();
// //
// return result;
// }
// //
// // Update Box ...
// if (isBullish)
// {
// box.upper = MathMax(box.upper, iBar.GetDown());
// }
// else if (isBearish)
// {
// box.lower = MathMin(box.lower, iBar.GetUp());
// }
bool IsTrigger(
XOHCL &bar,
XBoxZone &box,
XBoxZone &ob,
XBoxZone &fvg,
XBoxZone &liquidity,
XOHCL &swingBar,
int loopback = 10,
int hlDistance = 300,
double maxAlowedRange = 0.0,
bool forceOBOppositBar = true,
bool forceFVGBarType = true,
bool forceSwingBar = true,
bool forceGapBarBreakout = true,
bool forceCheckBarsSequence = true,
bool lookingEntry = false,
bool forceLiquidity = true,
bool forceLiquidityUsed = true,
bool forceEntryBar = true,
bool forceEntryBarPower = true
//
)
{
//
bool result = false;
//
// Normalize Args ...
ob.Clean();
fvg.Clean();
box.Clean();
swingBar.Clean();
liquidity.Clean();
loopback = NormalizeInt(loopback, 5);
//
// Validate Args ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
XOHCL pBar;
XOHCL iBar;
XOHCL iPBar;
int barIndex;
int pBarIndex;
ENUM_X_DIRECTION iDir;
//
result = bar.GetPreviousBar(pBar);
if (!result)
{
//
ob.Clean();
fvg.Clean();
box.Clean();
pBar.Clean();
iBar.Clean();
iPBar.Clean();
swingBar.Clean();
liquidity.Clean();
//
return result;
}
//
barIndex = bar.Index();
pBarIndex = pBar.Index();
//
// Loopback to Find a Block ...
for (int i = pBarIndex; i < pBarIndex + loopback; i++)
{
//
// Inital IBar ...
result = iBar.Init(
bar.symbol,
bar.period,
i //
);
if (!result)
{
break;
}
//
// Detect Block ...
result = IsOB(
iBar,
ob,
forceFVGBarType,
forceOBOppositBar //
);
if (result)
{
//
// Validate Block Last Bars ...
if (forceOBOppositBar)
{
//
XOHCL fromBar;
XOHCL fromBarPrev;
result = ob.FromBar(fromBar);
result =
result &&
fromBar.GetPreviousBar(fromBarPrev);
result =
result &&
(ob.IsBullish()
? fromBarPrev.IsBearish()
: fromBarPrev.IsBullish());
if (result)
{
//
// Detect FVG ...
result = IsFVG(
iBar,
fvg,
forceFVGBarType //
);
if (result)
{
//
box.Clone(ob);
box.type = "XTRG";
box.from = fromBarPrev.time;
break;
}
}
//
fromBar.Clean();
fromBarPrev.Clean();
}
//
break;
}
//
iBar.Clean();
}
iBar.Clean();
result = box.IsValid();
if (!result)
{
//
ob.Clean();
fvg.Clean();
box.Clean();
pBar.Clean();
iBar.Clean();
iPBar.Clean();
swingBar.Clean();
liquidity.Clean();
//
return result;
}
//
// Filter Using Max Allowed Range ...
if (maxAlowedRange > 0)
{
//
result = box.GetRange() <= (maxAlowedRange * GetPoints(bar.symbol));
if (!result)
{
//
ob.Clean();
fvg.Clean();
box.Clean();
pBar.Clean();
iBar.Clean();
iPBar.Clean();
swingBar.Clean();
liquidity.Clean();
//
return result;
}
}
//
// Validate Gap Bar ...
if (forceGapBarBreakout)
{
//
// We Have to Check Gap Bar's Breakout ...
result = fvg.ToBar(iBar);
result =
result &&
iBar.GetPreviousBar(iPBar);
result =
result &&
(box.IsBullish()
? iPBar.close > ob.upper
: iPBar.close < ob.lower);
if (!result)
{
//
ob.Clean();
fvg.Clean();
box.Clean();
pBar.Clean();
iBar.Clean();
iPBar.Clean();
swingBar.Clean();
liquidity.Clean();
//
return result;
}
//
iBar.Clean();
iPBar.Clean();
}
//
// Validate HH LL Distance ...
if (hlDistance > 0)
{
//
result = ob.FromBar(iBar);
if (result)
{
//
double ll = iBar.FindLowest(iBar.Index() + hlDistance, MODE_LOW);
double hh = iBar.FindHighest(iBar.Index() + hlDistance, MODE_HIGH);
//
result =
ll > 0 &&
hh > 0 &&
ob.upper < hh &&
ob.lower > ll;
}
//
if (!result)
{
//
ob.Clean();
fvg.Clean();
box.Clean();
pBar.Clean();
iBar.Clean();
iPBar.Clean();
swingBar.Clean();
liquidity.Clean();
//
return result;
}
//
iBar.Clean();
}
//
int toIDX = box.ToIndex();
int fromIDX = box.FromIndex();
bool isBullish = box.IsBullish();
bool isBearish = box.IsBearish();
//
// We Have to Make sure Bars until Spikes Closed ...
// for Bullish: bars must Close Above box.upper ...
// for Bearish: bars must Close Below box.lower ...
for (int i = pBarIndex; i < toIDX; i++)
{
//
// Initialize iBar ...
result = iBar.Init(
bar.symbol,
bar.period,
i //
);
result =
result &&
(isBullish
? iBar.close > box.upper
: iBar.close < box.lower);
//
if (!result)
{
break;
}
//
iBar.Clean();
}
iBar.Clean();
if (!result)
{
//
ob.Clean();
fvg.Clean();
box.Clean();
pBar.Clean();
iBar.Clean();
iPBar.Clean();
swingBar.Clean();
liquidity.Clean();
//
return result;
}
//
// Detect Swing Bar ...
int swingBarIDX = -1;
int swingLoopback = fromIDX - pBarIndex;
if (isBullish)
{
//
// Looking for Swing Low ...
swingBarIDX = pBar.FindLowestIndex(swingLoopback, MODE_LOW);
}
else if (isBearish)
{
//
// Looking for Swing High ...
swingBarIDX = pBar.FindHighestIndex(swingLoopback, MODE_LOW);
}
result = IsValidIndex(swingBarIDX);
if (!result)
{
//
ob.Clean();
fvg.Clean();
box.Clean();
pBar.Clean();
iBar.Clean();
iPBar.Clean();
swingBar.Clean();
liquidity.Clean();
//
return result;
}
//
// Initialize Swing Bar ...
result = swingBar.Init(
bar.symbol,
bar.period,
swingBarIDX //
);
if (forceSwingBar)
{
//
result =
result &&
IsSimpleSwing(
swingBar,
iDir //
) &&
iDir == fvg.dir;
}
if (!result)
{
//
ob.Clean();
fvg.Clean();
box.Clean();
pBar.Clean();
iBar.Clean();
iPBar.Clean();
swingBar.Clean();
liquidity.Clean();
//
return result;
}
//
// Update Trigger Box ...
if (isBullish)
{
box.lower = MathMin(box.lower, swingBar.GetDown());
}
else if (isBearish)
{
box.upper = MathMin(box.upper, swingBar.GetUp());
}
//
// Validating Bar Sequence ...
if (forceCheckBarsSequence)
{
//
// Now we Have to Check Spike from Swing Bar Next till Current Bar ...
// To Validate Highs and Lows ...
for (int i = pBarIndex; i < pBarIndex + (swingBarIDX - pBarIndex) - 1; i++)
{
//
// Initialize iBar ...
result = iBar.Init(
bar.symbol,
bar.period,
i //
);
result =
result &&
iBar.GetPreviousBar(iPBar);
if (!result)
{
break;
}
//
// Since we Go Backward Bars from Current Bar ...
// for Bullish: each Bar Low Must over Prev Bar Low ...
// for Bearish: each Bar High Must Under Prev Bar High ...
if (isBullish)
{
//
result =
result &&
iBar.low > iPBar.low;
}
else if (isBearish)
{
//
result =
result &&
iBar.high < iPBar.high;
}
if (!result)
{
break;
}
//
iBar.Clean();
iPBar.Clean();
}
if (!result)
{
//
ob.Clean();
fvg.Clean();
box.Clean();
pBar.Clean();
iBar.Clean();
iPBar.Clean();
swingBar.Clean();
liquidity.Clean();
//
return result;
}
//
box.to = pBar.time;
//
iBar.Clean();
iPBar.Clean();
}
//
toIDX = box.ToIndex();
fromIDX = box.FromIndex();
//
// Liquidity ...
if (forceLiquidity)
{
//
// Checking Swing Bar is Liquidity ...
result = IsRejected(
swingBar,
iDir,
true, // Force Bar Type ...
true // Foce Fibo Pressure ...
) &&
iDir == fvg.dir;
if (result)
{
//
// Filling Liquidity ...
liquidity.dir = iDir;
liquidity.to = box.to;
liquidity.type = "XLQ";
liquidity.from = swingBar.time;
liquidity.symbol = swingBar.symbol;
liquidity.period = swingBar.period;
liquidity.upper = isBullish
? swingBar.GetDown()
: swingBar.high;
liquidity.lower = isBullish
? swingBar.low
: swingBar.GetUp();
//
result = liquidity.IsValid();
}
result = liquidity.IsValid();
if (!result)
{
//
ob.Clean();
fvg.Clean();
box.Clean();
pBar.Clean();
iBar.Clean();
iPBar.Clean();
swingBar.Clean();
liquidity.Clean();
//
return result;
}
//
// Check Liquidity Usage ...
if (forceLiquidityUsed)
{
//
// now We have to Ensure Detected Liqudity is Used ...
toIDX = box.ToIndex();
fromIDX = liquidity.FromIndex();
for (int i = fromIDX - 1; i >= toIDX; i--)
{
//
// Initialize iBar ...
result = iBar.Init(
bar.symbol,
bar.period,
i //
);
result =
result &&
(isBullish
? iBar.low < liquidity.upper
: iBar.high > liquidity.lower);
if (result)
{
break;
}
//
iBar.Clean();
}
if (!result)
{
//
ob.Clean();
fvg.Clean();
box.Clean();
pBar.Clean();
iBar.Clean();
iPBar.Clean();
swingBar.Clean();
liquidity.Clean();
//
return result;
}
}
}
//
// Looking for Entry ...
if (lookingEntry)
{
//
// Entry Bar ...
if (forceEntryBar)
{
//
// Validate Bar is Not Opposit Powered Bar ...
//
// Momentum ...
bool isMomentum = IsMomentum(
bar,
iDir,
1 //
);
bool isBullishMomentum =
isMomentum &&
IsBullish(iDir);
bool isBearishMomentum =
isMomentum &&
IsBearish(iDir);
//
// Engulfed ...
bool isEngulfed = IsEngulfed(
bar,
iDir //
);
bool isBullishEngulfed =
isEngulfed &&
IsBullish(iDir);
bool isBearishEngulfed =
isEngulfed &&
IsBearish(iDir);
//
// Rejected ...
bool isRejected = IsRejected(
bar,
iDir,
false,
true //
);
bool isBullishRejected =
isRejected &&
IsBullish(iDir);
bool isBearishRejected =
isRejected &&
IsBearish(iDir);
//
bool isBullishPowered =
isBullishMomentum ||
isBullishEngulfed ||
isBullishRejected;
//
bool isBearishPowered =
isBearishMomentum ||
isBearishEngulfed ||
isBearishRejected;
//
// Make Sure Entry Bar is a Valid Bar ...
result =
isBullish
? !isBearishPowered && (!forceEntryBarPower
? true
: isBullishPowered)
: !isBullishPowered && (!forceEntryBarPower
? true
: isBearishPowered);
if (!result)
{
//
ob.Clean();
fvg.Clean();
box.Clean();
pBar.Clean();
iBar.Clean();
iPBar.Clean();
swingBar.Clean();
liquidity.Clean();
//
return result;
}
}
//
// Check Entry Bar Sequences ...
if (forceCheckBarsSequence)
{
//
// if Sequences is Important ...
// we have to detect sequence Breaker Bar ...
result =
result &&
(isBullish
? bar.low < pBar.low
: bar.high > pBar.high);
}
//
// Validate Bar Close ...
result =
result &&
(isBullish
? bar.close > box.lower
: bar.close < box.upper);
}
//
if (!lookingEntry)
{
result = fvg.to == pBar.time;
}
//
// Cleanup Resources ...
//
iBar.Clean();
pBar.Clean();
iPBar.Clean();
//
if (!result)
{
//
ob.Clean();
fvg.Clean();
box.Clean();
swingBar.Clean();
swingBar.Clean();
liquidity.Clean();
}
//
return result;
}
/////////////////////////////////////
//
void DetectTriggerZone(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
// Check Prev Bar ...
//
int lastBarIndex = bar_index + 1;
int maxBarIndex = startCalculationForLastBars > 0
? startCalculationForLastBars
: ratesTotal;
bool isFirstBar =
bar_index == maxBarIndex;
//
// Prevent Calculation ...
if (maxBarIndex - bar_index < minZoneLength)
{
return;
}
//
int zIDX = 0;
int cIDX = 0;
int pIDX = 0;
int p2IDX = 0;
int p3IDX = 0;
int p4IDX = 0;
double ll = 0;
double hh = 0;
bool has = false;
ENUM_X_DIRECTION iDir;
//
// Retrieve Required Bars ...
//
XOHCL zBar; // Current Start Checking Bar (Usually Used for Triggering) ...
XOHCL cBar; // Current Finished Bar which Start Detecting Structures based on it ( End of Block and FVG Bar ) ...
XOHCL pBar; // Determines Block Gap Bar (all Filtering must applied and Check using this Bar and it's Next Bar) ...
XOHCL p2Bar; // Determines FVG's Start Bar in a Block ...
XOHCL p3Bar; // First Verification of Block ...
XOHCL p4Bar; // Seccond Verification of Block ...
//
has = zBar.Init(
_Symbol,
_Period,
bar_index //
);
has =
has &&
zBar.GetPreviousBar(cBar);
has =
has &&
cBar.GetPreviousBar(pBar);
has =
has &&
pBar.GetPreviousBar(p2Bar);
has =
has &&
p2Bar.GetPreviousBar(p3Bar);
has =
has &&
p3Bar.GetPreviousBar(p4Bar);
if (!has)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
//
return;
}
//
// Define Zone Structure ...
XBoxZone zone;
//
// Detect Based Order Block using CBar ...
has = barAnalyser.IsOB(
cBar,
zone,
true, // Force FVG Bar Type ...
true // Force Block Two Bar Checking ...
);
//
// Ensure a Block is Detected ...
if (!has)
{
//
zone.Clean();
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
//
return;
}
//
zIDX = zBar.Index();
cIDX = cBar.Index();
pIDX = pBar.Index();
p2IDX = p2Bar.Index();
p3IDX = p3Bar.Index();
p4IDX = p4Bar.Index();
//
bool isBullish =
has &&
zone.IsBullish();
//
bool isBearish =
has &&
zone.IsBearish();
//
int toIDX = zone.ToIndex();
int fromIDX = zone.FromIndex();
//
// Validating p2Bar and p3Bar Direction ...
if (has)
{
//
iDir = Opposit(zone.dir);
//
has =
iDir == p3Bar.GetDirection() ||
iDir == p4Bar.GetDirection();
if (!has)
{
//
zone.Clean();
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
//
return;
}
}
//
// Start Validating Block based on
// Detected One ...
//
// Validating Using Max Range ...
has = maxZoneRangeInPoints > 0;
if (has)
{
//
double range = zone.GetRange();
has = range <= maxZoneRangeInPoints * mPoints;
if (!has)
{
//
zone.Clean();
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
//
return;
}
}
//
// Validate Gap Endup with PinBar ...
has = forceHasPinBarEntry;
if (has)
{
//
bool isBullishRejected =
isBullish &&
cBar.IsBullish() &&
cBar.GetLowShadow() > cBar.GetHighShadow();
//
bool isBearishRejected =
isBearish &&
cBar.IsBearish() &&
cBar.GetLowShadow() < cBar.GetHighShadow();
//
has = isBullishRejected ||
isBearishRejected;
if (!has)
{
//
zone.Clean();
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
//
return;
}
}
//
// Validating Gap Bar must a Momentum Bar and
// Breakes out Zone's Directional Edge ...
// for Bullish: Upper
// for Bearish: Lower
has = forceGapBarsBreakout;
if (has)
{
//
// Gap Bar is PBar ...
//
// Check Gap Bar is Momentum Bar ...
has = barAnalyser.IsMomentum(
pBar,
iDir //
);
bool isBullishMomentum =
has &&
IsBullish(iDir);
bool isBearishMomentum =
has &&
IsBearish(iDir);
//
// Check Gap Bar's Breakout ...
//
bool isBullishBreakedout =
isBullish &&
pBar.IsBullish() &&
isBullishMomentum &&
pBar.GetUp() > zone.upper &&
pBar.GetDown() < zone.upper;
//
bool isBearishBreakedout =
isBearish &&
pBar.IsBearish() &&
isBearishMomentum &&
pBar.GetUp() > zone.lower &&
pBar.GetDown() < zone.lower;
//
has = isBullishBreakedout ||
isBearishBreakedout;
if (!has)
{
//
zone.Clean();
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
//
return;
}
}
//
// Validate Zone Has Propper Swing ...
// for Bullish: p2Bar or p3Bar must be a Swing Low ...
// for Bearish: p2Bar or p3Bar must be a Swing High ...
has = forceHasSwing;
if (has)
{
//
// p2Bar ...
bool isP2BarSwing =
barAnalyser
.IsSimpleSwing(
p2Bar,
iDir //
);
bool isP2BarSwingLow =
isP2BarSwing &&
IsBullish(iDir);
bool isP2BarSwingHigh =
isP2BarSwing &&
IsBearish(iDir);
//
// p3Bar ...
bool isP3BarSwing =
barAnalyser
.IsSimpleSwing(
p3Bar,
iDir //
);
bool isP3BarSwingLow =
isP3BarSwing &&
IsBullish(iDir);
bool isP3BarSwingHigh =
isP3BarSwing &&
IsBearish(iDir);
//
bool hasSwingLow =
isBullish &&
(isP2BarSwingLow ||
isP3BarSwingLow);
//
bool hasSwingHigh =
isBearish &&
(isP2BarSwingHigh ||
isP3BarSwingHigh);
//
has =
hasSwingLow ||
hasSwingHigh;
if (!has)
{
//
zone.Clean();
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
//
return;
}
}
//
// Validating Using Swing Length ...
has = minZoneLength > 0;
if (has)
{
//
XOHCL fromBar;
has = zone.FromBar(fromBar);
if (has)
{
//
// Retrieve HH and LL ...
ll = fromBar.FindLowest(minZoneLength, MODE_LOW);
hh = fromBar.FindHighest(minZoneLength, MODE_HIGH);
//
// Validate Using HH and LL ...
//
bool isBullishValid =
isBullish &&
ll >= zone.lower;
//
bool isBearishValid =
isBearish &&
hh <= zone.upper;
//
has = isBullishValid ||
isBearishValid;
if (!has)
{
//
zone.Clean();
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
//
return;
}
//
// Update Zone's From Time ...
zone.from = GetBarTime(
zone.symbol,
zone.period,
fromBar.Index() + minZoneLength //
);
}
//
fromBar.Clean();
}
//
// Validate Max Allowed Entry Distance ...
has = maxAllowedEntryDistance > 0;
if (has)
{
//
double base =
isBullish
? zone.upper
: zone.lower;
double entryDistance = MathAbs(zBar.open - base);
has = entryDistance <= maxAllowedEntryDistance * mPoints;
if (!has)
{
//
zone.Clean();
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
//
return;
}
}
//
// Here we Ensure which have a Valid Zone using Different Applied Validations ...
// from now we are Going to Filtered Validate Zones ...
//
// Check Exists Filters or not ...
has = filterBasedOnSar ||
filterBasedOnRSI ||
filterBasedOnADX ||
filterBasedOnTrend;
if (has)
{
//
// Do Apply Several Exists Filters ...
//
// SAR Filter ...
if (filterBasedOnSar)
{
//
// Reading Conditions Values ...
//
double zSar = sarBuffer[zIDX];
double cSar = sarBuffer[cIDX];
double pSar = sarBuffer[pIDX];
double p2Sar = sarBuffer[p2IDX];
double p3Sar = sarBuffer[p3IDX];
double p4Sar = sarBuffer[p4IDX];
//
// Create Required Conditions ...
//
bool isZSarBullish = zSar < zBar.low;
bool isZSarBearish = zSar > zBar.high;
//
bool isCSarBullish = cSar < cBar.low;
bool isCSarBearish = cSar > cBar.high;
//
bool isPSarBullish = pSar < pBar.low;
bool isPSarBearish = pSar > pBar.high;
//
bool isP2SarBullish = p2Sar < p2Bar.low;
bool isP2SarBearish = p2Sar > p2Bar.high;
//
bool isCSarSwitchedToBullish =
isZSarBullish &&
isCSarBullish &&
!isPSarBullish &&
cBar.IsBullish() &&
cBar.GetUp() > pSar;
//
bool isCSarSwitchedToBearish =
isZSarBearish &&
isCSarBearish &&
!isPSarBearish &&
cBar.IsBearish() &&
cBar.GetDown() < pSar;
//
bool isPSarSwitchedToBullish =
isZSarBullish &&
isCSarBullish &&
isPSarBullish &&
!isP2SarBullish &&
pBar.IsBullish() &&
pBar.GetUp() > p2Sar;
//
bool isPSarSwitchedToBearish =
isZSarBearish &&
isCSarBearish &&
isPSarBearish &&
!isP2SarBearish &&
pBar.IsBearish() &&
pBar.GetDown() < p2Sar;
//
// Summarize Filtering ...
//
bool isBullishFiltered =
isBullish &&
(isCSarSwitchedToBullish ||
isPSarSwitchedToBullish);
//
bool isBearishFiltered =
isBearish &&
(isCSarSwitchedToBearish ||
isPSarSwitchedToBearish);
//
has =
isBullishFiltered ||
isBearishFiltered;
if (!has)
{
//
zone.Clean();
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
//
return;
}
}
//
// RSI Filter ...
if (filterBasedOnRSI)
{
//
// Reading Conditions Values ...
//
double rsiTrend = (rsiOBLevel + rsiOSLevel) / 2;
//
double zRSI = rsiBuffer[zIDX];
double cRSI = rsiBuffer[cIDX];
double pRSI = rsiBuffer[pIDX];
double p2RSI = rsiBuffer[p2IDX];
double p3RSI = rsiBuffer[p3IDX];
double p4RSI = rsiBuffer[p4IDX];
//
// Create Required Conditions ...
//
bool isZRSIBullish = zRSI > rsiTrend;
bool isZRSIBearish = zRSI < rsiTrend;
//
bool isCRSIBullish = cRSI > rsiTrend;
bool isCRSIBearish = cRSI < rsiTrend;
//
bool isPRSIBullish = pRSI > rsiTrend;
bool isPRSIBearish = pRSI < rsiTrend;
//
bool isP2RSIBullish = p2RSI > rsiTrend;
bool isP2RSIBearish = p2RSI < rsiTrend;
//
bool isP3RSIBullish = p3RSI > rsiTrend;
bool isP3RSIBearish = p3RSI < rsiTrend;
//
// Trending Conditions ...
//
bool isCRSISwitchedToBullish =
isZRSIBullish &&
isCRSIBullish &&
!isPRSIBullish;
//
bool isCRSISwitchedToBearish =
isZRSIBearish &&
isCRSIBearish &&
!isPRSIBearish;
//
bool isPRSISwitchedToBullish =
isZRSIBullish &&
isCRSIBullish &&
isPRSIBullish &&
!isP2RSIBullish;
//
bool isPRSISwitchedToBearish =
isZRSIBearish &&
isCRSIBearish &&
isPRSIBearish &&
!isP2RSIBearish;
//
bool isP2RSISwitchedToBullish =
isZRSIBullish &&
isCRSIBullish &&
isPRSIBullish &&
isP2RSIBullish &&
!isP3RSIBullish;
//
bool isP2RSISwitchedToBearish =
isZRSIBearish &&
isCRSIBearish &&
isPRSIBearish &&
isP2RSIBearish &&
!isP3RSIBearish;
//
// Crosses Conditions ...
//
bool isCBarCrossedOverOS =
zRSI > rsiOSLevel &&
cRSI > rsiOSLevel &&
pRSI <= rsiOSLevel;
//
bool isCBarCrossedUnderOB =
zRSI < rsiOBLevel &&
cRSI < rsiOBLevel &&
pRSI >= rsiOBLevel;
//
bool isPBarCrossedOverOS =
zRSI > rsiOSLevel &&
cRSI > rsiOSLevel &&
pRSI > rsiOSLevel &&
p2RSI <= rsiOSLevel;
//
bool isPBarCrossedUnderOB =
zRSI < rsiOBLevel &&
cRSI < rsiOBLevel &&
pRSI < rsiOBLevel &&
p2RSI >= rsiOBLevel;
//
// V Pattern Conditions ...
//
bool isCRSIHasVBullishPattern =
zRSI >= cRSI &&
cRSI > pRSI &&
p2RSI > pRSI &&
cRSI >= p2RSI;
//
bool isCRSIHasVBearishPattern =
zRSI <= cRSI &&
cRSI < pRSI &&
p2RSI < pRSI &&
cRSI <= p2RSI;
//
// Continuation Conditions ...
//
bool isRSIUp =
zRSI >= cRSI &&
(cRSI >= pRSI ||
pRSI >= p2RSI ||
p2RSI >= p3RSI);
//
bool isRSIDown =
zRSI <= cRSI &&
(cRSI <= pRSI ||
pRSI <= p2RSI ||
p2RSI <= p3RSI);
//
// Summarize Filtering ...
//
bool isBullishFiltered =
isBullish &&
(
//
// Grows ...
isRSIUp
//
||
//
// Crosses ...
(isCBarCrossedOverOS ||
isPBarCrossedOverOS)
//
||
//
// V Pattern ...
isCRSIHasVBullishPattern
//
||
//
// Trending ...
(isCRSISwitchedToBullish ||
isPRSISwitchedToBullish ||
isP2RSISwitchedToBullish)
//
);
//
bool isBearishFiltered =
isBearish &&
(
//
// Grows ...
isRSIDown
//
||
//
// Crosses ...
(isCBarCrossedUnderOB ||
isPBarCrossedUnderOB)
//
||
//
// V Pattern ...
isCRSIHasVBearishPattern
//
||
//
// Trending ...
(isCRSISwitchedToBearish ||
isPRSISwitchedToBearish ||
isP2RSISwitchedToBearish)
//
);
//
has =
isBullishFiltered ||
isBearishFiltered;
if (!has)
{
//
zone.Clean();
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
//
return;
}
}
//
// ADX Filter ...
if (filterBasedOnADX)
{
//
// Reading Conditions Values ...
//
// ADX ...
double zADX = adxBuffer[zIDX];
double cADX = adxBuffer[cIDX];
double pADX = adxBuffer[pIDX];
double p2ADX = adxBuffer[p2IDX];
double p3ADX = adxBuffer[p3IDX];
double p4ADX = adxBuffer[p4IDX];
//
// ADX +DI ...
double zADXP = adxpBuffer[zIDX];
double cADXP = adxpBuffer[cIDX];
double pADXP = adxpBuffer[pIDX];
double p2ADXP = adxpBuffer[p2IDX];
double p3ADXP = adxpBuffer[p3IDX];
double p4ADXP = adxpBuffer[p4IDX];
//
// ADX -DI ...
double zADXN = adxnBuffer[zIDX];
double cADXN = adxnBuffer[cIDX];
double pADXN = adxnBuffer[pIDX];
double p2ADXN = adxnBuffer[p2IDX];
double p3ADXN = adxnBuffer[p3IDX];
double p4ADXN = adxnBuffer[p4IDX];
//
// Create Required Conditions ...
//
// Grows ...
//
bool isADXUp =
zADX >= cADX &&
(cADX >= pADX ||
pADX >= p2ADX);
//
bool isADXDown =
zADX <= cADX &&
(cADX <= pADX ||
pADX <= p2ADX);
//
// Trending ...
//
bool isZADXBullish = zADX > adxThreshold;
bool isZADXBearish = zADX < adxThreshold;
//
bool isCADXBullish = cADX > adxThreshold;
bool isCADXBearish = cADX < adxThreshold;
//
bool isPADXBullish = pADX > adxThreshold;
bool isPADXBearish = pADX < adxThreshold;
//
bool isP2ADXBullish = p2ADX > adxThreshold;
bool isP2ADXBearish = p2ADX < adxThreshold;
//
bool isP3ADXBullish = p3ADX > adxThreshold;
bool isP3ADXBearish = p3ADX < adxThreshold;
//
bool isP4ADXBullish = p4ADX > adxThreshold;
bool isP4ADXBearish = p4ADX < adxThreshold;
//
bool isCADXSwitchedToBullish =
isZADXBullish &&
isCADXBullish &&
!isPADXBullish;
//
bool isCADXSwitchedToBearish =
isZADXBearish &&
isCADXBearish &&
!isPADXBearish;
//
bool isPADXSwitchedToBullish =
isZADXBullish &&
isCADXBullish &&
isPADXBullish &&
!isP2ADXBullish;
//
bool isPADXSwitchedToBearish =
isZADXBearish &&
isCADXBearish &&
isPADXBearish &&
!isP2ADXBearish;
//
// Powering ...
//
bool isZADXHasBullishPower = zADXP > zADXN;
bool isZADXHasBearishPower = zADXN > zADXP;
//
bool isCADXHasBullishPower = cADXP > cADXN;
bool isCADXHasBearishPower = cADXN > cADXP;
//
bool isPADXHasBullishPower = pADXP > pADXN;
bool isPADXHasBearishPower = pADXN > pADXP;
//
bool isP2ADXHasBullishPower = p2ADXP > p2ADXN;
bool isP2ADXHasBearishPower = p2ADXN > p2ADXP;
//
bool isP3ADXHasBullishPower = p3ADXP > p3ADXN;
bool isP3ADXHasBearishPower = p3ADXN > p3ADXP;
//
bool isP4ADXHasBullishPower = p4ADXP > p4ADXN;
bool isP4ADXHasBearishPower = p4ADXN > p4ADXP;
//
bool isCADXSwitchedToBullishPower =
isZADXHasBullishPower &&
isCADXHasBullishPower &&
!isPADXHasBullishPower;
//
bool isCADXSwitchedToBearishPower =
isZADXHasBearishPower &&
isCADXHasBearishPower &&
!isPADXHasBearishPower;
//
bool isPADXSwitchedToBullishPower =
isZADXHasBullishPower &&
isCADXHasBullishPower &&
isPADXHasBullishPower &&
!isP2ADXHasBullishPower;
//
bool isPADXSwitchedToBearishPower =
isZADXHasBearishPower &&
isCADXHasBearishPower &&
isPADXHasBearishPower &&
!isP2ADXHasBearishPower;
//
// Summarize Filtering ...
//
bool isBullishFiltered =
isBullish &&
(
//
// Grows ...
isADXUp
//
||
//
// Trending ...
(isCADXSwitchedToBullish ||
isPADXSwitchedToBullish)
//
||
//
// Powering ...
(isCADXSwitchedToBullishPower ||
isPADXSwitchedToBullishPower)
//
);
//
bool isBearishFiltered =
isBearish &&
(
//
// Grows ...
isADXDown
//
||
//
// Trending ...
(isCADXSwitchedToBearish ||
isPADXSwitchedToBearish)
//
||
//
// Powering ...
(isCADXSwitchedToBearishPower ||
isPADXSwitchedToBearishPower)
//
);
//
has =
isBullishFiltered ||
isBearishFiltered;
if (!has)
{
//
zone.Clean();
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
//
return;
}
}
//
// TREND Filter ...
if (filterBasedOnTrend)
{
//
// Reading Conditions Values ...
//
double zTrend = trendBuffer[zIDX];
double cTrend = trendBuffer[cIDX];
double pTrend = trendBuffer[pIDX];
double p2Trend = trendBuffer[p2IDX];
double p3Trend = trendBuffer[p3IDX];
double p4Trend = trendBuffer[p4IDX];
//
double trends[] = {
zTrend,
cTrend,
pTrend,
p2Trend,
p3Trend,
p4Trend //
};
double trendsMin = GetMin(trends);
double trendsMax = GetMax(trends);
double trendsAVG = GetAverage(trends);
//
double zTrendState = trendStateBuffer[zIDX];
double cTrendState = trendStateBuffer[cIDX];
double pTrendState = trendStateBuffer[pIDX];
double p2TrendState = trendStateBuffer[p2IDX];
double p3TrendState = trendStateBuffer[p3IDX];
double p4TrendState = trendStateBuffer[p4IDX];
//
// Create Required Conditions ...
//
// Grows ...
//
bool isTrendUp =
zTrend >= cTrend &&
cTrend >= trendsAVG &&
cTrend > trendsMin;
//
bool isTrendDown =
zTrend <= cTrend &&
cTrend <= trendsAVG &&
cTrend < trendsMax;
//
// Stating ...
//
bool isCTrendBullish =
zTrendState > 0 &&
cTrendState > 0;
//
bool isCTrendBearish =
zTrendState < 0 &&
cTrendState < 0;
//
bool isPTrendBullish =
zTrendState > 0 &&
cTrendState > 0 &&
pTrendState > 0;
//
bool isPTrendBearish =
zTrendState < 0 &&
cTrendState < 0 &&
pTrendState < 0;
//
bool isP2TrendBullish =
zTrendState > 0 &&
cTrendState > 0 &&
pTrendState > 0 &&
p2TrendState > 0;
//
bool isP2TrendBearish =
zTrendState < 0 &&
cTrendState < 0 &&
pTrendState < 0 &&
p2TrendState < 0;
//
bool isCTrendSwitchedToBullish =
isCTrendBullish &&
!isPTrendBullish;
//
bool isCTrendSwitchedToBearish =
isCTrendBearish &&
!isPTrendBearish;
//
bool isPTrendSwitchedToBullish =
isCTrendBullish &&
isPTrendBullish &&
!isP2TrendBullish;
//
bool isPTrendSwitchedToBearish =
isCTrendBearish &&
isPTrendBearish &&
!isP2TrendBearish;
//
// Summarize Filtering ...
//
bool isBullishFiltered =
isBullish &&
(
//
// Grows ...
isTrendUp
//
||
//
// Trend Stating ...
(isCTrendBullish &&
isPTrendBullish)
//
||
//
// Switching ...
(isCTrendSwitchedToBullish ||
isPTrendSwitchedToBullish)
//
);
//
bool isBearishFiltered =
isBearish &&
(
//
// Grows ...
isTrendDown
//
||
//
// Trend Stating ...
(isCTrendBearish &&
isPTrendBearish)
//
||
//
// Switching ...
(isCTrendSwitchedToBearish ||
isPTrendSwitchedToBearish)
//
);
//
has =
isBullishFiltered ||
isBearishFiltered;
if (!has)
{
//
zone.Clean();
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
//
return;
}
}
//
// SCORE Filter ...
//
// VOLUME Filter ...
}
//
// Detect Left Side of Box ...
XOHCL zoneLeftBar;
int idx = fromIDX + 1;
bool isBaseValid = true;
while (isBaseValid)
{
//
// Retrieve iteration Bar ...
has = zoneLeftBar.Init(
_Symbol,
_Period,
idx //
);
if (!has)
{
//
zoneLeftBar.Clean();
break;
}
//
// Check Bar's Validation ...
//
bool isBullishPassed =
isBullish &&
zoneLeftBar.low >= zone.lower;
//
bool isBearishPassed =
isBearish &&
zoneLeftBar.high <= zone.upper;
//
// Summarize Conditions ...
has =
isBullishPassed ||
isBearishPassed;
if (!has)
{
break;
}
//
idx++;
}
//
// Ray to Left Side Zone, if Provided ...
if (rayLeft)
{
//
// Update Value ...
fromIDX = zone.FromIndex();
//
// Check Last Iteration Bar is Valid Bar ...
// then Update Zone from Time ...
has = zoneLeftBar.IsValid();
if (has)
{
//
zone.from = zoneLeftBar.time;
fromIDX = zone.FromIndex();
}
}
//
// Draw Detected Zone ...
if (drawZones)
{
//
XCBoxObject *iZoneObj;
has = drawer.DrawBox(
zone,
iZoneObj //
);
if (has)
{
//
ApplyStyle(iZoneObj, zone.dir);
//
mObjects.Add(iZoneObj);
//
// TODO: Enable This for Debugging ...
// string message = ToString(zone.dir) + " Zone Detected (" + cBar.time + ") ...";
// Print(message);
}
ZeroMemory(iZoneObj);
}
//
// Draw RR Tool ...
if (drawRRofZones)
{
//
double rr[]{
1,
1.5,
2,
3,
4,
5,
6,
7,
8,
9,
10 //
};
XCRRObject *iRRObj;
iRRObj = new XCRRObject();
has = iRRObj.CreateBoxRR(
drawer.ChartIdentification(),
drawer.SubWindowIdentification(),
zone,
rr,
rrZoneLength //
);
if (has)
{
//
int iWidth = 2;
ENUM_LINE_STYLE iStyle = STYLE_SOLID;
//
iRRObj.TPWidth(iWidth);
iRRObj.SLWidth(iWidth);
iRRObj.EntryWidth(iWidth);
iRRObj.TargetWidth(iWidth);
//
iRRObj.TPStyle(iStyle);
iRRObj.SLStyle(iStyle);
iRRObj.EntryStyle(iStyle);
iRRObj.TargetStyle(iStyle);
//
iRRObj.TPColor(clrLime);
iRRObj.SLColor(clrRed);
iRRObj.EntryColor(clrYellow);
iRRObj.TargetColor(clrLightBlue);
//
mObjects.Add(iRRObj);
}
ZeroMemory(iRRObj);
}
//
// Handle Alerst ...
bool canAlert =
mEnableAlerts &&
prevCalculated > 0;
bool canLogOnly =
mEnableAlerts &&
prevCalculated == 0;
if (canAlert || canLogOnly)
{
//
string message =
zone.symbol + "," +
ToString(zone.period) + "> " +
ToString(zone.dir) +
" Zone Detected at: " + ToString(zone.to);
//
if (canLogOnly)
{
alert.LogAlert(message);
}
else if (canAlert)
{
alert.SendAlert(message);
}
}
//
// Cleanup Resources ...
//
zone.Clean();
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
zoneLeftBar.Clean();
}
//
// Detect Trigger Zone ...
// DetectTriggerZone(
// bar_index,
// prevCalculated,
// ratesTotal,
// open,
// high,
// close,
// low,
// tickVolume //
// );
//
// Implement all Volume and Delta Tests
// Here for Testing Purposes ...
void DoTest(int bar_index)
{
//
int lastBarIndex = bar_index + 1;
bool isFirstBar =
startCalculationForLastBars > 0
? bar_index == startCalculationForLastBars
: bar_index == firstBarIndex;
//
// Ignore Tests on First Bar ...
if (isFirstBar ||
bar_index == firstBarIndex - 1)
{
return;
}
//
bool has = false;
string iName = NULL;
color iClr = CLR_NONE;
datetime iTime = GetBarTime(
_Symbol,
_Period,
bar_index //
);
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
//
// Delta Testing ...
//
double iDelta = deltaBuffer[bar_index];
double iDeltaPrev = deltaBuffer[lastBarIndex];
double iDeltaP2 = deltaBuffer[lastBarIndex + 1];
//
bool isDeltaUp = iDelta > iDeltaPrev;
bool isDeltaDown = iDelta < iDeltaPrev;
//
double iDeltaSignal = deltaSignalBuffer[bar_index];
double iDeltaSignalPrev = deltaSignalBuffer[lastBarIndex];
//
bool isDeltaSignalUp = iDeltaSignal > iDeltaSignalPrev;
bool isDeltaSignalDown = iDeltaSignal < iDeltaSignalPrev;
//
bool isDeltaSwitchedToBullish =
isDeltaUp &&
isDeltaSignalUp &&
iDelta > iDeltaSignal &&
iDeltaPrev < iDeltaSignalPrev;
//
bool isDeltaSwitchedToBearish =
isDeltaDown &&
isDeltaSignalDown &&
iDelta < iDeltaSignal &&
iDeltaPrev > iDeltaSignalPrev;
//
if (false &&
(isDeltaSwitchedToBullish ||
isDeltaSwitchedToBearish))
{
//
iDir = isDeltaSwitchedToBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
iClr =
IsBullish(iDir)
? clrAqua
: clrMagenta;
//
iName = ToString(iDir) + "_Delta_" + ToFormatString(iTime);
//
CChartObjectVLine *iObj;
iObj = new CChartObjectVLine();
has = iObj.Create(
0,
iName,
0,
iTime //
);
if (has)
{
//
// Style Object ...
iObj.Color(iClr);
//
// Store Object ...
mObjects.Add(iObj);
}
}
//
// Volume Testing ...
//
double iBullishVolumeSignal = bullishVolumeSignalBuffer[bar_index];
double iBullishVolumeSignalPrev = bullishVolumeSignalBuffer[lastBarIndex];
//
bool isBullishVolumeSignalUp = iBullishVolumeSignal > iBullishVolumeSignalPrev;
bool isBullishVolumeSignalDown = iBullishVolumeSignal < iBullishVolumeSignalPrev;
//
double iBearishVolumeSignal = bearishVolumeSignalBuffer[bar_index];
double iBearishVolumeSignalPrev = bearishVolumeSignalBuffer[lastBarIndex];
//
bool isBearishVolumeSignalUp = iBearishVolumeSignal > iBearishVolumeSignalPrev;
bool isBearishVolumeSignalDown = iBearishVolumeSignal < iBearishVolumeSignalPrev;
//
bool isVolumeSwitchdToBullish =
isBullishVolumeSignalUp &&
!isBearishVolumeSignalUp &&
iBullishVolumeSignal > iBearishVolumeSignal &&
iBullishVolumeSignalPrev < iBearishVolumeSignalPrev;
//
bool isVolumeSwitchdToBearish =
isBearishVolumeSignalUp &&
!isBullishVolumeSignalUp &&
iBearishVolumeSignal > iBullishVolumeSignal &&
iBearishVolumeSignalPrev < iBullishVolumeSignalPrev;
//
if (false &&
(isVolumeSwitchdToBullish ||
isVolumeSwitchdToBearish))
{
//
iDir = isVolumeSwitchdToBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
iClr =
IsBullish(iDir)
? clrAqua
: clrMagenta;
//
iName = ToString(iDir) + "_Volume_" + ToFormatString(iTime);
//
CChartObjectVLine *iObj;
iObj = new CChartObjectVLine();
has = iObj.Create(
0,
iName,
0,
iTime //
);
if (has)
{
//
// Style Object ...
iObj.Color(iClr);
//
// Store Object ...
mObjects.Add(iObj);
}
}
//
// Signal Bar ...
//
double iSignalOpen = openSignalBuffer[bar_index];
double iSignalOpenPrev = openSignalBuffer[lastBarIndex];
//
double iSignalClose = closeSignalBuffer[bar_index];
double iSignalClosePrev = closeSignalBuffer[lastBarIndex];
//
bool isSignalBarBullish = iSignalOpen < iSignalClose;
bool isSignalBarBullishPrev = iSignalOpenPrev < iSignalClosePrev;
//
bool isSignalBarBearish = iSignalOpen > iSignalClose;
bool isSignalBarBearishPrev = iSignalOpenPrev > iSignalClosePrev;
//
bool isSignalBarSwitchedToBullish =
isSignalBarBullish &&
!isSignalBarBullishPrev;
//
bool isSignalBarSwitchedToBearish =
isSignalBarBearish &&
!isSignalBarBearishPrev;
//
// HK Signal Bar ...
//
double iHKSignalOpen = openHKSignalBuffer[bar_index];
double iHKSignalOpenPrev = openHKSignalBuffer[lastBarIndex];
//
double iHKSignalClose = closeHKSignalBuffer[bar_index];
double iHKSignalClosePrev = closeHKSignalBuffer[lastBarIndex];
//
bool isHKSignalBarBullish = iHKSignalOpen < iHKSignalClose;
bool isHKSignalBarBullishPrev = iHKSignalOpenPrev < iHKSignalClosePrev;
//
bool isHKSignalBarBearish = iHKSignalOpen > iHKSignalClose;
bool isHKSignalBarBearishPrev = iHKSignalOpenPrev > iHKSignalClosePrev;
//
bool isHKSignalBarSwitchedToBullish =
isHKSignalBarBullish &&
!isHKSignalBarBullishPrev;
//
bool isHKSignalBarSwitchedToBearish =
isHKSignalBarBearish &&
!isHKSignalBarBearishPrev;
//
// SAR ...
//
double iSarState = sarStateBuffer[bar_index];
double iSarStatePrev = sarStateBuffer[lastBarIndex];
//
bool isSarBullish = iSarState > 0;
bool isSarBullishPrev = iSarStatePrev > 0;
//
bool isSarBearish = iSarState < 0;
bool isSarBearishPrev = iSarStatePrev < 0;
//
bool isSarSwitchedToBullish =
isSarBullish &&
!isSarBullishPrev;
//
bool isSarSwitchedToBearish =
isSarBearish &&
!isSarBearishPrev;
//
// Full Testing Senario ...
//
bool isBullish =
isSarSwitchedToBullish &&
isDeltaSwitchedToBullish &&
isVolumeSwitchdToBullish &&
isSignalBarSwitchedToBullish &&
isHKSignalBarSwitchedToBullish;
//
bool isBearish =
isSarSwitchedToBearish &&
isDeltaSwitchedToBearish &&
isVolumeSwitchdToBearish &&
isSignalBarSwitchedToBearish &&
isHKSignalBarSwitchedToBearish;
//
if (true &&
(isBullish ||
isBearish))
{
//
iDir = isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
iClr =
IsBullish(iDir)
? clrAqua
: clrMagenta;
//
iName = ToString(iDir) + "_BSB_" + ToFormatString(iTime);
//
CChartObjectVLine *iObj;
iObj = new CChartObjectVLine();
has = iObj.Create(
0,
iName,
0,
iTime //
);
if (has)
{
//
// Style Object ...
iObj.Color(iClr);
//
// Store Object ...
mObjects.Add(iObj);
}
}
}