Files
MQL5Data/Documents/BKP/x-ob.fvg.tmp.mq5
T
2025-03-21 06:51:15 +03:30

1387 lines
24 KiB
Plaintext

//
struct XOBFVGPivot
{
//
// Props ...
double value;
datetime at;
//
// Constructor ...
XOBFVGPivot()
{
Clean();
}
//
// Tools ...
//
void Clean()
{
//
value = 0;
at = NULL;
//
ZeroMemory(this);
}
//
bool IsValid()
{
//
bool result = false;
//
result =
value > 0 &&
IsValid(at);
//
return result;
}
};
//
struct XOBFVG
{
//
// Props ...
XCFVG *fvgs[];
XCOrderBlock *ob;
//
// Constructor ...
XOBFVG()
{
Clean();
}
//
// Tools ...
//
void Clean()
{
//
Clean(fvgs);
ZeroMemory(ob);
//
ZeroMemory(this);
}
//
bool IsValid()
{
//
bool result = false;
//
result = HasOB() &&
HasFVGs();
if (!result)
{
return result;
}
//
XOHCL passedBar;
bool isBodyOut;
bool isOBStarted = ob.IsStarted(
ob.GetDirection(),
passedBar,
isBodyOut //
);
//
int idx = GetOldest(fvgs);
result = IsValidIndex(idx);
if (!result)
{
//
passedBar.Clean();
return result;
}
//
bool isFVGStarted = fvgs[idx].IsStarted(
ob.GetDirection(),
passedBar,
isBodyOut //
);
//
result = isOBStarted &&
isFVGStarted;
//
passedBar.Clean();
//
return result;
}
//
bool HasOB()
{
return ob != NULL &&
ob.IsValid();
}
//
bool HasFVGs()
{
return HasChild(fvgs);
}
//
int CountFVGs()
{
return ArraySize(fvgs);
}
//
ENUM_X_DIRECTION GetDirection()
{
//
ENUM_X_DIRECTION result = X_DIRECTION_NONE;
//
bool isValid = IsValid();
if (!isValid)
{
return result;
}
//
result = ob.GetDirection();
//
return result;
}
//
bool IsBullish()
{
return IsBullish(GetDirection());
}
//
bool IsBearish()
{
return IsBearish(GetDirection());
}
//
int GetSwings(
XOBFVGPivot &pivots[] //
)
{
//
int result = 0;
//
Clean(pivots);
//
if (!IsValid())
{
return result;
}
//
ENUM_X_DIRECTION forDir = GetDirection();
bool isBullish = IsBullish(forDir);
//
XOHCL passedBar;
XOBFVGPivot iPivot;
bool isPassed = false;
double appliedPrice = 0;
bool isBodyState = false;
//
// Start ...
isPassed = ob.IsStarted(
forDir,
passedBar,
isBodyState //
);
if (isPassed)
{
//
appliedPrice =
isBullish
? passedBar.low
: passedBar.high;
//
iPivot.Clean();
iPivot.value = appliedPrice;
iPivot.at = passedBar.time;
//
AddRef(
iPivot,
pivots //
);
//
iPivot.Clean();
}
//
// Activation ...
isPassed = ob.IsActivated(
forDir,
passedBar,
isBodyState //
);
if (isPassed)
{
//
appliedPrice =
isBullish
? passedBar.low
: passedBar.high;
//
iPivot.Clean();
iPivot.value = appliedPrice;
iPivot.at = passedBar.time;
//
AddRef(
iPivot,
pivots //
);
//
iPivot.Clean();
}
//
// Worked ...
isPassed = ob.IsWorked(
forDir,
passedBar,
isBodyState //
);
if (isPassed)
{
//
appliedPrice =
isBullish
? passedBar.low
: passedBar.high;
//
iPivot.Clean();
iPivot.value = appliedPrice;
iPivot.at = passedBar.time;
//
AddRef(
iPivot,
pivots //
);
//
iPivot.Clean();
}
//
passedBar.Clean();
//
result = ArraySize(pivots);
//
return result;
}
//
bool GetMainFVG(
XCFVG *&fvg //
)
{
//
bool result = false;
//
fvg = NULL;
//
result = IsValid();
if (!result)
{
return result;
}
//
int idx = GetOldest(fvgs);
result = IsValidIndex(idx);
if (!result)
{
//
ZeroMemory(fvg);
return result;
}
//
fvg = fvgs[idx];
result = fvg != NULL &&
fvg.IsValid();
//
return result;
}
//
bool IsValidZone(
int barIndex = 0 //
)
{
//
bool result = false;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
result = IsValid();
if (!result)
{
return result;
}
//
XCFVG *tmpFVGs[];
Copy(
fvgs,
tmpFVGs //
);
int count = CountFVGs();
for (int i = 0; i < count; i++)
{
//
XCFVG *iFVG = tmpFVGs[i];
//
XOHCL startedBar;
bool isBodyOut = false;
result = iFVG.IsStarted(
iFVG.GetDirection(),
startedBar,
isBodyOut //
);
if (!result)
{
//
ZeroMemory(iFVG);
startedBar.Clean();
ArrayRemove(
fvgs,
i,
1 //
);
//
continue;
}
//
XOHCL bar;
bool isBullish = iFVG.IsBullish();
datetime fromTime = startedBar.NextAt();
//
int fromIndex = iBarShift(
iFVG.GetSymbol(),
iFVG.GetPeriod(),
fromTime //
);
result = IsValidIndex(fromIndex);
if (!result)
{
//
bar.Clean();
ZeroMemory(iFVG);
startedBar.Clean();
ArrayRemove(
fvgs,
i,
1 //
);
//
continue;
}
//
bool isInited = false;
bool isValidFVG = false;
for (int j = barIndex; j < fromIndex; j++)
{
//
isInited = bar.Init(
iFVG.GetSymbol(),
iFVG.GetPeriod(),
j //
);
if (!isInited)
{
//
bar.Clean();
continue;
}
//
// bool isBarAbove =
// bar.low > iFVG.Upper();
// bool isBarBelow =
// bar.high < iFVG.Lower();
//
bool isBarAbove =
bar.GetDown() > iFVG.Upper();
bool isBarBelow =
bar.GetUp() < iFVG.Lower();
//
isValidFVG =
isBullish
? isBarAbove
: isBarBelow;
if (!isValidFVG)
{
//
bar.Clean();
//
break;
}
//
bar.Clean();
}
//
if (!isValidFVG)
{
//
ArrayRemove(
fvgs,
i,
1 //
);
}
//
bar.Clean();
ZeroMemory(iFVG);
startedBar.Clean();
}
//
Clean(tmpFVGs);
//
result = HasFVGs();
//
return result;
}
//
bool ToZone(XBoxZone &box)
{
//
bool result = false;
//
result = ToZoneBox(
box,
this //
);
//
return result;
}
//
void AddFVG(XCFVG *fvg)
{
//
int idx = -1;
bool has = false;
//
has =
HasOB() &&
fvg != NULL &&
fvg.IsValid() &&
ob.GetDirection() == fvg.GetDirection();
if (!has)
{
return;
}
//
idx = FindIndex(
fvg,
fvgs //
);
has = !IsValidIndex(idx);
if (!has)
{
return;
}
//
Add(
fvg,
fvgs //
);
}
//
bool IsSameAs(XOBFVG &item)
{
//
bool result = false;
//
result = IsValid() &&
IsSame(ob, item.ob);
//
return result;
}
//
void UpdateTo(datetime value = NULL)
{
//
value = NormalizeTime(value);
//
int count = 0;
bool has = false;
//
has = HasOB();
if (has)
{
ob.To(value);
}
//
has = HasFVGs();
if (has)
{
//
count = CountFVGs();
for (int i = 0; i < count; i++)
{
fvgs[i].To(value);
}
}
}
};
/**
* Update to Time of Specifiex Collection ...
*
* @param items: XOBFVG instance Collection ...
* @param value: datetime ...
*/
void SpecifiedUpdateTo(
XOBFVG &items[],
datetime value = NULL //
)
{
//
value = NormalizeTime(value);
//
int count = ArraySize(items);
bool has = HasChild(items);
if (!has)
{
return;
}
//
for (int i = 0; i < count; i++)
{
items[i].UpdateTo(value);
}
}
/**
* Extract Box Zone's of Specified OBFVG ...
*
* @param box: XBoxZone instance, represent result ...
* @param obfvg: XOBFVG instance, specified Model ...
*
* @return ( bool )
*/
bool ToZoneBox(
XBoxZone &box,
XOBFVG &obfvg //
)
{
//
bool result = false;
//
box.Clean();
//
// Check Model Validation ...
result = obfvg.IsValid();
if (!result)
{
return result;
}
//
// Retrieve Model Main Fair Value Gap ...
XCFVG *fvg;
result = obfvg.GetMainFVG(fvg);
if (!result)
{
//
box.Clean();
ZeroMemory(fvg);
//
return result;
}
//
bool isBullish = fvg.IsBullish();
//
// Retrieve Main Fair Value Gap's Started Bar ...
XOHCL startedBar;
bool isBodyOut = false;
bool isStarted = fvg.IsStarted(
fvg.GetDirection(),
startedBar,
isBodyOut //
);
result = isStarted;
if (!result)
{
//
box.Clean();
ZeroMemory(fvg);
startedBar.Clean();
//
return result;
}
//
// Converts Main Fair Value Gaps to Box ...
result = ToBox(
box,
fvg //
);
if (!result)
{
//
box.Clean();
ZeroMemory(fvg);
startedBar.Clean();
//
return result;
}
//
// Validate Start Bar ...
result =
isBullish
? startedBar.high >= fvg.Upper() &&
startedBar.low < fvg.Upper()
: startedBar.low <= fvg.Lower() &&
startedBar.high > fvg.Lower();
if (!result)
{
//
box.Clean();
ZeroMemory(fvg);
startedBar.Clean();
//
return result;
}
//
// Update Box using Started Bar ...
box.lower = isBullish
? box.lower
: startedBar.low;
box.upper =
isBullish
? startedBar.high
: box.upper;
//
box.from = startedBar.NextAt();
//
// Check Box Validation ...
result = box.IsValid();
if (!result)
{
box.Clean();
}
//
// Cleanup Resources ...
ZeroMemory(fvg);
startedBar.Clean();
//
return result;
}
/**
* Converts to XBoxZone ...
*
* @return ( bool )
*/
bool ToBox(
XBoxZone &box,
XOBFVG &item //
)
{
//
bool result = false;
//
result = ToBox(
box,
item.ob //
);
//
return result;
}
/**
* Converts to XBoxZone ...
*
* @return ( bool )
*/
int ToBox(
XOBFVG &source[],
XBoxZone &dest[] //
)
{
//
int result = 0;
//
Clean(dest);
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
for (int i = 0; i < count; i++)
{
//
XOBFVG iZone = source[i];
//
XBoxZone iBox;
bool hasBox = ToBox(
iBox,
iZone //
);
//
if (hasBox)
{
//
AddRef(
iBox,
dest //
);
}
//
iBox.Clean();
iZone.Clean();
}
//
result = ArraySize(dest);
//
return result;
}
/**
* Get Oldest Index ...
*
* @param source: XOBFVG instance Reference Collection ...
*
* @return ( int )
*/
int GetOldest(
XOBFVG &source[] //
)
{
//
int result = -1;
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XBoxZone tmpBoxes[];
int boxesCount = ToBox(
source,
tmpBoxes //
);
if (!IsValidSize(boxesCount))
{
//
Clean(tmpBoxes);
return result;
}
//
XBoxZone selected;
for (int i = 0; i < boxesCount; i++)
{
//
XBoxZone iBox = tmpBoxes[i];
//
bool canSet =
!selected.IsValid()
? true
: selected.from > iBox.from;
if (canSet)
{
//
result = i;
selected = iBox;
}
}
//
Clean(tmpBoxes);
selected.Clean();
//
return result;
}
/**
* Get Youngest Index ...
*
* @param source: XOBFVG instance Reference Collection ...
*
* @return ( int )
*/
int GetYoungest(
XOBFVG &source[] //
)
{
//
int result = -1;
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XBoxZone tmpBoxes[];
int boxesCount = ToBox(
source,
tmpBoxes //
);
if (!IsValidSize(boxesCount))
{
//
Clean(tmpBoxes);
return result;
}
//
XBoxZone selected;
for (int i = 0; i < boxesCount; i++)
{
//
XBoxZone iBox = tmpBoxes[i];
//
bool canSet =
!selected.IsValid()
? true
: selected.from < iBox.from;
if (canSet)
{
//
result = i;
selected = iBox;
}
}
//
Clean(tmpBoxes);
selected.Clean();
//
return result;
}
/**
* Get Highest Index ...
*
* @param source: XOBFVG instance Reference Collection ...
*
* @return ( int )
*/
int GetHighest(
XOBFVG &source[] //
)
{
//
int result = -1;
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XBoxZone tmpBoxes[];
int boxesCount = ToBox(
source,
tmpBoxes //
);
if (!IsValidSize(boxesCount))
{
//
Clean(tmpBoxes);
return result;
}
//
XBoxZone selected;
for (int i = 0; i < boxesCount; i++)
{
//
XBoxZone iBox = tmpBoxes[i];
//
bool canSet =
!selected.IsValid()
? true
: selected.upper < iBox.upper;
if (canSet)
{
//
result = i;
selected = iBox;
}
}
//
Clean(tmpBoxes);
selected.Clean();
//
return result;
}
/**
* Get Lowest Index ...
*
* @param source: XOBFVG instance Reference Collection ...
*
* @return ( int )
*/
int GetLowest(
XOBFVG &source[] //
)
{
//
int result = -1;
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XBoxZone tmpBoxes[];
int boxesCount = ToBox(
source,
tmpBoxes //
);
if (!IsValidSize(boxesCount))
{
//
Clean(tmpBoxes);
return result;
}
//
XBoxZone selected;
for (int i = 0; i < boxesCount; i++)
{
//
XBoxZone iBox = tmpBoxes[i];
//
bool canSet =
!selected.IsValid()
? true
: selected.lower > iBox.lower;
if (canSet)
{
//
result = i;
selected = iBox;
}
}
//
Clean(tmpBoxes);
selected.Clean();
//
return result;
}
bool AddIfNotExists(
XOBFVG &item,
XOBFVG &items[] //
)
{
//
bool result = false;
//
result = item.IsValid();
if (!result)
{
return result;
}
//
int before = ArraySize(items);
//
int idx = FindIndex(
item,
items //
);
bool has = IsValidIndex(idx);
result = !has;
if (!result)
{
return result;
}
//
AddRef(
item,
items //
);
//
int after = ArraySize(items);
//
result = after > before;
//
return result;
}
int AddIfNotExists(
XOBFVG &items[],
XOBFVG &sources[] //
)
{
//
int result = 0;
//
bool has = HasChild(items);
if (!has)
{
return result;
}
//
int before = ArraySize(sources);
//
int count = ArraySize(items);
for (int i = 0; i < count; i++)
{
//
has = AddIfNotExists(
items[i],
sources //
);
}
//
int after = ArraySize(sources);
//
result = after > before;
//
return result;
}
//
int DrawOBFVG(
//
XOBFVG &item,
XCBaseObject *&objects[],
//
bool drawOrderBlock = true,
bool drawFairValueGaps = true,
bool drawAllFVGs = true,
//
bool drawOBStartedBar = true,
bool drawOBActivatedBar = true,
bool drawOBBreakedBar = true,
bool drawOBWorkedBar = true,
//
bool drawFVGStartedBar = true,
bool drawFVGActivatedBar = true,
bool drawFVGBreakedBar = true,
bool drawFVGWorkedBar = true,
//
// Order Block Specs ...
//
int widthOBStartedBar = 1,
color clrOBStartedBar = clrYellow,
ENUM_LINE_STYLE styleOBStartedBar = STYLE_SOLID,
//
int widthOBActivatedBar = 1,
color clrOBActivatedBar = clrLime,
ENUM_LINE_STYLE styleOBActivatedBar = STYLE_SOLID,
//
int widthOBBreakedBar = 1,
color clrOBBreakedBar = clrRed,
ENUM_LINE_STYLE styleOBBreakedBar = STYLE_SOLID,
//
int widthOBWorkedBar = 1,
color clrOBWorkedBar = clrAqua,
ENUM_LINE_STYLE styleOBWorkedBar = STYLE_SOLID,
//
// Fair Value Gap Specs ...
//
int widthFVGStartedBar = 1,
color clrFVGStartedBar = clrYellow,
ENUM_LINE_STYLE styleFVGStartedBar = STYLE_SOLID,
//
int widthFVGActivatedBar = 1,
color clrFVGActivatedBar = clrLime,
ENUM_LINE_STYLE styleFVGActivatedBar = STYLE_SOLID,
//
int widthFVGBreakedBar = 1,
color clrFVGBreakedBar = clrRed,
ENUM_LINE_STYLE styleFVGBreakedBar = STYLE_SOLID,
//
int widthFVGWorkedBar = 1,
color clrFVGWorkedBar = clrAqua,
ENUM_LINE_STYLE styleFVGWorkedBar = STYLE_SOLID
//
)
{
//
int result = 0;
//
Clean(objects);
//
bool isValid = item.IsValid();
if (!isValid)
{
return result;
}
//
int count = 0;
bool has = false;
bool isCreated = false;
XCBaseObject *tmpObjects[];
//
// Order Block ...
has = item.HasOB();
if (has &&
drawOrderBlock)
{
//
Clean(tmpObjects);
count = DrawOrderBlock(
item.ob,
tmpObjects,
drawOBStartedBar,
drawOBActivatedBar,
drawOBBreakedBar,
drawOBWorkedBar,
widthOBStartedBar,
clrOBStartedBar,
styleOBStartedBar,
widthOBActivatedBar,
clrOBActivatedBar,
styleOBActivatedBar,
widthOBBreakedBar,
clrOBBreakedBar,
styleOBBreakedBar,
widthOBWorkedBar,
clrOBWorkedBar,
styleOBWorkedBar //
);
has = IsValidSize(count);
if (has)
{
//
Copy(
tmpObjects,
objects,
false //
);
}
}
//
// Fair Value Gap ...
if (!drawAllFVGs)
{
XCFVG *fvg;
has = item.GetMainFVG(fvg);
if (has &&
drawFairValueGaps)
{
//
Clean(tmpObjects);
int fvgsCount = DrawFairValueGap(
fvg,
tmpObjects,
drawFVGStartedBar,
drawFVGActivatedBar,
drawFVGBreakedBar,
drawFVGWorkedBar,
widthFVGStartedBar,
clrFVGStartedBar,
styleFVGStartedBar,
widthFVGActivatedBar,
clrFVGActivatedBar,
styleFVGActivatedBar,
widthFVGBreakedBar,
clrFVGBreakedBar,
styleFVGBreakedBar,
widthFVGWorkedBar,
clrFVGWorkedBar,
styleFVGWorkedBar //
);
has = IsValidSize(fvgsCount);
if (has)
{
//
Copy(
tmpObjects,
objects,
false //
);
}
}
}
else
{
//
has = item.HasFVGs();
if (has &&
drawFairValueGaps)
{
//
count = item.CountFVGs();
for (int i = 0; i < count; i++)
{
//
Clean(tmpObjects);
int fvgsCount = DrawFairValueGap(
item.fvgs[i],
tmpObjects,
drawFVGStartedBar,
drawFVGActivatedBar,
drawFVGBreakedBar,
drawFVGWorkedBar,
widthFVGStartedBar,
clrFVGStartedBar,
styleFVGStartedBar,
widthFVGActivatedBar,
clrFVGActivatedBar,
styleFVGActivatedBar,
widthFVGBreakedBar,
clrFVGBreakedBar,
styleFVGBreakedBar,
widthFVGWorkedBar,
clrFVGWorkedBar,
styleFVGWorkedBar //
);
has = IsValidSize(fvgsCount);
if (has)
{
//
Copy(
tmpObjects,
objects,
false //
);
}
}
}
}
//
Clean(tmpObjects);
//
result = ArraySize(objects);
//
return result;
}