コード例 #1
0
        /// <summary>
        ///     Paints the chart
        /// </summary>
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            if (ClientSize.Width == 0 || ClientSize.Height == 0)
            {
                return;
            }
            var      bitmap = new Bitmap(ClientSize.Width, ClientSize.Height);
            Graphics g      = Graphics.FromImage(bitmap);

            // Caption bar
            Data.GradientPaint(g, rectfCaption, LayoutColors.ColorCaptionBack, LayoutColors.DepthCaption);
            g.DrawString(chartTitle, Font, new SolidBrush(LayoutColors.ColorCaptionText), rectfCaption,
                         stringFormatCaption);

            // Border
            g.DrawLine(penBorder, 1, captionHeight, 1, ClientSize.Height);
            g.DrawLine(penBorder, ClientSize.Width - Border + 1, captionHeight, ClientSize.Width - Border + 1,
                       ClientSize.Height);
            g.DrawLine(penBorder, 0, ClientSize.Height - Border + 1, ClientSize.Width, ClientSize.Height - Border + 1);

            // Paints the background by gradient
            var rectChartField = new RectangleF(Border, captionHeight, ClientSize.Width - 2 * Border,
                                                ClientSize.Height - captionHeight - Border);

            Data.GradientPaint(g, rectChartField, LayoutColors.ColorChartBack, LayoutColors.DepthControl);

            if (isNotPaint)
            {
                return;
            }

            // Grid and Price labels
            for (int labelPrice = data.Minimum;
                 labelPrice <= data.Minimum + countLabels * labelStep;
                 labelPrice += labelStep)
            {
                var labelY = (int)(yBottom - (labelPrice - data.Minimum) * yScale);
                g.DrawString(labelPrice.ToString(CultureInfo.InvariantCulture), Font, brushFore, xRight,
                             labelY - Font.Height / 2 - 1);
                g.DrawLine(penGrid, xLeft, labelY, xRight, labelY);
            }

            // Price close
            if (showPriceLine)
            {
                g.DrawLines(new Pen(LayoutColors.ColorChartGrid), closePricePoints);
            }

            // Equity line
            g.DrawLines(new Pen(LayoutColors.ColorChartEquityLine), equityPoints);

            // Draw Long and Short balance
            if (Configs.AdditionalStatistics)
            {
                g.DrawLines(new Pen(Color.Red), shortBalancePoints);
                g.DrawLines(new Pen(Color.Green), longBalancePoints);
            }

            // Out of Sample
            if (IsOOS && OOSBar > 0)
            {
                g.DrawLine(new Pen(LayoutColors.ColorChartFore), xOOSBar, yTop, xOOSBar, yBottom);
                Brush brushOOS = new Pen(LayoutColors.ColorChartFore).Brush;
                g.DrawString("OOS", Font, brushOOS, xOOSBar, yBottom - Font.Height);
                float widthOOSBarDate = g.MeasureString(data.DataTimeBarOOS.ToShortDateString(), Font).Width;
                g.DrawString(data.DataTimeBarOOS.ToShortDateString(), Font, brushOOS, xOOSBar - widthOOSBarDate,
                             yBottom - Font.Height);
            }

            // Draw Balance Line
            if (data.MarginCallBar > 0) // In case of Margin Call
            {
                // Draw balance line up to Margin Call
                var balPoints = new PointF[data.MarginCallBar - data.FirstBar];
                for (int i = 0; i < balPoints.Length; i++)
                {
                    balPoints[i] = balancePoints[i];
                }
                if (balPoints.Length > 1)
                {
                    g.DrawLines(new Pen(LayoutColors.ColorChartBalanceLine), balPoints);
                }

                // Draw balance line after Margin Call
                var redBalancePoints = new PointF[data.Bars - data.MarginCallBar];
                for (int i = 0; i < redBalancePoints.Length; i++)
                {
                    redBalancePoints[i] = balancePoints[i + data.MarginCallBar - data.FirstBar];
                }
                g.DrawLines(new Pen(LayoutColors.ColorSignalRed), redBalancePoints);

                // Margin Call line
                g.DrawLine(new Pen(LayoutColors.ColorChartCross), xMarginCallBar, yTop, xMarginCallBar, yBottom);

                // Margin Call label
                float widthMarginCallLabel = g.MeasureString(Language.T("Margin Call"), Font).Width;
                if (xMarginCallBar < xRight - widthMarginCallLabel)
                {
                    g.DrawString(Language.T("Margin Call"), Font, brushFore, xMarginCallBar, yTop);
                }
                else if (xMarginCallBar > Space + widthMarginCallLabel)
                {
                    g.DrawString(Language.T("Margin Call"), Font, brushFore, xMarginCallBar - widthMarginCallLabel,
                                 yTop);
                }
                else
                {
                    g.DrawString("MC", Font, brushFore, xMarginCallBar, yTop);
                }
            }
            else
            {
                // Draw the balance line
                g.DrawLines(new Pen(LayoutColors.ColorChartBalanceLine), balancePoints);
            }

            // Scanning note
            var fontNote = new Font(Font.FontFamily, Font.Size - 1);

            if (Data.Period != DataPeriod.M1 && Configs.Autoscan && !Data.IsIntrabarData)
            {
                g.DrawString(Language.T("Load intrabar data"), fontNote, Brushes.Red, xLeft, captionHeight - 2);
            }
            else if (Data.Period != DataPeriod.M1 && isScanPerformed)
            {
                g.DrawString(Language.T("Scanned") + data.ModellingQuolity, fontNote, Brushes.LimeGreen, xLeft,
                             captionHeight - 2);
            }

            // Scanned bars
            if (isScanPerformed && !isHideScanningLine &&
                (Data.IntraBars != null && Data.IsIntrabarData ||
                 Data.Period == DataPeriod.M1 && Data.IsTickData && Configs.UseTickData))
            {
                DataPeriod dataPeriod = Data.Period;
                Color      color      = Data.PeriodColor[Data.Period];
                int        fromBar    = data.FirstBar;
                for (int bar = data.FirstBar; bar < data.Bars; bar++)
                {
                    if (Data.IntraBarsPeriods[bar] == dataPeriod && bar != data.Bars - 1)
                    {
                        continue;
                    }
                    int xStart = (int)((fromBar - data.FirstBar) * xScale) + xLeft;
                    int xEnd   = (int)((bar - data.FirstBar) * xScale) + xLeft;
                    fromBar    = bar;
                    dataPeriod = Data.IntraBarsPeriods[bar];
                    Data.GradientPaint(g, new RectangleF(xStart, yBottom + 4, xEnd - xStart + 2, 5), color, 60);
                    color = Data.PeriodColor[Data.IntraBarsPeriods[bar]];
                }

                // Tick Data
                if (Data.IsTickData && Configs.UseTickData)
                {
                    int firstBarWithTicks = -1;
                    int lastBarWithTicks  = -1;
                    for (int b = 0; b < data.Bars; b++)
                    {
                        if (firstBarWithTicks == -1 && Data.TickData[b] != null)
                        {
                            firstBarWithTicks = b;
                        }
                        if (Data.TickData[b] != null)
                        {
                            lastBarWithTicks = b;
                        }
                    }
                    int xStart = (int)(firstBarWithTicks * xScale) + xLeft;
                    int xEnd   = (int)((lastBarWithTicks - data.FirstBar) * xScale) + xLeft;
                    if (xStart < xLeft)
                    {
                        xStart = xLeft;
                    }
                    if (xEnd < xStart)
                    {
                        xEnd = xStart;
                    }

                    Data.DrawCheckerBoard(g, Color.ForestGreen, new Rectangle(xStart, yBottom + 5, xEnd - xStart + 2, 3));
                }

                // Vertical coordinate axes
                g.DrawLine(new Pen(LayoutColors.ColorChartFore), xLeft - 1, yBottom, xLeft - 1, yBottom + 9);
            }

            // Coordinate axes
            g.DrawLine(new Pen(LayoutColors.ColorChartFore), xLeft - 1, yTop - Space, xLeft - 1, yBottom + 1);
            g.DrawLine(new Pen(LayoutColors.ColorChartFore), xLeft - 1, yBottom + 1, xRight, yBottom + 1);

            // Balance level
            g.DrawLine(new Pen(LayoutColors.ColorChartCross), xLeft, yBalance, xRight - Space + 1, yBalance);

            // Balance label
            var labelSize  = new Size(labelWidth + Space, Font.Height + 2);
            var labelPoint = new Point(xRight - Space + 2, (int)(yBalance - Font.Height / 2.0 - 1));
            var labelRect  = new Rectangle(labelPoint, labelSize);

            g.FillRectangle(new SolidBrush(LayoutColors.ColorLabelBack), labelRect);
            g.DrawRectangle(new Pen(LayoutColors.ColorChartCross), labelRect);
            g.DrawString((Math.Round(data.NetBalance)).ToString(CultureInfo.InvariantCulture), Font,
                         new SolidBrush(LayoutColors.ColorLabelText), labelRect, stringFormatCaption);

            DIBSection.DrawOnPaint(e.Graphics, bitmap, Width, Height);
        }
