Cleanup Trigger Block Detection from xcaea detector and Drawer for Managing it's Differences ...
This commit is contained in:
@@ -156,7 +156,7 @@ string ToString(ENUM_X_CHART_IDS value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Library Functions ...
|
// Extensions ...
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a XBoxZone struct to XSignal instance ...
|
* Converts a XBoxZone struct to XSignal instance ...
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -929,16 +929,6 @@ class XCXCAEAPOIDetector : public XCBase
|
|||||||
detectTrendBullishPivots = false;
|
detectTrendBullishPivots = false;
|
||||||
detectTrendBearishPivots = false;
|
detectTrendBearishPivots = false;
|
||||||
|
|
||||||
//
|
|
||||||
// Trigger Block ...
|
|
||||||
triggerBlockSwingLength = 7;
|
|
||||||
triggerBlockMaxAllowedRange = 0;
|
|
||||||
filterTriggerBlocksBySar = true;
|
|
||||||
triggerBlockBarHasProperSwing = true;
|
|
||||||
detectTriggerBlockBullishPivots = false;
|
|
||||||
detectTriggerBlockBearishPivots = false;
|
|
||||||
triggerBlockBarPressureValidation = true;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -980,8 +970,6 @@ class XCXCAEAPOIDetector : public XCBase
|
|||||||
newFVGBearishPivotDetected = false;
|
newFVGBearishPivotDetected = false;
|
||||||
newTrendBullishPivotDetected = false;
|
newTrendBullishPivotDetected = false;
|
||||||
newTrendBearishPivotDetected = false;
|
newTrendBearishPivotDetected = false;
|
||||||
newTriggerBlockBullishPivotDetected = false;
|
|
||||||
newTriggerBlockBearishPivotDetected = false;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
int index = barIndex;
|
int index = barIndex;
|
||||||
@@ -1036,50 +1024,6 @@ class XCXCAEAPOIDetector : public XCBase
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Handle On Time Detection Pivots ...
|
|
||||||
bool isFirstBar = start == index;
|
|
||||||
if (isFirstBar)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// TRIGGER Block ...
|
|
||||||
// Since Trigger Block Pivots Only Used on Detection Time ...
|
|
||||||
// we have to Detect only when zBar Index is Zero, means at Last Bar ...
|
|
||||||
// in this Senario we Have to Ignore LoopBacks ...
|
|
||||||
|
|
||||||
//
|
|
||||||
// Bullish ...
|
|
||||||
if (detectTriggerBlockBullishPivots)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
newTriggerBlockBullishPivotDetected = DetectTriggerBlockPivot(
|
|
||||||
barIndex,
|
|
||||||
X_DIRECTION_BULLISH,
|
|
||||||
zBar,
|
|
||||||
cBar,
|
|
||||||
pBar,
|
|
||||||
p2Bar,
|
|
||||||
conditions //
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Bearish ...
|
|
||||||
if (detectTriggerBlockBearishPivots)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
newTriggerBlockBearishPivotDetected = DetectTriggerBlockPivot(
|
|
||||||
barIndex,
|
|
||||||
X_DIRECTION_BEARISH,
|
|
||||||
zBar,
|
|
||||||
cBar,
|
|
||||||
pBar,
|
|
||||||
p2Bar,
|
|
||||||
conditions //
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Checking Pivots ...
|
// Checking Pivots ...
|
||||||
|
|
||||||
@@ -1320,13 +1264,6 @@ class XCXCAEAPOIDetector : public XCBase
|
|||||||
barIndex //
|
barIndex //
|
||||||
);
|
);
|
||||||
|
|
||||||
//
|
|
||||||
// TRIGGER Block ...
|
|
||||||
ValidateTriggerBlockPivots(
|
|
||||||
unavailables,
|
|
||||||
barIndex //
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
SortPivots();
|
SortPivots();
|
||||||
}
|
}
|
||||||
@@ -3941,709 +3878,6 @@ class XCXCAEAPOIDetector : public XCBase
|
|||||||
return ArraySize(trendBearishPivots);
|
return ArraySize(trendBearishPivots);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// TRIGGER Blocks ...
|
|
||||||
|
|
||||||
//
|
|
||||||
int triggerBlockSwingLength;
|
|
||||||
int filterTriggerBlocksBySar;
|
|
||||||
double triggerBlockMaxAllowedRange;
|
|
||||||
bool triggerBlockBarHasProperSwing;
|
|
||||||
bool triggerBlockBarPressureValidation;
|
|
||||||
|
|
||||||
//
|
|
||||||
bool DetectTriggerBlockPivot(
|
|
||||||
int barIndex,
|
|
||||||
ENUM_X_DIRECTION forDir,
|
|
||||||
XOHCL &zBar,
|
|
||||||
XOHCL &cBar,
|
|
||||||
XOHCL &pBar,
|
|
||||||
XOHCL &p2Bar,
|
|
||||||
XCAEAConditions &conditions //
|
|
||||||
)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Checking Direction ...
|
|
||||||
result = HasDirection(forDir);
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
bool forBullish = IsBullish(forDir);
|
|
||||||
bool forBearish = IsBearish(forDir);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Check Allowed ...
|
|
||||||
result =
|
|
||||||
forBullish
|
|
||||||
? detectTriggerBlockBullishPivots
|
|
||||||
: detectTriggerBlockBearishPivots;
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Validate Args ...
|
|
||||||
result =
|
|
||||||
//
|
|
||||||
barIndex >= 0 &&
|
|
||||||
zBar.IsValid() &&
|
|
||||||
cBar.IsValid() &&
|
|
||||||
pBar.IsValid() &&
|
|
||||||
p2Bar.IsValid()
|
|
||||||
//
|
|
||||||
;
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Define Requirements ...
|
|
||||||
|
|
||||||
//
|
|
||||||
int zIDX = 0;
|
|
||||||
int cIDX = zIDX + 1;
|
|
||||||
int pIDX = cIDX + 1;
|
|
||||||
int p2IDX = pIDX + 1;
|
|
||||||
int p3IDX = p2IDX + 1;
|
|
||||||
|
|
||||||
//
|
|
||||||
datetime cTime = zBar.time;
|
|
||||||
string symbol = zBar.symbol;
|
|
||||||
ENUM_TIMEFRAMES period = zBar.period;
|
|
||||||
double points = GetPoints(symbol);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Reading Conditional Values ...
|
|
||||||
|
|
||||||
//
|
|
||||||
// Prepare Conditinal Conditions ...
|
|
||||||
|
|
||||||
//
|
|
||||||
// Checking Base Block Exists ...
|
|
||||||
XBoxZone iBlock;
|
|
||||||
result = helper.barAnalyser.IsOB(
|
|
||||||
cBar,
|
|
||||||
iBlock,
|
|
||||||
true, // Force FVG Bar Type ...
|
|
||||||
true // Force Two Bar ...
|
|
||||||
);
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
iBlock.Clean();
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Bullish ...
|
|
||||||
bool isBullish =
|
|
||||||
result &&
|
|
||||||
forBullish &&
|
|
||||||
iBlock.IsBullish();
|
|
||||||
|
|
||||||
//
|
|
||||||
// Bearish ...
|
|
||||||
bool isBearish =
|
|
||||||
result &&
|
|
||||||
forBearish &&
|
|
||||||
iBlock.IsBearish();
|
|
||||||
|
|
||||||
//
|
|
||||||
// Summarizing Conditions ...
|
|
||||||
|
|
||||||
//
|
|
||||||
result = isBullish ||
|
|
||||||
isBearish;
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
iBlock.Clean();
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Adding Pivot to Box Type ...
|
|
||||||
string iType = isBullish
|
|
||||||
? GetBoxType(XCA_TRIGGER_BULL)
|
|
||||||
: GetBoxType(XCA_TRIGGER_BEAR);
|
|
||||||
iBlock.type = iType;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Validate TriggerBlock ...
|
|
||||||
XOHCL p3Bar;
|
|
||||||
XOHCL p4Bar;
|
|
||||||
result =
|
|
||||||
p2Bar.GetPreviousBar(p3Bar);
|
|
||||||
result =
|
|
||||||
result &&
|
|
||||||
p3Bar.GetPreviousBar(p4Bar);
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
p3Bar.Clean();
|
|
||||||
p4Bar.Clean();
|
|
||||||
iBlock.Clean();
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
ENUM_X_DIRECTION iDir;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Validating Range ...
|
|
||||||
if (triggerBlockMaxAllowedRange > 0)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
double blockRange = iBlock.GetRange();
|
|
||||||
result = blockRange <= triggerBlockMaxAllowedRange * points;
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
p3Bar.Clean();
|
|
||||||
p4Bar.Clean();
|
|
||||||
iBlock.Clean();
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Validate Using Swing Bars ...
|
|
||||||
if (triggerBlockBarHasProperSwing)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Check Has Proper Swing ...
|
|
||||||
|
|
||||||
//
|
|
||||||
// CBar ...
|
|
||||||
bool isCBarSimpleSwing =
|
|
||||||
barAnalyser.IsSimpleSwing(
|
|
||||||
cBar,
|
|
||||||
iDir //
|
|
||||||
);
|
|
||||||
bool isCBarBullishSimpleSwing =
|
|
||||||
isCBarSimpleSwing &&
|
|
||||||
IsBullish(iDir);
|
|
||||||
bool isCBarBearishSimpleSwing =
|
|
||||||
isCBarSimpleSwing &&
|
|
||||||
IsBearish(iDir);
|
|
||||||
|
|
||||||
//
|
|
||||||
// PBar ...
|
|
||||||
bool isPBarSimpleSwing =
|
|
||||||
barAnalyser.IsSimpleSwing(
|
|
||||||
pBar,
|
|
||||||
iDir //
|
|
||||||
);
|
|
||||||
bool isPBarBullishSimpleSwing =
|
|
||||||
isPBarSimpleSwing &&
|
|
||||||
IsBullish(iDir);
|
|
||||||
bool isPBarBearishSimpleSwing =
|
|
||||||
isPBarSimpleSwing &&
|
|
||||||
IsBearish(iDir);
|
|
||||||
|
|
||||||
//
|
|
||||||
// P2Bar ...
|
|
||||||
bool isP2BarSimpleSwing =
|
|
||||||
barAnalyser.IsSimpleSwing(
|
|
||||||
p2Bar,
|
|
||||||
iDir //
|
|
||||||
);
|
|
||||||
bool isP2BarBullishSimpleSwing =
|
|
||||||
isP2BarSimpleSwing &&
|
|
||||||
IsBullish(iDir);
|
|
||||||
bool isP2BarBearishSimpleSwing =
|
|
||||||
isP2BarSimpleSwing &&
|
|
||||||
IsBearish(iDir);
|
|
||||||
|
|
||||||
//
|
|
||||||
// P3Bar ...
|
|
||||||
bool isP3BarSimpleSwing =
|
|
||||||
barAnalyser.IsSimpleSwing(
|
|
||||||
p3Bar,
|
|
||||||
iDir //
|
|
||||||
);
|
|
||||||
bool isP3BarBullishSimpleSwing =
|
|
||||||
isP3BarSimpleSwing &&
|
|
||||||
IsBullish(iDir);
|
|
||||||
bool isP3BarBearishSimpleSwing =
|
|
||||||
isP3BarSimpleSwing &&
|
|
||||||
IsBearish(iDir);
|
|
||||||
|
|
||||||
//
|
|
||||||
// P4Bar ...
|
|
||||||
bool isP4BarSimpleSwing =
|
|
||||||
barAnalyser.IsSimpleSwing(
|
|
||||||
p4Bar,
|
|
||||||
iDir //
|
|
||||||
);
|
|
||||||
bool isP4BarBullishSimpleSwing =
|
|
||||||
isP4BarSimpleSwing &&
|
|
||||||
IsBullish(iDir);
|
|
||||||
bool isP4BarBearishSimpleSwing =
|
|
||||||
isP4BarSimpleSwing &&
|
|
||||||
IsBearish(iDir);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Summarise Validation ...
|
|
||||||
|
|
||||||
//
|
|
||||||
bool isBullishSwimpleSwing =
|
|
||||||
isBullish &&
|
|
||||||
(isCBarBullishSimpleSwing ||
|
|
||||||
isPBarBullishSimpleSwing ||
|
|
||||||
isP2BarBullishSimpleSwing ||
|
|
||||||
isP3BarBullishSimpleSwing ||
|
|
||||||
isP4BarBullishSimpleSwing);
|
|
||||||
|
|
||||||
//
|
|
||||||
bool isBearishSwimpleSwing =
|
|
||||||
isBearish &&
|
|
||||||
(isCBarBearishSimpleSwing ||
|
|
||||||
isPBarBearishSimpleSwing ||
|
|
||||||
isP2BarBearishSimpleSwing ||
|
|
||||||
isP3BarBearishSimpleSwing ||
|
|
||||||
isP4BarBearishSimpleSwing);
|
|
||||||
|
|
||||||
//
|
|
||||||
result = isBullishSwimpleSwing ||
|
|
||||||
isBearishSwimpleSwing;
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
p3Bar.Clean();
|
|
||||||
p4Bar.Clean();
|
|
||||||
iBlock.Clean();
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Validating Using Bar Pressure ...
|
|
||||||
if (triggerBlockBarPressureValidation)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Check pBar is Momentum Bar ...
|
|
||||||
// and Breakd Block Side ...
|
|
||||||
|
|
||||||
//
|
|
||||||
bool isCBarMomentum = barAnalyser.IsMomentum(
|
|
||||||
pBar,
|
|
||||||
iDir //
|
|
||||||
);
|
|
||||||
bool isCBarBullishMomentum =
|
|
||||||
isCBarMomentum &&
|
|
||||||
IsBullish(iDir);
|
|
||||||
bool isCBarBearishMomentum =
|
|
||||||
isCBarMomentum &&
|
|
||||||
IsBearish(iDir);
|
|
||||||
|
|
||||||
//
|
|
||||||
bool isPBarMomentum = barAnalyser.IsMomentum(
|
|
||||||
pBar,
|
|
||||||
iDir //
|
|
||||||
);
|
|
||||||
bool isPBarBullishMomentum =
|
|
||||||
isPBarMomentum &&
|
|
||||||
IsBullish(iDir);
|
|
||||||
bool isPBarBearishMomentum =
|
|
||||||
isPBarMomentum &&
|
|
||||||
IsBearish(iDir);
|
|
||||||
|
|
||||||
//
|
|
||||||
bool isBullishBreakedOut =
|
|
||||||
isBullish &&
|
|
||||||
forBullish &&
|
|
||||||
pBar.IsBullish() &&
|
|
||||||
(isCBarBullishMomentum ||
|
|
||||||
isPBarBullishMomentum) &&
|
|
||||||
pBar.GetUp() > iBlock.upper &&
|
|
||||||
pBar.GetDown() < iBlock.upper;
|
|
||||||
|
|
||||||
//
|
|
||||||
bool isBearishBreakedOut =
|
|
||||||
isBearish &&
|
|
||||||
forBearish &&
|
|
||||||
pBar.IsBearish() &&
|
|
||||||
(isCBarBearishMomentum ||
|
|
||||||
isPBarBearishMomentum) &&
|
|
||||||
pBar.GetUp() > iBlock.lower &&
|
|
||||||
pBar.GetDown() < iBlock.lower;
|
|
||||||
|
|
||||||
//
|
|
||||||
result =
|
|
||||||
isBullishBreakedOut ||
|
|
||||||
isBearishBreakedOut;
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
p3Bar.Clean();
|
|
||||||
p4Bar.Clean();
|
|
||||||
iBlock.Clean();
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Extract to and from Info ...
|
|
||||||
|
|
||||||
//
|
|
||||||
int toIDX = iBlock.ToIndex();
|
|
||||||
int fromIDX = iBlock.FromIndex();
|
|
||||||
|
|
||||||
//
|
|
||||||
XOHCL toBar;
|
|
||||||
XOHCL fromBar;
|
|
||||||
|
|
||||||
//
|
|
||||||
result = iBlock.ToBar(toBar);
|
|
||||||
result = result &&
|
|
||||||
iBlock.FromBar(fromBar);
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
toBar.Clean();
|
|
||||||
p3Bar.Clean();
|
|
||||||
p4Bar.Clean();
|
|
||||||
iBlock.Clean();
|
|
||||||
fromBar.Clean();
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Validating Using HH and LL ...
|
|
||||||
if (triggerBlockSwingLength > 0)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
double toLL = toBar.FindLowest(triggerBlockSwingLength, MODE_LOW);
|
|
||||||
double toHH = toBar.FindHighest(triggerBlockSwingLength, MODE_HIGH);
|
|
||||||
|
|
||||||
//
|
|
||||||
double fromLL = fromBar.FindLowest(triggerBlockSwingLength, MODE_LOW);
|
|
||||||
double fromHH = fromBar.FindHighest(triggerBlockSwingLength, MODE_HIGH);
|
|
||||||
|
|
||||||
//
|
|
||||||
double selectedLL = fromLL; // MathMin(toLL, fromLL);
|
|
||||||
double selectedHH = fromHH; // MathMax(toHH, fromHH);
|
|
||||||
|
|
||||||
//
|
|
||||||
bool isBullishSwingPassed =
|
|
||||||
isBullish &&
|
|
||||||
forBullish &&
|
|
||||||
selectedLL >= iBlock.lower;
|
|
||||||
|
|
||||||
//
|
|
||||||
bool isBearishSwingPassed =
|
|
||||||
isBearish &&
|
|
||||||
forBearish &&
|
|
||||||
selectedHH <= iBlock.upper;
|
|
||||||
|
|
||||||
//
|
|
||||||
result = isBullishSwingPassed ||
|
|
||||||
isBearishSwingPassed;
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
toBar.Clean();
|
|
||||||
p3Bar.Clean();
|
|
||||||
p4Bar.Clean();
|
|
||||||
iBlock.Clean();
|
|
||||||
fromBar.Clean();
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Apply Filters ...
|
|
||||||
bool hasFilter =
|
|
||||||
filterTriggerBlocksBySar;
|
|
||||||
if (hasFilter)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Sar Filtering ...
|
|
||||||
if (filterTriggerBlocksBySar)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Reading Conditions ...
|
|
||||||
|
|
||||||
//
|
|
||||||
double zSar = conditions.sarBuffer[zIDX];
|
|
||||||
double cSar = conditions.sarBuffer[cIDX];
|
|
||||||
double pSar = conditions.sarBuffer[pIDX];
|
|
||||||
double p2Sar = conditions.sarBuffer[p2IDX];
|
|
||||||
double p3Sar = conditions.sarBuffer[p3IDX];
|
|
||||||
|
|
||||||
//
|
|
||||||
// Preparing Constom Conditions ...
|
|
||||||
|
|
||||||
//
|
|
||||||
bool isZSarBullish = zSar < zBar.low;
|
|
||||||
bool isCSarBullish = cSar < cBar.low;
|
|
||||||
bool isPSarBullish = pSar < pBar.low;
|
|
||||||
bool isP2SarBullish = p2Sar < p2Bar.low;
|
|
||||||
bool isP3SarBullish = p3Sar < p3Bar.low;
|
|
||||||
|
|
||||||
//
|
|
||||||
bool isZSarBearish = zSar > zBar.high;
|
|
||||||
bool isCSarBearish = cSar > cBar.high;
|
|
||||||
bool isPSarBearish = pSar > pBar.high;
|
|
||||||
bool isP2SarBearish = p2Sar > p2Bar.high;
|
|
||||||
bool isP3SarBearish = p3Sar > p3Bar.high;
|
|
||||||
|
|
||||||
//
|
|
||||||
bool isCSarSwitchedToBullish =
|
|
||||||
isCSarBullish &&
|
|
||||||
!isPSarBullish;
|
|
||||||
bool isPSarSwitchedToBullish =
|
|
||||||
isPSarBullish &&
|
|
||||||
!isP2SarBullish;
|
|
||||||
bool isP2SarSwitchedToBullish =
|
|
||||||
isP2SarBullish &&
|
|
||||||
!isP3SarBullish;
|
|
||||||
|
|
||||||
//
|
|
||||||
bool isCSarSwitchedToBearish =
|
|
||||||
isCSarBearish &&
|
|
||||||
!isPSarBearish;
|
|
||||||
bool isPSarSwitchedToBearish =
|
|
||||||
isPSarBearish &&
|
|
||||||
!isP2SarBearish;
|
|
||||||
bool isP2SarSwitchedToBearish =
|
|
||||||
isP2SarBearish &&
|
|
||||||
!isP3SarBearish;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Summarize Custom Conditions ...
|
|
||||||
|
|
||||||
//
|
|
||||||
// Bullish ...
|
|
||||||
|
|
||||||
//
|
|
||||||
bool isCSarBullishPassed =
|
|
||||||
isZSarBullish &&
|
|
||||||
isCSarSwitchedToBullish;
|
|
||||||
|
|
||||||
//
|
|
||||||
bool isPSarBullishPassed =
|
|
||||||
isZSarBullish &&
|
|
||||||
isCSarBullish &&
|
|
||||||
isPSarSwitchedToBullish;
|
|
||||||
|
|
||||||
//
|
|
||||||
bool isP2SarBullishPassed =
|
|
||||||
isZSarBullish &&
|
|
||||||
isCSarBullish &&
|
|
||||||
isPSarBullish &&
|
|
||||||
isP2SarSwitchedToBullish;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Bearish ...
|
|
||||||
|
|
||||||
//
|
|
||||||
bool isCSarBearishPassed =
|
|
||||||
isZSarBearish &&
|
|
||||||
isCSarSwitchedToBearish;
|
|
||||||
|
|
||||||
//
|
|
||||||
bool isPSarBearishPassed =
|
|
||||||
isZSarBearish &&
|
|
||||||
isCSarBearish &&
|
|
||||||
isPSarSwitchedToBearish;
|
|
||||||
|
|
||||||
//
|
|
||||||
bool isP2SarBearishPassed =
|
|
||||||
isZSarBearish &&
|
|
||||||
isCSarBearish &&
|
|
||||||
isPSarBearish &&
|
|
||||||
isP2SarSwitchedToBearish;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Summarize Conditions ...
|
|
||||||
|
|
||||||
//
|
|
||||||
bool isBullishFiltered =
|
|
||||||
isBullish &&
|
|
||||||
forBullish &&
|
|
||||||
(isCSarBullishPassed ||
|
|
||||||
isPSarBullishPassed ||
|
|
||||||
isP2SarBullishPassed);
|
|
||||||
|
|
||||||
//
|
|
||||||
bool isBearishFiltered =
|
|
||||||
isBearish &&
|
|
||||||
forBearish &&
|
|
||||||
(isCSarBearishPassed ||
|
|
||||||
isPSarBearishPassed ||
|
|
||||||
isP2SarBearishPassed);
|
|
||||||
|
|
||||||
//
|
|
||||||
result = isBullishFiltered ||
|
|
||||||
isBearishFiltered;
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
toBar.Clean();
|
|
||||||
p3Bar.Clean();
|
|
||||||
p4Bar.Clean();
|
|
||||||
iBlock.Clean();
|
|
||||||
fromBar.Clean();
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Summarize ...
|
|
||||||
|
|
||||||
//
|
|
||||||
isBullish =
|
|
||||||
isBullish &&
|
|
||||||
forBullish &&
|
|
||||||
iBlock.IsValid();
|
|
||||||
|
|
||||||
//
|
|
||||||
isBearish =
|
|
||||||
isBearish &&
|
|
||||||
forBearish &&
|
|
||||||
iBlock.IsValid();
|
|
||||||
|
|
||||||
//
|
|
||||||
result = isBullish ||
|
|
||||||
isBearish;
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
iBlock.Clean();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Storing Pivot ...
|
|
||||||
|
|
||||||
//
|
|
||||||
if (isBullish)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
result = AddBox(
|
|
||||||
iBlock,
|
|
||||||
triggerBlockBullishPivots //
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
if (isBearish)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
result = AddBox(
|
|
||||||
iBlock,
|
|
||||||
triggerBlockBearishPivots //
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Cleanup Resource ...
|
|
||||||
|
|
||||||
//
|
|
||||||
toBar.Clean();
|
|
||||||
p3Bar.Clean();
|
|
||||||
p4Bar.Clean();
|
|
||||||
iBlock.Clean();
|
|
||||||
fromBar.Clean();
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
void ValidateTriggerBlockPivots(
|
|
||||||
XBoxZone &unavailables[],
|
|
||||||
int barIndex = 0 //
|
|
||||||
)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Since Trigger Blocks Doesnt Use Multiple Times,
|
|
||||||
// there is not any Validation Required for them ...
|
|
||||||
bool has = false;
|
|
||||||
|
|
||||||
//
|
|
||||||
// bool applyLifetimeValidating = maxAllowedTriggerBlockLifetime > 0;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Bullish ...
|
|
||||||
has = HasTriggerBlockBullishPivots();
|
|
||||||
if (has)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Bearish ...
|
|
||||||
has = HasTriggerBlockBearishPivots();
|
|
||||||
if (has)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Bullish ...
|
|
||||||
|
|
||||||
//
|
|
||||||
XBoxZone triggerBlockBullishPivots[];
|
|
||||||
bool detectTriggerBlockBullishPivots;
|
|
||||||
bool newTriggerBlockBullishPivotDetected;
|
|
||||||
|
|
||||||
//
|
|
||||||
bool HasTriggerBlockBullishPivots()
|
|
||||||
{
|
|
||||||
return HasChild(triggerBlockBullishPivots);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
int CountTriggerBlockBullishPivots()
|
|
||||||
{
|
|
||||||
return ArraySize(triggerBlockBullishPivots);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Bearish ...
|
|
||||||
|
|
||||||
//
|
|
||||||
bool detectTriggerBlockBearishPivots;
|
|
||||||
XBoxZone triggerBlockBearishPivots[];
|
|
||||||
bool newTriggerBlockBearishPivotDetected;
|
|
||||||
|
|
||||||
//
|
|
||||||
bool HasTriggerBlockBearishPivots()
|
|
||||||
{
|
|
||||||
return HasChild(triggerBlockBearishPivots);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
int CountTriggerBlockBearishPivots()
|
|
||||||
{
|
|
||||||
return ArraySize(triggerBlockBearishPivots);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Protected ...
|
// Protected ...
|
||||||
protected:
|
protected:
|
||||||
@@ -4937,10 +4171,6 @@ class XCXCAEAPOIDetector : public XCBase
|
|||||||
//
|
//
|
||||||
Clean(trendBullishPivots);
|
Clean(trendBullishPivots);
|
||||||
Clean(trendBearishPivots);
|
Clean(trendBearishPivots);
|
||||||
|
|
||||||
//
|
|
||||||
Clean(triggerBlockBullishPivots);
|
|
||||||
Clean(triggerBlockBearishPivots);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -5051,25 +4281,6 @@ class XCXCAEAPOIDetector : public XCBase
|
|||||||
{
|
{
|
||||||
ApplySortOnBoxes(trendBearishPivots);
|
ApplySortOnBoxes(trendBearishPivots);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// TRIGGER Block ...
|
|
||||||
|
|
||||||
//
|
|
||||||
// Bullish ...
|
|
||||||
has = HasTriggerBlockBullishPivots();
|
|
||||||
if (has)
|
|
||||||
{
|
|
||||||
ApplySortOnBoxes(triggerBlockBullishPivots);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Bearish ...
|
|
||||||
has = HasTriggerBlockBearishPivots();
|
|
||||||
if (has)
|
|
||||||
{
|
|
||||||
ApplySortOnBoxes(triggerBlockBearishPivots);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -94,8 +94,6 @@ class XCXCAEAPOIDrawer : public XCBase
|
|||||||
bool drawFVGBearishPivots;
|
bool drawFVGBearishPivots;
|
||||||
bool drawTrendBullishPivots;
|
bool drawTrendBullishPivots;
|
||||||
bool drawTrendBearishPivots;
|
bool drawTrendBearishPivots;
|
||||||
bool drawTriggerBlockBullishPivots;
|
|
||||||
bool drawTriggerBlockBearishPivots;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Styling ...
|
// Styling ...
|
||||||
@@ -124,10 +122,6 @@ class XCXCAEAPOIDrawer : public XCBase
|
|||||||
XCAPivotStyle trendBullishPivotStyle;
|
XCAPivotStyle trendBullishPivotStyle;
|
||||||
XCAPivotStyle trendBearishPivotStyle;
|
XCAPivotStyle trendBearishPivotStyle;
|
||||||
|
|
||||||
//
|
|
||||||
XCAPivotStyle triggerBlockBullishPivotStyle;
|
|
||||||
XCAPivotStyle triggerBlockBearishPivotStyle;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Constructors ...
|
// Constructors ...
|
||||||
XCXCAEAPOIDrawer(
|
XCXCAEAPOIDrawer(
|
||||||
@@ -175,8 +169,6 @@ class XCXCAEAPOIDrawer : public XCBase
|
|||||||
drawFVGBearishPivots = false;
|
drawFVGBearishPivots = false;
|
||||||
drawTrendBullishPivots = false;
|
drawTrendBullishPivots = false;
|
||||||
drawTrendBearishPivots = false;
|
drawTrendBearishPivots = false;
|
||||||
drawTriggerBlockBullishPivots = false;
|
|
||||||
drawTriggerBlockBearishPivots = false;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Styling ...
|
// Styling ...
|
||||||
@@ -220,11 +212,6 @@ class XCXCAEAPOIDrawer : public XCBase
|
|||||||
// TREND ...
|
// TREND ...
|
||||||
trendBullishPivotStyle = defaultBullishStyle;
|
trendBullishPivotStyle = defaultBullishStyle;
|
||||||
trendBearishPivotStyle = defaultBearishStyle;
|
trendBearishPivotStyle = defaultBearishStyle;
|
||||||
|
|
||||||
//
|
|
||||||
// TRIGGER ...
|
|
||||||
triggerBlockBullishPivotStyle = defaultBullishStyle;
|
|
||||||
triggerBlockBearishPivotStyle = defaultBearishStyle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -254,11 +241,6 @@ class XCXCAEAPOIDrawer : public XCBase
|
|||||||
// TREND ...
|
// TREND ...
|
||||||
DrawTrendBullishPivots(to);
|
DrawTrendBullishPivots(to);
|
||||||
DrawTrendBearishPivots(to);
|
DrawTrendBearishPivots(to);
|
||||||
|
|
||||||
//
|
|
||||||
// TRIGGER ...
|
|
||||||
DrawTriggerBullishPivots(to);
|
|
||||||
DrawTriggerBearishPivots(to);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -403,24 +385,6 @@ class XCXCAEAPOIDrawer : public XCBase
|
|||||||
to //
|
to //
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//
|
|
||||||
case XCA_TRIGGER_BULL:
|
|
||||||
//
|
|
||||||
DrawTriggerBlockBullishPivot(
|
|
||||||
box,
|
|
||||||
to //
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
|
|
||||||
//
|
|
||||||
case XCA_TRIGGER_BEAR:
|
|
||||||
//
|
|
||||||
DrawTriggerBlockBearishPivot(
|
|
||||||
box,
|
|
||||||
to //
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
@@ -926,76 +890,6 @@ class XCXCAEAPOIDrawer : public XCBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
void DrawTriggerBullishPivots(datetime to = NULL)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
bool has = drawTriggerBlockBullishPivots;
|
|
||||||
if (!has)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
has = detector.HasTriggerBlockBullishPivots();
|
|
||||||
if (!has)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
int count = detector.CountTriggerBlockBullishPivots();
|
|
||||||
for (int i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
XBoxZone iBox = detector.triggerBlockBullishPivots[i];
|
|
||||||
|
|
||||||
//
|
|
||||||
DrawTriggerBlockBullishPivot(
|
|
||||||
iBox,
|
|
||||||
to //
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
iBox.Clean();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
void DrawTriggerBearishPivots(datetime to = NULL)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
bool has = drawTriggerBlockBearishPivots;
|
|
||||||
if (!has)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
has = detector.HasTriggerBlockBearishPivots();
|
|
||||||
if (!has)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
int count = detector.CountTriggerBlockBearishPivots();
|
|
||||||
for (int i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
XBoxZone iBox = detector.triggerBlockBearishPivots[i];
|
|
||||||
|
|
||||||
//
|
|
||||||
DrawTriggerBlockBearishPivot(
|
|
||||||
iBox,
|
|
||||||
to //
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
iBox.Clean();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// One Item Drawers ...
|
// One Item Drawers ...
|
||||||
|
|
||||||
@@ -1529,116 +1423,6 @@ class XCXCAEAPOIDrawer : public XCBase
|
|||||||
ZeroMemory(iObj);
|
ZeroMemory(iObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
void DrawTriggerBlockBullishPivot(
|
|
||||||
XBoxZone &item,
|
|
||||||
datetime to = NULL //
|
|
||||||
)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
bool has = drawTriggerBlockBullishPivots;
|
|
||||||
if (!has)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
has = item.IsValid() &&
|
|
||||||
item.type == GetBoxType(XCA_TRIGGER_BULL) &&
|
|
||||||
item.dir == GetDirection(XCA_TRIGGER_BULL);
|
|
||||||
if (!has)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Since Trigger Blocks only Used Once ...
|
|
||||||
to = NULL;
|
|
||||||
bool canUpdateTo = IsValid(to);
|
|
||||||
if (canUpdateTo)
|
|
||||||
{
|
|
||||||
item.to = to;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
XCBoxObject *iObj;
|
|
||||||
has = drawer.DrawBox(
|
|
||||||
item,
|
|
||||||
iObj //
|
|
||||||
);
|
|
||||||
if (has)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Style Object ...
|
|
||||||
ApplyPivotStyle(
|
|
||||||
iObj,
|
|
||||||
triggerBlockBullishPivotStyle //
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Store Object ...
|
|
||||||
mTriggerBlockBullishPivotObjects.Add(iObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
ZeroMemory(iObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
void DrawTriggerBlockBearishPivot(
|
|
||||||
XBoxZone &item,
|
|
||||||
datetime to = NULL //
|
|
||||||
)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
bool has = drawTriggerBlockBearishPivots;
|
|
||||||
if (!has)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
has = item.IsValid() &&
|
|
||||||
item.type == GetBoxType(XCA_TRIGGER_BEAR) &&
|
|
||||||
item.dir == GetDirection(XCA_TRIGGER_BEAR);
|
|
||||||
if (!has)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Since Trigger Blocks only Used Once ...
|
|
||||||
to = NULL;
|
|
||||||
bool canUpdateTo = IsValid(to);
|
|
||||||
if (canUpdateTo)
|
|
||||||
{
|
|
||||||
item.to = to;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
XCBoxObject *iObj;
|
|
||||||
has = drawer.DrawBox(
|
|
||||||
item,
|
|
||||||
iObj //
|
|
||||||
);
|
|
||||||
if (has)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Style Object ...
|
|
||||||
ApplyPivotStyle(
|
|
||||||
iObj,
|
|
||||||
triggerBlockBearishPivotStyle //
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Store Object ...
|
|
||||||
mTriggerBlockBearishPivotObjects.Add(iObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
ZeroMemory(iObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Protected ...
|
// Protected ...
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -1055,7 +1055,7 @@ bool DetectDecisionZone(
|
|||||||
|
|
||||||
//
|
//
|
||||||
// Custom Senarios ...
|
// Custom Senarios ...
|
||||||
,
|
|
||||||
//
|
//
|
||||||
bool isCond1Bullish =
|
bool isCond1Bullish =
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -1030,20 +1030,6 @@ class XCXCAEASignaller : XCBase
|
|||||||
detector.detectTrendBullishPivots = false;
|
detector.detectTrendBullishPivots = false;
|
||||||
detector.detectTrendBearishPivots = false;
|
detector.detectTrendBearishPivots = false;
|
||||||
|
|
||||||
//
|
|
||||||
// TRIGGER Blocks ...
|
|
||||||
|
|
||||||
//
|
|
||||||
detector.triggerBlockSwingLength = 7;
|
|
||||||
detector.triggerBlockMaxAllowedRange = 0;
|
|
||||||
detector.filterTriggerBlocksBySar = true;
|
|
||||||
detector.triggerBlockBarHasProperSwing = true;
|
|
||||||
detector.triggerBlockBarPressureValidation = true;
|
|
||||||
|
|
||||||
//
|
|
||||||
detector.detectTriggerBlockBullishPivots = true;
|
|
||||||
detector.detectTriggerBlockBearishPivots = true;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// DRAWER ...
|
// DRAWER ...
|
||||||
|
|
||||||
@@ -1066,8 +1052,6 @@ class XCXCAEASignaller : XCBase
|
|||||||
drawer.drawFVGBearishPivots = false;
|
drawer.drawFVGBearishPivots = false;
|
||||||
drawer.drawTrendBullishPivots = false;
|
drawer.drawTrendBullishPivots = false;
|
||||||
drawer.drawTrendBearishPivots = false;
|
drawer.drawTrendBearishPivots = false;
|
||||||
drawer.drawTriggerBlockBullishPivots = false;
|
|
||||||
drawer.drawTriggerBlockBearishPivots = false;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Configure Styles ...
|
// Configure Styles ...
|
||||||
@@ -1176,27 +1160,6 @@ class XCXCAEASignaller : XCBase
|
|||||||
trendBearishStyle.style = STYLE_DOT;
|
trendBearishStyle.style = STYLE_DOT;
|
||||||
drawer.trendBearishPivotStyle = trendBearishStyle;
|
drawer.trendBearishPivotStyle = trendBearishStyle;
|
||||||
trendBearishStyle.Clean();
|
trendBearishStyle.Clean();
|
||||||
|
|
||||||
//
|
|
||||||
// TRIGGER ...
|
|
||||||
|
|
||||||
//
|
|
||||||
// Bullish ...
|
|
||||||
XCAPivotStyle triggerBlockBullishStyle;
|
|
||||||
triggerBlockBullishStyle.width = 2;
|
|
||||||
triggerBlockBullishStyle.clr = clrLime;
|
|
||||||
triggerBlockBullishStyle.style = STYLE_DOT;
|
|
||||||
drawer.triggerBlockBullishPivotStyle = triggerBlockBullishStyle;
|
|
||||||
triggerBlockBullishStyle.Clean();
|
|
||||||
|
|
||||||
//
|
|
||||||
// Bearish ...
|
|
||||||
XCAPivotStyle triggerBlockBearishStyle;
|
|
||||||
triggerBlockBearishStyle.width = 2;
|
|
||||||
triggerBlockBearishStyle.clr = clrRed;
|
|
||||||
triggerBlockBearishStyle.style = STYLE_DOT;
|
|
||||||
drawer.triggerBlockBearishPivotStyle = triggerBlockBearishStyle;
|
|
||||||
triggerBlockBearishStyle.Clean();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user