2821 lines
71 KiB
Plaintext
2821 lines
71 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 X121 SMC Signal Class
|
|
// -------------------------------------------------
|
|
// Name: XWZ
|
|
// Description: provide all Signalling functions ...
|
|
//
|
|
//
|
|
// 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-trade.lib"
|
|
#include "../Classes/x-121.smc.market.cycle.helper.class.mq5"
|
|
#include "../Libraries/x-121.smc.guard.lib.mq5"
|
|
#include "../Libraries/x-121.smc.lib.mq5"
|
|
|
|
//
|
|
// Provided Signals Enumeration ...
|
|
enum ENUM_X121SMC_XWZ_PROVIDERS
|
|
{
|
|
X121SMC_XWZ_PROVIDER_NONE,
|
|
X121SMC_XWZ_PROVIDER_XWPVZ,
|
|
X121SMC_XWZ_PROVIDER_XFVGMA,
|
|
X121SMC_XWZ_PROVIDER_XBREAKED_BOX,
|
|
X121SMC_XWZ_PROVIDER_XREJECTED_BOX,
|
|
X121SMC_XWZ_PROVIDER_XACTIVATED_BOX,
|
|
};
|
|
|
|
//
|
|
// Provided Priority based on Working Zone and
|
|
// Quarter Places ...
|
|
enum ENUM_X121SMC_XWZ_PRIORITY
|
|
{
|
|
X121SMC_XWZ_PRIORITY_NONE,
|
|
X121SMC_XWZ_PRIORITY_WEAK,
|
|
X121SMC_XWZ_PRIORITY_LOW,
|
|
X121SMC_XWZ_PRIORITY_REGULAR,
|
|
X121SMC_XWZ_PRIORITY_HIGH,
|
|
X121SMC_XWZ_PRIORITY_STRONG_HIGH,
|
|
};
|
|
|
|
//
|
|
// Definitions ...
|
|
|
|
//
|
|
// XWZ Working Zone Model ...
|
|
struct X121SMCStrategyXWZWorkingZone
|
|
{
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
string symbol;
|
|
ENUM_TIMEFRAMES period;
|
|
|
|
//
|
|
double quarter1;
|
|
double quarter2;
|
|
double quarter3;
|
|
|
|
//
|
|
XCSupplyZone *supplyZone;
|
|
XCDemandZone *demandZone;
|
|
|
|
//
|
|
XBoxZone support;
|
|
XBoxZone resistance;
|
|
ENUM_X_DIRECTION trend;
|
|
|
|
//
|
|
XSignalBox waitingBoxes[];
|
|
XSignalBox breakedBoxes[];
|
|
XSignalBox unavailableBoxes[];
|
|
|
|
//
|
|
CArrayObj mDrawnObjects;
|
|
CArrayObj mWorkingZoneObjects;
|
|
|
|
//
|
|
// Constructor ...
|
|
X121SMCStrategyXWZWorkingZone()
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
// Properties ...
|
|
|
|
/**
|
|
* Check Working Zone has Supply Zone as Upper Boundary ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasSupplyZone()
|
|
{
|
|
return supplyZone != NULL &&
|
|
supplyZone.IsValid();
|
|
}
|
|
|
|
/**
|
|
* Check Working Zone has Demand Zone as Lower Boundary ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasDemandZone()
|
|
{
|
|
return demandZone != NULL &&
|
|
demandZone.IsValid();
|
|
}
|
|
|
|
/**
|
|
* Check Working Zone has Waiting Boxes or not ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasWaitingBoxes()
|
|
{
|
|
return HasChild(waitingBoxes);
|
|
}
|
|
|
|
/**
|
|
* Count Working Zone's Waiting Boxes ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountWaitingBoxes()
|
|
{
|
|
return ArraySize(waitingBoxes);
|
|
}
|
|
|
|
/**
|
|
* Check Working Zone has Breaked Boxes or not ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasBreakedBoxes()
|
|
{
|
|
return HasChild(breakedBoxes);
|
|
}
|
|
|
|
/**
|
|
* Count Working Zone's Breaked Boxes ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountBreakedBoxes()
|
|
{
|
|
return ArraySize(breakedBoxes);
|
|
}
|
|
|
|
/**
|
|
* Check Working Zone has Unavailable Boxes or not ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasUnavailableBoxes()
|
|
{
|
|
return HasChild(unavailableBoxes);
|
|
}
|
|
|
|
/**
|
|
* Count Working Zone's Unavailable Boxes ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountUnavailableBoxes()
|
|
{
|
|
return ArraySize(unavailableBoxes);
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
/**
|
|
* Cleanup Model ...
|
|
*/
|
|
void Clean()
|
|
{
|
|
//
|
|
quarter1 = 0;
|
|
quarter2 = 0;
|
|
quarter3 = 0;
|
|
|
|
//
|
|
symbol = NULL;
|
|
period = NULL;
|
|
|
|
//
|
|
Clean(waitingBoxes);
|
|
Clean(breakedBoxes);
|
|
Clean(unavailableBoxes);
|
|
|
|
//
|
|
ZeroMemory(supplyZone);
|
|
ZeroMemory(demandZone);
|
|
|
|
//
|
|
mDrawnObjects.Clear();
|
|
mWorkingZoneObjects.Clear();
|
|
}
|
|
|
|
/**
|
|
* Validate Model ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsValid()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
//
|
|
quarter1 > 0 &&
|
|
quarter2 > 0 &&
|
|
quarter3 > 0 &&
|
|
HasSupplyZone() &&
|
|
HasDemandZone() &&
|
|
quarter1 > quarter2 &&
|
|
quarter2 > quarter3
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Checking a Box Exists in Collections or not ...
|
|
*
|
|
* @param box: XBoxZone instance reference ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsExists(XSignalBox &box)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Check Validation ...
|
|
result = box.IsValid() &&
|
|
(HasWaitingBoxes() ||
|
|
HasBreakedBoxes() ||
|
|
HasUnavailableBoxes());
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int idx = -1;
|
|
bool has = false;
|
|
|
|
//
|
|
// Check Index in Waiting Boxes ...
|
|
has = HasWaitingBoxes();
|
|
if (has)
|
|
{
|
|
//
|
|
result = FindIndex(
|
|
idx,
|
|
box,
|
|
waitingBoxes //
|
|
);
|
|
if (result)
|
|
{
|
|
return result;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Index in Breaked Boxes ...
|
|
has = HasBreakedBoxes();
|
|
if (has)
|
|
{
|
|
//
|
|
result = FindIndex(
|
|
idx,
|
|
box,
|
|
breakedBoxes //
|
|
);
|
|
if (result)
|
|
{
|
|
return result;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Index in Unavailable Boxes ...
|
|
has = HasUnavailableBoxes();
|
|
if (has)
|
|
{
|
|
//
|
|
result = FindIndex(
|
|
idx,
|
|
box,
|
|
unavailableBoxes //
|
|
);
|
|
if (result)
|
|
{
|
|
return result;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Initialize Working Zone ...
|
|
*
|
|
* @param _symbol: String ...
|
|
* @param _period: ENUM_TIMEFRAMES member ...
|
|
* @param barIndex: int ...
|
|
* @param provider: X121SMCStrategySignalProviderData instance reference ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool Init(
|
|
string _symbol,
|
|
ENUM_TIMEFRAMES _period,
|
|
int barIndex,
|
|
X121SMCStrategySignalProviderData &provider //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
result =
|
|
//
|
|
IsValid(_symbol) &&
|
|
IsValid(_period) &&
|
|
//
|
|
provider.IsValid()
|
|
//
|
|
;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
symbol = _symbol;
|
|
period = _period;
|
|
|
|
//
|
|
int idx = -1;
|
|
int count = 0;
|
|
bool has = false;
|
|
|
|
//
|
|
XOHCL zBar;
|
|
has = zBar.Init(
|
|
symbol,
|
|
period,
|
|
barIndex //
|
|
);
|
|
result = has;
|
|
if (!result)
|
|
{
|
|
zBar.Clean();
|
|
return result;
|
|
}
|
|
double ll5 = zBar.FindLowest(5, MODE_LOW);
|
|
double hh5 = zBar.FindHighest(5, MODE_HIGH);
|
|
zBar.Clean();
|
|
|
|
//
|
|
// Supply Zone ...
|
|
has = HasSupplyZone();
|
|
if (!has)
|
|
{
|
|
//
|
|
idx = GetHighest(provider
|
|
.consolidationState
|
|
.supplyZones //
|
|
);
|
|
has = IsValidIndex(idx);
|
|
if (has)
|
|
{
|
|
//
|
|
supplyZone = provider
|
|
.consolidationState
|
|
.supplyZones[idx];
|
|
has = hh5 < supplyZone.Lower();
|
|
if (!has)
|
|
{
|
|
supplyZone = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Demand Zone ...
|
|
has = HasDemandZone();
|
|
if (!has)
|
|
{
|
|
//
|
|
idx = GetLowest(provider
|
|
.consolidationState
|
|
.demandZones //
|
|
);
|
|
has = IsValidIndex(idx);
|
|
if (has)
|
|
{
|
|
//
|
|
demandZone = provider
|
|
.consolidationState
|
|
.demandZones[idx];
|
|
has = ll5 > demandZone.Upper();
|
|
if (!has)
|
|
{
|
|
demandZone = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
if (supplyZone != NULL &&
|
|
demandZone != NULL &&
|
|
supplyZone.IsValid() &&
|
|
demandZone.IsValid())
|
|
{
|
|
//
|
|
double upper = supplyZone.Lower();
|
|
double lower = demandZone.Upper();
|
|
|
|
//
|
|
double delta = ((upper - lower) / 100) * 25;
|
|
|
|
//
|
|
quarter1 = upper - (1 * delta);
|
|
quarter2 = upper - (2 * delta);
|
|
quarter3 = upper - (3 * delta);
|
|
}
|
|
|
|
//
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Signal Boxes ...
|
|
*
|
|
* @param cycle: ENUM_X_CYCLES member ...
|
|
* @param provider: X121SMCStrategySignalProviderData instance reference ...
|
|
* @param barIndex: int ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectWaitingBoxes(
|
|
ENUM_X_CYCLES obCycle,
|
|
ENUM_X_CYCLES fvgCycle,
|
|
X121SMCStrategySignalProviderData &provider,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
int idx = -1;
|
|
int count = 0;
|
|
bool has = false;
|
|
datetime cTime = TimeCurrent();
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
// Select OB Cycle ...
|
|
XPOIState obState;
|
|
XPOIStateEvents obStateEvents;
|
|
X121Conditions obXConditions;
|
|
XC121SMCCycleHelper *obHelper;
|
|
X121SMCCycleConditions obConditions;
|
|
result = provider.SelectCycle(
|
|
obCycle,
|
|
obState,
|
|
obStateEvents,
|
|
obXConditions,
|
|
obHelper,
|
|
obConditions //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
obState.Clean();
|
|
ZeroMemory(obHelper);
|
|
obConditions.Clean();
|
|
obStateEvents.Clean();
|
|
obXConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Select FVG Cycle ...
|
|
XPOIState fvgState;
|
|
XPOIStateEvents fvgStateEvents;
|
|
X121Conditions fvgXConditions;
|
|
XC121SMCCycleHelper *fvgHelper;
|
|
X121SMCCycleConditions fvgConditions;
|
|
result = provider.SelectCycle(
|
|
fvgCycle,
|
|
fvgState,
|
|
fvgStateEvents,
|
|
fvgXConditions,
|
|
fvgHelper,
|
|
fvgConditions //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
obState.Clean();
|
|
ZeroMemory(obHelper);
|
|
obConditions.Clean();
|
|
obStateEvents.Clean();
|
|
obXConditions.Clean();
|
|
|
|
//
|
|
fvgState.Clean();
|
|
ZeroMemory(fvgHelper);
|
|
fvgConditions.Clean();
|
|
fvgStateEvents.Clean();
|
|
fvgXConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detect a Sharp Zone Which Contains
|
|
// an Order Block and Also an FVG ...
|
|
if (obStateEvents.hasNewSharp)
|
|
{
|
|
//
|
|
XBoxZone ob;
|
|
XBoxZone fvg;
|
|
XBoxZone currSharp;
|
|
XBoxZone prevSharp;
|
|
XBoxZone sharpConsolidation;
|
|
|
|
//
|
|
// Retrieve Current Sharp ...
|
|
XBoxZone tmpBoxes[];
|
|
Copy(
|
|
obState.sharps,
|
|
tmpBoxes //
|
|
);
|
|
idx = GetYoungest(tmpBoxes);
|
|
has = IsValidIndex(idx);
|
|
if (has)
|
|
{
|
|
//
|
|
currSharp = tmpBoxes[idx];
|
|
bool isBullish = currSharp.IsBullish();
|
|
|
|
//
|
|
ArrayRemove(
|
|
tmpBoxes,
|
|
idx,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
while (HasChild(tmpBoxes))
|
|
{
|
|
//
|
|
idx = GetYoungest(tmpBoxes);
|
|
has = IsValidIndex(idx);
|
|
|
|
//
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
XBoxZone iBox = tmpBoxes[idx];
|
|
ArrayRemove(
|
|
tmpBoxes,
|
|
idx,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
if (iBox.dir == currSharp.dir)
|
|
{
|
|
//
|
|
prevSharp = iBox;
|
|
iBox.Clean();
|
|
break;
|
|
}
|
|
|
|
//
|
|
iBox.Clean();
|
|
}
|
|
|
|
//
|
|
Clean(tmpBoxes);
|
|
}
|
|
Clean(tmpBoxes);
|
|
|
|
//
|
|
// Preparing Sharp Consolidation Box ...
|
|
has = currSharp.IsValid() &&
|
|
prevSharp.IsValid() &&
|
|
prevSharp.lower < currSharp.upper;
|
|
if (has)
|
|
{
|
|
//
|
|
sharpConsolidation.type = "XSHCNZ";
|
|
sharpConsolidation.dir = currSharp.dir;
|
|
sharpConsolidation.symbol = currSharp.symbol;
|
|
sharpConsolidation.period = currSharp.period;
|
|
|
|
//
|
|
sharpConsolidation.from = prevSharp.to;
|
|
sharpConsolidation.to = currSharp.from;
|
|
|
|
//
|
|
int toIDX = GetBarIndex(
|
|
currSharp.symbol,
|
|
currSharp.period,
|
|
sharpConsolidation.to //
|
|
);
|
|
int fromIDX = GetBarIndex(
|
|
currSharp.symbol,
|
|
currSharp.period,
|
|
sharpConsolidation.from //
|
|
);
|
|
int length = fromIDX - toIDX;
|
|
|
|
//
|
|
XOHCL toBar;
|
|
has = toBar.Init(
|
|
sharpConsolidation.symbol,
|
|
sharpConsolidation.period,
|
|
toIDX //
|
|
);
|
|
|
|
//
|
|
if (has)
|
|
{
|
|
//
|
|
double upper = toBar.FindHighest(
|
|
length,
|
|
MODE_HIGH //
|
|
);
|
|
|
|
//
|
|
double lower = toBar.FindLowest(
|
|
length,
|
|
MODE_LOW //
|
|
);
|
|
|
|
//
|
|
sharpConsolidation.upper = upper;
|
|
sharpConsolidation.lower = lower;
|
|
}
|
|
|
|
//
|
|
// Detect Order Block / FVG ...
|
|
has = sharpConsolidation.IsValid();
|
|
if (has)
|
|
{
|
|
//
|
|
// Check Direction ...
|
|
bool isBullish = sharpConsolidation.IsBullish();
|
|
|
|
//
|
|
// Find Inside Order Block ...
|
|
Clean(tmpBoxes);
|
|
if (isBullish)
|
|
{
|
|
//
|
|
ToBox(
|
|
obState.bullishOrderBlocks,
|
|
tmpBoxes //
|
|
);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
ToBox(
|
|
obState.bearishOrderBlocks,
|
|
tmpBoxes //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Select Order Block ...
|
|
has = HasChild(tmpBoxes);
|
|
if (has)
|
|
{
|
|
//
|
|
while (HasChild(tmpBoxes))
|
|
{
|
|
//
|
|
idx = GetYoungest(tmpBoxes);
|
|
has = IsValidIndex(idx);
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
XBoxZone iBox = tmpBoxes[idx];
|
|
ArrayRemove(
|
|
tmpBoxes,
|
|
idx,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
// Validate Selected Box ...
|
|
bool isDirPassed = iBox.dir == sharpConsolidation.dir;
|
|
bool isFromPassed = iBox.from > sharpConsolidation.from;
|
|
bool isInsidePassed = IsBoxInside(
|
|
iBox,
|
|
sharpConsolidation //
|
|
);
|
|
bool isValidationPassed = IsBoxValid(
|
|
iBox,
|
|
barIndex //
|
|
);
|
|
|
|
//
|
|
has = isDirPassed &&
|
|
isFromPassed &&
|
|
isInsidePassed &&
|
|
isValidationPassed;
|
|
if (has)
|
|
{
|
|
ob = iBox;
|
|
}
|
|
|
|
//
|
|
iBox.Clean();
|
|
|
|
//
|
|
if (ob.IsValid())
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
Clean(tmpBoxes);
|
|
|
|
//
|
|
// Find Inside FVG ...
|
|
has = ob.IsValid();
|
|
if (has)
|
|
{
|
|
//
|
|
Clean(tmpBoxes);
|
|
if (isBullish)
|
|
{
|
|
//
|
|
ToBox(
|
|
fvgState.bullishFairValueGaps,
|
|
tmpBoxes //
|
|
);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
ToBox(
|
|
fvgState.bearishFairValueGaps,
|
|
tmpBoxes //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Select FVG ...
|
|
has = HasChild(tmpBoxes);
|
|
if (has)
|
|
{
|
|
//
|
|
while (HasChild(tmpBoxes))
|
|
{
|
|
//
|
|
idx = isBullish
|
|
? GetLowest(tmpBoxes)
|
|
: GetHighest(tmpBoxes);
|
|
has = IsValidIndex(idx);
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
XBoxZone iBox = tmpBoxes[idx];
|
|
ArrayRemove(
|
|
tmpBoxes,
|
|
idx,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
// Validate Selected Box ...
|
|
bool isDirPassed = iBox.dir == ob.dir;
|
|
bool isFromPassed = iBox.from > ob.from;
|
|
bool isInsidePassed = IsBoxInside(
|
|
iBox,
|
|
ob //
|
|
);
|
|
|
|
//
|
|
has = isDirPassed &&
|
|
isFromPassed &&
|
|
isInsidePassed;
|
|
if (has)
|
|
{
|
|
fvg = iBox;
|
|
}
|
|
|
|
//
|
|
iBox.Clean();
|
|
|
|
//
|
|
if (fvg.IsValid())
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
Clean(tmpBoxes);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Checking Validation of Boxes ...
|
|
has = ob.IsValid() &&
|
|
fvg.IsValid() &&
|
|
sharpConsolidation.IsValid();
|
|
if (has)
|
|
{
|
|
//
|
|
// Update Time ...
|
|
ob.to = cTime;
|
|
fvg.to = cTime;
|
|
sharpConsolidation.to = cTime;
|
|
|
|
//
|
|
XSignalBox iSBox;
|
|
|
|
//
|
|
iSBox.ob = ob;
|
|
iSBox.fvg = fvg;
|
|
iSBox.sharp = sharpConsolidation;
|
|
|
|
//
|
|
has = iSBox.IsValid();
|
|
if (has)
|
|
{
|
|
//
|
|
AddRef(
|
|
iSBox,
|
|
waitingBoxes //
|
|
);
|
|
}
|
|
|
|
//
|
|
iSBox.Clean();
|
|
}
|
|
|
|
//
|
|
ob.Clean();
|
|
fvg.Clean();
|
|
toBar.Clean();
|
|
currSharp.Clean();
|
|
prevSharp.Clean();
|
|
sharpConsolidation.Clean();
|
|
}
|
|
|
|
//
|
|
Clean(tmpBoxes);
|
|
currSharp.Clean();
|
|
prevSharp.Clean();
|
|
sharpConsolidation.Clean();
|
|
}
|
|
|
|
//
|
|
// Preparing Waiting Box based on FVG State ...
|
|
if (fvgStateEvents.hasNewSharp)
|
|
{
|
|
//
|
|
// Select Newest Sharp Change ...
|
|
XBoxZone sharp;
|
|
idx = GetYoungest(fvgState.sharps);
|
|
has = IsValidIndex(idx);
|
|
if (has)
|
|
{
|
|
//
|
|
XOHCL endBar;
|
|
XOHCL startBar;
|
|
int totalBars = 0;
|
|
int orderBlocksIDX[];
|
|
int bullBarsCount = 0;
|
|
int bearBarsCount = 0;
|
|
int validPercent = 75;
|
|
|
|
//
|
|
sharp = fvgState.sharps[idx];
|
|
sharp.type = "XSHPOBX";
|
|
bool isSharpBullish = sharp.IsBullish();
|
|
|
|
//
|
|
// Validate End Bar ...
|
|
if (sharp.IsValid())
|
|
{
|
|
//
|
|
// Validate End Bar Direction ...
|
|
int endBarIDX = GetBarIndex(
|
|
sharp.symbol,
|
|
sharp.period,
|
|
sharp.to //
|
|
);
|
|
|
|
//
|
|
has = endBar.Init(
|
|
sharp.symbol,
|
|
sharp.period,
|
|
endBarIDX + 1 //
|
|
);
|
|
|
|
//
|
|
if (has)
|
|
{
|
|
//
|
|
has = sharp.dir == endBar.GetDirection();
|
|
if (!has)
|
|
{
|
|
sharp.Clean();
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Validate Start Bar ...
|
|
if (sharp.IsValid())
|
|
{
|
|
//
|
|
// Validate Start Bar Direction ...
|
|
int startBarIDX = GetBarIndex(
|
|
sharp.symbol,
|
|
sharp.period,
|
|
sharp.from //
|
|
);
|
|
|
|
//
|
|
has = startBar.Init(
|
|
sharp.symbol,
|
|
sharp.period,
|
|
startBarIDX + 1 //
|
|
);
|
|
|
|
//
|
|
if (has)
|
|
{
|
|
//
|
|
has = sharp.dir == Opposit(startBar.GetDirection());
|
|
if (!has)
|
|
{
|
|
sharp.Clean();
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Validate OrderBlocks ...
|
|
if (sharp.IsValid())
|
|
{
|
|
//
|
|
int end = endBar.Index();
|
|
int start = startBar.Index();
|
|
for (int i = start; i >= end; i--)
|
|
{
|
|
//
|
|
XOHCL iBar;
|
|
has = iBar.Init(
|
|
sharp.symbol,
|
|
sharp.period,
|
|
i //
|
|
);
|
|
if (!has)
|
|
{
|
|
//
|
|
iBar.Clean();
|
|
continue;
|
|
}
|
|
|
|
//
|
|
totalBars++;
|
|
|
|
//
|
|
bool isBullish = iBar.IsBullish();
|
|
if (isBullish)
|
|
{
|
|
//
|
|
bullBarsCount++;
|
|
|
|
//
|
|
if (!isSharpBullish)
|
|
{
|
|
//
|
|
Add(
|
|
i,
|
|
orderBlocksIDX //
|
|
);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
bearBarsCount++;
|
|
|
|
//
|
|
if (isSharpBullish)
|
|
{
|
|
//
|
|
Add(
|
|
i,
|
|
orderBlocksIDX //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
iBar.Clean();
|
|
}
|
|
|
|
//
|
|
// Follow Order Blocks ...
|
|
has = HasChild(orderBlocksIDX);
|
|
if (has)
|
|
{
|
|
//
|
|
int bullBarsPercent = (bullBarsCount * 100) / totalBars;
|
|
int bearBarsPercent = (bearBarsCount * 100) / totalBars;
|
|
|
|
//
|
|
has = isSharpBullish
|
|
? bullBarsPercent >= validPercent
|
|
: bearBarsPercent >= validPercent;
|
|
if (has)
|
|
{
|
|
//
|
|
// Prepare Waiting Boxes ...
|
|
count = ArraySize(orderBlocksIDX);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XOHCL iBar;
|
|
has = iBar.Init(
|
|
sharp.symbol,
|
|
sharp.period,
|
|
orderBlocksIDX[i] //
|
|
);
|
|
if (!has)
|
|
{
|
|
//
|
|
iBar.Clean();
|
|
continue;
|
|
}
|
|
|
|
//
|
|
XBoxZone iOB;
|
|
XBoxZone iFVG;
|
|
|
|
//
|
|
iOB.to = sharp.to;
|
|
iOB.type = "XOBX";
|
|
iOB.dir = sharp.dir;
|
|
iOB.from = iBar.time;
|
|
iOB.lower = iBar.low;
|
|
iOB.upper = iBar.high;
|
|
iOB.period = iBar.period;
|
|
iOB.symbol = iBar.symbol;
|
|
|
|
//
|
|
// Select FVG ...
|
|
has = iOB.IsValid();
|
|
if (has)
|
|
{
|
|
//
|
|
// Select FVG ...
|
|
has = HasChild(fvgState.fairValueGaps);
|
|
if (has)
|
|
{
|
|
//
|
|
XBoxZone tmpBoxes[];
|
|
if (isSharpBullish)
|
|
{
|
|
//
|
|
ToBox(
|
|
fvgState.bullishFairValueGaps,
|
|
tmpBoxes //
|
|
);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
ToBox(
|
|
fvgState.bearishFairValueGaps,
|
|
tmpBoxes //
|
|
);
|
|
}
|
|
has = HasChild(tmpBoxes);
|
|
if (has)
|
|
{
|
|
//
|
|
while (HasChild(tmpBoxes))
|
|
{
|
|
//
|
|
idx = GetYoungest(tmpBoxes);
|
|
has = IsValidIndex(idx);
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
XBoxZone iBox = tmpBoxes[idx];
|
|
ArrayRemove(
|
|
tmpBoxes,
|
|
idx,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
// Validate FVG ...
|
|
bool isDirPassed = iBox.dir == sharp.dir;
|
|
bool isFromPassed = iBox.from >= iOB.from;
|
|
bool isPricePassed = IsBoxInsideOr(iBox, iOB);
|
|
|
|
//
|
|
has = isDirPassed &&
|
|
isFromPassed &&
|
|
isPricePassed;
|
|
if (has)
|
|
{
|
|
//
|
|
iFVG = iBox;
|
|
iBox.Clean();
|
|
break;
|
|
}
|
|
|
|
//
|
|
iBox.Clean();
|
|
}
|
|
}
|
|
Clean(tmpBoxes);
|
|
}
|
|
}
|
|
|
|
//
|
|
has =
|
|
sharp.IsValid() &&
|
|
iOB.IsValid() &&
|
|
iFVG.IsValid();
|
|
if (has)
|
|
{
|
|
//
|
|
XSignalBox iSBox;
|
|
|
|
//
|
|
iSBox.ob = iOB;
|
|
iSBox.fvg = iFVG;
|
|
iSBox.sharp = sharp;
|
|
|
|
//
|
|
AddRef(
|
|
iSBox,
|
|
waitingBoxes //
|
|
);
|
|
|
|
//
|
|
iSBox.Clean();
|
|
}
|
|
|
|
//
|
|
iOB.Clean();
|
|
iFVG.Clean();
|
|
iBar.Clean();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Follow Non Order Block ...
|
|
// First Found FVGs ...
|
|
XBoxZone iOB;
|
|
XBoxZone iFVG;
|
|
XBoxZone tmpBoxes[];
|
|
if (isSharpBullish)
|
|
{
|
|
//
|
|
ToBox(
|
|
fvgState.bullishFairValueGaps,
|
|
tmpBoxes //
|
|
);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
ToBox(
|
|
fvgState.bearishFairValueGaps,
|
|
tmpBoxes //
|
|
);
|
|
}
|
|
has = HasChild(tmpBoxes);
|
|
if (has)
|
|
{
|
|
//
|
|
while (HasChild(tmpBoxes))
|
|
{
|
|
//
|
|
idx = GetYoungest(tmpBoxes);
|
|
has = IsValidIndex(idx);
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
XBoxZone iBox = tmpBoxes[idx];
|
|
ArrayRemove(
|
|
tmpBoxes,
|
|
idx,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
// Validate FVG ...
|
|
bool isDirPassed = iBox.dir == sharp.dir;
|
|
bool isFromPassed = iBox.from >= sharp.from;
|
|
bool isPricePassed = IsBoxInside(iBox, sharp);
|
|
|
|
//
|
|
has = isDirPassed &&
|
|
isFromPassed &&
|
|
isPricePassed;
|
|
if (has)
|
|
{
|
|
//
|
|
iFVG = iBox;
|
|
|
|
//
|
|
// Now we Have to Create an Order Block ...
|
|
|
|
//
|
|
XOHCL iToBar;
|
|
XOHCL iFromBar;
|
|
|
|
//
|
|
int fromIDX = GetBarIndex(
|
|
iBox.symbol,
|
|
iBox.period,
|
|
iBox.from //
|
|
);
|
|
int toIDX = GetBarIndex(
|
|
iBox.symbol,
|
|
iBox.period,
|
|
iBox.to //
|
|
);
|
|
has = iToBar.Init(
|
|
iBox.symbol,
|
|
iBox.period,
|
|
toIDX //
|
|
);
|
|
has =
|
|
has &&
|
|
iFromBar.Init(
|
|
iBox.symbol,
|
|
iBox.period,
|
|
fromIDX //
|
|
);
|
|
if (!has)
|
|
{
|
|
//
|
|
iBox.Clean();
|
|
iToBar.Clean();
|
|
iFromBar.Clean();
|
|
|
|
//
|
|
break;
|
|
}
|
|
|
|
//
|
|
iOB.to = iBox.to;
|
|
iOB.type = "XOBX";
|
|
iOB.dir = iBox.dir;
|
|
iOB.from = iBox.from;
|
|
iOB.symbol = iBox.symbol;
|
|
iOB.period = iBox.period;
|
|
iOB.lower = MathMin(iToBar.low, iFromBar.low);
|
|
iOB.upper = MathMax(iToBar.high, iFromBar.high);
|
|
|
|
//
|
|
iBox.Clean();
|
|
iToBar.Clean();
|
|
iFromBar.Clean();
|
|
break;
|
|
}
|
|
|
|
//
|
|
iBox.Clean();
|
|
}
|
|
}
|
|
Clean(tmpBoxes);
|
|
|
|
//
|
|
has = iOB.IsValid() &&
|
|
iFVG.IsValid() &&
|
|
sharp.IsValid();
|
|
if (has)
|
|
{
|
|
//
|
|
XSignalBox iSBox;
|
|
|
|
//
|
|
iSBox.ob = iOB;
|
|
iSBox.fvg = iFVG;
|
|
iSBox.sharp = sharp;
|
|
|
|
//
|
|
AddRef(
|
|
iSBox,
|
|
waitingBoxes //
|
|
);
|
|
|
|
//
|
|
iSBox.Clean();
|
|
}
|
|
|
|
//
|
|
iOB.Clean();
|
|
iFVG.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
endBar.Clean();
|
|
startBar.Clean();
|
|
Clean(orderBlocksIDX);
|
|
}
|
|
}
|
|
|
|
//
|
|
count = CountWaitingBoxes();
|
|
result = IsValidSize(count);
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
|
|
//
|
|
obState.Clean();
|
|
ZeroMemory(obHelper);
|
|
obConditions.Clean();
|
|
obStateEvents.Clean();
|
|
obXConditions.Clean();
|
|
|
|
//
|
|
fvgState.Clean();
|
|
ZeroMemory(fvgHelper);
|
|
fvgConditions.Clean();
|
|
fvgStateEvents.Clean();
|
|
fvgXConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Validating Waiting Boxes and Detect Breaked Boxes ...
|
|
*
|
|
* @param barIndex: int ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int ValidateWaitingBoxes(
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
bool has = false;
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
if (barIndex == 0)
|
|
{
|
|
barIndex = 1;
|
|
}
|
|
|
|
//
|
|
has = HasWaitingBoxes();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int removeIDX[];
|
|
result = CountWaitingBoxes();
|
|
for (int i = 0; i < result; i++)
|
|
{
|
|
//
|
|
XOHCL iBar;
|
|
XSignalBox iBox = waitingBoxes[i];
|
|
bool isInite = iBar.Init(
|
|
iBox.ob.symbol,
|
|
iBox.ob.period,
|
|
iBox.ob.from //
|
|
);
|
|
|
|
//
|
|
has = isInite &&
|
|
(
|
|
//
|
|
IsBoxBreaked(
|
|
iBox.ob,
|
|
iBar.Index() - 1,
|
|
barIndex,
|
|
period //
|
|
)
|
|
//
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
Add(
|
|
i,
|
|
removeIDX //
|
|
);
|
|
|
|
//
|
|
AddRef(
|
|
iBox,
|
|
breakedBoxes //
|
|
);
|
|
}
|
|
|
|
//
|
|
// iBox.Clean();
|
|
iBar.Clean();
|
|
}
|
|
|
|
//
|
|
has = HasChild(removeIDX);
|
|
if (has)
|
|
{
|
|
//
|
|
CleanupArray(
|
|
removeIDX,
|
|
waitingBoxes //
|
|
);
|
|
}
|
|
Clean(removeIDX);
|
|
|
|
//
|
|
result = CountWaitingBoxes();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Trend Based On Boxes ...
|
|
*
|
|
* @param dir: ENUM_X_DIRECTION ember ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectTreand(
|
|
ENUM_X_CYCLES cycle,
|
|
ENUM_X_DIRECTION &dir,
|
|
X121SMCStrategySignalProviderData &provider,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
support.Clean();
|
|
resistance.Clean();
|
|
dir = X_DIRECTION_NONE;
|
|
trend = X_DIRECTION_NONE;
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
result = IsValid(cycle);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Select Cycle ...
|
|
XPOIState cState;
|
|
XPOIStateEvents cStateEvents;
|
|
X121Conditions cXConditions;
|
|
XC121SMCCycleHelper *cHelper;
|
|
X121SMCCycleConditions cConditions;
|
|
result = provider.SelectCycle(
|
|
cycle,
|
|
cState,
|
|
cStateEvents,
|
|
cXConditions,
|
|
cHelper,
|
|
cConditions //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
cState.Clean();
|
|
ZeroMemory(cHelper);
|
|
cConditions.Clean();
|
|
cStateEvents.Clean();
|
|
cXConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detect Trend ...
|
|
|
|
//
|
|
int idx = -1;
|
|
bool has = false;
|
|
|
|
//
|
|
XBoxZone tmp[];
|
|
XBoxZone tmpBoxes[];
|
|
|
|
//
|
|
// Select Supports ...
|
|
ToBox(
|
|
cState.supportZones,
|
|
tmp //
|
|
);
|
|
Copy(
|
|
tmp,
|
|
tmpBoxes,
|
|
false //
|
|
);
|
|
Clean(tmp);
|
|
|
|
//
|
|
// Select Resistances ...
|
|
ToBox(
|
|
cState.resistanceZones,
|
|
tmp //
|
|
);
|
|
Copy(
|
|
tmp,
|
|
tmpBoxes,
|
|
false //
|
|
);
|
|
Clean(tmp);
|
|
|
|
//
|
|
result = HasChild(tmpBoxes);
|
|
if (!result)
|
|
{
|
|
//
|
|
Clean(tmpBoxes);
|
|
|
|
//
|
|
cState.Clean();
|
|
ZeroMemory(cHelper);
|
|
cConditions.Clean();
|
|
cStateEvents.Clean();
|
|
cXConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Select Youngest Valid Zone ...
|
|
while (HasChild(tmpBoxes) ||
|
|
!(support.IsValid() &&
|
|
resistance.IsValid()))
|
|
{
|
|
//
|
|
// Check Yongest Zone ...
|
|
idx = GetYoungest(tmpBoxes);
|
|
has = IsValidIndex(idx);
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Remove Extracted Box ...
|
|
XBoxZone iBox = tmpBoxes[idx];
|
|
ArrayRemove(
|
|
tmpBoxes,
|
|
idx,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
// Check Validation of Box ...
|
|
has = IsBoxValid(
|
|
iBox,
|
|
barIndex,
|
|
period //
|
|
);
|
|
if (!has)
|
|
{
|
|
//
|
|
iBox.Clean();
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Assign Support or Resistance ...
|
|
bool isBullish = iBox.IsBullish();
|
|
if (isBullish &&
|
|
!support.IsValid())
|
|
{
|
|
support = iBox;
|
|
}
|
|
else if (!isBullish &&
|
|
!resistance.IsValid())
|
|
{
|
|
resistance = iBox;
|
|
}
|
|
|
|
//
|
|
// Validate Support and Resistance ...
|
|
has =
|
|
support.IsValid() &&
|
|
resistance.IsValid();
|
|
if (!has)
|
|
{
|
|
//
|
|
iBox.Clean();
|
|
continue;
|
|
}
|
|
|
|
//
|
|
iBox.Clean();
|
|
}
|
|
|
|
//
|
|
// Checking Result ...
|
|
bool isBullish =
|
|
support.from > resistance.from;
|
|
bool isBearish =
|
|
support.from < resistance.from;
|
|
result = isBullish ||
|
|
isBearish;
|
|
if (result)
|
|
{
|
|
//
|
|
dir =
|
|
isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
trend = dir;
|
|
|
|
//
|
|
support.to = TimeCurrent();
|
|
resistance.to = TimeCurrent();
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
|
|
//
|
|
Clean(tmp);
|
|
cState.Clean();
|
|
Clean(tmpBoxes);
|
|
ZeroMemory(cHelper);
|
|
cConditions.Clean();
|
|
cStateEvents.Clean();
|
|
cXConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Update all Collections Members To Time ...
|
|
*
|
|
* @param value: datetime, Specified To Time ...
|
|
*/
|
|
void UpdateTo(datetime value = NULL)
|
|
{
|
|
//
|
|
value = NormalizeTime(value);
|
|
|
|
//
|
|
int count = 0;
|
|
bool has = false;
|
|
|
|
//
|
|
has = HasSupplyZone();
|
|
if (has)
|
|
{
|
|
supplyZone.To(value);
|
|
}
|
|
|
|
//
|
|
has = HasDemandZone();
|
|
if (has)
|
|
{
|
|
demandZone.To(value);
|
|
}
|
|
|
|
//
|
|
has = HasWaitingBoxes();
|
|
if (has)
|
|
{
|
|
//
|
|
count = CountWaitingBoxes();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
waitingBoxes[i].UpdateTo(value);
|
|
}
|
|
}
|
|
|
|
//
|
|
}
|
|
|
|
/**
|
|
* Check Working Zone is Destroyed or not ...
|
|
*
|
|
* @param barIndex: int, bar index ...
|
|
* @param forPeriod: ENUM_TIMEFRAMES member ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsDestroyed(
|
|
int barIndex = 0,
|
|
ENUM_TIMEFRAMES forPeriod = NULL //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
if (!IsValid(forPeriod))
|
|
{
|
|
forPeriod = period;
|
|
}
|
|
|
|
//
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL bar;
|
|
result = bar.Init(
|
|
symbol,
|
|
period,
|
|
barIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL cBar;
|
|
result = bar.GetPreviousBar(cBar);
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
cBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isSupplyZoneBreaked =
|
|
//
|
|
bar.low > supplyZone.Upper() &&
|
|
cBar.low > supplyZone.Upper()
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isDemandZoneBreaked =
|
|
//
|
|
bar.high < demandZone.Lower() &&
|
|
cBar.high < demandZone.Lower()
|
|
//
|
|
;
|
|
|
|
//
|
|
bar.Clean();
|
|
cBar.Clean();
|
|
|
|
//
|
|
result = isSupplyZoneBreaked ||
|
|
isDemandZoneBreaked;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Signal Box Conditions ...
|
|
*
|
|
* @param box: XBoxZone instance reference, Signalled Box ...
|
|
* @param dir: ENUM_X_DIRECTION member, Specified Signal Direction ...
|
|
* @param signalProvider: ENUM_X121SMC_XWZ_PROVIDERS member, Specified Signal Type ...
|
|
* @param provider: X121SMCStrategySignalProviderData instance reference ...
|
|
* @param barIndex: int ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectSignalConditions(
|
|
XSignalBox &box,
|
|
ENUM_X_DIRECTION &dir,
|
|
ENUM_X121SMC_XWZ_PROVIDERS &signalProvider,
|
|
X121SMCStrategySignalProviderData &provider,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize Bars ...
|
|
|
|
//
|
|
box.Clean();
|
|
dir = X_DIRECTION_NONE;
|
|
signalProvider = X121SMC_XWZ_PROVIDER_NONE;
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
// TODO: Ignor Working Zone Validation ...
|
|
// result = IsValid();
|
|
// if (!result)
|
|
// {
|
|
// return result;
|
|
// }
|
|
|
|
//
|
|
int idx = -1;
|
|
int count = 0;
|
|
bool has = false;
|
|
|
|
//
|
|
int zIDX = barIndex;
|
|
int cIDX = zIDX + 1;
|
|
int pIDX = cIDX + 1;
|
|
|
|
//
|
|
bool isBullish = false;
|
|
bool isBearish = false;
|
|
|
|
//
|
|
X121SMCStrategyConditionParser cParser;
|
|
|
|
//
|
|
// Senario 1:
|
|
// ---------------------------------------------
|
|
// Rejected Box ...
|
|
// ---------------------------------------------
|
|
bool useSenario1 = false;
|
|
bool isSenario1Happend = false;
|
|
bool isSenario1Bullish = false;
|
|
bool isSenario1Bearish = false;
|
|
if (useSenario1)
|
|
{
|
|
//
|
|
isSenario1Happend = cParser.HasRejectedBoxConditions(
|
|
X_CYCLE_DECISION,
|
|
box,
|
|
dir,
|
|
waitingBoxes,
|
|
provider,
|
|
barIndex //
|
|
);
|
|
|
|
//
|
|
isSenario1Bullish =
|
|
isSenario1Happend &&
|
|
IsBullish(dir);
|
|
|
|
//
|
|
isSenario1Bearish =
|
|
isSenario1Happend &&
|
|
IsBearish(dir);
|
|
|
|
//
|
|
if (isSenario1Happend)
|
|
{
|
|
signalProvider = X121SMC_XWZ_PROVIDER_XREJECTED_BOX;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Senario 2:
|
|
// ---------------------------------------------------
|
|
// Activated Box ...
|
|
// ---------------------------------------------------
|
|
bool useSenario2 = false;
|
|
bool isSenario2Happend = false;
|
|
bool isSenario2Bullish = false;
|
|
bool isSenario2Bearish = false;
|
|
if (!isSenario1Happend &&
|
|
useSenario2)
|
|
{
|
|
//
|
|
isSenario2Happend = cParser.HasActivatedBoxConditions(
|
|
X_CYCLE_DECISION,
|
|
box,
|
|
dir,
|
|
waitingBoxes,
|
|
provider,
|
|
barIndex //
|
|
);
|
|
|
|
//
|
|
isSenario2Bullish =
|
|
isSenario2Happend &&
|
|
IsBullish(dir);
|
|
|
|
//
|
|
isSenario2Bearish =
|
|
isSenario2Happend &&
|
|
IsBearish(dir);
|
|
|
|
//
|
|
if (isSenario2Happend)
|
|
{
|
|
signalProvider = X121SMC_XWZ_PROVIDER_XACTIVATED_BOX;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Senario 3:
|
|
// ---------------------------------------------------
|
|
// Breaked Box ...
|
|
// ---------------------------------------------------
|
|
bool useSenario3 = false;
|
|
bool isSenario3Happend = false;
|
|
bool isSenario3Bullish = false;
|
|
bool isSenario3Bearish = false;
|
|
if (!isSenario1Happend &&
|
|
!isSenario2Happend &&
|
|
useSenario3)
|
|
{
|
|
//
|
|
isSenario3Happend = cParser.HasBreakedBoxConditions(
|
|
X_CYCLE_DECISION,
|
|
box,
|
|
dir,
|
|
breakedBoxes,
|
|
provider,
|
|
barIndex //
|
|
);
|
|
|
|
//
|
|
isSenario3Bullish =
|
|
isSenario3Happend &&
|
|
IsBullish(dir);
|
|
|
|
//
|
|
isSenario3Bearish =
|
|
isSenario3Happend &&
|
|
IsBearish(dir);
|
|
|
|
//
|
|
if (isSenario3Happend)
|
|
{
|
|
signalProvider = X121SMC_XWZ_PROVIDER_XACTIVATED_BOX;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Senario 4:
|
|
// -----------------------------------------------
|
|
// Detect Signal Box Based On FVG Conditions ...
|
|
// -----------------------------------------------
|
|
bool useSenario4 = false;
|
|
bool isSenario4Happend = false;
|
|
bool isSenario4Bullish = false;
|
|
bool isSenario4Bearish = false;
|
|
if (!isSenario1Happend &&
|
|
!isSenario2Happend &&
|
|
!isSenario3Happend &&
|
|
useSenario4)
|
|
{
|
|
//
|
|
isSenario4Happend = cParser.HasXFVGMAConditions(
|
|
X_CYCLE_DECISION,
|
|
box,
|
|
dir,
|
|
waitingBoxes,
|
|
provider,
|
|
barIndex //
|
|
);
|
|
|
|
//
|
|
isSenario4Bullish =
|
|
isSenario4Happend &&
|
|
IsBullish(dir);
|
|
|
|
//
|
|
isSenario4Bearish =
|
|
isSenario4Happend &&
|
|
IsBearish(dir);
|
|
|
|
//
|
|
if (isSenario4Happend)
|
|
{
|
|
signalProvider = X121SMC_XWZ_PROVIDER_XFVGMA;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Senario 5:
|
|
// ---------------------------------------------
|
|
// XWPVZ ...
|
|
// ---------------------------------------------
|
|
bool useSenario5 = true;
|
|
bool isSenario5Happend = false;
|
|
bool isSenario5Bullish = false;
|
|
bool isSenario5Bearish = false;
|
|
if (!isSenario1Happend &&
|
|
!isSenario2Happend &&
|
|
!isSenario3Happend &&
|
|
!isSenario4Happend &&
|
|
useSenario5)
|
|
{
|
|
//
|
|
isSenario5Happend = cParser.HasXWPVZConditions(
|
|
X_CYCLE_DECISION,
|
|
box,
|
|
dir,
|
|
provider,
|
|
barIndex //
|
|
);
|
|
|
|
//
|
|
isSenario5Bullish =
|
|
isSenario5Happend &&
|
|
IsBullish(dir);
|
|
|
|
//
|
|
isSenario5Bearish =
|
|
isSenario5Happend &&
|
|
IsBearish(dir);
|
|
|
|
//
|
|
if (isSenario5Happend)
|
|
{
|
|
signalProvider = X121SMC_XWZ_PROVIDER_XWPVZ;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Senario 6:
|
|
// ---------------------------------------------
|
|
// ---------------------------------------------
|
|
bool useSenario6 = false;
|
|
bool isSenario6Happend = false;
|
|
bool isSenario6Bullish = false;
|
|
bool isSenario6Bearish = false;
|
|
if (!isSenario1Happend &&
|
|
!isSenario2Happend &&
|
|
!isSenario3Happend &&
|
|
!isSenario4Happend &&
|
|
!isSenario5Happend &&
|
|
useSenario6)
|
|
{
|
|
}
|
|
|
|
//
|
|
// Summarize All Senario(s) Conditions ...
|
|
|
|
//
|
|
isBullish =
|
|
//
|
|
isSenario1Bullish ||
|
|
isSenario2Bullish ||
|
|
isSenario3Bullish ||
|
|
isSenario4Bullish ||
|
|
isSenario5Bullish ||
|
|
isSenario6Bullish
|
|
//
|
|
;
|
|
|
|
//
|
|
isBearish =
|
|
//
|
|
isSenario1Bearish ||
|
|
isSenario2Bearish ||
|
|
isSenario3Bearish ||
|
|
isSenario4Bearish ||
|
|
isSenario5Bearish ||
|
|
isSenario6Bearish
|
|
//
|
|
;
|
|
|
|
//
|
|
// Check All Conditions ...
|
|
result =
|
|
box.IsValid() &&
|
|
HasDirection(dir) &&
|
|
(isBullish ||
|
|
isBearish);
|
|
|
|
//
|
|
if (!result)
|
|
{
|
|
box.Clean();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect a Signal Priority forDynamic Risk Reward ratio ...
|
|
*
|
|
* @param priority: ENUM_X121SMC_XWZ_PRIORITY member, holds Specified position Priority ...
|
|
* @param forDir: ENUM_X_DIRECTION member, Specified Position Direction for Priority ...
|
|
* @param barIndex: int ...
|
|
* @param forPeriod: ENUM_TIMEFRAMES member ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectPriority(
|
|
ENUM_X121SMC_XWZ_PRIORITY &priority,
|
|
ENUM_X_DIRECTION forDir,
|
|
int barIndex = 0,
|
|
ENUM_TIMEFRAMES forPeriod = NULL //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
priority = X121SMC_XWZ_PRIORITY_NONE;
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
if (!IsValid(forPeriod))
|
|
{
|
|
forPeriod = period;
|
|
}
|
|
|
|
//
|
|
result = IsValid() &&
|
|
HasDirection(forDir);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isBullish = IsBullish(forDir);
|
|
|
|
//
|
|
XOHCL bar;
|
|
result = bar.Init(
|
|
symbol,
|
|
forPeriod,
|
|
barIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
return result;
|
|
}
|
|
|
|
//
|
|
if (bar.high < supplyZone.Upper() &&
|
|
bar.low > supplyZone.Lower())
|
|
{
|
|
//
|
|
priority =
|
|
isBullish
|
|
? X121SMC_XWZ_PRIORITY_NONE
|
|
: X121SMC_XWZ_PRIORITY_STRONG_HIGH;
|
|
}
|
|
else if (bar.high < supplyZone.Lower() &&
|
|
bar.low > quarter1)
|
|
{
|
|
//
|
|
priority =
|
|
isBullish
|
|
? X121SMC_XWZ_PRIORITY_WEAK
|
|
: X121SMC_XWZ_PRIORITY_HIGH;
|
|
}
|
|
else if (bar.high < quarter1 &&
|
|
bar.low > quarter2)
|
|
{
|
|
//
|
|
priority =
|
|
isBullish
|
|
? X121SMC_XWZ_PRIORITY_LOW
|
|
: X121SMC_XWZ_PRIORITY_REGULAR;
|
|
}
|
|
else if (bar.high < quarter2 &&
|
|
bar.low > quarter3)
|
|
{
|
|
//
|
|
priority =
|
|
isBullish
|
|
? X121SMC_XWZ_PRIORITY_REGULAR
|
|
: X121SMC_XWZ_PRIORITY_LOW;
|
|
}
|
|
else if (bar.high < quarter3 &&
|
|
bar.low > demandZone.Upper())
|
|
{
|
|
//
|
|
priority =
|
|
isBullish
|
|
? X121SMC_XWZ_PRIORITY_HIGH
|
|
: X121SMC_XWZ_PRIORITY_WEAK;
|
|
}
|
|
else if (bar.high < demandZone.Upper() &&
|
|
bar.low > demandZone.Lower())
|
|
{
|
|
//
|
|
priority =
|
|
isBullish
|
|
? X121SMC_XWZ_PRIORITY_STRONG_HIGH
|
|
: X121SMC_XWZ_PRIORITY_NONE;
|
|
}
|
|
|
|
//
|
|
result = priority != X121SMC_XWZ_PRIORITY_NONE &&
|
|
priority != X121SMC_XWZ_PRIORITY_WEAK;
|
|
|
|
//
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Draw Working Zne and all of
|
|
* it's Collections and Conditions ...
|
|
*
|
|
* @param drawSupplyZone: boolean ...
|
|
* @param drawDemandZone: boolean ...
|
|
* @param drawWaitingBoxes: boolean ...
|
|
*/
|
|
void Draw(
|
|
XCPOIDrawer *drawer,
|
|
bool drawSupplyZone = false,
|
|
bool drawDemandZone = false,
|
|
bool drawWaitingBoxes = false,
|
|
bool drawTrend = false //
|
|
)
|
|
{
|
|
//
|
|
if (drawer == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
int count = 0;
|
|
bool has = false;
|
|
bool isCreated = false;
|
|
|
|
//
|
|
ulong chartID = drawer.ChartIdentification();
|
|
int subWindow = drawer.SubWindowIdentification();
|
|
color bullishColor = drawer.BarBullishColor();
|
|
color bearishColor = drawer.BarBearishColor();
|
|
|
|
//
|
|
// Supply Zone ...
|
|
if (drawSupplyZone)
|
|
{
|
|
//
|
|
has = HasSupplyZone();
|
|
if (has)
|
|
{
|
|
//
|
|
XCSupplyZoneObject *iObj;
|
|
isCreated = drawer.CreateSupplyZone(
|
|
supplyZone,
|
|
iObj //
|
|
);
|
|
|
|
//
|
|
if (isCreated)
|
|
{
|
|
mWorkingZoneObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Demand Zone ...
|
|
if (drawDemandZone)
|
|
{
|
|
//
|
|
has = HasDemandZone();
|
|
if (has)
|
|
{
|
|
//
|
|
XCDemandZoneObject *iObj;
|
|
isCreated = drawer.CreateDemandZone(
|
|
demandZone,
|
|
iObj //
|
|
);
|
|
|
|
//
|
|
if (isCreated)
|
|
{
|
|
mWorkingZoneObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
//
|
|
// Quarters ...
|
|
has = IsValid();
|
|
if (has)
|
|
{
|
|
//
|
|
double zoneUpper = supplyZone.Upper();
|
|
double upper = supplyZone.Lower();
|
|
|
|
//
|
|
double lower = demandZone.Upper();
|
|
double zoneLower = demandZone.Lower();
|
|
|
|
//
|
|
string prefix = "X121WZone_" + symbol + "_" + ToString(period);
|
|
|
|
//
|
|
// Zone Upper ...
|
|
CChartObjectHLine *zoneUpperLine;
|
|
zoneUpperLine = new CChartObjectHLine();
|
|
isCreated = zoneUpperLine.Create(
|
|
chartID,
|
|
prefix + "_ZoneTop",
|
|
subWindow,
|
|
zoneUpper //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
zoneUpperLine.Color(clrRed);
|
|
|
|
//
|
|
mWorkingZoneObjects.Add(zoneUpperLine);
|
|
}
|
|
|
|
//
|
|
// Zone Lower ...
|
|
CChartObjectHLine *zoneLowerLine;
|
|
zoneLowerLine = new CChartObjectHLine();
|
|
isCreated = zoneLowerLine.Create(
|
|
chartID,
|
|
prefix + "_ZoneDown",
|
|
subWindow,
|
|
zoneLower //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
zoneLowerLine.Color(clrRed);
|
|
|
|
//
|
|
mWorkingZoneObjects.Add(zoneLowerLine);
|
|
}
|
|
|
|
//
|
|
// Upper ...
|
|
CChartObjectHLine *upperLine;
|
|
upperLine = new CChartObjectHLine();
|
|
isCreated = upperLine.Create(
|
|
chartID,
|
|
prefix + "_Upper",
|
|
subWindow,
|
|
upper //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
upperLine.Color(clrLime);
|
|
|
|
//
|
|
mWorkingZoneObjects.Add(upperLine);
|
|
}
|
|
|
|
//
|
|
// Lower ...
|
|
CChartObjectHLine *lowerLine;
|
|
lowerLine = new CChartObjectHLine();
|
|
isCreated = lowerLine.Create(
|
|
chartID,
|
|
prefix + "_Lower",
|
|
subWindow,
|
|
lower //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
lowerLine.Color(clrLime);
|
|
|
|
//
|
|
mWorkingZoneObjects.Add(lowerLine);
|
|
}
|
|
|
|
//
|
|
// Quarters ...
|
|
|
|
//
|
|
// Quarter 1 ...
|
|
CChartObjectHLine *q1Line;
|
|
q1Line = new CChartObjectHLine();
|
|
isCreated = q1Line.Create(
|
|
chartID,
|
|
prefix + "_Q1",
|
|
subWindow,
|
|
quarter1 //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
q1Line.Color(clrYellow);
|
|
|
|
//
|
|
mWorkingZoneObjects.Add(q1Line);
|
|
}
|
|
|
|
//
|
|
// Quarter 2 ...
|
|
CChartObjectHLine *q2Line;
|
|
q2Line = new CChartObjectHLine();
|
|
isCreated = q2Line.Create(
|
|
chartID,
|
|
prefix + "_Q2",
|
|
subWindow,
|
|
quarter2 //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
q2Line.Color(clrYellow);
|
|
|
|
//
|
|
mWorkingZoneObjects.Add(q2Line);
|
|
}
|
|
|
|
//
|
|
// Quarter 3 ...
|
|
CChartObjectHLine *q3Line;
|
|
q3Line = new CChartObjectHLine();
|
|
isCreated = q3Line.Create(
|
|
chartID,
|
|
prefix + "_Q3",
|
|
subWindow,
|
|
quarter3 //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
q3Line.Color(clrYellow);
|
|
|
|
//
|
|
mWorkingZoneObjects.Add(q3Line);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Waiting Zones ...
|
|
if (drawWaitingBoxes)
|
|
{
|
|
//
|
|
has = HasWaitingBoxes();
|
|
if (has)
|
|
{
|
|
//
|
|
count = CountWaitingBoxes();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XCBaseObject *objects[];
|
|
has = drawer.DrawSignalBox(
|
|
waitingBoxes[i],
|
|
objects //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
int objectsCount = ArraySize(objects);
|
|
for (int i = 0; i < objectsCount; i++)
|
|
{
|
|
mWorkingZoneObjects.Add(objects[i]);
|
|
}
|
|
}
|
|
Clean(objects);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Draw Trend if Exists ...
|
|
if (drawTrend)
|
|
{
|
|
//
|
|
// Check Trend Exists ...
|
|
has =
|
|
support.IsValid() &&
|
|
HasDirection(trend) &&
|
|
resistance.IsValid();
|
|
if (has)
|
|
{
|
|
//
|
|
// Draw Support ...
|
|
XCBoxObject *supportObject;
|
|
has = drawer.DrawBox(
|
|
support,
|
|
supportObject //
|
|
);
|
|
if (has)
|
|
{
|
|
mWorkingZoneObjects.Add(supportObject);
|
|
}
|
|
|
|
//
|
|
// Draw Resistance ...
|
|
XCBoxObject *resistanceObject;
|
|
has = drawer.DrawBox(
|
|
resistance,
|
|
resistanceObject //
|
|
);
|
|
if (has)
|
|
{
|
|
mWorkingZoneObjects.Add(resistanceObject);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
//
|
|
// XWZ Signal Conditions ...
|
|
struct X121SMCStrategyXWZSignalConditions
|
|
{
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
string symbol;
|
|
ENUM_TIMEFRAMES period;
|
|
|
|
//
|
|
double sl;
|
|
double reward;
|
|
double amountPercent;
|
|
ENUM_X_DIRECTION dir;
|
|
ENUM_X_POSITION_TYPES type;
|
|
|
|
//
|
|
// Setup Props ...
|
|
|
|
//
|
|
datetime setupTime;
|
|
datetime triggerTime;
|
|
|
|
//
|
|
double pivot;
|
|
double point;
|
|
double sls[];
|
|
double targets[];
|
|
|
|
//
|
|
XBoxZone signalBox;
|
|
|
|
//
|
|
ENUM_X121SMC_XWZ_PRIORITY priority;
|
|
ENUM_X121SMC_XWZ_PROVIDERS provider;
|
|
|
|
//
|
|
// Constructor ...
|
|
X121SMCStrategyXWZSignalConditions()
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
/**
|
|
* Cleaning Up ...
|
|
*/
|
|
void Clean()
|
|
{
|
|
//
|
|
sl = 0;
|
|
|
|
//
|
|
dir = X_DIRECTION_NONE;
|
|
type = X_POSITION_TYPE_NONE;
|
|
|
|
//
|
|
symbol = NULL;
|
|
period = NULL;
|
|
setupTime = NULL;
|
|
triggerTime = NULL;
|
|
|
|
//
|
|
ExtensionClean();
|
|
|
|
//
|
|
ZeroMemory(this);
|
|
}
|
|
|
|
/**
|
|
* Check Condition is Setting Up ...
|
|
*
|
|
* @param dir: ENUM_X_DIRECTION member, Setting Up Direction ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSetuped()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = IsValid(setupTime) &&
|
|
HasDirection(dir);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Calculate Setup Age ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int GetSetupAge()
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (!IsSetuped())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = (int)(TimeCurrent() - setupTime) / PeriodSeconds(period);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect How we Can Trigger Signal ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool CanTrigger()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
//
|
|
sl > 0 &&
|
|
IsValid(symbol) &&
|
|
IsValid(period) &&
|
|
IsValid(triggerTime) &&
|
|
type != X_POSITION_TYPE_ALL &&
|
|
type != X_POSITION_TYPE_NONE
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extensions ...
|
|
|
|
/**
|
|
* Clean Additional Properties ...
|
|
*/
|
|
void ExtensionClean()
|
|
{
|
|
//
|
|
pivot = 0;
|
|
point = 0;
|
|
|
|
//
|
|
reward = 0;
|
|
amountPercent = 0;
|
|
|
|
//
|
|
Clean(sls);
|
|
Clean(targets);
|
|
signalBox.Clean();
|
|
|
|
//
|
|
provider = X121SMC_XWZ_PROVIDER_NONE;
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
//
|
|
void UpdateTo(datetime value = NULL)
|
|
{
|
|
//
|
|
value = NormalizeTime(value);
|
|
|
|
//
|
|
int count = 0;
|
|
bool has = false;
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
//
|
|
// Extension Functions ...
|
|
|
|
// |