1898 lines
47 KiB
Plaintext
1898 lines
47 KiB
Plaintext
// ///////////////////////////////////////////////////////
|
|
// //
|
|
// // SaherElm IT Center MQL5 Seriallize Library
|
|
// // ---------------------------------------
|
|
// // Name: XOBFVGLib
|
|
// // Description: All models related to POIs ...
|
|
// //
|
|
// //
|
|
// // Maintainer:
|
|
// // ------------
|
|
// // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
|
// //
|
|
// //////////////////////////////////////////////////////
|
|
// //
|
|
// // Global Properties ...
|
|
// #property library
|
|
// #property copyright "Copyright `023, SaherElm IT Center"
|
|
// #property link "https://www.saherelm.ir"
|
|
// #property version "1.00"
|
|
// #property strict
|
|
|
|
// //
|
|
// // Imports ...
|
|
// #include "../Libraries/x-saherelm.x-poi.state.lib.mq5"
|
|
|
|
// //
|
|
// 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 *fvg;
|
|
// XCOrderBlock *ob;
|
|
|
|
// //
|
|
// XCSupplyZone *supplyZones[];
|
|
// XCDemandZone *demandZones[];
|
|
|
|
// //
|
|
// XCSupportZone *supportZones[];
|
|
// XCResistanceZone *resistanceZones[];
|
|
|
|
// //
|
|
// // Constructor ...
|
|
// XOBFVG()
|
|
// {
|
|
// Clean();
|
|
// }
|
|
|
|
// //
|
|
// // Tools ...
|
|
|
|
// //
|
|
// void Clean()
|
|
// {
|
|
// //
|
|
// ZeroMemory(ob);
|
|
// ZeroMemory(fvg);
|
|
|
|
// //
|
|
// Clean(supplyZones);
|
|
// Clean(demandZones);
|
|
// Clean(supportZones);
|
|
// Clean(resistanceZones);
|
|
|
|
// //
|
|
// ZeroMemory(this);
|
|
// }
|
|
|
|
// //
|
|
// bool IsValid()
|
|
// {
|
|
// return HasOB() &&
|
|
// HasFVG();
|
|
// }
|
|
|
|
// //
|
|
// bool HasOB()
|
|
// {
|
|
// return ob != NULL &&
|
|
// ob.IsValid();
|
|
// }
|
|
|
|
// //
|
|
// bool HasFVG()
|
|
// {
|
|
// return fvg != NULL &&
|
|
// fvg.IsValid();
|
|
// }
|
|
|
|
// //
|
|
// bool HasSupplyZones()
|
|
// {
|
|
// return HasChild(supplyZones);
|
|
// }
|
|
|
|
// //
|
|
// int CountSupplyZones()
|
|
// {
|
|
// return ArraySize(supplyZones);
|
|
// }
|
|
|
|
// //
|
|
// bool HasDemandZones()
|
|
// {
|
|
// return HasChild(demandZones);
|
|
// }
|
|
|
|
// //
|
|
// int CountDemandZones()
|
|
// {
|
|
// return ArraySize(demandZones);
|
|
// }
|
|
|
|
// //
|
|
// bool HasSupportZones()
|
|
// {
|
|
// return HasChild(supportZones);
|
|
// }
|
|
|
|
// //
|
|
// int CountSupportZones()
|
|
// {
|
|
// return ArraySize(supportZones);
|
|
// }
|
|
|
|
// //
|
|
// bool HasResistanceZones()
|
|
// {
|
|
// return HasChild(resistanceZones);
|
|
// }
|
|
|
|
// //
|
|
// int CountResistanceZones()
|
|
// {
|
|
// return ArraySize(resistanceZones);
|
|
// }
|
|
|
|
// //
|
|
// 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;
|
|
// }
|
|
|
|
// //
|
|
// void UpdateZones(
|
|
// XPOIState &state //
|
|
// )
|
|
// {
|
|
// //
|
|
// Clean(supplyZones);
|
|
// Clean(demandZones);
|
|
// Clean(supportZones);
|
|
// Clean(resistanceZones);
|
|
|
|
// //
|
|
// bool isValid =
|
|
// IsValid() &&
|
|
// state.HasChild();
|
|
// if (!isValid)
|
|
// {
|
|
// return;
|
|
// }
|
|
|
|
// //
|
|
// int count = 0;
|
|
// bool has = false;
|
|
// bool isPassed = false;
|
|
|
|
// //
|
|
// // Supply Zones ...
|
|
// has = state.HasSupplyZones();
|
|
// if (has)
|
|
// {
|
|
// //
|
|
// count = state.CountSupplyZones();
|
|
// for (int i = 0; i < count; i++)
|
|
// {
|
|
// //
|
|
// XCSupplyZone *iZone = state.supplyZones[i];
|
|
|
|
// //
|
|
// isPassed = iZone.From() > ob.From();
|
|
// if (!isPassed)
|
|
// {
|
|
// //
|
|
// ZeroMemory(iZone);
|
|
// continue;
|
|
// }
|
|
|
|
// //
|
|
// isPassed = IsInsideDiff(
|
|
// iZone,
|
|
// ob //
|
|
// );
|
|
// if (!isPassed)
|
|
// {
|
|
// //
|
|
// ZeroMemory(iZone);
|
|
// continue;
|
|
// }
|
|
|
|
// //
|
|
// Add(
|
|
// iZone,
|
|
// supplyZones //
|
|
// );
|
|
// }
|
|
// }
|
|
|
|
// //
|
|
// // Demand Zones ...
|
|
// has = state.HasDemandZones();
|
|
// if (has)
|
|
// {
|
|
// //
|
|
// count = state.CountDemandZones();
|
|
// for (int i = 0; i < count; i++)
|
|
// {
|
|
// //
|
|
// XCDemandZone *iZone = state.demandZones[i];
|
|
|
|
// //
|
|
// isPassed = iZone.From() > ob.From();
|
|
// if (!isPassed)
|
|
// {
|
|
// //
|
|
// ZeroMemory(iZone);
|
|
// continue;
|
|
// }
|
|
|
|
// //
|
|
// isPassed = IsInsideDiff(
|
|
// iZone,
|
|
// ob //
|
|
// );
|
|
// if (!isPassed)
|
|
// {
|
|
// //
|
|
// ZeroMemory(iZone);
|
|
// continue;
|
|
// }
|
|
|
|
// //
|
|
// Add(
|
|
// iZone,
|
|
// demandZones //
|
|
// );
|
|
// }
|
|
// }
|
|
|
|
// //
|
|
// // Support Zones ...
|
|
// has = state.HasSupportZones();
|
|
// if (has)
|
|
// {
|
|
// //
|
|
// count = state.CountSupportZones();
|
|
// for (int i = 0; i < count; i++)
|
|
// {
|
|
// //
|
|
// XCSupportZone *iZone = state.supportZones[i];
|
|
|
|
// //
|
|
// isPassed = iZone.From() > ob.From();
|
|
// if (!isPassed)
|
|
// {
|
|
// //
|
|
// ZeroMemory(iZone);
|
|
// continue;
|
|
// }
|
|
|
|
// //
|
|
// isPassed = IsInsideDiff(
|
|
// iZone,
|
|
// ob //
|
|
// );
|
|
// if (!isPassed)
|
|
// {
|
|
// //
|
|
// ZeroMemory(iZone);
|
|
// continue;
|
|
// }
|
|
|
|
// //
|
|
// Add(
|
|
// iZone,
|
|
// supportZones //
|
|
// );
|
|
// }
|
|
// }
|
|
|
|
// //
|
|
// // Resistance Zones ...
|
|
// has = state.HasResistanceZones();
|
|
// if (has)
|
|
// {
|
|
// //
|
|
// count = state.CountResistanceZones();
|
|
// for (int i = 0; i < count; i++)
|
|
// {
|
|
// //
|
|
// XCResistanceZone *iZone = state.resistanceZones[i];
|
|
|
|
// //
|
|
// isPassed = iZone.From() > ob.From();
|
|
// if (!isPassed)
|
|
// {
|
|
// //
|
|
// ZeroMemory(iZone);
|
|
// continue;
|
|
// }
|
|
|
|
// //
|
|
// isPassed = IsInsideDiff(
|
|
// iZone,
|
|
// ob //
|
|
// );
|
|
// if (!isPassed)
|
|
// {
|
|
// //
|
|
// ZeroMemory(iZone);
|
|
// continue;
|
|
// }
|
|
|
|
// //
|
|
// Add(
|
|
// iZone,
|
|
// resistanceZones //
|
|
// );
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// //
|
|
// void UpdateTo(datetime value = NULL)
|
|
// {
|
|
// //
|
|
// value = NormalizeTime(value);
|
|
|
|
// //
|
|
// int count = 0;
|
|
// bool has = false;
|
|
|
|
// //
|
|
// has = HasOB();
|
|
// if (has)
|
|
// {
|
|
// ob.To(value);
|
|
// }
|
|
|
|
// //
|
|
// has = HasFVG();
|
|
// if (has)
|
|
// {
|
|
// fvg.To(value);
|
|
// }
|
|
|
|
// //
|
|
// // Supply Zones ...
|
|
// has = HasSupplyZones();
|
|
// if (has)
|
|
// {
|
|
// //
|
|
// count = CountSupplyZones();
|
|
// for (int i = 0; i < count; i++)
|
|
// {
|
|
// supplyZones[i].To(value);
|
|
// }
|
|
// }
|
|
|
|
// //
|
|
// // Demand Zones ...
|
|
// has = HasDemandZones();
|
|
// if (has)
|
|
// {
|
|
// //
|
|
// count = CountDemandZones();
|
|
// for (int i = 0; i < count; i++)
|
|
// {
|
|
// demandZones[i].To(value);
|
|
// }
|
|
// }
|
|
|
|
// //
|
|
// // Support Zones ...
|
|
// has = HasSupportZones();
|
|
// if (has)
|
|
// {
|
|
// //
|
|
// count = CountSupportZones();
|
|
// for (int i = 0; i < count; i++)
|
|
// {
|
|
// supportZones[i].To(value);
|
|
// }
|
|
// }
|
|
|
|
// //
|
|
// // Resistance Zones ...
|
|
// has = HasResistanceZones();
|
|
// if (has)
|
|
// {
|
|
// //
|
|
// count = CountResistanceZones();
|
|
// for (int i = 0; i < count; i++)
|
|
// {
|
|
// resistanceZones[i].To(value);
|
|
// }
|
|
// }
|
|
// }
|
|
// };
|
|
|
|
// //
|
|
// //
|
|
// //
|
|
|
|
// /**
|
|
// * Extract XOBFVG Collection of Market ...
|
|
// *
|
|
// * @param htfState: Higher Time Frame POI State (Used For Detecting Order Blocks) ...
|
|
// * @param mtfState: Medium Time Frame POI State (Used For Detecting Fair Value Gaps) ...
|
|
// * @param stfState: Short Time Frame POI State (Used For Detecting Other POI(s)) ...
|
|
// * @param dest: Result Collection ...
|
|
// * @param forDir: Market Direction for Detecting POI(s) ...
|
|
// * @param forPeriod: Time Frame which Used for Zones actions (NULL for Default) ...
|
|
// * @param startState: Zones Start State ...
|
|
// * @param forceStartedBodyOut: Zones Started Bar's Body State ...
|
|
// * @param activeState: Zones Activation State ...
|
|
// * @param forceActivatedBodyIn: Zones Activated Bar's Body State ...
|
|
// * @param breakState: Zones Breaked State ...
|
|
// * @param forceBreakedBodyOut: Zone Breaker Bar's Body State ...
|
|
// * @param workState: Zones Worked State ...
|
|
// * @param forceWorkedBodyOut: Zones Worked Bar's Body State ...
|
|
// * @param applySort: Specify Applying Sorting on Collections ...
|
|
// * @param applyFromFilter: Filter Sorted Zones based on Occured Date ...
|
|
// * @param applyPlaceFilter: Filter Sorted Zones based on Occured Place ...
|
|
// * @param ignoreInside: Ignore Inside Sides of POI(s) Zones in Related to Order Block ...
|
|
// * @param applyFromFilterForPOIs: Apply From Filter for Other POI(s) ...
|
|
// *
|
|
// * @return ( int )
|
|
// */
|
|
// int ExtractOBFVGZones(
|
|
// XPOIState &htfState,
|
|
// XPOIState &mtfState,
|
|
// XPOIState &stfState,
|
|
// XOBFVG &dest[],
|
|
// //
|
|
// ENUM_X_DIRECTION forDir,
|
|
// ENUM_TIMEFRAMES forPeriod = NULL,
|
|
// //
|
|
// // Start ...
|
|
// ENUM_XZONE_STATE startState = XZONE_STATE_PASSED,
|
|
// bool forceStartedBodyOut = false,
|
|
// //
|
|
// // Activation ...
|
|
// ENUM_XZONE_STATE activeState = XZONE_STATE_FAILED,
|
|
// bool forceActivatedBodyIn = false,
|
|
// //
|
|
// // Breaktion ...
|
|
// ENUM_XZONE_STATE breakState = XZONE_STATE_FAILED,
|
|
// bool forceBreakedBodyOut = false,
|
|
// //
|
|
// // Works ...
|
|
// ENUM_XZONE_STATE workState = XZONE_STATE_FAILED,
|
|
// bool forceWorkedBodyOut = false,
|
|
// //
|
|
// bool applySort = true,
|
|
// bool applyFromFilter = true,
|
|
// bool applyPlaceFilter = true,
|
|
// //
|
|
// bool ignoreInside = true,
|
|
// //
|
|
// bool detectInsideOBPOIs = true,
|
|
// bool detectInsideFVGPOIs = true,
|
|
// bool applyFromFilterForPOIs = true
|
|
// //
|
|
// )
|
|
// {
|
|
// //
|
|
// int result = 0;
|
|
|
|
// //
|
|
// Clean(dest);
|
|
|
|
// //
|
|
// bool isValid =
|
|
// //
|
|
// htfState.HasChild() &&
|
|
// mtfState.HasChild() &&
|
|
// stfState.HasChild() &&
|
|
// HasDirection(forDir)
|
|
// //
|
|
// ;
|
|
// if (!isValid)
|
|
// {
|
|
// return result;
|
|
// }
|
|
|
|
// //
|
|
// // Implement Logic ...
|
|
|
|
// //
|
|
// int idx = -1;
|
|
// int count = 0;
|
|
// bool has = false;
|
|
// XCFVG *tmpFVGs[];
|
|
// XOBFVG tmpOBFVGs[];
|
|
// XCOrderBlock *tmpOBs[];
|
|
// XCOrderBlock *tmpWorkingOBs[];
|
|
// datetime cTime = TimeCurrent();
|
|
// bool isBullish = IsBullish(forDir);
|
|
|
|
// //
|
|
// if (isBullish)
|
|
// {
|
|
// //
|
|
// has = htfState.HasBullishOrderBlocks();
|
|
// if (has)
|
|
// {
|
|
// //
|
|
// Copy(
|
|
// htfState.bullishOrderBlocks,
|
|
// tmpOBs //
|
|
// );
|
|
|
|
// //
|
|
// has = mtfState.HasBullishFairValueGaps();
|
|
// if (has)
|
|
// {
|
|
// //
|
|
// Copy(
|
|
// mtfState.bullishFairValueGaps,
|
|
// tmpFVGs //
|
|
// );
|
|
// }
|
|
// }
|
|
// }
|
|
// else
|
|
// {
|
|
// //
|
|
// has = htfState.HasBearishOrderBlocks();
|
|
// if (has)
|
|
// {
|
|
// //
|
|
// Copy(
|
|
// htfState.bearishOrderBlocks,
|
|
// tmpOBs //
|
|
// );
|
|
|
|
// //
|
|
// has = mtfState.HasBearishFairValueGaps();
|
|
// if (has)
|
|
// {
|
|
// //
|
|
// Copy(
|
|
// mtfState.bearishFairValueGaps,
|
|
// tmpFVGs //
|
|
// );
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// //
|
|
// count = ArraySize(tmpOBs);
|
|
// has = IsValidSize(count);
|
|
// if (has)
|
|
// {
|
|
// //
|
|
// for (int i = 0; i < count; i++)
|
|
// {
|
|
// //
|
|
// XCOrderBlock *iOB = tmpOBs[i];
|
|
|
|
// //
|
|
// // Check Started State ...
|
|
// if (startState == XZONE_STATE_PASSED ||
|
|
// startState == XZONE_STATE_FAILED)
|
|
// {
|
|
// //
|
|
// XOHCL passedBar;
|
|
// bool isBodyOut = false;
|
|
// bool isStarted = iOB.IsStarted(
|
|
// forDir,
|
|
// passedBar,
|
|
// isBodyOut,
|
|
// forPeriod //
|
|
// );
|
|
|
|
// //
|
|
// bool isPassed =
|
|
// startState == XZONE_STATE_FAILED
|
|
// ? !isStarted
|
|
// : !forceStartedBodyOut
|
|
// ? isStarted
|
|
// : isStarted &&
|
|
// isBodyOut;
|
|
|
|
// //
|
|
// passedBar.Clean();
|
|
// if (!isPassed)
|
|
// {
|
|
// continue;
|
|
// }
|
|
// }
|
|
|
|
// //
|
|
// // Check Activation State ...
|
|
// if (activeState == XZONE_STATE_PASSED ||
|
|
// activeState == XZONE_STATE_FAILED)
|
|
// {
|
|
// //
|
|
// XOHCL passedBar;
|
|
// bool isBodyIn = false;
|
|
// bool isActivated = iOB.IsActivated(
|
|
// forDir,
|
|
// passedBar,
|
|
// isBodyIn,
|
|
// forceStartedBodyOut,
|
|
// forPeriod //
|
|
// );
|
|
|
|
// //
|
|
// bool isPassed =
|
|
// activeState == XZONE_STATE_FAILED
|
|
// ? !isActivated
|
|
// : !forceActivatedBodyIn
|
|
// ? isActivated
|
|
// : isActivated &&
|
|
// isBodyIn;
|
|
|
|
// //
|
|
// passedBar.Clean();
|
|
// if (!isPassed)
|
|
// {
|
|
// continue;
|
|
// }
|
|
// }
|
|
|
|
// //
|
|
// // Check Break State ...
|
|
// if (breakState == XZONE_STATE_PASSED ||
|
|
// breakState == XZONE_STATE_FAILED)
|
|
// {
|
|
// //
|
|
// XOHCL passedBar;
|
|
// bool isBodyOut = false;
|
|
// bool isBreaked = iOB.IsBreaked(
|
|
// forDir,
|
|
// passedBar,
|
|
// isBodyOut,
|
|
// forceStartedBodyOut,
|
|
// forPeriod //
|
|
// );
|
|
|
|
// //
|
|
// bool isPassed =
|
|
// breakState == XZONE_STATE_FAILED
|
|
// ? !isBreaked
|
|
// : !forceBreakedBodyOut
|
|
// ? isBreaked
|
|
// : isBreaked &&
|
|
// isBodyOut;
|
|
|
|
// //
|
|
// passedBar.Clean();
|
|
// if (!isPassed)
|
|
// {
|
|
// continue;
|
|
// }
|
|
// }
|
|
|
|
// //
|
|
// // Check Work State ...
|
|
// if (workState == XZONE_STATE_PASSED ||
|
|
// workState == XZONE_STATE_FAILED)
|
|
// {
|
|
// //
|
|
// bool ignoreActivation = activeState != XZONE_STATE_PASSED;
|
|
|
|
// //
|
|
// XOHCL passedBar;
|
|
// bool isBodyOut = false;
|
|
// bool isWorked = iOB.IsWorked(
|
|
// forDir,
|
|
// passedBar,
|
|
// isBodyOut,
|
|
// ignoreActivation,
|
|
// forceStartedBodyOut,
|
|
// forceActivatedBodyIn,
|
|
// forPeriod //
|
|
// );
|
|
|
|
// //
|
|
// bool isPassed =
|
|
// workState == XZONE_STATE_FAILED
|
|
// ? !isWorked
|
|
// : !forceWorkedBodyOut
|
|
// ? isWorked
|
|
// : isWorked &&
|
|
// isBodyOut;
|
|
|
|
// //
|
|
// passedBar.Clean();
|
|
// if (!isPassed)
|
|
// {
|
|
// continue;
|
|
// }
|
|
// }
|
|
|
|
// //
|
|
// has = FindIndex(
|
|
// idx,
|
|
// iOB,
|
|
// tmpWorkingOBs //
|
|
// );
|
|
// if (has)
|
|
// {
|
|
// //
|
|
// ZeroMemory(iOB);
|
|
// continue;
|
|
// }
|
|
|
|
// //
|
|
// Add(
|
|
// iOB,
|
|
// tmpWorkingOBs //
|
|
// );
|
|
// }
|
|
// }
|
|
|
|
// //
|
|
// // Clean ...
|
|
// Clean(tmpOBs);
|
|
// has = HasChild(tmpWorkingOBs);
|
|
// if (has)
|
|
// {
|
|
// //
|
|
// Clean(tmpOBs);
|
|
// Copy(
|
|
// tmpWorkingOBs,
|
|
// tmpOBs //
|
|
// );
|
|
|
|
// //
|
|
// Clean(tmpWorkingOBs);
|
|
// }
|
|
|
|
// //
|
|
// // Sorting ...
|
|
// if (applySort)
|
|
// {
|
|
// //
|
|
// Clean(tmpWorkingOBs);
|
|
// has = HasChild(tmpOBs);
|
|
// count = ArraySize(tmpOBs);
|
|
|
|
// //
|
|
// // Sorting Applied Only when there is more than one item ...
|
|
// if (has && count > 1)
|
|
// {
|
|
// //
|
|
// bool hasLast = false;
|
|
// XCOrderBlock *last = NULL;
|
|
// while (HasChild(tmpOBs))
|
|
// {
|
|
// //
|
|
// // Extract First Last Item ...
|
|
// if (!hasLast)
|
|
// {
|
|
// //
|
|
// idx =
|
|
// isBullish
|
|
// ? GetLowest(tmpOBs)
|
|
// : GetHighest(tmpOBs);
|
|
// hasLast = IsValidIndex(idx);
|
|
// if (hasLast)
|
|
// {
|
|
// //
|
|
// last = tmpOBs[idx];
|
|
// ArrayRemove(
|
|
// tmpOBs,
|
|
// idx,
|
|
// 1 //
|
|
// );
|
|
|
|
// //
|
|
// Add(
|
|
// last,
|
|
// tmpWorkingOBs //
|
|
// );
|
|
// }
|
|
// }
|
|
|
|
// //
|
|
// has = false;
|
|
// XCOrderBlock *iOB = NULL;
|
|
// idx =
|
|
// isBullish
|
|
// ? GetLowest(tmpOBs)
|
|
// : GetHighest(tmpOBs);
|
|
// has = IsValidIndex(idx);
|
|
// if (has)
|
|
// {
|
|
// //
|
|
// iOB = tmpOBs[idx];
|
|
// ArrayRemove(
|
|
// tmpOBs,
|
|
// idx,
|
|
// 1 //
|
|
// );
|
|
// }
|
|
|
|
// //
|
|
// if (!has)
|
|
// {
|
|
// break;
|
|
// }
|
|
|
|
// //
|
|
// // Apply From Filter ...
|
|
// if (applyFromFilter)
|
|
// {
|
|
// //
|
|
// bool isFromPassed =
|
|
// hasLast &&
|
|
// last.From() < iOB.From();
|
|
// if (!isFromPassed)
|
|
// {
|
|
// continue;
|
|
// }
|
|
// }
|
|
|
|
// //
|
|
// // Apply Place Filter ...
|
|
// if (applyPlaceFilter)
|
|
// {
|
|
// //
|
|
// bool isAbove =
|
|
// hasLast &&
|
|
// IsAbove(
|
|
// iOB,
|
|
// last,
|
|
// ignoreInside //
|
|
// );
|
|
|
|
// //
|
|
// bool isBelow =
|
|
// hasLast &&
|
|
// IsBelow(
|
|
// iOB,
|
|
// last,
|
|
// ignoreInside //
|
|
// );
|
|
|
|
// //
|
|
// bool isPlacePassed =
|
|
// isBullish
|
|
// ? isAbove
|
|
// : isBelow;
|
|
// if (!isPlacePassed)
|
|
// {
|
|
// continue;
|
|
// }
|
|
// }
|
|
|
|
// //
|
|
// last = iOB;
|
|
// Add(
|
|
// iOB,
|
|
// tmpWorkingOBs //
|
|
// );
|
|
// }
|
|
|
|
// //
|
|
// if (hasLast &&
|
|
// !HasChild(tmpWorkingOBs))
|
|
// {
|
|
// //
|
|
// Add(
|
|
// last,
|
|
// tmpWorkingOBs //
|
|
// );
|
|
// }
|
|
// }
|
|
// else
|
|
// {
|
|
// //
|
|
// Copy(
|
|
// tmpOBs,
|
|
// tmpWorkingOBs //
|
|
// );
|
|
// }
|
|
|
|
// //
|
|
// if (HasChild(tmpWorkingOBs))
|
|
// {
|
|
// //
|
|
// Copy(
|
|
// tmpWorkingOBs,
|
|
// tmpOBs //
|
|
// );
|
|
// }
|
|
// //
|
|
// }
|
|
|
|
// //
|
|
// count = ArraySize(tmpOBs);
|
|
// has = IsValidSize(count);
|
|
|
|
// //
|
|
// // Converts to XOBFVG ...
|
|
// if (has)
|
|
// {
|
|
// //
|
|
// for (int i = 0; i < count; i++)
|
|
// {
|
|
// //
|
|
// XOBFVG iOBFVG;
|
|
|
|
// //
|
|
// iOBFVG.ob = tmpOBs[i];
|
|
|
|
// //
|
|
// AddRef(
|
|
// iOBFVG,
|
|
// tmpOBFVGs //
|
|
// );
|
|
|
|
// //
|
|
// iOBFVG.Clean();
|
|
// }
|
|
// }
|
|
|
|
// //
|
|
// Clean(dest);
|
|
// Clean(tmpOBs);
|
|
// Clean(tmpWorkingOBs);
|
|
|
|
// //
|
|
// // Here we Going to Complete XOBFVGs ...
|
|
// has = HasChild(tmpOBFVGs);
|
|
// if (has && HasChild(tmpFVGs))
|
|
// {
|
|
// //
|
|
// count = ArraySize(tmpOBFVGs);
|
|
// for (int i = 0; i < count; i++)
|
|
// {
|
|
// //
|
|
// XOBFVG iOBFVG = tmpOBFVGs[i];
|
|
|
|
// //
|
|
// // Detecting FVG ...
|
|
// XCFVG *tmpWorkingFVGs[];
|
|
// for (int j = 0; j < ArraySize(tmpFVGs); j++)
|
|
// {
|
|
// //
|
|
// XCFVG *jFVG = tmpFVGs[j];
|
|
|
|
// //
|
|
// // Check Start Date ...
|
|
// bool isFromPassed = jFVG.From() > iOBFVG.ob.From();
|
|
// if (!isFromPassed)
|
|
// {
|
|
// //
|
|
// ZeroMemory(jFVG);
|
|
// continue;
|
|
// }
|
|
|
|
// //
|
|
// // Check Place ...
|
|
|
|
// //
|
|
// bool isAbove = IsAboveDiff(
|
|
// jFVG,
|
|
// iOBFVG.ob,
|
|
// ignoreInside //
|
|
// );
|
|
|
|
// //
|
|
// bool isBelow = IsBelowDiff(
|
|
// jFVG,
|
|
// iOBFVG.ob,
|
|
// ignoreInside //
|
|
// );
|
|
|
|
// //
|
|
// bool isInside = IsInsideDiff(
|
|
// jFVG,
|
|
// iOBFVG.ob,
|
|
// false //
|
|
// );
|
|
|
|
// //
|
|
// bool isPlacePassed =
|
|
// isInside ||
|
|
// (isBullish
|
|
// ? isAbove
|
|
// : isBelow);
|
|
// if (!isPlacePassed)
|
|
// {
|
|
// //
|
|
// ZeroMemory(jFVG);
|
|
// continue;
|
|
// }
|
|
|
|
// //
|
|
// Add(
|
|
// jFVG,
|
|
// tmpWorkingFVGs //
|
|
// );
|
|
// }
|
|
|
|
// //
|
|
// int fvgsCount = ArraySize(tmpWorkingFVGs);
|
|
// has = IsValidSize(fvgsCount);
|
|
// if (has)
|
|
// {
|
|
// //
|
|
// idx =
|
|
// isBullish
|
|
// ? GetLowest(tmpWorkingFVGs)
|
|
// : GetHighest(tmpWorkingFVGs);
|
|
|
|
// //
|
|
// if (IsValidIndex(idx))
|
|
// {
|
|
// //
|
|
// XCFVG *selectedFVG = tmpWorkingFVGs[idx];
|
|
|
|
// //
|
|
// iOBFVG.fvg = selectedFVG;
|
|
|
|
// //
|
|
// bool isExists = FindIndex(
|
|
// idx,
|
|
// selectedFVG,
|
|
// tmpFVGs //
|
|
// );
|
|
// if (isExists)
|
|
// {
|
|
// //
|
|
// ArrayRemove(
|
|
// tmpFVGs,
|
|
// idx,
|
|
// 1 //
|
|
// );
|
|
// }
|
|
// }
|
|
// }
|
|
// Clean(tmpWorkingFVGs);
|
|
|
|
// //
|
|
// bool isFVGPassed = iOBFVG.HasFVG();
|
|
// if (!isFVGPassed)
|
|
// {
|
|
// //
|
|
// iOBFVG.Clean();
|
|
// continue;
|
|
// }
|
|
|
|
// //
|
|
// // Validate Model ...
|
|
// bool isValid = iOBFVG.IsValid();
|
|
// if (!isValid)
|
|
// {
|
|
// //
|
|
// iOBFVG.Clean();
|
|
// continue;
|
|
// }
|
|
|
|
// //
|
|
// iOBFVG.UpdateTo(cTime);
|
|
|
|
// //
|
|
// AddRef(
|
|
// iOBFVG,
|
|
// dest //
|
|
// );
|
|
|
|
// //
|
|
// iOBFVG.Clean();
|
|
// }
|
|
|
|
// //
|
|
// Clean(tmpOBFVGs);
|
|
// }
|
|
|
|
// //
|
|
// // Detecting Other POI(s) ...
|
|
// has = HasChild(dest);
|
|
// bool canDetectPOIs =
|
|
// detectInsideOBPOIs ||
|
|
// detectInsideFVGPOIs;
|
|
// if (has &&
|
|
// canDetectPOIs)
|
|
// {
|
|
// //
|
|
// count = ArraySize(dest);
|
|
// for (int i = 0; i < count; i++)
|
|
// {
|
|
// //
|
|
// // Supply Zones ...
|
|
// has = stfState.HasSupplyZones();
|
|
// if (has)
|
|
// {
|
|
// //
|
|
// for (int j = 0; j < stfState.CountSupplyZones(); j++)
|
|
// {
|
|
// //
|
|
// bool isInsideOB = IsInsideDiff(
|
|
// stfState.supplyZones[j],
|
|
// dest[i].ob //
|
|
// );
|
|
|
|
// //
|
|
// bool isInsideFVG = IsInsideDiff(
|
|
// stfState.supplyZones[j],
|
|
// dest[i].fvg //
|
|
// );
|
|
|
|
// //
|
|
// bool isInside = isInsideOB ||
|
|
// isInsideFVG;
|
|
// if (isInside)
|
|
// {
|
|
// //
|
|
// bool isPassed =
|
|
// detectInsideOBPOIs
|
|
// ? isInsideOB
|
|
// : detectInsideFVGPOIs
|
|
// ? isInsideFVG
|
|
// : false;
|
|
// if (isPassed)
|
|
// {
|
|
// //
|
|
// isPassed =
|
|
// !applyFromFilterForPOIs
|
|
// ? isPassed
|
|
// : isInsideOB
|
|
// ? stfState.supplyZones[j].From() > dest[i].ob.From()
|
|
// : isInsideFVG
|
|
// ? stfState.supplyZones[j].From() > dest[i].fvg.From()
|
|
// : false;
|
|
// }
|
|
|
|
// //
|
|
// if (isPassed)
|
|
// {
|
|
// //
|
|
// Add(
|
|
// stfState.supplyZones[j],
|
|
// dest[i].supplyZones //
|
|
// );
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// //
|
|
// // Demand Zones ...
|
|
// has = stfState.HasDemandZones();
|
|
// if (has)
|
|
// {
|
|
// //
|
|
// for (int j = 0; j < stfState.CountDemandZones(); j++)
|
|
// {
|
|
// //
|
|
// bool isInsideOB = IsInsideDiff(
|
|
// stfState.demandZones[j],
|
|
// dest[i].ob //
|
|
// );
|
|
|
|
// //
|
|
// bool isInsideFVG = IsInsideDiff(
|
|
// stfState.demandZones[j],
|
|
// dest[i].fvg //
|
|
// );
|
|
|
|
// //
|
|
// bool isInside = isInsideOB ||
|
|
// isInsideFVG;
|
|
// if (isInside)
|
|
// {
|
|
// //
|
|
// bool isPassed =
|
|
// detectInsideOBPOIs
|
|
// ? isInsideOB
|
|
// : detectInsideFVGPOIs
|
|
// ? isInsideFVG
|
|
// : false;
|
|
// if (isPassed)
|
|
// {
|
|
// //
|
|
// isPassed =
|
|
// !applyFromFilterForPOIs
|
|
// ? isPassed
|
|
// : isInsideOB
|
|
// ? stfState.demandZones[j].From() > dest[i].ob.From()
|
|
// : isInsideFVG
|
|
// ? stfState.demandZones[j].From() > dest[i].fvg.From()
|
|
// : false;
|
|
// }
|
|
|
|
// //
|
|
// if (isPassed)
|
|
// {
|
|
// //
|
|
// Add(
|
|
// stfState.demandZones[j],
|
|
// dest[i].demandZones //
|
|
// );
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// //
|
|
// // Support Zones ...
|
|
// has = stfState.HasSupportZones();
|
|
// if (has)
|
|
// {
|
|
// //
|
|
// for (int j = 0; j < stfState.CountSupportZones(); j++)
|
|
// {
|
|
// //
|
|
// bool isInsideOB = IsInsideDiff(
|
|
// stfState.supportZones[j],
|
|
// dest[i].ob //
|
|
// );
|
|
|
|
// //
|
|
// bool isInsideFVG = IsInsideDiff(
|
|
// stfState.supportZones[j],
|
|
// dest[i].fvg //
|
|
// );
|
|
|
|
// //
|
|
// bool isInside = isInsideOB ||
|
|
// isInsideFVG;
|
|
// if (isInside)
|
|
// {
|
|
// //
|
|
// bool isPassed =
|
|
// detectInsideOBPOIs
|
|
// ? isInsideOB
|
|
// : detectInsideFVGPOIs
|
|
// ? isInsideFVG
|
|
// : false;
|
|
// if (isPassed)
|
|
// {
|
|
// //
|
|
// isPassed =
|
|
// !applyFromFilterForPOIs
|
|
// ? isPassed
|
|
// : isInsideOB
|
|
// ? stfState.supportZones[j].From() > dest[i].ob.From()
|
|
// : isInsideFVG
|
|
// ? stfState.supportZones[j].From() > dest[i].fvg.From()
|
|
// : false;
|
|
// }
|
|
|
|
// //
|
|
// if (isPassed)
|
|
// {
|
|
// //
|
|
// Add(
|
|
// stfState.supportZones[j],
|
|
// dest[i].supportZones //
|
|
// );
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// //
|
|
// // Resistance Zones ...
|
|
// has = stfState.HasResistanceZones();
|
|
// if (has)
|
|
// {
|
|
// //
|
|
// for (int j = 0; j < stfState.CountResistanceZones(); j++)
|
|
// {
|
|
// //
|
|
// bool isInsideOB = IsInsideDiff(
|
|
// stfState.resistanceZones[j],
|
|
// dest[i].ob //
|
|
// );
|
|
|
|
// //
|
|
// bool isInsideFVG = IsInsideDiff(
|
|
// stfState.resistanceZones[j],
|
|
// dest[i].fvg //
|
|
// );
|
|
|
|
// //
|
|
// bool isInside = isInsideOB ||
|
|
// isInsideFVG;
|
|
// if (isInside)
|
|
// {
|
|
// //
|
|
// bool isPassed =
|
|
// detectInsideOBPOIs
|
|
// ? isInsideOB
|
|
// : detectInsideFVGPOIs
|
|
// ? isInsideFVG
|
|
// : false;
|
|
// if (isPassed)
|
|
// {
|
|
// //
|
|
// isPassed =
|
|
// !applyFromFilterForPOIs
|
|
// ? isPassed
|
|
// : isInsideOB
|
|
// ? stfState.resistanceZones[j].From() > dest[i].ob.From()
|
|
// : isInsideFVG
|
|
// ? stfState.resistanceZones[j].From() > dest[i].fvg.From()
|
|
// : false;
|
|
// }
|
|
|
|
// //
|
|
// if (isPassed)
|
|
// {
|
|
// //
|
|
// Add(
|
|
// stfState.resistanceZones[j],
|
|
// dest[i].resistanceZones //
|
|
// );
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// //
|
|
// Clean(tmpOBs);
|
|
// Clean(tmpFVGs);
|
|
// Clean(tmpOBFVGs);
|
|
|
|
// //
|
|
// result = ArraySize(dest);
|
|
|
|
// //
|
|
// return result;
|
|
// }
|
|
|
|
// /**
|
|
// * Find Highest Order Block of XOBFVG Collection ...
|
|
// *
|
|
// * @param source: XOBFVG Collection ...
|
|
// *
|
|
// * @return ( int )
|
|
// */
|
|
// int GetHighest(
|
|
// XOBFVG &source[] //
|
|
// )
|
|
// {
|
|
// //
|
|
// int result = -1;
|
|
|
|
// //
|
|
// int count = ArraySize(source);
|
|
// bool has = IsValidSize(count);
|
|
// if (!has)
|
|
// {
|
|
// return result;
|
|
// }
|
|
|
|
// //
|
|
// XOBFVG item;
|
|
// for (int i = 0; i < count; i++)
|
|
// {
|
|
// //
|
|
// XOBFVG iOBFVG = source[i];
|
|
|
|
// //
|
|
// bool canSet =
|
|
// !item.IsValid()
|
|
// ? true
|
|
// : item.ob.Upper() < iOBFVG.ob.Upper();
|
|
// if (canSet)
|
|
// {
|
|
// //
|
|
// item = iOBFVG;
|
|
// result = i;
|
|
// }
|
|
|
|
// //
|
|
// iOBFVG.Clean();
|
|
// }
|
|
|
|
// //
|
|
// item.Clean();
|
|
|
|
// //
|
|
// return result;
|
|
// }
|
|
|
|
// /**
|
|
// * Find Lowest Order Block of XOBFVG Collection ...
|
|
// *
|
|
// * @param source: XOBFVG Collection ...
|
|
// *
|
|
// * @return ( int )
|
|
// */
|
|
// int GetLowest(
|
|
// XOBFVG &source[] //
|
|
// )
|
|
// {
|
|
// //
|
|
// int result = -1;
|
|
|
|
// //
|
|
// int count = ArraySize(source);
|
|
// bool has = IsValidSize(count);
|
|
// if (!has)
|
|
// {
|
|
// return result;
|
|
// }
|
|
|
|
// //
|
|
// XOBFVG item;
|
|
// for (int i = 0; i < count; i++)
|
|
// {
|
|
// //
|
|
// XOBFVG iOBFVG = source[i];
|
|
|
|
// //
|
|
// bool canSet =
|
|
// !item.IsValid()
|
|
// ? true
|
|
// : item.ob.Lower() > iOBFVG.ob.Lower();
|
|
// if (canSet)
|
|
// {
|
|
// //
|
|
// item = iOBFVG;
|
|
// result = i;
|
|
// }
|
|
|
|
// //
|
|
// iOBFVG.Clean();
|
|
// }
|
|
|
|
// //
|
|
// item.Clean();
|
|
|
|
// //
|
|
// return result;
|
|
// }
|
|
|
|
// /**
|
|
// * Find Youngest Order Block of XOBFVG Collection ...
|
|
// *
|
|
// * @param source: XOBFVG Collection ...
|
|
// *
|
|
// * @return ( int )
|
|
// */
|
|
// int GetYoungest(
|
|
// XOBFVG &source[] //
|
|
// )
|
|
// {
|
|
// //
|
|
// int result = -1;
|
|
|
|
// //
|
|
// int count = ArraySize(source);
|
|
// bool has = IsValidSize(count);
|
|
// if (!has)
|
|
// {
|
|
// return result;
|
|
// }
|
|
|
|
// //
|
|
// XOBFVG item;
|
|
// for (int i = 0; i < count; i++)
|
|
// {
|
|
// //
|
|
// XOBFVG iOBFVG = source[i];
|
|
|
|
// //
|
|
// bool canSet =
|
|
// !item.IsValid()
|
|
// ? true
|
|
// : item.ob.From() < iOBFVG.ob.From();
|
|
// if (canSet)
|
|
// {
|
|
// //
|
|
// item = iOBFVG;
|
|
// result = i;
|
|
// }
|
|
|
|
// //
|
|
// iOBFVG.Clean();
|
|
// }
|
|
|
|
// //
|
|
// item.Clean();
|
|
|
|
// //
|
|
// return result;
|
|
// }
|
|
|
|
// /**
|
|
// * Find Oldest Order Block of XOBFVG Collection ...
|
|
// *
|
|
// * @param source: XOBFVG Collection ...
|
|
// *
|
|
// * @return ( int )
|
|
// */
|
|
// int GetOldest(
|
|
// XOBFVG &source[] //
|
|
// )
|
|
// {
|
|
// //
|
|
// int result = -1;
|
|
|
|
// //
|
|
// int count = ArraySize(source);
|
|
// bool has = IsValidSize(count);
|
|
// if (!has)
|
|
// {
|
|
// return result;
|
|
// }
|
|
|
|
// //
|
|
// XOBFVG item;
|
|
// for (int i = 0; i < count; i++)
|
|
// {
|
|
// //
|
|
// XOBFVG iOBFVG = source[i];
|
|
|
|
// //
|
|
// bool canSet =
|
|
// !item.IsValid()
|
|
// ? true
|
|
// : item.ob.From() > iOBFVG.ob.From();
|
|
// if (canSet)
|
|
// {
|
|
// //
|
|
// item = iOBFVG;
|
|
// result = i;
|
|
// }
|
|
|
|
// //
|
|
// iOBFVG.Clean();
|
|
// }
|
|
|
|
// //
|
|
// item.Clean();
|
|
|
|
// //
|
|
// return result;
|
|
// }
|
|
|
|
// /**
|
|
// * Sort XOBFVG Collection based on OB Place ...
|
|
// *
|
|
// * @param source: XOBFVG instance Collection ...
|
|
// * @param forDir: ENUM_X_DIRECTION member ...
|
|
// * @param ignoreInside: Specified Ignoring price inside in Sorting ...
|
|
// */
|
|
// void Sort(
|
|
// XOBFVG &source[],
|
|
// ENUM_X_DIRECTION forDir,
|
|
// bool ignoreInside = true //
|
|
// )
|
|
// {
|
|
// //
|
|
// int idx = -1;
|
|
// int count = 0;
|
|
// bool has = false;
|
|
|
|
// //
|
|
// has = HasDirection(forDir);
|
|
// if (!has)
|
|
// {
|
|
// return;
|
|
// }
|
|
|
|
// //
|
|
// bool isBullish = IsBullish(forDir);
|
|
|
|
// //
|
|
// count = ArraySize(source);
|
|
// has = IsValidSize(count);
|
|
// if (!has)
|
|
// {
|
|
// return;
|
|
// }
|
|
|
|
// //
|
|
// XOBFVG last;
|
|
// XOBFVG tmpItems[];
|
|
// bool hasLast = false;
|
|
// while (HasChild(source))
|
|
// {
|
|
// //
|
|
// if (!hasLast)
|
|
// {
|
|
// //
|
|
// idx = GetOldest(source);
|
|
// hasLast = IsValidIndex(idx);
|
|
// if (hasLast)
|
|
// {
|
|
// //
|
|
// last = source[idx];
|
|
// ArrayRemove(
|
|
// source,
|
|
// idx,
|
|
// 1 //
|
|
// );
|
|
|
|
// //
|
|
// AddRef(
|
|
// last,
|
|
// tmpItems //
|
|
// );
|
|
// }
|
|
|
|
// //
|
|
// count = ArraySize(source);
|
|
// has = IsValidSize(count);
|
|
// if (!has)
|
|
// {
|
|
// //
|
|
// last.Clean();
|
|
// break;
|
|
// }
|
|
// }
|
|
// if (!hasLast)
|
|
// {
|
|
// //
|
|
// last.Clean();
|
|
// break;
|
|
// }
|
|
|
|
// //
|
|
// XOBFVG item;
|
|
// idx = GetOldest(source);
|
|
// has = IsValidIndex(idx);
|
|
// if (!has)
|
|
// {
|
|
// //
|
|
// item.Clean();
|
|
// last.Clean();
|
|
// break;
|
|
// }
|
|
// item = source[idx];
|
|
// ArrayRemove(
|
|
// source,
|
|
// idx,
|
|
// 1 //
|
|
// );
|
|
|
|
// //
|
|
// bool isAbove = IsAbove(
|
|
// item.ob,
|
|
// last.ob,
|
|
// ignoreInside //
|
|
// );
|
|
|
|
// //
|
|
// bool isBelow = IsBelow(
|
|
// item.ob,
|
|
// last.ob,
|
|
// ignoreInside //
|
|
// );
|
|
|
|
// //
|
|
// has =
|
|
// isBullish
|
|
// ? isAbove
|
|
// : isBelow;
|
|
// if (has)
|
|
// {
|
|
// //
|
|
// AddRef(
|
|
// item,
|
|
// tmpItems //
|
|
// );
|
|
|
|
// //
|
|
// last = item;
|
|
// hasLast = item.IsValid();
|
|
// }
|
|
// }
|
|
|
|
// //
|
|
// Clean(source);
|
|
// Copy(
|
|
// tmpItems,
|
|
// source //
|
|
// );
|
|
|
|
// //
|
|
// Clean(tmpItems);
|
|
// }
|
|
|
|
// //
|