コード例 #2
0
        /// <summary>
        ///     Paints the charts
        /// </summary>
        private void PnlChartPaint(object sender, PaintEventArgs e)
        {
            var      pnl = (Panel)sender;
            Graphics g   = e.Graphics;

            const int space  = 5;
            const int border = 2;

            // Chart Title
            string unit                = " [" + (Configs.AccountInMoney ? Configs.AccountCurrency : Language.T("points")) + "]";
            string str                 = Language.T("Balance Chart") + unit;
            var    font                = new Font(Font.FontFamily, 9);
            var    fCaptionHeight      = (float)Math.Max(font.Height, 18);
            var    rectfCaption        = new RectangleF(0, 0, pnl.ClientSize.Width, fCaptionHeight);
            var    stringFormatCaption = new StringFormat
            {
                Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center
            };

            Data.GradientPaint(g, rectfCaption, LayoutColors.ColorCaptionBack, LayoutColors.DepthCaption);
            g.DrawString(str, Font, new SolidBrush(LayoutColors.ColorCaptionText), rectfCaption, stringFormatCaption);

            // Paint the panel background
            var rectClient = new RectangleF(border, fCaptionHeight, pnl.ClientSize.Width - 2 * border,
                                            pnl.Height - fCaptionHeight - border);

            Data.GradientPaint(g, rectClient, LayoutColors.ColorChartBack, LayoutColors.DepthControl);

            var penBorder = new Pen(Data.GetGradientColor(LayoutColors.ColorCaptionBack, -LayoutColors.DepthCaption),
                                    border);

            g.DrawLine(penBorder, 1, fCaptionHeight, 1, pnl.ClientSize.Height);
            g.DrawLine(penBorder, pnl.ClientSize.Width - border + 1, fCaptionHeight, pnl.ClientSize.Width - border + 1,
                       pnl.ClientSize.Height);
            g.DrawLine(penBorder, 0, pnl.ClientSize.Height - border + 1, pnl.ClientSize.Width,
                       pnl.ClientSize.Height - border + 1);

            if (!isPaintChart)
            {
                if (Backtester.AmbiguousBars == 0)
                {
                    string sNote     = Language.T("The Comparator is useful when the backtest shows ambiguous bars!");
                    var    rectfNote = new RectangleF(0, 30, pnl.ClientSize.Width, Font.Height);
                    g.DrawString(sNote, Font, new SolidBrush(LayoutColors.ColorChartFore), rectfNote,
                                 stringFormatCaption);
                }
                return;
            }

            int bars = Data.Bars - Data.FirstBar;
            int max  = (int)Math.Max(maximum, maximumRandom) + 1;
            int min  = (int)Math.Min(minimum, minimumRandom) - 1;

            min = (int)Math.Floor(min / 10f) * 10;
            int yTop       = (int)fCaptionHeight + 2 * space + 1;
            int yBottom    = (pnl.ClientSize.Height - 2 * space - border);
            var labelWidth =
                (int)
                Math.Max(g.MeasureString(min.ToString(CultureInfo.InvariantCulture), Font).Width,
                         g.MeasureString(max.ToString(CultureInfo.InvariantCulture), Font).Width);

            labelWidth = Math.Max(labelWidth, 30);
            int xRight = pnl.ClientSize.Width - border - space - labelWidth;
            int xLeft  = border + space;

            //
            // Grid
            //
            int cntLabels = Math.Max((yBottom - yTop) / 20, 1);
            var delta     = (float)Math.Max(Math.Round((max - min) / (float)cntLabels), 10);
            int step      = (int)Math.Ceiling(delta / 10) * 10;

            cntLabels = (int)Math.Ceiling((max - min) / (float)step);
            max       = min + cntLabels * step;
            float scaleY    = (yBottom - yTop) / (cntLabels * (float)step);
            Brush brushFore = new SolidBrush(LayoutColors.ColorChartFore);
            var   penGrid   = new Pen(LayoutColors.ColorChartGrid)
            {
                DashStyle = DashStyle.Dash, DashPattern = new float[] { 4, 2 }
            };

            // Price labels
            for (int label = min; label <= max; label += step)
            {
                var labelY = (int)(yBottom - (label - min) * scaleY);
                g.DrawString(label.ToString(CultureInfo.InvariantCulture), Font, brushFore, xRight,
                             labelY - Font.Height / 2 - 1);
                g.DrawLine(penGrid, border + space, labelY, xRight, labelY);
            }

            float xScale = (xRight - 2 * space - border) / (float)bars;

            if (isRandom)
            {
                // Draws the random area and Min Max lines
                var apntMinRandom = new PointF[bars];
                var apntMaxRandom = new PointF[bars];
                for (int iBar = 0; iBar < bars; iBar++)
                {
                    apntMinRandom[iBar].X = border + space + iBar * xScale;
                    apntMinRandom[iBar].Y = yBottom - (afMinRandom[iBar] - min) * scaleY;
                    apntMaxRandom[iBar].X = border + space + iBar * xScale;
                    apntMaxRandom[iBar].Y = yBottom - (afMaxRandom[iBar] - min) * scaleY;
                }
                apntMinRandom[0].Y = apntMaxRandom[0].Y;
                var path = new GraphicsPath();
                path.AddLines(apntMinRandom);
                path.AddLine(apntMinRandom[bars - 1], apntMaxRandom[bars - 1]);
                path.AddLines(apntMaxRandom);
                var region = new Region(path);
                g.FillRegion(brushRandArea, region);
                g.DrawLines(penRandBands, apntMinRandom);
                g.DrawLines(penRandBands, apntMaxRandom);
            }

            // Draws the lines
            for (int m = 0; m < countMethods; m++)
            {
                if (!AchboxMethods[m].Checked)
                {
                    continue;
                }

                var apntLines = new PointF[bars];
                for (int iBar = 0; iBar < bars; iBar++)
                {
                    apntLines[iBar].X = border + space + iBar * xScale;
                    apntLines[iBar].Y = yBottom - (afMethods[m, iBar] - min) * scaleY;
                }

                var pen = new Pen(LayoutColors.ColorSignalRed);
                switch ((InterpolationMethod)AchboxMethods[m].Tag)
                {
                case InterpolationMethod.Pessimistic:
                    pen = penPessimistic;
                    break;

                case InterpolationMethod.Shortest:
                    pen = penShortest;
                    break;

                case InterpolationMethod.Nearest:
                    pen = penNearest;
                    break;

                case InterpolationMethod.Optimistic:
                    pen = penOptimistic;
                    break;

                case InterpolationMethod.Random:
                    pen = penRandom;
                    break;
                }
                g.DrawLines(pen, apntLines);
            }

            // Draws the average balance
            var apntBalance = new PointF[bars];

            for (int bar = 0; bar < bars; bar++)
            {
                apntBalance[bar].X = border + space + bar * xScale;
                apntBalance[bar].Y = yBottom - (afBalance[bar] - min) * scaleY;
            }
            g.DrawLines(penBalance, apntBalance);

            // Coordinate axes
            g.DrawLine(new Pen(LayoutColors.ColorChartFore), xLeft - 1, yTop - space, xLeft - 1, yBottom);
            g.DrawLine(new Pen(LayoutColors.ColorChartFore), xLeft, yBottom, xRight, yBottom);

            // Balance label
            float fBalanceY = yBottom - (afBalance[bars - 1] - min) * scaleY;

            g.DrawLine(new Pen(LayoutColors.ColorChartCross), xLeft, fBalanceY, xRight - space, fBalanceY);

            var    szBalance = new Size(labelWidth + space, Font.Height + 2);
            var    point     = new Point(xRight - space + 2, (int)(fBalanceY - Font.Height / 2.0 - 1));
            var    rec       = new Rectangle(point, szBalance);
            string sBalance  = ((int)afBalance[bars - 1]).ToString(CultureInfo.InvariantCulture);

            g.FillRectangle(new SolidBrush(LayoutColors.ColorLabelBack), rec);
            g.DrawRectangle(new Pen(LayoutColors.ColorChartCross), rec);
            g.DrawString(sBalance, Font, new SolidBrush(LayoutColors.ColorLabelText), rec, stringFormatCaption);

            // Scanning note
            var fontNote = new Font(Font.FontFamily, Font.Size - 1);

            if (Configs.Autoscan && !Data.IsIntrabarData)
            {
                g.DrawString(Language.T("Load intrabar data"), fontNote, Brushes.Red, xLeft, fCaptionHeight - 2);
            }
            else if (Backtester.IsScanPerformed)
            {
                g.DrawString(Language.T("Scanned") + " MQ " + Data.ModellingQuality.ToString("N2") + "%", fontNote,
                             Brushes.LimeGreen, border + space, fCaptionHeight - 2);
            }

            // Scanned bars
            if (Backtester.IsScanPerformed &&
                (Data.IntraBars != null && Data.IsIntrabarData ||
                 Data.Period == DataPeriod.M1 && Data.IsTickData && Configs.UseTickData))
            {
                g.DrawLine(new Pen(LayoutColors.ColorChartFore), xLeft - 1, yBottom, xLeft - 1,
                           yBottom + 8);
                DataPeriod dataPeriod = Data.Period;
                Color      color      = Data.PeriodColor[Data.Period];
                int        iFromBar   = Data.FirstBar;
                for (int bar = Data.FirstBar; bar < Data.Bars; bar++)
                {
                    if (Data.IntraBarsPeriods[bar] != dataPeriod || bar == Data.Bars - 1)
                    {
                        int xStart = (int)((iFromBar - Data.FirstBar) * xScale) + xLeft;
                        int xEnd   = (int)((bar - Data.FirstBar) * xScale) + xLeft;
                        iFromBar   = bar;
                        dataPeriod = Data.IntraBarsPeriods[bar];
                        Data.GradientPaint(g, new RectangleF(xStart, yBottom + 3, xEnd - xStart + 2, 5), color, 60);
                        color = Data.PeriodColor[Data.IntraBarsPeriods[bar]];
                    }
                }

                // Tick Data
                if (Data.IsTickData && Configs.UseTickData)
                {
                    int firstBarWithTicks = -1;
                    int lastBarWithTicks  = -1;
                    for (int b = 0; b < Data.Bars; b++)
                    {
                        if (firstBarWithTicks == -1 && Data.TickData[b] != null)
                        {
                            firstBarWithTicks = b;
                        }
                        if (Data.TickData[b] != null)
                        {
                            lastBarWithTicks = b;
                        }
                    }
                    int xStart = (int)(firstBarWithTicks * xScale) + xLeft;
                    int xEnd   = (int)((lastBarWithTicks - Data.FirstBar) * xScale) + xLeft;
                    if (xStart < xLeft)
                    {
                        xStart = xLeft;
                    }
                    if (xEnd < xStart)
                    {
                        xEnd = xStart;
                    }

                    Data.DrawCheckerBoard(g, Color.ForestGreen, new Rectangle(xStart, yBottom + 4, xEnd - xStart + 2, 3));
                }
            }
        }
