/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Indicator // ------------------------------------------------- // Name: X121 X3MA // Description: X3MA ... // // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://saherelm.ir" #property version "1.00" #property description "SaherElm X121 X3MA Indicator" #property strict // // Definitions ... // #define ShortName "X121 XCZone" // // Includes Common Library ... #include "../Classes/x-saherelm.x-bar.analyser.class.mq5" #include "../Classes/x-saherelm.x-poi.drawer.class.mq5" #include "../Libraries/x-saherelm.common.lib.mq5" #include "../Libraries/x-saherelm.x-poi.lib.mq5" // // Inputs ... input group "Market"; input int minZoneLength = 7; // Minimum Length of Consolidation Zone input double maxZoneRangeInPoints = 0; // Max Zone Range in Point input ENUM_X_PERIOD_METHOD trendPeriodMethod = X_PERIOD_AUTO; // How to Find Trend Period input ENUM_TIMEFRAMES trendPeriod = NULL; // Trend Time Period input ENUM_MA_METHOD trendMode = MODE_SMA; // Trend Mode input ENUM_APPLIED_PRICE trendAppliedTo = PRICE_CLOSE; // Trend Applied To input double sarStep = 0.02; // Sar Step input double sarMax = 0.2; // Sar Maximum // // Filtering ... input group "Filtering"; input bool filterBasedOnSar = true; // Filter Pivots Based on Sar input bool filterBasedOnTrend = false; // Filter Pivots Based on Trend // // Presentation ... input group "Presentation"; input bool showUpper = true; // Show Upper input bool showLower = true; // Show Lower input bool showTrend = false; // Show Trend input bool showSar = false; // Show Sar // input int startCalculationForLastBars = 1000; // Calculate Last n Bars int sarArrowCode = 159; // Sar Arrow Code int upperArrowCode = 117; // Upper Arrow Code int lowerArrowCode = 117; // Lower Arrow Code // // Buffers ... // #define hideColorIDX 0 #define bullishColorIDX 1 #define bearishColorIDX 2 #define neuturalColorIDX 3 // #define bullishState 1 #define neuturalState 0 #define bearishState -1 // #define emptyValue 0.0 // #property indicator_chart_window // #property indicator_buffers 8 #property indicator_plots 4 // // Plot Buffers ... // // UPPER ... // #define upperBufferIndex 0 double upperBuffer[]; // #property indicator_label1 "X121 Upper" #property indicator_type1 DRAW_ARROW #property indicator_color1 clrOrange #property indicator_style1 STYLE_SOLID #property indicator_width1 2 // // LOWER ... // #define lowerBufferIndex 1 double lowerBuffer[]; // #property indicator_label2 "X121 Lower" #property indicator_type2 DRAW_ARROW #property indicator_color2 clrOrange #property indicator_style2 STYLE_DASHDOTDOT #property indicator_width2 2 // // TREND ... // #define trendBufferIndex 2 #define trendBufferPlotIndex 2 double trendBuffer[]; // #define trendColorBufferIndex 3 double trendColorBuffer[]; // #property indicator_label3 "X121 Trend" #property indicator_type3 DRAW_COLOR_LINE #property indicator_color3 CLR_NONE, clrAqua, clrMagenta, clrGray #property indicator_style3 STYLE_DASH #property indicator_width3 2 // // SAR ... // #define sarBufferIndex 4 #define sarBufferPlotIndex 3 double sarBuffer[]; // #define sarColorBufferIndex 5 double sarColorBuffer[]; // #property indicator_label4 "X121 SAR" #property indicator_type4 DRAW_COLOR_ARROW #property indicator_color4 CLR_NONE, clrAqua, clrMagenta, clrGray #property indicator_width4 2 // // Data Buffers ... #define mLastBufferIndex 5 // #define trendStateBufferIndex mLastBufferIndex + 1 double trendStateBuffer[]; // #define sarStateBufferIndex mLastBufferIndex + 2 double sarStateBuffer[]; // // Variables, Properties and etc ... // int limit; // int maxLength; // XCPOIDrawer *drawer; CArrayObj mObjects; XCBarAnalyser *barAnalyser; int mTrendPeriodLength = 0; int sarHandler = INVALID_HANDLE; int trendHandler = INVALID_HANDLE; ENUM_TIMEFRAMES mTrendPeriod = NULL; // // Event Handlers ... /** * Initialize Indicator ... * * @return ( int ) */ int OnInit() { // // Validate Inputs ... if (!ValidateInputs()) { return INIT_PARAMETERS_INCORRECT; } // // Initialize Indicator Handlers ... // drawer = new XCPOIDrawer(); barAnalyser = new XCBarAnalyser(); // // Initializing TrendPeriod ... int cPeriodSeconds = PeriodSeconds(_Period); if (trendPeriodMethod == X_PERIOD_AUTO) { // // Select Period ... mTrendPeriod = GetCyclePeriod( X_MARKET_CYCLE_HIND, _Period // ); } else { mTrendPeriod = trendPeriod; } if (IsValid(mTrendPeriod)) { mTrendPeriodLength = PeriodSeconds(mTrendPeriod) / cPeriodSeconds; } // // SAR ... sarHandler = iSAR( _Symbol, _Period, sarStep, sarMax // ); bool isInited = sarHandler != INVALID_HANDLE; if (!isInited) { return INIT_FAILED; } // // TREND ... trendHandler = iMA( _Symbol, _Period, mTrendPeriodLength, 0, trendMode, trendAppliedTo // ); isInited = trendHandler != INVALID_HANDLE; if (!isInited) { return INIT_FAILED; } // // because in some cases we may have more than one input for // calculation and we must prevent any calculation // untill we pass the biggest input length, here we get max Input length // and then wait until pass it ... maxLength = ExtractMaxLengthOfInputs(); // // Define Index Buffers ... DefineBuffers(); // // Set Indicator ShortName ... SetIndicatorName(); // // Init Succeed ... return INIT_SUCCEEDED; } /** * De Initialize Indicator ... * * @param reason: Integer, De Initialization Reason ... */ void OnDeinit(const int reason) { // // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function // REASON_REMOVE 1 Program removed from a chart // REASON_RECOMPILE 2 Program recompiled // REASON_CHARTCHANGE 3 A symbol or a chart period is changed // REASON_CHARTCLOSE 4 Chart closed // REASON_PARAMETERS 5 Inputs changed by a user // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings // REASON_TEMPLATE 7 Another chart template applied // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value // REASON_CLOSE 9 Terminal closed // mObjects.Clear(); ZeroMemory(drawer); ZeroMemory(barAnalyser); // IndicatorRelease(sarHandler); IndicatorRelease(trendHandler); } /** * Calculate Bars ... * * @param rates_total: Integer, Total Bars on Chart ... * @param prev_calculated: Integer, Total Calculated Bars on Charts ... * @param time: DateTime Array, History of Open Time ... * @param open: Double Array, History of Open Prices ... * @param high: Double Array, History of High Prices ... * @param low: Double Array, History of Low Prices ... * @param close: Double Array, History of Close Prices ... * @param tick_volume: Long, History of Tick Volumes on Bar ... * @param volume: Long, History of Trade Volumes ... * @param spread: Double, History of Spread Price ... * * @return ( int ) */ int OnCalculate( const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[] // ) { // // Prepare Buffers ... ArraySetAsSeries(time, true); ArraySetAsSeries(open, true); ArraySetAsSeries(high, true); ArraySetAsSeries(low, true); ArraySetAsSeries(close, true); ArraySetAsSeries(tick_volume, true); ArraySetAsSeries(volume, true); ArraySetAsSeries(spread, true); // // Validate Calculated Bars ... // // SAR ... int sarCalculatedBars = BarsCalculated(sarHandler); // // TREND ... int trendCalculatedBars = BarsCalculated(trendHandler); // bool isPassedRequiredCalculatedBars = // // SAR ... sarCalculatedBars >= maxLength && // // TREND ... trendCalculatedBars >= maxLength // ; if (!isPassedRequiredCalculatedBars) { return prev_calculated; } // limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; // // Buffers Copy ... // // SAR ... int copiedSars = CopyBuffer(sarHandler, 0, 0, limit, sarBuffer); // // TREND ... int copiedTrends = CopyBuffer(trendHandler, MAIN_LINE, 0, limit + 1, trendBuffer); // // Validate Copied Items ... bool isPassedRequiredCopiedItems = // // SAR ... copiedSars >= limit && // // TREND ... copiedTrends >= limit // ; if (!isPassedRequiredCopiedItems) { return prev_calculated; } // // Main Loop ... for (int i = limit - 1; i >= 0 && !IsStopped(); i--) { // CalculateBuffers( i, prev_calculated, rates_total, // open, high, close, low, tick_volume // ); } // return rates_total; } // // Functions ... /** * Validate Input Args for Initialization ... * * @return ( bool ) */ bool ValidateInputs() { // bool result = false; // result = // sarMax > 0 && sarStep > 0 && sarMax > sarStep && minZoneLength > 2 && IsValid(trendPeriodMethod, trendPeriod) // ; // return result; } /** * Extract Max Length of Inputs ... * * @return ( int ) */ int ExtractMaxLengthOfInputs() { // int result = 0; // result = MathMax(minZoneLength, result); // return result; } /** * Define Required Buffers ... */ void DefineBuffers() { // // Plot Buffers ... // // UPPER ... // ENUM_DRAW_TYPE upperDrawType = showUpper ? DRAW_ARROW : DRAW_NONE; // ArraySetAsSeries(upperBuffer, true); SetIndexBuffer(upperBufferIndex, upperBuffer, INDICATOR_DATA); // PlotIndexSetInteger(upperBufferIndex, PLOT_SHOW_DATA, showUpper); PlotIndexSetInteger(upperBufferIndex, PLOT_DRAW_TYPE, upperDrawType); // PlotIndexSetDouble(upperBufferIndex, PLOT_EMPTY_VALUE, emptyValue); PlotIndexSetInteger(upperBufferIndex, PLOT_ARROW, upperArrowCode); // // LOWER ... // ENUM_DRAW_TYPE lowerDrawType = showLower ? DRAW_ARROW : DRAW_NONE; // ArraySetAsSeries(lowerBuffer, true); SetIndexBuffer(lowerBufferIndex, lowerBuffer, INDICATOR_DATA); // PlotIndexSetInteger(lowerBufferIndex, PLOT_SHOW_DATA, showLower); PlotIndexSetInteger(lowerBufferIndex, PLOT_DRAW_TYPE, lowerDrawType); // PlotIndexSetDouble(lowerBufferIndex, PLOT_EMPTY_VALUE, emptyValue); PlotIndexSetInteger(lowerBufferIndex, PLOT_ARROW, lowerArrowCode); // // TREND ... // ArraySetAsSeries(trendBuffer, true); SetIndexBuffer(trendBufferIndex, trendBuffer, INDICATOR_DATA); // PlotIndexSetInteger(trendBufferPlotIndex, PLOT_SHOW_DATA, showTrend); // PlotIndexSetDouble(trendBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); // ArraySetAsSeries(trendColorBuffer, true); SetIndexBuffer(trendColorBufferIndex, trendColorBuffer, INDICATOR_COLOR_INDEX); // // SAR ... // ArraySetAsSeries(sarBuffer, true); SetIndexBuffer(sarBufferIndex, sarBuffer, INDICATOR_DATA); // PlotIndexSetInteger(sarBufferPlotIndex, PLOT_SHOW_DATA, showSar); // PlotIndexSetDouble(sarBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); PlotIndexSetInteger(sarBufferPlotIndex, PLOT_ARROW, sarArrowCode); // ArraySetAsSeries(sarColorBuffer, true); SetIndexBuffer(sarColorBufferIndex, sarColorBuffer, INDICATOR_COLOR_INDEX); // // Data Buffers ... // ArraySetAsSeries(trendStateBuffer, true); SetIndexBuffer(trendStateBufferIndex, trendStateBuffer, INDICATOR_CALCULATIONS); // ArraySetAsSeries(sarStateBuffer, true); SetIndexBuffer(sarStateBufferIndex, sarStateBuffer, INDICATOR_CALCULATIONS); } /** * Set Indicator Short Name and also we can define Buffers Labels ... */ void SetIndicatorName() { // IndicatorSetInteger(INDICATOR_DIGITS, _Digits); IndicatorSetString(INDICATOR_SHORTNAME, ShortName); } /** * Calculate Custom Buffers ... * * @param bar_index: Integer, Represent Current Bar ... * @param prevCalculated: Integer, Represent Previous Calculated Bars ... * @param ratesTotal: Integer, Represents All Available Bars ... * @param open: Double Array, History of Open Prices ... * @param high: Double Array, History of High Prices ... * @param close: Double Array, History of Close Prices ... * @param low: Double Array, History of Low Prices ... * @param tickVolume: Long, History of Tick Volumes on Bar ... */ void CalculateBuffers( int bar_index, // Selected Bar Index const int prevCalculated, const int ratesTotal, const double &open[], const double &high[], const double &close[], const double &low[], const long &tickVolume[] // ) { // int barsLimit = startCalculationForLastBars > 0 ? startCalculationForLastBars : 0; // // bool canCalculate = true; bool canCalculate = barsLimit == 0 || bar_index <= barsLimit; if (canCalculate) { // // Calculate Values ... CalculateValues( bar_index, prevCalculated, ratesTotal, open, high, close, low, tickVolume // ); } else { FillBuffersZero(bar_index); } } /** * Fill All Bufers to Zero Vlue for Specified Bar Index ... * * @param barIndex: Integer ... */ void FillBuffersZero(int barIndex) { // // UPPER ... upperBuffer[barIndex] = emptyValue; // // LOWER ... lowerBuffer[barIndex] = emptyValue; // // SAR ... sarBuffer[barIndex] = emptyValue; sarColorBuffer[barIndex] = hideColorIDX; sarStateBuffer[barIndex] = neuturalState; // // TREND ... trendBuffer[barIndex] = emptyValue; trendColorBuffer[barIndex] = hideColorIDX; trendStateBuffer[barIndex] = neuturalState; } /** * Calculate Values ... * * @param bar_index: int, Specified Bar Index ... * @param prevCalculated: int, Provides Previous Calculated Bars ... * @param ratesTotal: int, Provides All Availabled Bars ... * @param open: double Collection, Provides Open Prices Time Series ... * @param high: double Collection, Provides High Prices Time Series ... * @param close: double Collection, Provides Close Prices Time Series ... * @param low: double Collection, Provides Low Prices Time Series ... * @param tickVolume: long Collection, Provides Ticks Volume Prices Time Series ... */ void CalculateValues( int bar_index, // Selected Bar Index const int prevCalculated, const int ratesTotal, const double &open[], const double &high[], const double &close[], const double &low[], const long &tickVolume[] // ) { // // Check Prev Bar ... // int lastBarIndex = bar_index + 1; int maxBarIndex = startCalculationForLastBars > 0 ? startCalculationForLastBars : ratesTotal; bool isFirstBar = bar_index == maxBarIndex; // double iLow = high[bar_index]; double iHigh = high[bar_index]; double iClose = close[bar_index]; // double points = GetPoints(_Symbol); // // Calculate Sar Color Buffer ... double iSar = sarBuffer[bar_index]; // double iSarState = neuturalState; double iSarColor = neuturalColorIDX; if (iLow > iSar) { // iSarState = bullishState; iSarColor = !showSar ? hideColorIDX : bullishColorIDX; } else if (iHigh < iSar) { // iSarState = bearishState; iSarColor = !showSar ? hideColorIDX : bearishColorIDX; } sarStateBuffer[bar_index] = iSarState; sarColorBuffer[bar_index] = iSarColor; // // Calculate Trend Color Buffer ... double iTrend = trendBuffer[bar_index]; // double iTrendState = neuturalState; double iTrendColor = neuturalColorIDX; if (iClose > iTrend) { // iTrendState = bullishState; iTrendColor = !showTrend ? hideColorIDX : bullishColorIDX; } else if (iClose < iTrend) { // iTrendState = bearishState; iTrendColor = !showTrend ? hideColorIDX : bearishColorIDX; } trendStateBuffer[bar_index] = iTrendState; trendColorBuffer[bar_index] = iTrendColor; // // Prevent Calculation ... if (maxBarIndex - bar_index < minZoneLength) { return; } // // Detect Consolidation Zone ... XOHCL iBar; bool has = iBar.Init( _Symbol, _Period, bar_index // ); if (!has) { return; } // // Checking Base Zone Exists ... XBoxZone iZone; has = barAnalyser.IsOB( iBar, iZone, true, // Force FVG Bar Type ... true // Force Two Bar ... ); if (!has) { // iBar.Clean(); iZone.Clean(); } bool isBullish = has && iZone.IsBullish(); bool isBearish = has && iZone.IsBearish(); // // Apply Max Range ... has = maxZoneRangeInPoints > 0; if (has) { // double range = iZone.GetRange(); has = range <= maxZoneRangeInPoints * points; if (!has) { // iBar.Clean(); iZone.Clean(); } } // XOHCL iPBar; has = iBar.GetPreviousBar(iPBar); if (!has) { // iBar.Clean(); iPBar.Clean(); iZone.Clean(); // return; } // // Ensure we Have Order Block ... ENUM_X_DIRECTION iDir; // // Validate FVG Gap Candle Breakeout by Body ... // // Check iPBar is Momentum Bar ... has = barAnalyser.IsMomentum( iPBar, iDir // ); bool isBullishMomentum = has && IsBullish(iDir); bool isBearishMomentum = has && IsBearish(iDir); // bool isBullishBreakedOut = isBullish && iPBar.IsBullish() && isBullishMomentum && iPBar.GetUp() > iZone.upper && iPBar.GetDown() < iZone.upper; // bool isBearishBreakedOut = isBearish && iPBar.IsBearish() && isBearishMomentum && iPBar.GetUp() > iZone.lower && iPBar.GetDown() < iZone.lower; // has = isBullishBreakedOut || isBearishBreakedOut; if (!has) { // iBar.Clean(); iPBar.Clean(); iZone.Clean(); // return; } // // Check Has Proper Swing ... // bool isIBarSimpleSwing = barAnalyser.IsSimpleSwing( iBar, iDir // ); bool isIBarBullishSimpleSwing = isIBarSimpleSwing && IsBullish(iDir); bool isIBarBearishSimpleSwing = isIBarSimpleSwing && IsBearish(iDir); // bool isIPBarSimpleSwing = barAnalyser.IsSimpleSwing( iPBar, iDir // ); bool isIPBarBullishSimpleSwing = isIPBarSimpleSwing && IsBullish(iDir); bool isIPBarBearishSimpleSwing = isIPBarSimpleSwing && IsBearish(iDir); // bool isBullishSwimpleSwing = isBullish && (isIBarBullishSimpleSwing || isIPBarBullishSimpleSwing); // bool isBearishSwimpleSwing = isBearish && (isIBarBearishSimpleSwing || isIPBarBearishSimpleSwing); // has = isBullishSwimpleSwing || isBearishSwimpleSwing; if (!has) { // iBar.Clean(); iPBar.Clean(); iZone.Clean(); // return; } // int toIDX = iZone.ToIndex(); int fromIDX = iZone.FromIndex(); // // Retrieve Box From Bar ... XOHCL fromBar; has = iZone.FromBar(fromBar); if (!has) { // iBar.Clean(); iPBar.Clean(); iZone.Clean(); fromBar.Clean(); // return; } // // Retrieve Highest High and Lowest Low ... double ll = fromBar.FindLowest(minZoneLength, MODE_LOW); double hh = fromBar.FindHighest(minZoneLength, MODE_HIGH); // // Validate Directional Based HH/LL Passed ... // bool isBullishLLPassed = isBullish && ll >= iZone.lower; // bool isBearishHHPassed = isBearish && hh <= iZone.upper; // has = isBullishLLPassed || isBearishHHPassed; if (!has) { // iBar.Clean(); iPBar.Clean(); iZone.Clean(); fromBar.Clean(); // return; } // // Update Zone From ... datetime iFrom = GetBarTime( _Symbol, _Period, fromBar.Index() + minZoneLength // ); iZone.from = iFrom; // // Apply Filters ... has = filterBasedOnSar || filterBasedOnTrend; if (has) { // // Retrieve Indexes ... int iBarIndex = iBar.Index(); int ipBarIndex = iPBar.Index(); int iBarPrevIndex = iBarIndex + 1; int ipBarPrevIndex = ipBarIndex + 1; // // Apply Using Sar ... if (filterBasedOnSar) { // double iSarState = sarStateBuffer[iBarIndex]; double iPSarState = sarStateBuffer[ipBarIndex]; double iSarPrevState = sarStateBuffer[iBarPrevIndex]; double iPSarPrevState = sarStateBuffer[ipBarPrevIndex]; // bool isISarBullish = iSarState > 0; bool isIPSarBullish = iPSarState > 0; bool isISarPrevBullish = iSarPrevState > 0; bool isIPSarPrevBullish = iPSarPrevState > 0; // bool isISarBearish = iSarState < 0; bool isIPSarBearish = iPSarState < 0; bool isISarPrevBearish = iSarPrevState < 0; bool isIPSarPrevBearish = iPSarPrevState < 0; // bool isISarSwitchedToBullish = isISarBullish && !isISarPrevBullish; bool isISarSwitchedToBearish = isISarBearish && !isISarPrevBearish; // bool isIPSarSwitchedToBullish = isIPSarBullish && !isIPSarPrevBullish; bool isIPSarSwitchedToBearish = isIPSarBearish && !isIPSarPrevBearish; // // Check iPBar (Gap Bar which Breaks Edge and is a Momentum Bar) is Sar Change Bar ... // bool isBullishSarFiltered = isBullish && (isISarSwitchedToBullish || isIPSarSwitchedToBullish); // bool isBearishSarFiltered = isBearish && (isISarSwitchedToBearish || isIPSarSwitchedToBearish); // has = isBullishSarFiltered || isBearishSarFiltered; if (!has) { // iBar.Clean(); iPBar.Clean(); iZone.Clean(); fromBar.Clean(); // return; } } // // Apply Using Trend ... if (filterBasedOnTrend) { // double iBarTrendState = trendStateBuffer[iBarIndex]; double iBarPrevTrendState = trendStateBuffer[iBarPrevIndex]; // double iPBarTrendState = trendStateBuffer[ipBarIndex]; double iPBarPrevTrendState = trendStateBuffer[ipBarPrevIndex]; // bool isIBarTrendBullish = iBarTrendState > 0; bool isIBarPrevTrendBullish = iBarPrevTrendState > 0; // bool isIBarTrendBearish = iBarTrendState < 0; bool isIBarPrevTrendBearish = iBarPrevTrendState < 0; // bool isITrendSwitchedToBullish = isIBarTrendBullish && !isIBarPrevTrendBullish; bool isITrendSwitchedToBearish = isIBarTrendBearish && !isIBarPrevTrendBearish; // bool isIPBarTrendBullish = iPBarTrendState > 0; bool isIPBarPrevTrendBullish = iPBarPrevTrendState > 0; // bool isIPBarTrendBearish = iPBarTrendState < 0; bool isIPBarPrevTrendBearish = iPBarPrevTrendState < 0; // bool isIPTrendSwitchedToBullish = isIPBarTrendBullish && !isIPBarPrevTrendBullish; bool isIPTrendSwitchedToBearish = isIPBarTrendBearish && !isIPBarPrevTrendBearish; // // Check iPBar (Gap Bar which Breaks Edge and is a Momentum Bar) is Trend Change Bar ... // bool isBullishTrendFiltered = isBullish && (isITrendSwitchedToBullish || isIPTrendSwitchedToBullish); // bool isBearishTrendFiltered = isBearish && (isITrendSwitchedToBearish || isIPTrendSwitchedToBearish); // has = isBullishTrendFiltered || isBearishTrendFiltered; if (!has) { // iBar.Clean(); iPBar.Clean(); iZone.Clean(); fromBar.Clean(); // return; } } } // // Fill Buffers Based on Object ... toIDX = iZone.ToIndex(); fromIDX = iZone.FromIndex(); for (int i = fromIDX; i > toIDX; i--) { // upperBuffer[i] = iZone.upper; lowerBuffer[i] = iZone.lower; } // // Draw Object ... XCBoxObject *iZoneObj; has = drawer.DrawBox( iZone, iZoneObj // ); if (has) { mObjects.Add(iZoneObj); } ZeroMemory(iZoneObj); // // Cleanup Resources ... // iBar.Clean(); iPBar.Clean(); iZone.Clean(); } //