/// <summary>
 /// Public constructor
 /// </summary>
 public IndicatorComp()
 {
     compName           = "Not defined";
     dataType           = IndComponentType.NotDefined;
     chartType          = IndChartType.NoChart;
     chartColor         = Color.Red;
     firstBar           = 0;
     previous           = 0;
     isDynInfo          = true;
     values             = new double[] { };
     posPriceDependence = PositionPriceDependence.None;
 }
 /// <summary>
 /// Public constructor
 /// </summary>
 public IndicatorComp()
 {
     compName   = "Not defined";
     dataType   = IndComponentType.NotDefined;
     chartType  = IndChartType.NoChart;
     chartColor = Color.Red;
     firstBar   = 0;
     previous   = 0;
     isDynInfo  = true;
     values     = new double[] { };
     posPriceDependence = PositionPriceDependence.None;
 }
示例#3
0
        /// <summary>
        /// Prepare the parameters
        /// </summary>
        public void SetUpChart()
        {
            // Panel caption
            stringCaptionText                  = Language.T("Indicator Chart");
            fontCaptionText                    = new Font(Font.FontFamily, 9);
            captionHeight                      = Math.Max(fontCaptionText.Height, 18);
            captionWidth                       = this.ClientSize.Width;
            brushCaptionText                   = new SolidBrush(LayoutColors.ColorCaptionText);
            rectfCaption                       = new RectangleF(0, 0, captionWidth, captionHeight);
            stringFormatCaption                = new StringFormat();
            stringFormatCaption.Alignment     |= StringAlignment.Center;
            stringFormatCaption.LineAlignment |= StringAlignment.Center;
            stringFormatCaption.Trimming      |= StringTrimming.EllipsisCharacter;
            stringFormatCaption.FormatFlags   |= StringFormatFlags.NoWrap;

            if (!Data.IsData || !Data.IsResult || Data.Bars <= Data.FirstBar)
            {
                return;
            }

            clSzWidth  = this.ClientSize.Width;
            clSzHeight = this.ClientSize.Height;
            xLeft      = space;
            xRight     = clSzWidth - space;
            yTop       = (int)captionHeight + space;
            yBottom    = clSzHeight - scrollBar.Height - space;
            yPrcBottom = yBottom; // Price chart y
            inds       = 0;       // Count of separated indicators
            indHeight  = 0;       // Height of Ind charts
            aiIndSlot  = new int[12];

            penFore   = new Pen(LayoutColors.ColorChartFore);
            penVolume = new Pen(LayoutColors.ColorVolume);
            penBorder = new Pen(Data.GetGradientColor(LayoutColors.ColorCaptionBack, -LayoutColors.DepthCaption), border);

            for (int slot = Data.Strategy.Slots - 1; slot >= 0; slot--)
            {
                if (Data.Strategy.Slot[slot].SeparatedChart)
                {
                    aiIndSlot[inds++] = slot;
                }
            }

            if (inds > 0)
            {
                indHeight  = (yBottom - yTop) / (2 + inds);
                yPrcBottom = yBottom - inds * indHeight;
            }

            maxPrice  = double.MinValue;
            minPrice  = double.MaxValue;
            maxVolume = int.MinValue;

            for (int bar = firstBar; bar <= lastBar; bar++)
            {
                if (Data.High[bar] > maxPrice)
                {
                    maxPrice = Data.High[bar];
                }
                if (Data.Low[bar] < minPrice)
                {
                    minPrice = Data.Low[bar];
                }
                if (Data.Volume[bar] > maxVolume)
                {
                    maxVolume = Data.Volume[bar];
                }
            }
            minPrice  = Math.Round(minPrice, Data.InstrProperties.Point < 0.001 ? 3 : 1) - Data.InstrProperties.Point * 10;
            maxPrice  = Math.Round(maxPrice, Data.InstrProperties.Point < 0.001 ? 3 : 1) + Data.InstrProperties.Point * 10;
            scaleY    = (yPrcBottom - yTop) / (maxPrice - minPrice);
            scaleYVol = maxVolume > 0 ? ((yPrcBottom - yTop) / 8d) / maxVolume : 0d;

            // Volume, Lots and Price
            x             = new int[chartBars];
            yOpen         = new int[chartBars];
            yHigh         = new int[chartBars];
            yLow          = new int[chartBars];
            yClose        = new int[chartBars];
            yVolume       = new int[chartBars];
            rectPosition  = new Rectangle[chartBars];
            brushPosition = new Brush[chartBars];

            int index = 0;

            for (int bar = firstBar; bar <= lastBar; bar++)
            {
                x[index]       = (bar - firstBar) * barPixels + xLeft;
                yOpen[index]   = (int)(yPrcBottom - (Data.Open[bar] - minPrice) * scaleY);
                yHigh[index]   = (int)(yPrcBottom - (Data.High[bar] - minPrice) * scaleY);
                yLow[index]    = (int)(yPrcBottom - (Data.Low[bar] - minPrice) * scaleY);
                yClose[index]  = (int)(yPrcBottom - (Data.Close[bar] - minPrice) * scaleY);
                yVolume[index] = (int)(yPrcBottom - Data.Volume[bar] * scaleYVol);

                // Draw position lots
                if (Backtester.IsPos(bar))
                {
                    int iPosHight = (int)(Math.Max(Backtester.SummaryLots(bar) * 2, 2));

                    int iPosY = yPrcBottom - iPosHight;

                    if (Backtester.SummaryDir(bar) == PosDirection.Long)
                    {   // Long
                        rectPosition[index]  = new Rectangle(x[index], iPosY, 1, iPosHight);
                        brushPosition[index] = new SolidBrush(LayoutColors.ColorTradeLong);
                    }
                    else if (Backtester.SummaryDir(bar) == PosDirection.Short)
                    {   // Short
                        rectPosition[index]  = new Rectangle(x[index], iPosY, 1, iPosHight);
                        brushPosition[index] = new SolidBrush(LayoutColors.ColorTradeShort);
                    }
                    else
                    {   // Close position
                        rectPosition[index]  = new Rectangle(x[index], iPosY - 2, 1, 2);
                        brushPosition[index] = new SolidBrush(LayoutColors.ColorTradeClose);
                    }
                }
                else
                {   // There is no position
                    rectPosition[index]  = Rectangle.Empty;
                    brushPosition[index] = new SolidBrush(LayoutColors.ColorChartBack);
                }
                index++;
            }

            // Indicators in the chart
            slots             = Data.Strategy.Slots;
            bIsSeparatedChart = new bool[slots];
            iComponentLenght  = new int[slots];
            chartType         = new IndChartType[slots][];
            chartLine         = new Point[slots][][];
            chartDot          = new Rectangle[slots][][];
            chartLevel        = new Rectangle[slots][][];
            chartValue        = new double[slots][][];
            chartPen          = new Pen[slots][][];
            chartBrush        = new Brush[slots][];
            for (int iSlot = 0; iSlot < slots; iSlot++)
            {
                bIsSeparatedChart[iSlot] = Data.Strategy.Slot[iSlot].SeparatedChart;
                int iLenght = Data.Strategy.Slot[iSlot].Component.Length;
                iComponentLenght[iSlot] = iLenght;
                chartType[iSlot]        = new IndChartType[iLenght];
                chartLine[iSlot]        = new Point[iLenght][];
                chartDot[iSlot]         = new Rectangle[iLenght][];
                chartLevel[iSlot]       = new Rectangle[iLenght][];
                chartValue[iSlot]       = new double[iLenght][];
                chartPen[iSlot]         = new Pen[iLenght][];
                chartBrush[iSlot]       = new Brush[iLenght];
            }

            for (int slot = 0; slot < slots; slot++)
            {
                if (bIsSeparatedChart[slot])
                {
                    continue;
                }

                for (int comp = 0; comp < iComponentLenght[slot]; comp++)
                {
                    chartType[slot][comp] = Data.Strategy.Slot[slot].Component[comp].ChartType;
                    if (Data.Strategy.Slot[slot].Component[comp].ChartType == IndChartType.Line ||
                        Data.Strategy.Slot[slot].Component[comp].ChartType == IndChartType.CloudUp ||
                        Data.Strategy.Slot[slot].Component[comp].ChartType == IndChartType.CloudDown)
                    {   // Line
                        chartBrush[slot][comp] = new SolidBrush(Data.Strategy.Slot[slot].Component[comp].ChartColor);
                        chartLine[slot][comp]  = new Point[lastBar - firstBar + 1];
                        for (int bar = firstBar; bar <= lastBar; bar++)
                        {
                            double dValue = Data.Strategy.Slot[slot].Component[comp].Value[bar];
                            int    ix     = (bar - firstBar) * barPixels + xLeft;
                            int    iy     = (int)(yPrcBottom - (dValue - minPrice) * scaleY);

                            if (dValue == 0)
                            {
                                chartLine[slot][comp][bar - firstBar] = chartLine[slot][comp][Math.Max(bar - firstBar - 1, 0)];
                            }
                            else
                            {
                                chartLine[slot][comp][bar - firstBar] = new Point(ix, iy);
                            }
                        }
                    }
                    else if (Data.Strategy.Slot[slot].Component[comp].ChartType == IndChartType.Dot)
                    {   // Dots
                        chartBrush[slot][comp] = new SolidBrush(Data.Strategy.Slot[slot].Component[comp].ChartColor);
                        chartDot[slot][comp]   = new Rectangle[lastBar - firstBar + 1];
                        for (int bar = firstBar; bar <= lastBar; bar++)
                        {
                            double dValue = Data.Strategy.Slot[slot].Component[comp].Value[bar];
                            int    ix     = (bar - firstBar) * barPixels + xLeft;
                            int    iy     = (int)(yPrcBottom - (dValue - minPrice) * scaleY);
                            chartDot[slot][comp][bar - firstBar] = new Rectangle(ix, iy, 1, 1);
                        }
                    }
                    else if (Data.Strategy.Slot[slot].Component[comp].ChartType == IndChartType.Level)
                    {   // Level
                        chartBrush[slot][comp] = new SolidBrush(Data.Strategy.Slot[slot].Component[comp].ChartColor);
                        chartLevel[slot][comp] = new Rectangle[lastBar - firstBar + 1];
                        for (int bar = firstBar; bar <= lastBar; bar++)
                        {
                            double dValue = Data.Strategy.Slot[slot].Component[comp].Value[bar];
                            int    ix     = (bar - firstBar) * barPixels + xLeft;
                            int    iy     = (int)(yPrcBottom - (dValue - minPrice) * scaleY);
                            chartLevel[slot][comp][bar - firstBar] = new Rectangle(ix, iy, barPixels, 1);
                        }
                    }
                }
            }

            // Separate indicators
            yIndTop    = new int[inds];
            yIndBottom = new int[inds];
            dMaxValue  = new double[inds];
            dMinValue  = new double[inds];
            dScale     = new double[inds];
            for (int ind = 0; ind < inds; ind++)
            {
                yIndTop[ind]    = yBottom - (ind + 1) * indHeight + 1;
                yIndBottom[ind] = yBottom - ind * indHeight - 1;
                dMaxValue[ind]  = double.MinValue;
                dMinValue[ind]  = double.MaxValue;
                int    iSlot = aiIndSlot[ind];
                double dValue;

                for (int iComp = 0; iComp < iComponentLenght[iSlot]; iComp++)
                {
                    if (Data.Strategy.Slot[iSlot].Component[iComp].ChartType != IndChartType.NoChart)
                    {
                        for (bar = Math.Max(firstBar, Data.Strategy.Slot[iSlot].Component[iComp].FirstBar); bar <= lastBar; bar++)
                        {
                            dValue = Data.Strategy.Slot[iSlot].Component[iComp].Value[bar];
                            if (dValue > dMaxValue[ind])
                            {
                                dMaxValue[ind] = dValue;
                            }
                            if (dValue < dMinValue[ind])
                            {
                                dMinValue[ind] = dValue;
                            }
                        }
                    }
                }

                dMaxValue[ind] = Math.Max(dMaxValue[ind], Data.Strategy.Slot[iSlot].MaxValue);
                dMinValue[ind] = Math.Min(dMinValue[ind], Data.Strategy.Slot[iSlot].MinValue);

                foreach (double dSpecVal in Data.Strategy.Slot[iSlot].SpecValue)
                {
                    if (dSpecVal == 0)
                    {
                        dMaxValue[ind] = Math.Max(dMaxValue[ind], 0);
                        dMinValue[ind] = Math.Min(dMinValue[ind], 0);
                    }
                }

                dScale[ind] = (yIndBottom[ind] - yIndTop[ind] - 2) / (Math.Max(dMaxValue[ind] - dMinValue[ind], 0.0001f));

                // Indicator chart
                for (int iComp = 0; iComp < Data.Strategy.Slot[iSlot].Component.Length; iComp++)
                {
                    chartType[iSlot][iComp] = Data.Strategy.Slot[iSlot].Component[iComp].ChartType;
                    if (Data.Strategy.Slot[iSlot].Component[iComp].ChartType == IndChartType.Line)
                    {   // Line
                        chartBrush[iSlot][iComp] = new SolidBrush(Data.Strategy.Slot[iSlot].Component[iComp].ChartColor);
                        chartLine[iSlot][iComp]  = new Point[lastBar - firstBar + 1];
                        for (bar = firstBar; bar <= lastBar; bar++)
                        {
                            dValue = Data.Strategy.Slot[iSlot].Component[iComp].Value[bar];
                            int ix = (bar - firstBar) * barPixels + xLeft;
                            int iy = (int)(yIndBottom[ind] - 1 - (dValue - dMinValue[ind]) * dScale[ind]);
                            chartLine[iSlot][iComp][bar - firstBar] = new Point(ix, iy);
                        }
                    }
                    else if (Data.Strategy.Slot[iSlot].Component[iComp].ChartType == IndChartType.Histogram)
                    {   // Histogram
                        chartValue[iSlot][iComp] = new double[lastBar - firstBar + 1];
                        chartPen[iSlot][iComp]   = new Pen[lastBar - firstBar + 1];
                        for (bar = firstBar; bar <= lastBar; bar++)
                        {
                            dValue = Data.Strategy.Slot[iSlot].Component[iComp].Value[bar];
                            chartValue[iSlot][iComp][bar - firstBar] = dValue;
                            if (dValue > Data.Strategy.Slot[iSlot].Component[iComp].Value[bar - 1])
                            {
                                chartPen[iSlot][iComp][bar - firstBar] = penGreen;
                            }
                            else
                            {
                                chartPen[iSlot][iComp][bar - firstBar] = penRed;
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Prepare the parameters
        /// </summary>
        private void SetUpPaintData()
        {
            // Panel caption
            _captionText = Language.T("Indicator Chart");
            _captionFont = new Font(Font.FontFamily, 9);
            _captionHeight = Math.Max(_captionFont.Height, 18);
            _captionWidth = ClientSize.Width;
            _captionBrush = new SolidBrush(LayoutColors.ColorCaptionText);
            _captionRectangle = new RectangleF(0, 0, _captionWidth, _captionHeight);
            _captionStringFormat = new StringFormat
                                       {
                                           Alignment = StringAlignment.Center,
                                           LineAlignment = StringAlignment.Center,
                                           Trimming = StringTrimming.EllipsisCharacter,
                                           FormatFlags = StringFormatFlags.NoWrap
                                       };

            if (!Data.IsData || !Data.IsResult || Data.Bars <= StatsBuffer.FirstBar) return;

            _xLeft = Space;
            _xRight = ClientSize.Width - Space;
            _yTop = (int) _captionHeight + Space;
            _yBottom = ClientSize.Height - _scrollBar.Height - Space;
            _yPriceBottom = _yBottom;
            _separateIndicatorsCount = 0;
            _separateIndicatorsChartHeight = 0;
            _indicatorSlots = new int[Configs.MaxEntryFilters + Configs.MaxExitFilters + 2];

            _penFore = new Pen(LayoutColors.ColorChartFore);
            _penVolume = new Pen(LayoutColors.ColorVolume);
            _penBorder = new Pen(Data.GetGradientColor(LayoutColors.ColorCaptionBack, -LayoutColors.DepthCaption),
                                 Border);

            for (int slot = StatsBuffer.Strategy.Slots - 1; slot >= 0; slot--)
                if (StatsBuffer.Strategy.Slot[slot].SeparatedChart)
                    _indicatorSlots[_separateIndicatorsCount++] = slot;

            if (_separateIndicatorsCount > 0)
            {
                _separateIndicatorsChartHeight = (_yBottom - _yTop)/(2 + _separateIndicatorsCount);
                _yPriceBottom = _yBottom - _separateIndicatorsCount*_separateIndicatorsChartHeight;
            }

            _maxPrice = double.MinValue;
            _minPrice = double.MaxValue;
            _maxVolume = int.MinValue;

            for (int bar = _chartFirstBar; bar <= _chartLastBar; bar++)
            {
                if (Data.High[bar] > _maxPrice) _maxPrice = Data.High[bar];
                if (Data.Low[bar] < _minPrice) _minPrice = Data.Low[bar];
                if (Data.Volume[bar] > _maxVolume) _maxVolume = Data.Volume[bar];
            }
            _minPrice = Math.Round(_minPrice, Data.InstrProperties.Point < 0.001 ? 3 : 1) -
                        Data.InstrProperties.Point*10;
            _maxPrice = Math.Round(_maxPrice, Data.InstrProperties.Point < 0.001 ? 3 : 1) +
                        Data.InstrProperties.Point*10;
            _scaleY = (_yPriceBottom - _yTop)/(_maxPrice - _minPrice);
            _scaleYVol = _maxVolume > 0 ? ((_yPriceBottom - _yTop)/8d)/_maxVolume : 0d;

            // Volume, Lots and Price
            _x = new int[_chartBars];
            _yOpen = new int[_chartBars];
            _yHigh = new int[_chartBars];
            _yLow = new int[_chartBars];
            _yClose = new int[_chartBars];
            _yVolume = new int[_chartBars];
            _rectPosition = new Rectangle[_chartBars];
            _brushPosition = new Brush[_chartBars];

            int index = 0;
            for (int bar = _chartFirstBar; bar <= _chartLastBar; bar++)
            {
                _x[index] = (bar - _chartFirstBar)*_chartBarWidth + _xLeft;
                _yOpen[index] = (int) (_yPriceBottom - (Data.Open[bar] - _minPrice)*_scaleY);
                _yHigh[index] = (int) (_yPriceBottom - (Data.High[bar] - _minPrice)*_scaleY);
                _yLow[index] = (int) (_yPriceBottom - (Data.Low[bar] - _minPrice)*_scaleY);
                _yClose[index] = (int) (_yPriceBottom - (Data.Close[bar] - _minPrice)*_scaleY);
                _yVolume[index] = (int) (_yPriceBottom - Data.Volume[bar]*_scaleYVol);

                // Draw position lots
                if (StatsBuffer.IsPos(bar))
                {
                    var posHight = (int) (Math.Max(StatsBuffer.SummaryLots(bar)*2, 2));
                    int yPos = _yPriceBottom - posHight;

                    switch (StatsBuffer.SummaryDir(bar))
                    {
                        case PosDirection.Long:
                            _rectPosition[index] = new Rectangle(_x[index], yPos, 1, posHight);
                            _brushPosition[index] = new SolidBrush(LayoutColors.ColorTradeLong);
                            break;
                        case PosDirection.Short:
                            _rectPosition[index] = new Rectangle(_x[index], yPos, 1, posHight);
                            _brushPosition[index] = new SolidBrush(LayoutColors.ColorTradeShort);
                            break;
                        case PosDirection.Closed:
                            _rectPosition[index] = new Rectangle(_x[index], yPos - 2, 1, 2);
                            _brushPosition[index] = new SolidBrush(LayoutColors.ColorTradeClose);
                            break;
                    }
                }
                else
                {
                    // There is no position
                    _rectPosition[index] = Rectangle.Empty;
                    _brushPosition[index] = new SolidBrush(LayoutColors.ColorChartBack);
                }
                index++;
            }

            // Indicators in the chart
            int slots = StatsBuffer.Strategy.Slots;
            _isSeparatedChart = new bool[slots];
            _componentLenght = new int[slots];
            _chartType = new IndChartType[slots][];
            _chartLine = new Point[slots][][];
            _chartDot = new Rectangle[slots][][];
            _chartLevel = new Rectangle[slots][][];
            _chartValue = new double[slots][][];
            _chartPen = new Pen[slots][][];
            _chartBrush = new Brush[slots][];

            for (int slot = 0; slot < slots; slot++)
            {
                _isSeparatedChart[slot] = StatsBuffer.Strategy.Slot[slot].SeparatedChart;
                int count = StatsBuffer.Strategy.Slot[slot].Component.Length;
                _componentLenght[slot] = count;
                _chartType[slot] = new IndChartType[count];
                _chartLine[slot] = new Point[count][];
                _chartDot[slot] = new Rectangle[count][];
                _chartLevel[slot] = new Rectangle[count][];
                _chartValue[slot] = new double[count][];
                _chartPen[slot] = new Pen[count][];
                _chartBrush[slot] = new Brush[count];
            }

            for (int slot = 0; slot < slots; slot++)
            {
                if (_isSeparatedChart[slot]) continue;

                for (int comp = 0; comp < _componentLenght[slot]; comp++)
                {
                    _chartType[slot][comp] = StatsBuffer.Strategy.Slot[slot].Component[comp].ChartType;
                    switch (StatsBuffer.Strategy.Slot[slot].Component[comp].ChartType)
                    {
                        case IndChartType.Line:
                        case IndChartType.CloudUp:
                        case IndChartType.CloudDown:
                            _chartBrush[slot][comp] =
                                new SolidBrush(StatsBuffer.Strategy.Slot[slot].Component[comp].ChartColor);
                            _chartLine[slot][comp] = new Point[_chartLastBar - _chartFirstBar + 1];
                            for (int bar = _chartFirstBar; bar <= _chartLastBar; bar++)
                            {
                                double value = StatsBuffer.Strategy.Slot[slot].Component[comp].Value[bar];
                                int x = (bar - _chartFirstBar)*_chartBarWidth + _xLeft;
                                var y = (int) (_yPriceBottom - (value - _minPrice)*_scaleY);

                                if (Math.Abs(value - 0) < 0.0001)
                                    _chartLine[slot][comp][bar - _chartFirstBar] =
                                        _chartLine[slot][comp][Math.Max(bar - _chartFirstBar - 1, 0)];
                                else
                                    _chartLine[slot][comp][bar - _chartFirstBar] = new Point(x, y);
                            }
                            break;
                        case IndChartType.Dot:
                            _chartBrush[slot][comp] =
                                new SolidBrush(StatsBuffer.Strategy.Slot[slot].Component[comp].ChartColor);
                            _chartDot[slot][comp] = new Rectangle[_chartLastBar - _chartFirstBar + 1];
                            for (int bar = _chartFirstBar; bar <= _chartLastBar; bar++)
                            {
                                double value = StatsBuffer.Strategy.Slot[slot].Component[comp].Value[bar];
                                int x = (bar - _chartFirstBar)*_chartBarWidth + _xLeft;
                                var y = (int) (_yPriceBottom - (value - _minPrice)*_scaleY);
                                _chartDot[slot][comp][bar - _chartFirstBar] = new Rectangle(x, y, 1, 1);
                            }
                            break;
                        case IndChartType.Level:
                            _chartBrush[slot][comp] =
                                new SolidBrush(StatsBuffer.Strategy.Slot[slot].Component[comp].ChartColor);
                            _chartLevel[slot][comp] = new Rectangle[_chartLastBar - _chartFirstBar + 1];
                            for (int bar = _chartFirstBar; bar <= _chartLastBar; bar++)
                            {
                                double value = StatsBuffer.Strategy.Slot[slot].Component[comp].Value[bar];
                                int x = (bar - _chartFirstBar)*_chartBarWidth + _xLeft;
                                var y = (int) (_yPriceBottom - (value - _minPrice)*_scaleY);
                                _chartLevel[slot][comp][bar - _chartFirstBar] = new Rectangle(x, y, _chartBarWidth, 1);
                            }
                            break;
                    }
                }
            }

            // Separate indicators
            _yIndTop = new int[_separateIndicatorsCount];
            _yIndBottom = new int[_separateIndicatorsCount];
            _maxValues = new double[_separateIndicatorsCount];
            _minValues = new double[_separateIndicatorsCount];
            _scales = new double[_separateIndicatorsCount];

            for (int ind = 0; ind < _separateIndicatorsCount; ind++)
            {
                _yIndTop[ind] = _yBottom - (ind + 1)*_separateIndicatorsChartHeight + 1;
                _yIndBottom[ind] = _yBottom - ind*_separateIndicatorsChartHeight - 1;
                _maxValues[ind] = double.MinValue;
                _minValues[ind] = double.MaxValue;
                int slot = _indicatorSlots[ind];

                for (int comp = 0; comp < _componentLenght[slot]; comp++)
                    if (StatsBuffer.Strategy.Slot[slot].Component[comp].ChartType != IndChartType.NoChart)
                        for (
                            int bar = Math.Max(_chartFirstBar, StatsBuffer.Strategy.Slot[slot].Component[comp].FirstBar);
                            bar <= _chartLastBar;
                            bar++)
                        {
                            double value = StatsBuffer.Strategy.Slot[slot].Component[comp].Value[bar];
                            if (value > _maxValues[ind]) _maxValues[ind] = value;
                            if (value < _minValues[ind]) _minValues[ind] = value;
                        }

                _maxValues[ind] = Math.Max(_maxValues[ind], StatsBuffer.Strategy.Slot[slot].MaxValue);
                _minValues[ind] = Math.Min(_minValues[ind], StatsBuffer.Strategy.Slot[slot].MinValue);

                foreach (double specialValue in StatsBuffer.Strategy.Slot[slot].SpecValue)
                    if (Math.Abs(specialValue - 0) < 0.0001)
                    {
                        _maxValues[ind] = Math.Max(_maxValues[ind], 0);
                        _minValues[ind] = Math.Min(_minValues[ind], 0);
                    }

                _scales[ind] = (_yIndBottom[ind] - _yIndTop[ind] - 2)/ (Math.Max(_maxValues[ind] - _minValues[ind], 0.0001f));

                // Indicator chart
                for (int comp = 0; comp < StatsBuffer.Strategy.Slot[slot].Component.Length; comp++)
                {
                    _chartType[slot][comp] = StatsBuffer.Strategy.Slot[slot].Component[comp].ChartType;
                    switch (_chartType[slot][comp])
                    {
                        case IndChartType.Line:
                            _chartBrush[slot][comp] =
                                new SolidBrush(StatsBuffer.Strategy.Slot[slot].Component[comp].ChartColor);
                            _chartLine[slot][comp] = new Point[_chartLastBar - _chartFirstBar + 1];
                            for (int bar = _chartFirstBar; bar <= _chartLastBar; bar++)
                            {
                                double value = StatsBuffer.Strategy.Slot[slot].Component[comp].Value[bar];
                                int x = (bar - _chartFirstBar)*_chartBarWidth + _xLeft;
                                var y = (int) (_yIndBottom[ind] - 1 - (value - _minValues[ind])*_scales[ind]);
                                _chartLine[slot][comp][bar - _chartFirstBar] = new Point(x, y);
                            }
                            break;
                        case IndChartType.Histogram:
                            _chartValue[slot][comp] = new double[_chartLastBar - _chartFirstBar + 1];
                            _chartPen[slot][comp] = new Pen[_chartLastBar - _chartFirstBar + 1];
                            for (int bar = _chartFirstBar; bar <= _chartLastBar; bar++)
                            {
                                double value = StatsBuffer.Strategy.Slot[slot].Component[comp].Value[bar];
                                _chartValue[slot][comp][bar - _chartFirstBar] = value;
                                if (value > StatsBuffer.Strategy.Slot[slot].Component[comp].Value[bar - 1])
                                    _chartPen[slot][comp][bar - _chartFirstBar] = _penGreen;
                                else
                                    _chartPen[slot][comp][bar - _chartFirstBar] = _penRed;
                            }
                            break;
                    }
                }
            }
        }
        /// <summary>
        /// Prepare the parameters
        /// </summary>
        public void SetUpChart()
        {
            // Panel caption
            stringCaptionText = Language.T("Indicator Chart");
            fontCaptionText   = new Font(Font.FontFamily, 9);
            captionHeight     = Math.Max(fontCaptionText.Height, 18);
            captionWidth      = this.ClientSize.Width;
            brushCaptionText  = new SolidBrush(LayoutColors.ColorCaptionText);
            rectfCaption      = new RectangleF(0, 0, captionWidth, captionHeight);
            stringFormatCaption                = new StringFormat();
            stringFormatCaption.Alignment     |= StringAlignment.Center;
            stringFormatCaption.LineAlignment |= StringAlignment.Center;
            stringFormatCaption.Trimming      |= StringTrimming.EllipsisCharacter;
            stringFormatCaption.FormatFlags   |= StringFormatFlags.NoWrap;

            if (!Data.IsData || !Data.IsResult || Data.Bars <= Data.FirstBar) return;

            clSzWidth  = this.ClientSize.Width;
            clSzHeight = this.ClientSize.Height;
            xLeft      = space;
            xRight     = clSzWidth - space;
            yTop       = (int)captionHeight + space;
            yBottom    = clSzHeight - scrollBar.Height - space;
            yPrcBottom = yBottom;		// Price chart y
            inds       = 0; // Count of separated indicators
            indHeight  = 0; // Height of Ind charts
            aiIndSlot  = new int[12];

            penFore   = new Pen(LayoutColors.ColorChartFore);
            penVolume = new Pen(LayoutColors.ColorVolume);
            penBorder = new Pen(Data.GetGradientColor(LayoutColors.ColorCaptionBack, -LayoutColors.DepthCaption), border);

            for (int slot = Data.Strategy.Slots - 1; slot >= 0; slot--)
                if (Data.Strategy.Slot[slot].SeparatedChart)
                    aiIndSlot[inds++] = slot;

            if (inds > 0)
            {
                indHeight = (yBottom - yTop) / (2 + inds);
                yPrcBottom = yBottom - inds * indHeight;
            }

            maxPrice  = double.MinValue;
            minPrice  = double.MaxValue;
            maxVolume = int.MinValue;

            for (int bar = firstBar; bar <= lastBar; bar++)
            {
                if (Data.High[bar]   > maxPrice ) maxPrice  = Data.High[bar];
                if (Data.Low[bar]    < minPrice ) minPrice  = Data.Low[bar];
                if (Data.Volume[bar] > maxVolume) maxVolume = Data.Volume[bar];
            }
            minPrice  = Math.Round(minPrice, Data.InstrProperties.Point < 0.001 ? 3 : 1) - Data.InstrProperties.Point * 10;
            maxPrice  = Math.Round(maxPrice, Data.InstrProperties.Point < 0.001 ? 3 : 1) + Data.InstrProperties.Point * 10;
            scaleY    = (yPrcBottom - yTop) / (maxPrice - minPrice);
            scaleYVol = maxVolume > 0 ? ((yPrcBottom - yTop) / 8d) / maxVolume : 0d;

            // Volume, Lots and Price
            x       = new int[chartBars];
            yOpen   = new int[chartBars];
            yHigh   = new int[chartBars];
            yLow    = new int[chartBars];
            yClose  = new int[chartBars];
            yVolume = new int[chartBars];
            rectPosition  = new Rectangle[chartBars];
            brushPosition = new Brush[chartBars];

            int index = 0;
            for (int bar = firstBar; bar <= lastBar; bar++)
            {
                x[index]       = (bar - firstBar) * barPixels + xLeft;
                yOpen[index]   = (int)(yPrcBottom - (Data.Open[bar]   - minPrice) * scaleY);
                yHigh[index]   = (int)(yPrcBottom - (Data.High[bar]   - minPrice) * scaleY);
                yLow[index]    = (int)(yPrcBottom - (Data.Low[bar]    - minPrice) * scaleY);
                yClose[index]  = (int)(yPrcBottom - (Data.Close[bar]  - minPrice) * scaleY);
                yVolume[index] = (int)(yPrcBottom -  Data.Volume[bar] * scaleYVol);

                // Draw position lots
                if (Backtester.IsPos(bar))
                {
                    int iPosHight = (int)(Math.Max(Backtester.SummaryLots(bar) * 2, 2));

                    int iPosY = yPrcBottom - iPosHight;

                    if (Backtester.SummaryDir(bar) == PosDirection.Long)
                    {   // Long
                        rectPosition[index]  = new Rectangle(x[index], iPosY, 1, iPosHight);
                        brushPosition[index] = new SolidBrush(LayoutColors.ColorTradeLong);
                    }
                    else if (Backtester.SummaryDir(bar) == PosDirection.Short)
                    {   // Short
                        rectPosition[index]  = new Rectangle(x[index], iPosY, 1, iPosHight);
                        brushPosition[index] = new SolidBrush(LayoutColors.ColorTradeShort);
                    }
                    else
                    {   // Close position
                        rectPosition[index]  = new Rectangle(x[index], iPosY - 2, 1, 2);
                        brushPosition[index] = new SolidBrush(LayoutColors.ColorTradeClose);
                    }
                }
                else
                {   // There is no position
                    rectPosition[index]  = Rectangle.Empty;
                    brushPosition[index] = new SolidBrush(LayoutColors.ColorChartBack);
                }
                index++;
            }

            // Indicators in the chart
            slots = Data.Strategy.Slots;
            bIsSeparatedChart = new bool[slots];
            iComponentLenght  = new int[slots];
            chartType         = new IndChartType[slots][];
            chartLine         = new Point[slots][][];
            chartDot          = new Rectangle[slots][][];
            chartLevel        = new Rectangle[slots][][];
            chartValue        = new double[slots][][];
            chartPen          = new Pen[slots][][];
            chartBrush        = new Brush[slots][];
            for (int iSlot = 0; iSlot < slots; iSlot++)
            {
                bIsSeparatedChart[iSlot] = Data.Strategy.Slot[iSlot].SeparatedChart;
                int iLenght = Data.Strategy.Slot[iSlot].Component.Length;
                iComponentLenght[iSlot] = iLenght;
                chartType[iSlot]  = new IndChartType[iLenght];
                chartLine[iSlot]  = new Point[iLenght][];
                chartDot[iSlot]   = new Rectangle[iLenght][];
                chartLevel[iSlot] = new Rectangle[iLenght][];
                chartValue[iSlot] = new double[iLenght][];
                chartPen[iSlot]   = new Pen[iLenght][];
                chartBrush[iSlot] = new Brush[iLenght];
            }

            for (int slot = 0; slot < slots; slot++)
            {
                if (bIsSeparatedChart[slot]) continue;

                for (int comp = 0; comp < iComponentLenght[slot]; comp++)
                {
                    chartType[slot][comp] = Data.Strategy.Slot[slot].Component[comp].ChartType;
                    if (Data.Strategy.Slot[slot].Component[comp].ChartType == IndChartType.Line    ||
                        Data.Strategy.Slot[slot].Component[comp].ChartType == IndChartType.CloudUp ||
                        Data.Strategy.Slot[slot].Component[comp].ChartType == IndChartType.CloudDown )
                    {   // Line
                        chartBrush[slot][comp] = new SolidBrush(Data.Strategy.Slot[slot].Component[comp].ChartColor);
                        chartLine[slot][comp]  = new Point[lastBar - firstBar + 1];
                        for (int bar = firstBar; bar <= lastBar; bar++)
                        {
                            double dValue = Data.Strategy.Slot[slot].Component[comp].Value[bar];
                            int ix = (bar - firstBar) * barPixels + xLeft;
                            int iy = (int)(yPrcBottom - (dValue - minPrice) * scaleY);

                            if(dValue == 0)
                                chartLine[slot][comp][bar - firstBar] = chartLine[slot][comp][Math.Max(bar - firstBar - 1, 0)];
                            else
                                chartLine[slot][comp][bar - firstBar] = new Point(ix, iy);

                        }
                    }
                    else if (Data.Strategy.Slot[slot].Component[comp].ChartType == IndChartType.Dot)
                    {   // Dots
                        chartBrush[slot][comp] = new SolidBrush(Data.Strategy.Slot[slot].Component[comp].ChartColor);
                        chartDot[slot][comp]   = new Rectangle[lastBar - firstBar + 1];
                        for (int bar = firstBar; bar <= lastBar; bar++)
                        {
                            double dValue = Data.Strategy.Slot[slot].Component[comp].Value[bar];
                            int ix = (bar - firstBar) * barPixels + xLeft;
                            int iy = (int)(yPrcBottom - (dValue - minPrice) * scaleY);
                            chartDot[slot][comp][bar-firstBar] = new Rectangle(ix, iy, 1, 1);
                        }
                    }
                    else if (Data.Strategy.Slot[slot].Component[comp].ChartType == IndChartType.Level)
                    {   // Level
                        chartBrush[slot][comp] = new SolidBrush(Data.Strategy.Slot[slot].Component[comp].ChartColor);
                        chartLevel[slot][comp] = new Rectangle[lastBar - firstBar + 1];
                        for (int bar = firstBar; bar <= lastBar; bar++)
                        {
                            double dValue = Data.Strategy.Slot[slot].Component[comp].Value[bar];
                            int ix = (bar - firstBar) * barPixels + xLeft;
                            int iy = (int)(yPrcBottom - (dValue - minPrice) * scaleY);
                            chartLevel[slot][comp][bar - firstBar] = new Rectangle(ix, iy, barPixels, 1);
                        }
                    }
                }
            }

            // Separate indicators
            yIndTop    = new int[inds];
            yIndBottom = new int[inds];
            dMaxValue  = new double[inds];
            dMinValue  = new double[inds];
            dScale     = new double[inds];
            for (int ind = 0; ind < inds; ind++)
            {
                yIndTop[ind]    = yBottom - (ind + 1) * indHeight + 1;
                yIndBottom[ind] = yBottom - ind * indHeight - 1;
                dMaxValue[ind]  = double.MinValue;
                dMinValue[ind]  = double.MaxValue;
                int    iSlot = aiIndSlot[ind];
                double dValue;

                for (int iComp = 0; iComp < iComponentLenght[iSlot]; iComp++)
                    if (Data.Strategy.Slot[iSlot].Component[iComp].ChartType != IndChartType.NoChart)
                        for (bar = Math.Max(firstBar, Data.Strategy.Slot[iSlot].Component[iComp].FirstBar); bar <= lastBar; bar++)
                        {
                            dValue = Data.Strategy.Slot[iSlot].Component[iComp].Value[bar];
                            if (dValue > dMaxValue[ind]) dMaxValue[ind] = dValue;
                            if (dValue < dMinValue[ind]) dMinValue[ind] = dValue;
                        }

                dMaxValue[ind] = Math.Max(dMaxValue[ind], Data.Strategy.Slot[iSlot].MaxValue);
                dMinValue[ind] = Math.Min(dMinValue[ind], Data.Strategy.Slot[iSlot].MinValue);

                foreach (double dSpecVal in Data.Strategy.Slot[iSlot].SpecValue)
                    if (dSpecVal == 0)
                    {
                        dMaxValue[ind] = Math.Max(dMaxValue[ind], 0);
                        dMinValue[ind] = Math.Min(dMinValue[ind], 0);
                    }

                dScale[ind] = (yIndBottom[ind] - yIndTop[ind] - 2) / (Math.Max(dMaxValue[ind] - dMinValue[ind], 0.0001f));

                // Indicator chart
                for (int iComp = 0; iComp < Data.Strategy.Slot[iSlot].Component.Length; iComp++)
                {
                    chartType[iSlot][iComp] = Data.Strategy.Slot[iSlot].Component[iComp].ChartType;
                    if (Data.Strategy.Slot[iSlot].Component[iComp].ChartType == IndChartType.Line)
                    {   // Line
                        chartBrush[iSlot][iComp] = new SolidBrush(Data.Strategy.Slot[iSlot].Component[iComp].ChartColor);
                        chartLine[iSlot][iComp]  = new Point[lastBar - firstBar + 1];
                        for (bar = firstBar; bar <= lastBar; bar++)
                        {
                            dValue = Data.Strategy.Slot[iSlot].Component[iComp].Value[bar];
                            int ix = (bar - firstBar) * barPixels + xLeft;
                            int iy = (int)(yIndBottom[ind] - 1 - (dValue - dMinValue[ind]) * dScale[ind]);
                            chartLine[iSlot][iComp][bar - firstBar] = new Point(ix, iy);
                        }
                    }
                    else if (Data.Strategy.Slot[iSlot].Component[iComp].ChartType == IndChartType.Histogram)
                    {   // Histogram
                        chartValue[iSlot][iComp] = new double[lastBar - firstBar + 1];
                        chartPen[iSlot][iComp]   = new Pen[lastBar - firstBar + 1];
                        for (bar = firstBar; bar <= lastBar; bar++)
                        {
                            dValue = Data.Strategy.Slot[iSlot].Component[iComp].Value[bar];
                            chartValue[iSlot][iComp][bar - firstBar] = dValue;
                            if (dValue > Data.Strategy.Slot[iSlot].Component[iComp].Value[bar - 1])
                                chartPen[iSlot][iComp][bar - firstBar] = penGreen;
                            else
                                chartPen[iSlot][iComp][bar - firstBar] = penRed;
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Prepare the parameters
        /// </summary>
        private void SetUpPaintData()
        {
            // Panel caption
            _captionText         = Language.T("Indicator Chart");
            _captionFont         = new Font(Font.FontFamily, 9);
            _captionHeight       = Math.Max(_captionFont.Height, 18);
            _captionWidth        = ClientSize.Width;
            _captionBrush        = new SolidBrush(LayoutColors.ColorCaptionText);
            _captionRectangle    = new RectangleF(0, 0, _captionWidth, _captionHeight);
            _captionStringFormat = new StringFormat
            {
                Alignment     = StringAlignment.Center,
                LineAlignment = StringAlignment.Center,
                Trimming      = StringTrimming.EllipsisCharacter,
                FormatFlags   = StringFormatFlags.NoWrap
            };

            if (!Data.IsData || !Data.IsResult || Data.Bars <= StatsBuffer.FirstBar)
            {
                return;
            }

            _xLeft                         = Space;
            _xRight                        = ClientSize.Width - Space;
            _yTop                          = (int)_captionHeight + Space;
            _yBottom                       = ClientSize.Height - _scrollBar.Height - Space;
            _yPriceBottom                  = _yBottom;
            _separateIndicatorsCount       = 0;
            _separateIndicatorsChartHeight = 0;
            _indicatorSlots                = new int[Configs.MaxEntryFilters + Configs.MaxExitFilters + 2];

            _penFore   = new Pen(LayoutColors.ColorChartFore);
            _penVolume = new Pen(LayoutColors.ColorVolume);
            _penBorder = new Pen(Data.GetGradientColor(LayoutColors.ColorCaptionBack, -LayoutColors.DepthCaption),
                                 Border);

            for (int slot = StatsBuffer.Strategy.Slots - 1; slot >= 0; slot--)
            {
                if (StatsBuffer.Strategy.Slot[slot].SeparatedChart)
                {
                    _indicatorSlots[_separateIndicatorsCount++] = slot;
                }
            }

            if (_separateIndicatorsCount > 0)
            {
                _separateIndicatorsChartHeight = (_yBottom - _yTop) / (2 + _separateIndicatorsCount);
                _yPriceBottom = _yBottom - _separateIndicatorsCount * _separateIndicatorsChartHeight;
            }

            _maxPrice  = double.MinValue;
            _minPrice  = double.MaxValue;
            _maxVolume = int.MinValue;

            for (int bar = _chartFirstBar; bar <= _chartLastBar; bar++)
            {
                if (Data.High[bar] > _maxPrice)
                {
                    _maxPrice = Data.High[bar];
                }
                if (Data.Low[bar] < _minPrice)
                {
                    _minPrice = Data.Low[bar];
                }
                if (Data.Volume[bar] > _maxVolume)
                {
                    _maxVolume = Data.Volume[bar];
                }
            }
            _minPrice = Math.Round(_minPrice, Data.InstrProperties.Point < 0.001 ? 3 : 1) -
                        Data.InstrProperties.Point * 10;
            _maxPrice = Math.Round(_maxPrice, Data.InstrProperties.Point < 0.001 ? 3 : 1) +
                        Data.InstrProperties.Point * 10;
            _scaleY    = (_yPriceBottom - _yTop) / (_maxPrice - _minPrice);
            _scaleYVol = _maxVolume > 0 ? ((_yPriceBottom - _yTop) / 8d) / _maxVolume : 0d;

            // Volume, Lots and Price
            _x             = new int[_chartBars];
            _yOpen         = new int[_chartBars];
            _yHigh         = new int[_chartBars];
            _yLow          = new int[_chartBars];
            _yClose        = new int[_chartBars];
            _yVolume       = new int[_chartBars];
            _rectPosition  = new Rectangle[_chartBars];
            _brushPosition = new Brush[_chartBars];

            int index = 0;

            for (int bar = _chartFirstBar; bar <= _chartLastBar; bar++)
            {
                _x[index]       = (bar - _chartFirstBar) * _chartBarWidth + _xLeft;
                _yOpen[index]   = (int)(_yPriceBottom - (Data.Open[bar] - _minPrice) * _scaleY);
                _yHigh[index]   = (int)(_yPriceBottom - (Data.High[bar] - _minPrice) * _scaleY);
                _yLow[index]    = (int)(_yPriceBottom - (Data.Low[bar] - _minPrice) * _scaleY);
                _yClose[index]  = (int)(_yPriceBottom - (Data.Close[bar] - _minPrice) * _scaleY);
                _yVolume[index] = (int)(_yPriceBottom - Data.Volume[bar] * _scaleYVol);

                // Draw position lots
                if (StatsBuffer.IsPos(bar))
                {
                    var posHight = (int)(Math.Max(StatsBuffer.SummaryLots(bar) * 2, 2));
                    int yPos     = _yPriceBottom - posHight;

                    switch (StatsBuffer.SummaryDir(bar))
                    {
                    case PosDirection.Long:
                        _rectPosition[index]  = new Rectangle(_x[index], yPos, 1, posHight);
                        _brushPosition[index] = new SolidBrush(LayoutColors.ColorTradeLong);
                        break;

                    case PosDirection.Short:
                        _rectPosition[index]  = new Rectangle(_x[index], yPos, 1, posHight);
                        _brushPosition[index] = new SolidBrush(LayoutColors.ColorTradeShort);
                        break;

                    case PosDirection.Closed:
                        _rectPosition[index]  = new Rectangle(_x[index], yPos - 2, 1, 2);
                        _brushPosition[index] = new SolidBrush(LayoutColors.ColorTradeClose);
                        break;
                    }
                }
                else
                {
                    // There is no position
                    _rectPosition[index]  = Rectangle.Empty;
                    _brushPosition[index] = new SolidBrush(LayoutColors.ColorChartBack);
                }
                index++;
            }

            // Indicators in the chart
            int slots = StatsBuffer.Strategy.Slots;

            _isSeparatedChart = new bool[slots];
            _componentLenght  = new int[slots];
            _chartType        = new IndChartType[slots][];
            _chartLine        = new Point[slots][][];
            _chartDot         = new Rectangle[slots][][];
            _chartLevel       = new Rectangle[slots][][];
            _chartValue       = new double[slots][][];
            _chartPen         = new Pen[slots][][];
            _chartBrush       = new Brush[slots][];

            for (int slot = 0; slot < slots; slot++)
            {
                _isSeparatedChart[slot] = StatsBuffer.Strategy.Slot[slot].SeparatedChart;
                int count = StatsBuffer.Strategy.Slot[slot].Component.Length;
                _componentLenght[slot] = count;
                _chartType[slot]       = new IndChartType[count];
                _chartLine[slot]       = new Point[count][];
                _chartDot[slot]        = new Rectangle[count][];
                _chartLevel[slot]      = new Rectangle[count][];
                _chartValue[slot]      = new double[count][];
                _chartPen[slot]        = new Pen[count][];
                _chartBrush[slot]      = new Brush[count];
            }

            for (int slot = 0; slot < slots; slot++)
            {
                if (_isSeparatedChart[slot])
                {
                    continue;
                }

                for (int comp = 0; comp < _componentLenght[slot]; comp++)
                {
                    _chartType[slot][comp] = StatsBuffer.Strategy.Slot[slot].Component[comp].ChartType;
                    switch (StatsBuffer.Strategy.Slot[slot].Component[comp].ChartType)
                    {
                    case IndChartType.Line:
                    case IndChartType.CloudUp:
                    case IndChartType.CloudDown:
                        _chartBrush[slot][comp] =
                            new SolidBrush(StatsBuffer.Strategy.Slot[slot].Component[comp].ChartColor);
                        _chartLine[slot][comp] = new Point[_chartLastBar - _chartFirstBar + 1];
                        for (int bar = _chartFirstBar; bar <= _chartLastBar; bar++)
                        {
                            double value = StatsBuffer.Strategy.Slot[slot].Component[comp].Value[bar];
                            int    x     = (bar - _chartFirstBar) * _chartBarWidth + _xLeft;
                            var    y     = (int)(_yPriceBottom - (value - _minPrice) * _scaleY);

                            if (Math.Abs(value - 0) < 0.0001)
                            {
                                _chartLine[slot][comp][bar - _chartFirstBar] =
                                    _chartLine[slot][comp][Math.Max(bar - _chartFirstBar - 1, 0)];
                            }
                            else
                            {
                                _chartLine[slot][comp][bar - _chartFirstBar] = new Point(x, y);
                            }
                        }
                        break;

                    case IndChartType.Dot:
                        _chartBrush[slot][comp] =
                            new SolidBrush(StatsBuffer.Strategy.Slot[slot].Component[comp].ChartColor);
                        _chartDot[slot][comp] = new Rectangle[_chartLastBar - _chartFirstBar + 1];
                        for (int bar = _chartFirstBar; bar <= _chartLastBar; bar++)
                        {
                            double value = StatsBuffer.Strategy.Slot[slot].Component[comp].Value[bar];
                            int    x     = (bar - _chartFirstBar) * _chartBarWidth + _xLeft;
                            var    y     = (int)(_yPriceBottom - (value - _minPrice) * _scaleY);
                            _chartDot[slot][comp][bar - _chartFirstBar] = new Rectangle(x, y, 1, 1);
                        }
                        break;

                    case IndChartType.Level:
                        _chartBrush[slot][comp] =
                            new SolidBrush(StatsBuffer.Strategy.Slot[slot].Component[comp].ChartColor);
                        _chartLevel[slot][comp] = new Rectangle[_chartLastBar - _chartFirstBar + 1];
                        for (int bar = _chartFirstBar; bar <= _chartLastBar; bar++)
                        {
                            double value = StatsBuffer.Strategy.Slot[slot].Component[comp].Value[bar];
                            int    x     = (bar - _chartFirstBar) * _chartBarWidth + _xLeft;
                            var    y     = (int)(_yPriceBottom - (value - _minPrice) * _scaleY);
                            _chartLevel[slot][comp][bar - _chartFirstBar] = new Rectangle(x, y, _chartBarWidth, 1);
                        }
                        break;
                    }
                }
            }

            // Separate indicators
            _yIndTop    = new int[_separateIndicatorsCount];
            _yIndBottom = new int[_separateIndicatorsCount];
            _maxValues  = new double[_separateIndicatorsCount];
            _minValues  = new double[_separateIndicatorsCount];
            _scales     = new double[_separateIndicatorsCount];

            for (int ind = 0; ind < _separateIndicatorsCount; ind++)
            {
                _yIndTop[ind]    = _yBottom - (ind + 1) * _separateIndicatorsChartHeight + 1;
                _yIndBottom[ind] = _yBottom - ind * _separateIndicatorsChartHeight - 1;
                _maxValues[ind]  = double.MinValue;
                _minValues[ind]  = double.MaxValue;
                int slot = _indicatorSlots[ind];

                for (int comp = 0; comp < _componentLenght[slot]; comp++)
                {
                    if (StatsBuffer.Strategy.Slot[slot].Component[comp].ChartType != IndChartType.NoChart)
                    {
                        for (
                            int bar = Math.Max(_chartFirstBar, StatsBuffer.Strategy.Slot[slot].Component[comp].FirstBar);
                            bar <= _chartLastBar;
                            bar++)
                        {
                            double value = StatsBuffer.Strategy.Slot[slot].Component[comp].Value[bar];
                            if (value > _maxValues[ind])
                            {
                                _maxValues[ind] = value;
                            }
                            if (value < _minValues[ind])
                            {
                                _minValues[ind] = value;
                            }
                        }
                    }
                }

                _maxValues[ind] = Math.Max(_maxValues[ind], StatsBuffer.Strategy.Slot[slot].MaxValue);
                _minValues[ind] = Math.Min(_minValues[ind], StatsBuffer.Strategy.Slot[slot].MinValue);

                foreach (double specialValue in StatsBuffer.Strategy.Slot[slot].SpecValue)
                {
                    if (Math.Abs(specialValue - 0) < 0.0001)
                    {
                        _maxValues[ind] = Math.Max(_maxValues[ind], 0);
                        _minValues[ind] = Math.Min(_minValues[ind], 0);
                    }
                }

                _scales[ind] = (_yIndBottom[ind] - _yIndTop[ind] - 2) / (Math.Max(_maxValues[ind] - _minValues[ind], 0.0001f));

                // Indicator chart
                for (int comp = 0; comp < StatsBuffer.Strategy.Slot[slot].Component.Length; comp++)
                {
                    _chartType[slot][comp] = StatsBuffer.Strategy.Slot[slot].Component[comp].ChartType;
                    switch (_chartType[slot][comp])
                    {
                    case IndChartType.Line:
                        _chartBrush[slot][comp] =
                            new SolidBrush(StatsBuffer.Strategy.Slot[slot].Component[comp].ChartColor);
                        _chartLine[slot][comp] = new Point[_chartLastBar - _chartFirstBar + 1];
                        for (int bar = _chartFirstBar; bar <= _chartLastBar; bar++)
                        {
                            double value = StatsBuffer.Strategy.Slot[slot].Component[comp].Value[bar];
                            int    x     = (bar - _chartFirstBar) * _chartBarWidth + _xLeft;
                            var    y     = (int)(_yIndBottom[ind] - 1 - (value - _minValues[ind]) * _scales[ind]);
                            _chartLine[slot][comp][bar - _chartFirstBar] = new Point(x, y);
                        }
                        break;

                    case IndChartType.Histogram:
                        _chartValue[slot][comp] = new double[_chartLastBar - _chartFirstBar + 1];
                        _chartPen[slot][comp]   = new Pen[_chartLastBar - _chartFirstBar + 1];
                        for (int bar = _chartFirstBar; bar <= _chartLastBar; bar++)
                        {
                            double value = StatsBuffer.Strategy.Slot[slot].Component[comp].Value[bar];
                            _chartValue[slot][comp][bar - _chartFirstBar] = value;
                            if (value > StatsBuffer.Strategy.Slot[slot].Component[comp].Value[bar - 1])
                            {
                                _chartPen[slot][comp][bar - _chartFirstBar] = _penGreen;
                            }
                            else
                            {
                                _chartPen[slot][comp][bar - _chartFirstBar] = _penRed;
                            }
                        }
                        break;
                    }
                }
            }
        }