コード例 #3
0
        /// <summary>
        ///     Repaint the panel Info
        /// </summary>
        private void PnlInfoPaint(object sender, PaintEventArgs e)
        {
            // +------------------------------------------------------+
            // |                   Data                               |
            // |------------------- ----------------------------------+
            // | Period  | Bars  | From | Until | Cover |  %  | Label |
            // |------------------------------------------------------+
            //xp0       xp1     xp2    xp3     xp4     xp5   xp6     xp7

            Graphics g = e.Graphics;

            g.Clear(LayoutColors.ColorControlBack);

            if (!Data.IsData || !Data.IsResult)
            {
                return;
            }

            var       pnl    = (Panel)sender;
            const int border = 2;
            const int xp0    = border;
            const int xp1    = 80;
            const int xp2    = 140;
            const int xp3    = 200;
            const int xp4    = 260;
            const int xp5    = 320;
            const int xp6    = 370;
            int       xp7    = pnl.ClientSize.Width - border;

            var size = new Size(xp7 - xp0, infoRowHeight);

            var sf = new StringFormat {
                Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Near
            };

            // Caption background
            var   pntStart     = new PointF(0, 0);
            SizeF szfCaption   = new Size(pnl.ClientSize.Width - 0, 2 * infoRowHeight);
            var   rectfCaption = new RectangleF(pntStart, szfCaption);

            Data.GradientPaint(g, rectfCaption, LayoutColors.ColorCaptionBack, LayoutColors.DepthCaption);

            // Caption Text
            var stringFormatCaption = new StringFormat
            {
                LineAlignment = StringAlignment.Center,
                Trimming      = StringTrimming.EllipsisCharacter,
                FormatFlags   = StringFormatFlags.NoWrap,
                Alignment     = StringAlignment.Near
            };
            string stringCaptionText = Language.T("Intrabar Data");
            float  captionWidth      = Math.Min(InfoPanel.ClientSize.Width, xp7 - xp0);
            float  captionTextWidth  = g.MeasureString(stringCaptionText, fontInfo).Width;
            float  captionTextX      = Math.Max((captionWidth - captionTextWidth) / 2f, 0);
            var    pfCaptionText     = new PointF(captionTextX, 0);
            var    sfCaptionText     = new SizeF(captionWidth - captionTextX, infoRowHeight);

            rectfCaption = new RectangleF(pfCaptionText, sfCaptionText);

            Brush brush = new SolidBrush(LayoutColors.ColorCaptionText);

            // First caption row
            g.DrawString(stringCaptionText, fontInfo, brush, rectfCaption, stringFormatCaption);

            // Second title row
            g.DrawString(Language.T("Period"), fontInfo, brush, (xp1 + xp0) / 2f, infoRowHeight, sf);
            g.DrawString(Language.T("Bars"), fontInfo, brush, (xp2 + xp1) / 2f, infoRowHeight, sf);
            g.DrawString(Language.T("From"), fontInfo, brush, (xp3 + xp2) / 2f, infoRowHeight, sf);
            g.DrawString(Language.T("Until"), fontInfo, brush, (xp4 + xp3) / 2f, infoRowHeight, sf);
            g.DrawString(Language.T("Coverage"), fontInfo, brush, (xp5 + xp4) / 2f, infoRowHeight, sf);
            g.DrawString("%", fontInfo, brush, (xp6 + xp5) / 2f, infoRowHeight, sf);
            g.DrawString(Language.T("Label"), fontInfo, brush, (xp7 + xp6) / 2f, infoRowHeight, sf);

            brush = new SolidBrush(LayoutColors.ColorControlText);
            int allPeriods = Enum.GetValues(typeof(DataPeriod)).Length;

            for (int period = 0; period <= allPeriods; period++)
            {
                int y     = (period + 2) * infoRowHeight;
                var point = new Point(xp0, y);

                if (Math.Abs(period % 2f - 0) > 0.0001)
                {
                    g.FillRectangle(new SolidBrush(LayoutColors.ColorEvenRowBack), new Rectangle(point, size));
                }
            }

            // Tick statistics
            if (isTickDataFile)
            {
                g.DrawString(Language.T("Tick"), fontInfo, brush, (xp1 + xp0) / 2, 2 * infoRowHeight, sf);
                if (Data.IsTickData && Configs.UseTickData)
                {
                    int firstBarWithTicks = -1;
                    int lastBarWithTicks  = -1;
                    int tickBars          = 0;
                    for (int b = 0; b < Data.Bars; b++)
                    {
                        if (firstBarWithTicks == -1 && Data.TickData[b] != null)
                        {
                            firstBarWithTicks = b;
                        }
                        if (Data.TickData[b] != null)
                        {
                            lastBarWithTicks = b;
                            tickBars++;
                        }
                    }
                    double percentage = 100d * tickBars / Data.Bars;

                    int    y     = 2 * infoRowHeight;
                    string ticks = (Data.Ticks > 999999)
                                       ? (Data.Ticks / 1000).ToString(CultureInfo.InvariantCulture) + "K"
                                       : Data.Ticks.ToString(CultureInfo.InvariantCulture);
                    g.DrawString(ticks, fontInfo, brush, (xp2 + xp1) / 2, y, sf);
                    g.DrawString((firstBarWithTicks + 1).ToString(CultureInfo.InvariantCulture), fontInfo, brush,
                                 (xp3 + xp2) / 2, y, sf);
                    g.DrawString((lastBarWithTicks + 1).ToString(CultureInfo.InvariantCulture), fontInfo, brush,
                                 (xp4 + xp3) / 2, y, sf);
                    g.DrawString(tickBars.ToString(CultureInfo.InvariantCulture), fontInfo, brush, (xp5 + xp4) / 2, y, sf);
                    g.DrawString(percentage.ToString("F2"), fontInfo, brush, (xp6 + xp5) / 2, y, sf);

                    Data.DrawCheckerBoard(g, Color.ForestGreen, new Rectangle(xp6 + 10, y + 4, xp7 - xp6 - 20, 9));
                }
            }

            for (int prd = 0; prd < allPeriods; prd++)
            {
                int startY = isTickDataFile ? 3 : 2;
                int y      = (prd + startY) * infoRowHeight;

                var    period      = (DataPeriod)Enum.GetValues(typeof(DataPeriod)).GetValue(prd);
                int    intraBars   = Data.IntraBars == null || !Data.IsIntrabarData ? 0 : Data.IntraBars[prd];
                int    fromBar     = 0;
                int    untilBar    = 0;
                int    coveredBars = 0;
                double percentage  = 0;

                bool isMultyAreas = false;
                if (intraBars > 0)
                {
                    bool isFromBarFound  = false;
                    bool isUntilBarFound = false;
                    untilBar = Data.Bars;
                    for (int bar = 0; bar < Data.Bars; bar++)
                    {
                        if (!isFromBarFound && Data.IntraBarsPeriods[bar] == period)
                        {
                            fromBar        = bar;
                            isFromBarFound = true;
                        }
                        if (isFromBarFound && !isUntilBarFound &&
                            (Data.IntraBarsPeriods[bar] != period || bar == Data.Bars - 1))
                        {
                            if (bar < Data.Bars - 1)
                            {
                                isUntilBarFound = true;
                                untilBar        = bar;
                            }
                            else
                            {
                                untilBar = Data.Bars;
                            }
                            coveredBars = untilBar - fromBar;
                        }
                        if (isFromBarFound && isUntilBarFound && Data.IntraBarsPeriods[bar] == period)
                        {
                            isMultyAreas = true;
                            coveredBars++;
                        }
                    }
                    if (isFromBarFound)
                    {
                        percentage = 100d * coveredBars / Data.Bars;
                        fromBar++;
                    }
                    else
                    {
                        fromBar     = 0;
                        untilBar    = 0;
                        coveredBars = 0;
                        percentage  = 0;
                    }
                }
                else if (period == Data.Period)
                {
                    intraBars   = Data.Bars;
                    fromBar     = 1;
                    untilBar    = Data.Bars;
                    coveredBars = Data.Bars;
                    percentage  = 100;
                }

                g.DrawString(Data.DataPeriodToString(period), fontInfo, brush, (xp1 + xp0) / 2, y, sf);

                if (coveredBars > 0 || period == Data.Period)
                {
                    g.DrawString(intraBars.ToString(CultureInfo.InvariantCulture), fontInfo, brush, (xp2 + xp1) / 2, y, sf);
                    g.DrawString(fromBar.ToString(CultureInfo.InvariantCulture), fontInfo, brush, (xp3 + xp2) / 2, y, sf);
                    g.DrawString(untilBar.ToString(CultureInfo.InvariantCulture), fontInfo, brush, (xp4 + xp3) / 2, y, sf);
                    g.DrawString(coveredBars.ToString(CultureInfo.InvariantCulture) + (isMultyAreas ? "*" : ""),
                                 fontInfo, brush, (xp5 + xp4) / 2, y, sf);
                    g.DrawString(percentage.ToString("F2"), fontInfo, brush, (xp6 + xp5) / 2, y, sf);

                    var rectf = new RectangleF(xp6 + 10, y + 4, xp7 - xp6 - 20, 9);
                    Data.GradientPaint(g, rectf, Data.PeriodColor[period], 60);
                }
            }

            var penLine = new Pen(LayoutColors.ColorJournalLines);

            g.DrawLine(penLine, xp1, 2 * infoRowHeight, xp1, pnl.ClientSize.Height);
            g.DrawLine(penLine, xp2, 2 * infoRowHeight, xp2, pnl.ClientSize.Height);
            g.DrawLine(penLine, xp3, 2 * infoRowHeight, xp3, pnl.ClientSize.Height);
            g.DrawLine(penLine, xp4, 2 * infoRowHeight, xp4, pnl.ClientSize.Height);
            g.DrawLine(penLine, xp5, 2 * infoRowHeight, xp5, pnl.ClientSize.Height);
            g.DrawLine(penLine, xp6, 2 * infoRowHeight, xp6, pnl.ClientSize.Height);

            // Border
            var penBorder = new Pen(Data.GetGradientColor(LayoutColors.ColorCaptionBack, -LayoutColors.DepthCaption),
                                    border);

            g.DrawLine(penBorder, 1, 2 * infoRowHeight, 1, pnl.ClientSize.Height);
            g.DrawLine(penBorder, pnl.ClientSize.Width - border + 1, 2 * infoRowHeight, pnl.ClientSize.Width - border + 1,
                       pnl.ClientSize.Height);
            g.DrawLine(penBorder, 0, pnl.ClientSize.Height - border + 1, pnl.ClientSize.Width,
                       pnl.ClientSize.Height - border + 1);
        }