/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Seriallize Library // --------------------------------------- // Name: XPOILib // 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.lib.mq5" // // Extensions ... template bool ToBox( T *&source[], XBoxZone &dest[] // ) { // bool result = false; // Clean(dest); // int count = ArraySize(source); result = IsValidSize(count); if (!result) { return result; } // for (int i = 0; i < count; i++) { // T *item = source[i]; // if (item != NULL) { // XBoxZone iBox; bool hasBox = ToBox( iBox, item // ); // if (hasBox) { // AddRef( iBox, dest // ); } } } // int destCount = ArraySize(dest); result = IsValidSize(destCount); // return result; } template int GetOldest( T *&source[] // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone boxes[]; bool isConverted = ToBox( source, boxes // ); if (!isConverted) { return result; } // int boxesCount = ArraySize(boxes); // if (count != boxesCount) { return result; } // result = GetOldest(boxes); // Clean(boxes); // return result; } template int GetYoungest( T *&source[] // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone boxes[]; bool isConverted = ToBox( source, boxes // ); if (!isConverted) { return result; } // int boxesCount = ArraySize(boxes); // if (count != boxesCount) { return result; } // result = GetYoungest(boxes); // Clean(boxes); // return result; } template int GetLowest( T *&source[] // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone boxes[]; bool isConverted = ToBox( source, boxes // ); if (!isConverted) { return result; } // int boxesCount = ArraySize(boxes); // if (count != boxesCount) { return result; } // result = GetLowest(boxes); // Clean(boxes); // return result; } template int GetHighest( T *&source[] // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone boxes[]; bool isConverted = ToBox( source, boxes // ); if (!isConverted) { return result; } // int boxesCount = ArraySize(boxes); // if (count != boxesCount) { return result; } // result = GetHighest(boxes); // Clean(boxes); // return result; } template bool IsSame( T *source, T *dest // ) { // bool result = false; // XBoxZone sourceBox; result = ToBox( sourceBox, source // ); if (!result) { return result; } // XBoxZone destBox; result = ToBox( destBox, dest // ); if (!result) { return result; } // result = sourceBox.IsSameAs(destBox); // return result; } template bool IsBelow( T *source, T *dest, bool ignoreInside = false // ) { // bool result = false; // XBoxZone sourceBox; result = ToBox( sourceBox, source // ); if (!result) { return result; } // XBoxZone destBox; result = ToBox( destBox, dest // ); if (!result) { return result; } // result = IsBoxBelow( sourceBox, destBox, ignoreInside // ); // return result; } template bool IsAbove( T *source, T *dest, bool ignoreInside = false // ) { // bool result = false; // XBoxZone sourceBox; result = ToBox( sourceBox, source // ); if (!result) { return result; } // XBoxZone destBox; result = ToBox( destBox, dest // ); if (!result) { return result; } // result = IsBoxAbove( sourceBox, destBox, ignoreInside // ); // return result; } template bool IsInside( T *source, T *dest // ) { // bool result = false; // XBoxZone sourceBox; result = ToBox( sourceBox, source // ); if (!result) { return result; } // XBoxZone destBox; result = ToBox( destBox, dest // ); if (!result) { return result; } // result = IsBoxInside( sourceBox, destBox // ); // return result; } template bool IsInsideOr( T *source, T *dest // ) { // bool result = false; // XBoxZone sourceBox; result = ToBox( sourceBox, source // ); if (!result) { return result; } // XBoxZone destBox; result = ToBox( destBox, dest // ); if (!result) { return result; } // result = IsBoxInsideOr( sourceBox, destBox // ); // return result; } template bool FindIndex( int &index, T *item, T *&items[] // ) { // bool result = false; // index = -1; // XBoxZone itemBox; result = ToBox( itemBox, item // ); if (!result) { return result; } // XBoxZone itemsBox[]; result = ToBox( items, itemsBox // ); if (!result) { return result; } // result = FindBoxIndex( index, itemBox, itemsBox // ); // return result; } template bool IsInside( double value, T *source // ) { // bool result = false; // XBoxZone sourceBox; result = ToBox( sourceBox, source // ); if (!result) { return result; } // result = IsInsideBox( value, sourceBox // ); // return result; } template bool IsAbove( double value, T *source // ) { // bool result = false; // XBoxZone sourceBox; result = ToBox( sourceBox, source // ); if (!result) { return result; } // result = IsAboveBox( value, sourceBox // ); // return result; } template bool IsBelow( double value, T *source // ) { // bool result = false; // XBoxZone sourceBox; result = ToBox( sourceBox, source // ); if (!result) { return result; } // result = IsBelowBox( value, sourceBox // ); // return result; } /** * Find Specified Box Index inside a Collection of Boxes ... * * @param box: XBoxZone instance Reference ... * @param boxes: XBoxZone instance Reference Collection ... * * @return ( int ) */ bool FindBoxIndex( int &index, XBoxZone &box, XBoxZone &boxes[] // ) { // bool result = false; // index = -1; // int count = ArraySize(boxes); result = box.IsValid() && IsValidSize(count); if (!result) { return result; } // for (int i = 0; i < count; i++) { // XBoxZone iBox = boxes[i]; // bool isSame = box.IsSameAs(iBox); if (isSame) { // index = i; break; } } // result = IsValidIndex(index); // return result; } /** * Check a BaxHas Valid Place for Specified Bar ... * * @param bar: XOHCL instance reference, Specified Bar ... * #param box: XBoxZone instance reference, Specified Box ... * * @return ( bool ) */ bool IsBoxPlaceValidForBar( XOHCL &bar, XBoxZone &box // ) { // bool result = false; // result = bar.IsValid() && box.IsValid(); if (!result) { return result; } // result = box.IsBullish() ? bar.low > box.upper : bar.high < box.upper; // return result; } /** * Check Source Box is Below Dest ... * * @param source: XBoxZone instance Reference ... * @param dest: XBoxZone instance Reference ... * @param ignoreInside: bool ... * * @return ( bool ) */ bool IsBoxBelow( XBoxZone &source, XBoxZone &dest, bool ignoreInside = false // ) { // bool result = false; // result = source.IsValid() && dest.IsValid() && !source.IsSameAs(dest); if (!result) { return result; } // if (!ignoreInside) { result = source.upper < dest.lower; } else { result = (source.upper < dest.lower || source.upper >= dest.upper) && source.lower < dest.lower; } // return result; } /** * Check Source Box is Above Dest ... * * @param source: XBoxZone instance Reference ... * @param dest: XBoxZone instance Reference ... * @param ignoreInside: bool ... * * @return ( bool ) */ bool IsBoxAbove( XBoxZone &source, XBoxZone &dest, bool ignoreInside = false // ) { // bool result = false; // result = source.IsValid() && dest.IsValid() && !source.IsSameAs(dest); if (!result) { return result; } // if (!ignoreInside) { result = source.lower > dest.upper; } else { result = (source.lower > dest.upper || source.lower <= dest.upper) && source.upper > dest.upper; } // return result; } /** * Check Source Box is Inside Dest ... * * @param source: XBoxZone instance Reference ... * @param dest: XBoxZone instance Reference ... * @param forceSideOut: bool, force check Box has One Side Out ... * @param ignoreSideOut: bool, Accept if source Box one Side is out of Dest Box ... * * @return ( bool ) */ bool IsBoxInside( XBoxZone &source, XBoxZone &dest, bool forceSideOut = false, // bool ignoreSideOut = true // ) { // bool result = false; // result = source.IsValid() && dest.IsValid() && !source.IsSameAs(dest); if (!result) { return result; } // bool isBullish = IsBullish(dest.dir); // if (!forceSideOut) { // if (ignoreSideOut) { // result = source.lower >= dest.lower && source.upper <= dest.upper; } else { result = source.lower >= dest.lower || source.upper <= dest.upper; } } else { // bool hasSideIn = isBullish ? source.lower >= dest.lower : source.upper <= dest.upper; bool hasSideOut = isBullish ? source.upper >= dest.upper : source.lower <= dest.lower; result = hasSideIn && hasSideOut; } // return result; } /** * Detect source BoX is Inside Dest Box or Have a Side Out on it ... * * @param source: XBoxZone instance, source box which checks by dest ... * @param dest: XBoxZone instance, dest Box which compares source with it ... * * @return ( bool ) */ bool IsBoxInsideOr( XBoxZone &source, XBoxZone &dest, bool forceInside = false // ) { // bool result = false; // result = source.IsValid() && dest.IsValid() && !source.IsSameAs(dest); if (!result) { return result; } // bool isInside = source.upper <= dest.upper && source.upper >= dest.lower && source.lower >= dest.lower && source.lower <= dest.upper; bool isUpperInside = source.upper <= dest.upper && source.upper >= dest.lower; bool isLowerInside = source.lower >= dest.lower && source.lower <= dest.upper; // result = forceInside ? isInside : (isInside || isLowerInside || isUpperInside); // return result; } /** * Check Value is Inside Specified Box ... * * @param value: double ... * @param box: XCBozZone instance Reference ... * * @return ( bool ) */ bool IsInsideBox( double value, XBoxZone &box // ) { // bool result = false; // result = value > 0 && box.IsValid() && value <= box.upper && value >= box.lower; // return result; } /** * Check Bar is Inside Specified Box ... * * @param bar: XOHCL instance reference, Specified Bar ... * @param box: XCBozZone instance Reference ... * * @return ( bool ) */ bool IsInsideBox( XOHCL &bar, XBoxZone &box // ) { // bool result = false; // // Validate Args ... result = bar.IsValid() && box.IsValid(); if (!result) { return result; } // result = bar.close <= box.upper && bar.close >= box.lower; // return result; } /** * Check Value is Above Specified Box ... * * @param value: double ... * @param box: XCBozZone instance Reference ... * * @return ( bool ) */ bool IsAboveBox( double value, XBoxZone &box // ) { // bool result = false; // result = value > 0 && box.IsValid() && value > box.upper; // return result; } /** * Check Value is Below Specified Box ... * * @param value: double ... * @param box: XCBozZone instance Reference ... * * @return ( bool ) */ bool IsBelowBox( double value, XBoxZone &box // ) { // bool result = false; // result = value > 0 && box.IsValid() && value < box.lower; // return result; } /** * Check a Box is Used or not ... * * @param box: XBoxZone instance Reference ... * @param fromIndex: int ... * @param toIndex: int * @param forPeriod: Specified Period ... * * @return ( bool ) */ bool IsBoxUsed( XBoxZone &box, int fromIndex, int toIndex = 0, ENUM_TIMEFRAMES forPeriod = NULL // ) { // bool result = false; // if (toIndex < 0) { toIndex = 0; } // result = // box.IsValid() && fromIndex > 0 && fromIndex > toIndex // ; if (!result) { return result; } // if (!IsValid(forPeriod)) { forPeriod = box.period; } // ENUM_X_DIRECTION forDir = box.dir; bool isBullish = IsBullish(forDir); // bool isTouched = false; for (int i = fromIndex; i >= toIndex; i--) { // XOHCL iBar; bool isInited = iBar.Init( box.symbol, forPeriod, i // ); // isTouched = isInited && (isBullish ? iBar.low > box.upper : iBar.high < box.lower); if (!isTouched) { continue; } // iBar.Clean(); break; } // result = isTouched; // return result; } /** * Validate Box ... * * @param box: XBoxZone instance ... * @param barIndex: int, Current Bar Index ... * @param forPeriod: Testing Period ... * * @return ( bool ) */ bool IsBoxValid( XBoxZone &box, int barIndex = 0, ENUM_TIMEFRAMES forPeriod = NULL // ) { // bool result = false; // result = box.IsValid(); if (!result) { return result; } // if (barIndex < 0) { barIndex = 0; } // if (!IsValid(forPeriod)) { forPeriod = box.period; } // int toIndex = iBarShift( box.symbol, forPeriod, box.to // ); result = IsValidIndex(toIndex); if (!result) { return result; } // XOHCL iBar; bool isBullish = box.IsBullish(); for (int i = barIndex; i < toIndex; i++) { // result = iBar.Init( box.symbol, forPeriod, i // ); if (!result) { break; } // result = isBullish ? iBar.low > box.upper : iBar.high < box.lower; if (!result) { break; } // iBar.Clean(); } // iBar.Clean(); // return result; } /** * Check Box Breaked ... * * @param box: XBoxZone instance ... * @param barIndex: int, Current Bar Index ... * @param forPeriod: Testing Period ... * * @return ( bool ) */ bool IsBoxBreaked( XBoxZone &box, int barIndex = 0, ENUM_TIMEFRAMES forPeriod = NULL // ) { // bool result = false; // result = box.IsValid(); if (!result) { return result; } // if (barIndex < 0) { barIndex = 0; } // if (!IsValid(forPeriod)) { forPeriod = box.period; } // int toIndex = iBarShift( box.symbol, forPeriod, box.to // ); result = IsValidIndex(toIndex); if (!result) { return result; } // XOHCL iBar; bool isBullish = box.IsBullish(); for (int i = barIndex; i < toIndex; i++) { // result = iBar.Init( box.symbol, forPeriod, i // ); if (!result) { break; } // result = isBullish ? iBar.high < box.lower : iBar.low > box.upper; if (!result) { break; } // iBar.Clean(); } // iBar.Clean(); // return result; } /** * Check a Box is Breaked or not ... * * @param box: XBoxZone instance Reference ... * @param fromIndex: int ... * @param toIndex: int * @param forPeriod: Specified Period ... * * @return ( bool ) */ bool IsBoxBreaked( XBoxZone &box, int fromIndex, int toIndex = 0, ENUM_TIMEFRAMES forPeriod = NULL // ) { // bool result = false; // if (toIndex < 0) { toIndex = 0; } // result = // box.IsValid() && fromIndex > 0 && fromIndex > toIndex // ; if (!result) { return result; } // if (!IsValid(forPeriod)) { forPeriod = box.period; } // ENUM_X_DIRECTION forDir = box.dir; bool isBullish = IsBullish(forDir); // bool isBreaked = false; for (int i = fromIndex; i >= toIndex; i--) { // XOHCL iBar; bool isInited = iBar.Init( box.symbol, forPeriod, i // ); // isBreaked = isInited && (isBullish ? iBar.high <= box.lower : iBar.low >= box.upper); if (!isBreaked) { continue; } // iBar.Clean(); break; } // result = isBreaked; // return result; } /** * Find an Inside Box of source in a Collection ... * * @param index: int, Founded Index ... * @param source: XBoxZone instance ... * @param dest: XBoxZone instance Collection ... * * @return ( bool ) */ bool HasInsideBox( int &index, XBoxZone &source, XBoxZone &dest[] // ) { // bool result = false; // index = -1; // result = source.IsValid() && HasChild(dest); // int count = ArraySize(dest); for (int i = 0; i < count; i++) { // XBoxZone iBox = dest[i]; // bool isInside = !iBox.IsSameAs(source) && IsBoxInsideOr( iBox, source // ); if (isInside) { // index = i; iBox.Clean(); // break; } // iBox.Clean(); } // result = IsValidIndex(index); // return result; } /** * Remove Specified Box from Collection ... */ bool RemoveBox( XBoxZone &box, XBoxZone &boxes[] // ) { // bool result = false; // result = box.IsValid() && HasChild(boxes); if (!result) { return result; } // int idx = -1; result = FindBoxIndex( idx, box, boxes // ); if (!result) { return result; } // result = ArrayRemove( boxes, idx, 1 // ); // return result; } /** * Get Oldest Box Index ... * * @param source: XBoxZone instance Reference Collection ... * * @return ( int ) */ int GetOldest( XBoxZone &source[] // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone selected; for (int i = 0; i < count; i++) { // XBoxZone iBox = source[i]; // bool canSet = !selected.IsValid() ? true : selected.from > iBox.from; if (canSet) { // result = i; selected = iBox; } // iBox.Clean(); } // selected.Clean(); // return result; } int GetOldest( XOHCL &bar, XBoxZone &source[] // ) { // int result = -1; // if (!bar.IsValid()) { return result; } // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone selected; for (int i = 0; i < count; i++) { // XBoxZone iBox = source[i]; // bool isBoxValidForBar = IsBoxPlaceValidForBar(bar, iBox); if (!isBoxValidForBar) { // iBox.Clean(); // continue; } // bool canSet = !selected.IsValid() ? true : selected.from > iBox.from; if (canSet) { // result = i; selected = iBox; } // iBox.Clean(); } // selected.Clean(); // return result; } /** * Get Youngest Box Index ... * * @param source: XBoxZone instance Reference Collection ... * * @return ( int ) */ int GetYoungest( XBoxZone &source[] // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone selected; for (int i = 0; i < count; i++) { // XBoxZone iBox = source[i]; // bool canSet = !selected.IsValid() ? true : selected.from < iBox.from; if (canSet) { // result = i; selected = iBox; } // iBox.Clean(); } // selected.Clean(); // return result; } int GetYoungest( XOHCL &bar, XBoxZone &source[] // ) { // int result = -1; // if (!bar.IsValid()) { return result; } // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone selected; for (int i = 0; i < count; i++) { // XBoxZone iBox = source[i]; // bool isBoxValidForBar = IsBoxPlaceValidForBar(bar, iBox); if (!isBoxValidForBar) { // iBox.Clean(); // continue; } // bool canSet = !selected.IsValid() ? true : selected.from < iBox.from; if (canSet) { // result = i; selected = iBox; } // iBox.Clean(); } // selected.Clean(); // return result; } /** * Get Highest Box Index ... * * @param source: XBoxZone instance Reference Collection ... * * @return ( int ) */ int GetHighest( XBoxZone &source[] // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone selected; for (int i = 0; i < count; i++) { // XBoxZone iBox = source[i]; // bool canSet = !selected.IsValid() ? true : selected.upper < iBox.upper; if (canSet) { // result = i; selected = iBox; } // iBox.Clean(); } // selected.Clean(); // return result; } int GetHighest( XOHCL &bar, XBoxZone &source[] // ) { // int result = -1; // if (!bar.IsValid()) { return result; } // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone selected; for (int i = 0; i < count; i++) { // XBoxZone iBox = source[i]; // bool isBoxValidForBar = IsBoxPlaceValidForBar(bar, iBox); if (!isBoxValidForBar) { // iBox.Clean(); // continue; } // bool canSet = !selected.IsValid() ? true : selected.upper < iBox.upper; if (canSet) { // result = i; selected = iBox; } // iBox.Clean(); } // selected.Clean(); // return result; } /** * Get Lowest Box Index ... * * @param source: XBoxZone instance Reference Collection ... * * @return ( int ) */ int GetLowest( XBoxZone &source[] // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone selected; for (int i = 0; i < count; i++) { // XBoxZone iBox = source[i]; // bool canSet = !selected.IsValid() ? true : selected.lower > iBox.lower; if (canSet) { // result = i; selected = iBox; } // iBox.Clean(); } // selected.Clean(); // return result; } int GetLowest( XOHCL &bar, XBoxZone &source[] // ) { // int result = -1; // if (!bar.IsValid()) { return result; } // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone selected; for (int i = 0; i < count; i++) { // XBoxZone iBox = source[i]; // bool isBoxValidForBar = IsBoxPlaceValidForBar(bar, iBox); if (!isBoxValidForBar) { // iBox.Clean(); // continue; } // bool canSet = !selected.IsValid() ? true : selected.lower > iBox.lower; if (canSet) { // result = i; selected = iBox; } // iBox.Clean(); } // selected.Clean(); // return result; } // // // // template void SortZones( T *&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; } // T *tmpItems[]; T *last = NULL; bool hasLast = false; while (HasChild(source)) { // if (!hasLast) { // idx = GetOldest(source); hasLast = IsValidIndex(idx); if (hasLast) { // last = source[idx]; ArrayRemove( source, idx, 1 // ); // Add( last, tmpItems // ); } // count = ArraySize(source); has = IsValidSize(count); if (!has) { // ZeroMemory(last); break; } } if (!hasLast) { // ZeroMemory(last); break; } // T *item = NULL; idx = GetOldest(source); has = IsValidIndex(idx); if (!has) { // ZeroMemory(last); ZeroMemory(item); break; } item = source[idx]; ArrayRemove( source, idx, 1 // ); // bool isAbove = IsAbove( item, last, ignoreInside // ); // bool isBelow = IsBelow( item, last, ignoreInside // ); // has = isBullish ? isAbove : isBelow; if (has) { // Add( item, tmpItems // ); // last = item; hasLast = item != NULL; } } // Clean(source); Copy( tmpItems, source // ); // Clean(tmpItems); } /** * Extract all Zones Which provided bar is Inside it ... * * @return ( int ) */ template int ExtractInsideZones( XOHCL &bar, // Bar ... T *&zones[], // Source of Zones ... T *&dest[] // Dest (all inside Zones) ... ) { // int result = 0; // Clean(dest); // int count = ArraySize(zones); bool isValid = bar.IsValid() && IsValidSize(count); if (!isValid) { return result; } // for (int i = 0; i < count; i++) { // T *iZone = zones[i]; // bool isHighInside = IsInside( bar.high, iZone // ); // bool isLowInside = IsInside( bar.low, iZone // ); // bool isInside = isLowInside && isHighInside; // if (isInside) { // Add( iZone, dest // ); } // ZeroMemory(iZone); } // result = ArraySize(dest); // return result; } /** * Add Specific Item into a Collection Reference only if it's not Exists ... * * @return ( bool ) */ template bool AddIfNotExists( T *item, T *&items[] // ) { // bool result = false; // result = item != NULL; if (!result) { return result; } // int before = ArraySize(items); // int idx = FindIndex( item, items // ); bool has = IsValidIndex(idx); result = !has; if (!result) { return result; } // Add( item, items // ); // int after = ArraySize(items); // result = after > before; // return result; } bool AddIfNotExists( XConsolidationZone &item, XConsolidationZone &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; } /** * Add items Collection reference Members into source Collection only if it's not Exists ...alignas * @return ( int ) */ template int AddIfNotExists( T *&items[], T *&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 AddIfNotExists( XConsolidationZone &items[], XConsolidationZone &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; } /** * Update to Time of Specifiex Collection ... * * @param items: XOBFVG instance Collection ... * @param value: datetime ... */ template void SpecifiedUpdateTo( T *&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].To(value); } } //