GetGradientColor() public static method

Color change
public static GetGradientColor ( Color baseColor, int depth ) : Color
baseColor Color
depth int
return Color
        /// <summary>
        /// Constructor
        /// </summary>
        public FancyPanel(string captionText, Color borderColor)
        {
            _caption          = captionText;
            _colorCaptionBack = borderColor;
            _brushCaption     = new SolidBrush(LayoutColors.ColorCaptionText);
            _penBorder        = new Pen(Data.GetGradientColor(borderColor, -LayoutColors.DepthCaption), Border);

            InitializeParameters();
        }
        /// <summary>
        /// Constructor
        /// </summary>
        public Fancy_Panel(string sCaption, Color colorCaption)
        {
            this.caption     = sCaption;
            colorCaptionBack = colorCaption;
            brushCaption     = new SolidBrush(LayoutColors.ColorCaptionText);
            penBorder        = new Pen(Data.GetGradientColor(colorCaption, -LayoutColors.DepthCaption), border);

            InitializeParameters();

            return;
        }
Esempio n. 3
0
        /// <summary>
        /// Sets the journal colors
        /// </summary>
        void SetJournalColors()
        {
            colorBack        = LayoutColors.ColorControlBack;
            colorCaptionBack = LayoutColors.ColorCaptionBack;
            brushCaptionText = new SolidBrush(LayoutColors.ColorCaptionText);
            brushEvenRowBack = new SolidBrush(LayoutColors.ColorEvenRowBack);
            brushRowText     = new SolidBrush(LayoutColors.ColorControlText);
            penLines         = new Pen(LayoutColors.ColorJournalLines);
            penBorder        = new Pen(Data.GetGradientColor(LayoutColors.ColorCaptionBack, -LayoutColors.DepthCaption), border);

            return;
        }
Esempio n. 4
0
        /// <summary>
        /// Sets the panel colors
        /// </summary>
        public void SetColors()
        {
            _colorCaptionBack         = LayoutColors.ColorCaptionBack;
            _colorBackroundEvenRows   = LayoutColors.ColorEvenRowBack;
            _colorBackroundWarningRow = LayoutColors.ColorWarningRowBack;
            _colorTextWarningRow      = LayoutColors.ColorWarningRowText;
            _colorBackroundOddRows    = LayoutColors.ColorOddRowBack;

            _brushCaption = new SolidBrush(LayoutColors.ColorCaptionText);
            _brushParams  = new SolidBrush(LayoutColors.ColorControlText);
            _brushData    = new SolidBrush(LayoutColors.ColorControlText);

            _penBorder = new Pen(Data.GetGradientColor(LayoutColors.ColorCaptionBack, -LayoutColors.DepthCaption), Border);
        }
Esempio n. 5
0
        /// <summary>
        /// Sets the journal colors
        /// </summary>
        private void SetJournalColors()
        {
            _colorBack        = LayoutColors.ColorControlBack;
            _brushCaptionText = new SolidBrush(LayoutColors.ColorCaptionText);
            _brushEvenRowBack = new SolidBrush(LayoutColors.ColorEvenRowBack);
            _brushRowText     = new SolidBrush(LayoutColors.ColorControlText);
            _penLines         = new Pen(LayoutColors.ColorJournalLines);
            _penBorder        = new Pen(Data.GetGradientColor(LayoutColors.ColorCaptionBack, -LayoutColors.DepthCaption),
                                        Border);

            ButtonsColorBack     = LayoutColors.ColorCaptionBack;
            ButtonColorFore      = LayoutColors.ColorCaptionText;
            ContextMenuColorBack = LayoutColors.ColorControlBack;
            ContextMenuColorFore = LayoutColors.ColorControlText;
        }
        /// <summary>
        /// Paints panel pnlChart
        /// </summary>
        void PnlChart_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;

            g.Clear(LayoutColors.ColorChartBack);

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

            Panel  pnl     = (Panel)sender;
            Pen    penFore = new Pen(LayoutColors.ColorControlText);
            string FF      = Data.FF;    // Format modifier to print the floats
            int    width   = pnl.ClientSize.Width;

            Size size = new Size(width, infoRowHeight);

            StringFormat sf = new StringFormat();

            sf.Alignment     = StringAlignment.Center;
            sf.LineAlignment = StringAlignment.Near;

            // Caption background
            PointF     pntStart     = new PointF(0, 0);
            SizeF      szfCaption   = new Size(width, infoRowHeight);
            RectangleF rectfCaption = new RectangleF(pntStart, szfCaption);

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

            // Caption Text
            StringFormat stringFormatCaption = new StringFormat();

            stringFormatCaption.LineAlignment = StringAlignment.Center;
            stringFormatCaption.Trimming      = StringTrimming.EllipsisCharacter;
            stringFormatCaption.FormatFlags   = StringFormatFlags.NoWrap;
            stringFormatCaption.Alignment     = StringAlignment.Center;
            string stringCaptionText = Language.T("Price Route Inside the Bar");

            rectfCaption = new RectangleF(border, 0, pnl.ClientSize.Width - 2 * border, infoRowHeight);
            g.DrawString(stringCaptionText, fontInfo, brushCaptionText, rectfCaption, stringFormatCaption);

            // Paint the panel background
            RectangleF rectClient = new RectangleF(0, infoRowHeight, pnl.ClientSize.Width, pnl.Height - infoRowHeight);

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

            // Paint bar info
            RectangleF rectBarInfo = new RectangleF(border, infoRowHeight + 1, pnl.ClientSize.Width - 2 * border, infoRowHeight);

            g.DrawString(barInfo, fontInfo, brushGridText, rectBarInfo, stringFormatCaption);

            // Searching the min and the max price and volume
            width = pnl.ClientSize.Width - 2 * border;
            double maxPrice   = Data.High[bar];
            double minPrice   = Data.Low[bar];
            int    space      = 8;
            int    spcRight   = szPrice.Width + 4;
            int    XLeft      = border + space;
            int    XRight     = width - spcRight;
            int    chartWidth = XRight - XLeft;
            int    YTop       = 2 * infoRowHeight + 6;
            int    YBottom    = pnl.ClientSize.Height - 22;
            int    barPixels  = 28;
            int    spcLeft    = 3;
            int    x          = barPixels + spcLeft;

            int pointLeft   = x + barPixels + 30;
            int pointX      = pointLeft;
            int pointRight  = XRight - 20;
            int points      = Backtester.WayPoints(bar);
            int pointRadius = 3;

            // Grid
            int    iCntLabels = (int)Math.Max((YBottom - YTop) / 30d, 1);
            double deltaPoint = (Data.InstrProperties.Digits == 5 || Data.InstrProperties.Digits == 3) ? Data.InstrProperties.Point * 100 : Data.InstrProperties.Point * 10;
            double delta      = Math.Max(Math.Round((maxPrice - minPrice) / iCntLabels, Data.InstrProperties.Point < 0.001 ? 3 : 1), deltaPoint);

            minPrice   = Math.Round(minPrice, Data.InstrProperties.Point < 0.001f ? 3 : 1) - Data.InstrProperties.Point * 10;
            minPrice  -= delta;
            maxPrice  += delta;
            iCntLabels = (int)Math.Ceiling((maxPrice - minPrice) / delta);
            maxPrice   = minPrice + iCntLabels * delta;

            double scaleY = (YBottom - YTop) / (iCntLabels * delta);
            int    yOpen  = (int)(YBottom - (Data.Open[bar] - minPrice) * scaleY);
            int    yHigh  = (int)(YBottom - (Data.High[bar] - minPrice) * scaleY);
            int    yLow   = (int)(YBottom - (Data.Low[bar] - minPrice) * scaleY);
            int    yClose = (int)(YBottom - (Data.Close[bar] - minPrice) * scaleY);

            // Find the price distance
            double priceDistance = 0;

            for (int point = 1; point < points; point++)
            {
                priceDistance += Math.Abs(Backtester.WayPoint(bar, point).Price - Backtester.WayPoint(bar, point - 1).Price);
            }
            double dPriceForAPixel = (pointRight - pointLeft) / priceDistance;

            // Points X
            int[] aiPointX = new int[points];
            aiPointX[0] = pointLeft;
            for (int point = 1; point < points - 1; point++)
            {
                int iDistance = (int)(Math.Abs(Backtester.WayPoint(bar, point).Price - Backtester.WayPoint(bar, point - 1).Price) * dPriceForAPixel);
                aiPointX[point] = aiPointX[point - 1] + iDistance;
            }
            aiPointX[points - 1] = pointRight;
            for (int point = 1; point < points - 1; point++)
            {
                if (aiPointX[point] - aiPointX[point - 1] < barPixels + 1)
                {
                    aiPointX[point] = aiPointX[point - 1] + barPixels + 1;
                }
            }
            for (int point = points - 2; point > 0; point--)
            {
                if (aiPointX[point + 1] - aiPointX[point] < barPixels + 1)
                {
                    aiPointX[point] = aiPointX[point + 1] - barPixels - 1;
                }
            }

            // Find coordinates of the Way Points
            Point[] pntWay = new Point[points];
            for (int point = 0; point < points; point++)
            {
                int pointY = (int)(YBottom - (Backtester.WayPoint(bar, point).Price - minPrice) * scaleY);
                pntWay[point] = new Point(aiPointX[point], pointY);
            }

            // Horizontal grid and Price labels
            for (double label = minPrice; label <= maxPrice + Data.InstrProperties.Point; label += delta)
            {
                int labelY = (int)(YBottom - (label - minPrice) * scaleY);
                g.DrawString(label.ToString(Data.FF), Font, brushGridText, XRight, labelY - Font.Height / 2 - 1);
                g.DrawLine(penGrid, border + space, labelY, XRight, labelY);
            }

            // Vertical Grid
            g.DrawLine(penGrid, x + barPixels / 2 - 1, YTop, x + barPixels / 2 - 1, YBottom + 2);
            for (int point = 0; point < points; point++)
            {
                Point pt1 = new Point(pntWay[point].X, YTop);
                Point pt2 = new Point(pntWay[point].X, YBottom + 2);
                Point pt3 = new Point(pntWay[point].X - 5, YBottom + 4);
                g.DrawLine(penGrid, pt1, pt2);
                g.DrawString((point + 1).ToString(), Font, brushGridText, pt3);
            }

            // Bar Number
            string barNumber = (bar + 1).ToString();
            int    stringX   = x + barPixels / 2 - 1 - g.MeasureString(barNumber, Font).ToSize().Width / 2;

            if (Backtester.BackTestEval(bar) == "Ambiguous")
            {
                g.DrawString(barNumber, Font, brushRed, stringX, YBottom + 4);
            }
            else
            {
                g.DrawString(barNumber, Font, brushGridText, stringX, YBottom + 4);
            }

            // Draw the bar
            g.DrawLine(penBarBorder, x + barPixels / 2 - 1, yLow, x + barPixels / 2 - 1, yHigh);
            if (yClose < yOpen) // White bar
            {
                Rectangle           rect    = new Rectangle(x, yClose, barPixels - 2, yOpen - yClose);
                LinearGradientBrush lgBrush = new LinearGradientBrush(rect, colorBarWight1, colorBarWight2, 5f);
                g.FillRectangle(lgBrush, rect);
                g.DrawRectangle(penBarBorder, x, yClose, barPixels - 2, yOpen - yClose);
            }
            else if (yClose > yOpen) // Black bar
            {
                Rectangle           rect    = new Rectangle(x, yOpen, barPixels - 2, yClose - yOpen);
                LinearGradientBrush lgBrush = new LinearGradientBrush(rect, colorBarBlack1, colorBarBlack2, 5f);
                g.FillRectangle(lgBrush, rect);
                g.DrawRectangle(penBarBorder, x, yOpen, barPixels - 2, yClose - yOpen);
            }
            else    // Cross
            {
                g.DrawLine(penBarBorder, x, yClose, x + barPixels - 2, yClose);
            }

            // Draw cancelled orders
            for (int orderIndex = 0; orderIndex < Backtester.Orders(bar); orderIndex++)
            {
                int   ordNumber = Backtester.OrdNumb(bar, orderIndex);
                Order order     = Backtester.OrdFromNumb(ordNumber);
                if (order.OrdStatus != OrderStatus.Cancelled)
                {
                    continue;
                }

                if (order.OrdPrice > Data.High[bar] || order.OrdPrice < Data.Low[bar])
                {
                    continue;
                }

                int d     = barPixels / 2 - 1;
                int x1    = x + d;
                int x2    = x + barPixels - 2;
                int yDeal = (int)(YBottom - (order.OrdPrice - minPrice) * scaleY);
                Pen pen   = new Pen(LayoutColors.ColorChartGrid, 2);

                if (order.OrdDir == OrderDirection.Buy)
                {
                    g.DrawLine(pen, x, yDeal, x1, yDeal);
                    g.DrawLine(pen, x1, yDeal, x2, yDeal - d);
                    g.DrawLine(pen, x2 + 1, yDeal - d + 1, x1 + d / 2 + 1, yDeal - d + 1);
                    g.DrawLine(pen, x2, yDeal - d, x2, yDeal - d / 2);
                }
                else if (order.OrdDir == OrderDirection.Sell)
                {
                    g.DrawLine(pen, x, yDeal + 1, x1 + 1, yDeal + 1);
                    g.DrawLine(pen, x1, yDeal, x2, yDeal + d);
                    g.DrawLine(pen, x1 + d / 2 + 1, yDeal + d, x2, yDeal + d);
                    g.DrawLine(pen, x2, yDeal + d, x2, yDeal + d / 2 + 1);
                }
            }

            // Draw the deals on the bar
            for (int pos = 0; pos < Backtester.Positions(bar); pos++)
            {
                if (Backtester.PosTransaction(bar, pos) == Transaction.Transfer)
                {
                    continue;
                }

                int yDeal = (int)(YBottom - (Backtester.PosOrdPrice(bar, pos) - minPrice) * scaleY);

                if (Backtester.PosDir(bar, pos) == PosDirection.Long ||
                    Backtester.PosDir(bar, pos) == PosDirection.Short)
                {
                    int d  = barPixels / 2 - 1;
                    int x1 = x + d;
                    int x2 = x + barPixels - 2;
                    if (Backtester.OrdFromNumb(Backtester.PosOrdNumb(bar, pos)).OrdDir == OrderDirection.Buy)
                    {   // Buy
                        Pen pen = new Pen(LayoutColors.ColorTradeLong, 2);
                        g.DrawLine(pen, x, yDeal, x1, yDeal);
                        g.DrawLine(pen, x1, yDeal, x2, yDeal - d);
                        g.DrawLine(pen, x2 + 1, yDeal - d + 1, x1 + d / 2 + 1, yDeal - d + 1);
                        g.DrawLine(pen, x2, yDeal - d, x2, yDeal - d / 2);
                    }
                    else
                    {   // Sell
                        Pen pen = new Pen(LayoutColors.ColorTradeShort, 2);
                        g.DrawLine(pen, x, yDeal + 1, x1 + 1, yDeal + 1);
                        g.DrawLine(pen, x1, yDeal, x2, yDeal + d);
                        g.DrawLine(pen, x1 + d / 2 + 1, yDeal + d, x2, yDeal + d);
                        g.DrawLine(pen, x2, yDeal + d, x2, yDeal + d / 2 + 1);
                    }
                }
                else if (Backtester.PosDir(bar, pos) == PosDirection.Closed)
                {   // Close position
                    int d   = barPixels / 2 - 1;
                    int x1  = x + d;
                    int x2  = x + barPixels - 3;
                    Pen pen = new Pen(LayoutColors.ColorTradeClose, 2);
                    g.DrawLine(pen, x, yDeal, x1, yDeal);
                    g.DrawLine(pen, x1, yDeal + d / 2, x2, yDeal - d / 2);
                    g.DrawLine(pen, x1, yDeal - d / 2, x2, yDeal + d / 2);
                }
            }

            // Draw position lots
            for (int point = 0; point < points; point++)
            {
                int posNumber = Backtester.WayPoint(bar, point).PosNumb;
                if (posNumber == -1)
                {
                    continue;
                }

                double       posLots      = Backtester.PosFromNumb(posNumber).PosLots;
                PosDirection posDirection = Backtester.PosFromNumb(posNumber).PosDir;
                WayPointType wpType       = Backtester.WayPoint(bar, point).WPType;

                int posHight = (int)(Math.Max(posLots * 2, 2));
                int posY     = YBottom - posHight;
                int d        = (barPixels - 1) / 2;
                x = pntWay[point].X - d;

                if (posDirection == PosDirection.Long)
                {    // Long
                    Rectangle           rect    = new Rectangle(x - 1, posY, barPixels + 1, posHight);
                    LinearGradientBrush lgBrush = new LinearGradientBrush(rect, colorLongTrade1, colorLongTrade2, 0f);
                    rect = new Rectangle(x, posY, barPixels - 1, posHight);
                    g.FillRectangle(lgBrush, rect);
                }
                else if (posDirection == PosDirection.Short)
                {   // Short
                    Rectangle           rect    = new Rectangle(x - 1, posY, barPixels + 1, posHight);
                    LinearGradientBrush lgBrush = new LinearGradientBrush(rect, colorShortTrade1, colorShortTrade2, 0f);
                    rect = new Rectangle(x, posY, barPixels - 1, posHight);
                    g.FillRectangle(lgBrush, rect);
                }
                else if (posDirection == PosDirection.Closed && wpType == WayPointType.Exit)
                {   // Closed
                    Rectangle           rect    = new Rectangle(x - 1, YBottom - 2, barPixels + 1, 2);
                    LinearGradientBrush lgBrush = new LinearGradientBrush(rect, colorClosedTrade1, colorClosedTrade2, 0f);
                    rect = new Rectangle(x, YBottom - 2, barPixels - 1, 2);
                    g.FillRectangle(lgBrush, rect);
                }
            }

            // Draw the Beziers
            for (int point = 1; point < points; point++)
            {
                Point ptKnot1 = pntWay[point - 1];
                Point ptKnot2 = pntWay[point];

                int ctrlX1 = (ptKnot1.X + ptKnot2.X) / 2;
                int ctrlX2 = (ptKnot1.X + ptKnot2.X) / 2;

                int ctrlY1 = ptKnot1.Y;
                int ctrlY2 = ptKnot2.Y;

                if (point > 1)
                {
                    if (pntWay[point - 2].Y > pntWay[point - 1].Y && pntWay[point - 1].Y > pntWay[point].Y ||
                        pntWay[point - 2].Y < pntWay[point - 1].Y && pntWay[point - 1].Y < pntWay[point].Y)
                    {
                        ctrlY1 = (pntWay[point - 1].Y + pntWay[point].Y) / 2;
                    }
                }
                if (point < points - 1)
                {
                    if (pntWay[point - 1].Y > pntWay[point].Y && pntWay[point].Y > pntWay[point + 1].Y ||
                        pntWay[point - 1].Y < pntWay[point].Y && pntWay[point].Y < pntWay[point + 1].Y)
                    {
                        ctrlY2 = (pntWay[point - 1].Y + pntWay[point].Y) / 2;
                    }
                }

                if (point == 1)
                {
                    ctrlX1 = ptKnot1.X;
                    ctrlY1 = ptKnot1.Y;
                }
                if (point == points - 1)
                {
                    ctrlX2 = ptKnot2.X;
                    ctrlY2 = ptKnot2.Y;
                }

                Point ptControl1 = new Point(ctrlX1, ctrlY1);
                Point ptControl2 = new Point(ctrlX2, ctrlY2);

                g.DrawBezier(penCross, ptKnot1, ptControl1, ptControl2, ptKnot2);
            }

            // Draw the WayPoints
            Brush brushWeyPnt = new SolidBrush(LayoutColors.ColorChartBack);

            for (int point = 0; point < points; point++)
            {
                g.FillEllipse(brushWeyPnt, pntWay[point].X - pointRadius, pntWay[point].Y - pointRadius, 2 * pointRadius, 2 * pointRadius);
                g.DrawEllipse(penCross, pntWay[point].X - pointRadius, pntWay[point].Y - pointRadius, 2 * pointRadius, 2 * pointRadius);
            }

            // Draw the deals on the route
            for (int point = 0; point < points; point++)
            {
                int posNumber = Backtester.WayPoint(bar, point).PosNumb;
                int ordNumber = Backtester.WayPoint(bar, point).OrdNumb;

                if (posNumber < 0 || ordNumber < 0)
                {
                    continue;
                }

                PosDirection   posDirection = Backtester.PosFromNumb(posNumber).PosDir;
                OrderDirection ordDirection = Backtester.OrdFromNumb(ordNumber).OrdDir;
                WayPointType   wpType       = Backtester.WayPoint(bar, point).WPType;

                if (Backtester.PosFromNumb(posNumber).Transaction == Transaction.Transfer ||
                    wpType == WayPointType.Cancel || wpType == WayPointType.None ||
                    wpType == WayPointType.Open || wpType == WayPointType.High ||
                    wpType == WayPointType.Low || wpType == WayPointType.Close)
                {
                    continue;
                }

                int yDeal = pntWay[point].Y;

                if (posDirection == PosDirection.Long ||
                    posDirection == PosDirection.Short)
                {
                    int d = barPixels / 2 - 1;
                    x = pntWay[point].X - d;
                    int x1 = pntWay[point].X;
                    int x2 = x + barPixels - 2;
                    if (ordDirection == OrderDirection.Buy)
                    {   // Buy
                        Pen pen = new Pen(LayoutColors.ColorTradeLong, 2);
                        g.DrawLine(pen, x, yDeal, x1, yDeal);
                        g.DrawLine(pen, x1, yDeal, x2, yDeal - d);
                        g.DrawLine(pen, x2 + 1, yDeal - d + 1, x1 + d / 2 + 1, yDeal - d + 1);
                        g.DrawLine(pen, x2, yDeal - d, x2, yDeal - d / 2);
                    }
                    else
                    {   // Sell
                        Pen pen = new Pen(LayoutColors.ColorTradeShort, 2);
                        g.DrawLine(pen, x, yDeal + 1, x1 + 1, yDeal + 1);
                        g.DrawLine(pen, x1, yDeal, x2, yDeal + d);
                        g.DrawLine(pen, x1 + d / 2 + 1, yDeal + d, x2, yDeal + d);
                        g.DrawLine(pen, x2, yDeal + d, x2, yDeal + d / 2 + 1);
                    }
                }
                else if (posDirection == PosDirection.Closed)
                {   // Close position
                    int d = barPixels / 2 - 1;
                    x = pntWay[point].X - d;
                    int x1  = pntWay[point].X;
                    int x2  = x + barPixels - 3;
                    Pen pen = new Pen(LayoutColors.ColorTradeClose, 2);
                    g.DrawLine(pen, x, yDeal, x1, yDeal);
                    g.DrawLine(pen, x1, yDeal + d / 2, x2, yDeal - d / 2);
                    g.DrawLine(pen, x1, yDeal - d / 2, x2, yDeal + d / 2);
                }
            }

            // Coordinate axes
            g.DrawLine(penAxes, XLeft, YTop - 4, XLeft, YBottom); // Vertical left line
            g.DrawLine(penAxes, XLeft, YBottom, XRight, YBottom);

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

            g.DrawLine(penBorder, 1, infoRowHeight, 1, pnl.ClientSize.Height);
            g.DrawLine(penBorder, pnl.ClientSize.Width - border + 1, 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);
        }
        /// <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("pips")) + "]";
            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;

            //
            // 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 fScaleX = (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 * fScaleX;
                    apntMinRandom[iBar].Y = yBottom - (_afMinRandom[iBar] - min) * scaleY;
                    apntMaxRandom[iBar].X = border + space + iBar * fScaleX;
                    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 * fScaleX;
                    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 * fScaleX;
                apntBalance[bar].Y = yBottom - (_afBalance[bar] - min) * scaleY;
            }
            g.DrawLines(_penBalance, apntBalance);

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

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

            g.DrawLine(new Pen(LayoutColors.ColorChartCross), border + space, 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, border + space, 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 (Data.IntraBars != null && Data.IsIntrabarData && Backtester.IsScanPerformed)
            {
                g.DrawLine(new Pen(LayoutColors.ColorChartFore), border + space - 1, yBottom, border + space - 1,
                           yBottom + 8);
                DataPeriods 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) * fScaleX) + border + space;
                        int xEnd   = (int)((bar - Data.FirstBar) * fScaleX) + border + space;
                        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]];
                    }
                }
            }
        }
        /// <summary>
        /// Panel Slot Paint
        /// </summary>
        void PnlSlot_Paint(object sender, PaintEventArgs e)
        {
            Panel     pnl      = (Panel)sender;
            Graphics  g        = e.Graphics;
            int       slot     = (int)pnl.Tag;
            int       width    = pnl.ClientSize.Width;
            SlotTypes slotType = strategy.GetSlotType(slot);

            Color colorBackground             = LayoutColors.ColorSlotBackground;
            Color colorCaptionText            = LayoutColors.ColorSlotCaptionText;
            Color colorCaptionBackOpen        = LayoutColors.ColorSlotCaptionBackOpen;
            Color colorCaptionBackOpenFilter  = LayoutColors.ColorSlotCaptionBackOpenFilter;
            Color colorCaptionBackClose       = LayoutColors.ColorSlotCaptionBackClose;
            Color colorCaptionBackCloseFilter = LayoutColors.ColorSlotCaptionBackCloseFilter;
            Color colorIndicatorNameText      = LayoutColors.ColorSlotIndicatorText;
            Color colorLogicText = LayoutColors.ColorSlotLogicText;
            Color colorParamText = LayoutColors.ColorSlotParamText;
            Color colorValueText = LayoutColors.ColorSlotValueText;
            Color colorDash      = LayoutColors.ColorSlotDash;

            // Caption
            string stringCaptionText = string.Empty;
            Color  colorCaptionBack  = LayoutColors.ColorSignalRed;

            switch (slotType)
            {
            case SlotTypes.Open:
                stringCaptionText = Language.T("Opening Point of the Position");
                colorCaptionBack  = colorCaptionBackOpen;
                break;

            case SlotTypes.OpenFilter:
                stringCaptionText = Language.T("Opening Logic Condition");
                colorCaptionBack  = colorCaptionBackOpenFilter;
                break;

            case SlotTypes.Close:
                stringCaptionText = Language.T("Closing Point of the Position");
                colorCaptionBack  = colorCaptionBackClose;
                break;

            case SlotTypes.CloseFilter:
                stringCaptionText = Language.T("Closing Logic Condition");
                colorCaptionBack  = colorCaptionBackCloseFilter;
                break;

            default:
                break;
            }

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

            Font         fontCaptionText     = new Font(Font.FontFamily, 9);
            float        fCaptionHeight      = (float)Math.Max(fontCaptionText.Height, 18);
            float        fCaptionWidth       = width;
            Brush        brushCaptionText    = new SolidBrush(colorCaptionText);
            StringFormat stringFormatCaption = new StringFormat();

            stringFormatCaption.LineAlignment = StringAlignment.Center;
            stringFormatCaption.Trimming      = StringTrimming.EllipsisCharacter;
            stringFormatCaption.FormatFlags   = StringFormatFlags.NoWrap;
            stringFormatCaption.Alignment     = StringAlignment.Center;

            RectangleF rectfCaption = new RectangleF(0, 0, fCaptionWidth, fCaptionHeight);

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

            if (showRemoveSlotButtons && slot != strategy.OpenSlot && slot != strategy.CloseSlot)
            {
                int iButtonDimentions = (int)fCaptionHeight - 2;
                int iButtonX          = width - iButtonDimentions - 1;
                abtnRemoveSlot[slot].Size     = new Size(iButtonDimentions, iButtonDimentions);
                abtnRemoveSlot[slot].Location = new Point(iButtonX, 1);

                float  fCaptionTextWidth = g.MeasureString(stringCaptionText, fontCaptionText).Width;
                float  fCaptionTextX     = (float)Math.Max((fCaptionWidth - fCaptionTextWidth) / 2f, 0);
                PointF pfCaptionText     = new PointF(fCaptionTextX, 0);
                SizeF  sfCaptionText     = new SizeF(iButtonX - fCaptionTextX, fCaptionHeight);
                rectfCaption = new RectangleF(pfCaptionText, sfCaptionText);
                stringFormatCaption.Alignment = StringAlignment.Near;
            }
            g.DrawString(stringCaptionText, fontCaptionText, brushCaptionText, rectfCaption, stringFormatCaption);

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

            // Paints the panel
            RectangleF rectfPanel = new RectangleF(border, fCaptionHeight, pnl.Width - 2 * border, pnl.Height - fCaptionHeight - border);

            Data.GradientPaint(g, rectfPanel, colorBackground, LayoutColors.DepthControl);

            int iVPosition = (int)fCaptionHeight + 3;

            // Padlock image
            if (showPadlockImg)
            {
                if (strategy.Slot[slot].SlotStatus == StrategySlotStatus.Locked)
                {
                    g.DrawImage(Properties.Resources.padlock_img, 1, 1, 16, 16);
                }
                else if (strategy.Slot[slot].SlotStatus == StrategySlotStatus.Open)
                {
                    g.DrawImage(Properties.Resources.open_padlock, 1, 1, 16, 16);
                }
                else if (strategy.Slot[slot].SlotStatus == StrategySlotStatus.Linked)
                {
                    g.DrawImage(Properties.Resources.linked, 1, 1, 16, 16);
                }
            }

            // Indicator name
            StringFormat stringFormatIndicatorName = new StringFormat();

            stringFormatIndicatorName.Alignment     = StringAlignment.Center;
            stringFormatIndicatorName.LineAlignment = StringAlignment.Center;

            stringFormatIndicatorName.FormatFlags = StringFormatFlags.NoWrap;

            Font  fontIndicator  = new Font(Font.FontFamily, 11f, FontStyle.Regular);
            Brush brushIndName   = new SolidBrush(colorIndicatorNameText);
            float fIndNameHeight = fontIndicator.Height;
            float fGroupWidth    = 0;

            if (Configs.UseLogicalGroups && (slotType == SlotTypes.OpenFilter || slotType == SlotTypes.CloseFilter))
            {
                string sLogicalGroup = "[" + strategy.Slot[slot].LogicalGroup + "]";
                fGroupWidth = g.MeasureString(sLogicalGroup, fontIndicator).Width;
                RectangleF rectGroup = new RectangleF(0, iVPosition, fGroupWidth, fIndNameHeight);
                g.DrawString(sLogicalGroup, fontIndicator, brushIndName, rectGroup, stringFormatIndicatorName);
            }
            stringFormatIndicatorName.Trimming = StringTrimming.EllipsisCharacter;
            string sIndicatorName  = strategy.Slot[slot].IndicatorName;
            float  fIndicatorWidth = g.MeasureString(sIndicatorName, fontIndicator).Width;

            RectangleF rectIndName;

            if (width >= 2 * fGroupWidth + fIndicatorWidth)
            {
                rectIndName = new RectangleF(0, iVPosition, width, fIndNameHeight);
            }
            else
            {
                rectIndName = new RectangleF(fGroupWidth, iVPosition, width - fGroupWidth, fIndNameHeight);
            }

            g.DrawString(sIndicatorName, fontIndicator, brushIndName, rectIndName, stringFormatIndicatorName);
            iVPosition += (int)fIndNameHeight;

            if (slotMinMidMax == SlotSizeMinMidMax.min)
            {
                return;
            }

            // Logic
            StringFormat stringFormatLogic = new StringFormat();

            stringFormatLogic.Alignment     = StringAlignment.Center;
            stringFormatLogic.LineAlignment = StringAlignment.Center;
            stringFormatLogic.Trimming      = StringTrimming.EllipsisCharacter;
            stringFormatLogic.FormatFlags   = StringFormatFlags.NoClip;

            float padding = space;

            if (strategy.Slot[slot].IndParam.ListParam[0].Enabled)
            {
                string     sValue     = strategy.Slot[slot].IndParam.ListParam[0].Text;
                Font       fontLogic  = new Font(Font.FontFamily, 10.5f, FontStyle.Regular);
                SizeF      sizeValue  = g.MeasureString(sValue, fontLogic, (int)(width - 2 * padding), stringFormatLogic);
                RectangleF rectValue  = new RectangleF(padding, iVPosition, width - 2 * padding, sizeValue.Height);
                Brush      brushLogic = new SolidBrush(colorLogicText);

                g.DrawString(sValue, fontLogic, brushLogic, rectValue, stringFormatLogic);
                iVPosition += (int)sizeValue.Height;
            }

            if (slotMinMidMax == SlotSizeMinMidMax.mid)
            {
                return;
            }

            // Parameters
            StringFormat stringFormat = new StringFormat();

            stringFormat.Trimming    = StringTrimming.EllipsisCharacter;
            stringFormat.FormatFlags = StringFormatFlags.NoWrap;

            Font  fontParam  = new Font(Font.FontFamily, 9f, FontStyle.Regular);
            Font  fontValue  = new Font(Font.FontFamily, 9f, FontStyle.Regular);
            Brush brushParam = new SolidBrush(colorParamText);
            Brush brushValue = new SolidBrush(colorValueText);
            Pen   penDash    = new Pen(colorDash);

            // Find Maximum width of the strings
            float maxParamWidth = 0;
            float maxValueWidth = 0;

            for (int i = 1; i < 5; i++)
            {
                if (!strategy.Slot[slot].IndParam.ListParam[i].Enabled)
                {
                    continue;
                }

                string sParam    = strategy.Slot[slot].IndParam.ListParam[i].Caption;
                string sValue    = strategy.Slot[slot].IndParam.ListParam[i].Text;
                SizeF  sizeParam = g.MeasureString(sParam, fontParam);
                SizeF  sizeValue = g.MeasureString(sValue, fontValue);

                if (maxParamWidth < sizeParam.Width)
                {
                    maxParamWidth = sizeParam.Width;
                }

                if (maxValueWidth < sizeValue.Width)
                {
                    maxValueWidth = sizeValue.Width;
                }
            }

            foreach (NumericParam numericParam in strategy.Slot[slot].IndParam.NumParam)
            {
                if (!numericParam.Enabled)
                {
                    continue;
                }

                string sParam    = numericParam.Caption;
                string sValue    = numericParam.ValueToString;
                SizeF  sizeParam = g.MeasureString(sParam, fontParam);
                SizeF  sizeValue = g.MeasureString(sValue, fontValue);

                if (maxParamWidth < sizeParam.Width)
                {
                    maxParamWidth = sizeParam.Width;
                }

                if (maxValueWidth < sizeValue.Width)
                {
                    maxValueWidth = sizeValue.Width;
                }
            }

            foreach (CheckParam checkParam in strategy.Slot[slot].IndParam.CheckParam)
            {
                if (!checkParam.Enabled)
                {
                    continue;
                }

                string param     = checkParam.Caption;
                string value     = checkParam.Checked ? "Yes" : "No";
                SizeF  sizeParam = g.MeasureString(param, fontParam);
                SizeF  sizeValue = g.MeasureString(value, fontValue);

                if (maxParamWidth < sizeParam.Width)
                {
                    maxParamWidth = sizeParam.Width;
                }

                if (maxValueWidth < sizeValue.Width)
                {
                    maxValueWidth = sizeValue.Width;
                }
            }

            // Padding Param Padding Dash Padding Value Padding
            float dashWidth      = 5;
            float necessaryWidth = 4 * padding + maxParamWidth + maxValueWidth + dashWidth;

            if (width > necessaryWidth)
            {   // 2*Padding Param Padding Dash Padding Value 2*Padding
                padding = (float)Math.Max((pnl.ClientSize.Width - maxParamWidth - maxValueWidth - dashWidth) / 6, padding);
            }
            else
            {
                padding = 2;
            }

            float tabParam = 2 * padding;
            float tabDash  = tabParam + maxParamWidth + padding;
            float tabValue = tabDash + dashWidth + padding;

            // List Params
            for (int i = 1; i < 5; i++)
            {
                if (!strategy.Slot[slot].IndParam.ListParam[i].Enabled)
                {
                    continue;
                }

                string     sParam     = strategy.Slot[slot].IndParam.ListParam[i].Caption;
                string     sValue     = strategy.Slot[slot].IndParam.ListParam[i].Text;
                PointF     pointParam = new PointF(tabParam, iVPosition);
                PointF     pointDash1 = new PointF(tabDash, iVPosition + fontParam.Height / 2 + 2);
                PointF     pointDash2 = new PointF(tabDash + dashWidth, iVPosition + fontParam.Height / 2 + 2);
                PointF     pointValue = new PointF(tabValue, iVPosition);
                SizeF      sizefValue = new SizeF(Math.Max(width - tabValue, 0), fontValue.Height + 2);
                RectangleF rectfValue = new RectangleF(pointValue, sizefValue);

                g.DrawString(sParam, fontParam, brushParam, pointParam);
                g.DrawLine(penDash, pointDash1, pointDash2);
                g.DrawString(sValue, fontValue, brushValue, rectfValue, stringFormat);
                iVPosition += fontValue.Height;
            }

            // Num Params
            foreach (NumericParam numericParam in strategy.Slot[slot].IndParam.NumParam)
            {
                if (!numericParam.Enabled)
                {
                    continue;
                }

                string     sParam     = numericParam.Caption;
                string     sValue     = numericParam.ValueToString;
                PointF     pointParam = new PointF(tabParam, iVPosition);
                PointF     pointDash1 = new PointF(tabDash, iVPosition + fontParam.Height / 2 + 2);
                PointF     pointDash2 = new PointF(tabDash + dashWidth, iVPosition + fontParam.Height / 2 + 2);
                PointF     pointValue = new PointF(tabValue, iVPosition);
                SizeF      sizefValue = new SizeF(Math.Max(width - tabValue, 0), fontValue.Height + 2);
                RectangleF rectfValue = new RectangleF(pointValue, sizefValue);

                g.DrawString(sParam, fontParam, brushParam, pointParam);
                g.DrawLine(penDash, pointDash1, pointDash2);
                g.DrawString(sValue, fontValue, brushValue, rectfValue, stringFormat);
                iVPosition += fontValue.Height;
            }

            // Check Params
            foreach (CheckParam checkParam in strategy.Slot[slot].IndParam.CheckParam)
            {
                if (!checkParam.Enabled)
                {
                    continue;
                }

                string     param      = checkParam.Caption;
                string     salue      = checkParam.Checked ? "Yes" : "No";
                PointF     pointParam = new PointF(tabParam, iVPosition);
                PointF     pointDash1 = new PointF(tabDash, iVPosition + fontParam.Height / 2 + 2);
                PointF     pointDash2 = new PointF(tabDash + dashWidth, iVPosition + fontParam.Height / 2 + 2);
                PointF     pointValue = new PointF(tabValue, iVPosition);
                SizeF      sizefValue = new SizeF(Math.Max(width - tabValue, 0), fontValue.Height + 2);
                RectangleF rectfValue = new RectangleF(pointValue, sizefValue);

                g.DrawString(param, fontParam, brushParam, pointParam);
                g.DrawLine(penDash, pointDash1, pointDash2);
                g.DrawString(salue, fontValue, brushValue, rectfValue, stringFormat);
                iVPosition += fontValue.Height;
            }

            return;
        }
Esempio n. 9
0
        /// <summary>
        /// Sets the chart parameters
        /// </summary>
        public void InitChart()
        {
            // Chart Title
            _strChartTitle = Language.T("Trade Distribution Chart");
            _font          = new Font(Font.FontFamily, 9);
            _captionHeight = Math.Max(_font.Height, 18);
            _rectfCaption  = new RectangleF(0, 0, ClientSize.Width, _captionHeight);
            _rectSubHeader = new RectangleF(0, _captionHeight, ClientSize.Width, _captionHeight);

            _sfCaption = new StringFormat
            {
                Alignment     = StringAlignment.Center,
                LineAlignment = StringAlignment.Center,
                Trimming      = StringTrimming.EllipsisCharacter,
                FormatFlags   = StringFormatFlags.NoWrap
            };

            _brushFore = new SolidBrush(LayoutColors.ColorChartFore);
            _penGrid   = new Pen(LayoutColors.ColorChartGrid)
            {
                DashStyle = DashStyle.Dash, DashPattern = new float[] { 4, 2 }
            };
            _penBorder = new Pen(Data.GetGradientColor(LayoutColors.ColorCaptionBack, -LayoutColors.DepthCaption), Border);

            if (_isNotPaint)
            {
                return;
            }

            _yTop    = (int)(2 * _captionHeight + Space + 1);
            _yBottom = ClientSize.Height - 2 * Space - 1 - Border;
            _xAxisY  = _yBottom - 3 - _font.Height;

            Graphics g = CreateGraphics();

            _labelWidthY = (int)
                           Math.Max(g.MeasureString(_yAxisMin.ToString(CultureInfo.InvariantCulture), Font).Width,
                                    g.MeasureString(_yAxisMax.ToString(CultureInfo.InvariantCulture), Font).Width);
            _labelWidthX = (int)
                           Math.Max(g.MeasureString(_xAxisMin.ToString(CultureInfo.InvariantCulture), Font).Width,
                                    g.MeasureString(_xAxisMax.ToString(CultureInfo.InvariantCulture), Font).Width);
            g.Dispose();
            _labelWidthY  = Math.Max(_labelWidthY, 30);
            _labelWidthX += 3;

            _xLeft  = Border + Space;
            _xRight = ClientSize.Width - Border - Space - _labelWidthY;
            _xScale = (_xRight - 2 * Space - Border) / (float)_chartBars;

            _countLabelsX = Math.Min((_xRight - _xLeft) / _labelWidthX, 20);
            _deltaX       = (float)Math.Max(Math.Round((_xAxisMax - _xAxisMin) / (float)_countLabelsX), 10);
            _stepX        = (int)Math.Ceiling(_deltaX / 10) * 10;
            _countLabelsX = (int)Math.Ceiling((_xAxisMax - _xAxisMin) / (float)_stepX);
            _xAxisMax     = _xAxisMin + _countLabelsX * _stepX;

            // difference from Y Axis for Small_Balance_Chart:
            // prefer minimums because histogram counts are usually small, less than 10
            _countLabelsY = Math.Min((_xAxisY - _yTop) / 20, 20);
            _deltaY       = (float)Math.Round((_yAxisMax - _yAxisMin) / (float)_countLabelsY);
            // protect against deltaY infinity and stepY = Number.min
            _stepY = (float.IsInfinity(_deltaY)) ? 20 : (int)_deltaY;
            // protect against dividing by zero in case of no counts
            _stepY        = (_stepY == 0) ? 1 : _stepY;
            _countLabelsY = (int)Math.Ceiling((_yAxisMax - _yAxisMin) / (float)_stepY);
            // protect against dividing by zero in case of no counts
            _countLabelsY = (_countLabelsY == 0) ? 5 : _countLabelsY;

            // protect against dividing by zero in case of no counts
            _yAxisMax = (_yAxisMax == 0) ? 5 : _yAxisMax;
            _yScale   = (_xAxisY - _yTop) / (_countLabelsY * (float)_stepY);

            // Context button colors.
            ButtonsColorBack     = LayoutColors.ColorCaptionBack;
            ButtonColorFore      = LayoutColors.ColorCaptionText;
            ContextMenuColorBack = LayoutColors.ColorControlBack;
            ContextMenuColorFore = LayoutColors.ColorControlText;
        }
        /// <summary>
        /// Sets the chart params
        /// </summary>
        public void InitChart()
        {
            if (!Data.IsData || !Data.IsResult || Data.Bars <= Data.FirstBar)
            {
                return;
            }

            firstBar  = Data.FirstBar;
            bars      = Data.Bars;
            chartBars = Data.Bars - firstBar;
            int iMaxBalance = Configs.AccountInMoney ? (int)Backtester.MaxMoneyBalance : Backtester.MaxBalance;
            int iMinBalance = Configs.AccountInMoney ? (int)Backtester.MinMoneyBalance : Backtester.MinBalance;
            int iMaxEquity  = Configs.AccountInMoney ? (int)Backtester.MaxMoneyEquity  : Backtester.MaxEquity;
            int iMinEquity  = Configs.AccountInMoney ? (int)Backtester.MinMoneyEquity  : Backtester.MinEquity;

            if (Configs.AdditionalStatistics)
            {
                int iMaxLongBalance  = Configs.AccountInMoney ? (int)Backtester.MaxLongMoneyBalance  : Backtester.MaxLongBalance;
                int iMinLongBalance  = Configs.AccountInMoney ? (int)Backtester.MinLongMoneyBalance  : Backtester.MinLongBalance;
                int iMaxShortBalance = Configs.AccountInMoney ? (int)Backtester.MaxShortMoneyBalance : Backtester.MaxShortBalance;
                int iMinShortBalance = Configs.AccountInMoney ? (int)Backtester.MinShortMoneyBalance : Backtester.MinShortBalance;
                int iMaxLSBalance    = Math.Max(iMaxLongBalance, iMaxShortBalance);
                int iMinLSBalance    = Math.Min(iMinLongBalance, iMinShortBalance);

                maximum = Math.Max(Math.Max(iMaxBalance, iMaxEquity), iMaxLSBalance) + 1;
                minimum = Math.Min(Math.Min(iMinBalance, iMinEquity), iMinLSBalance) - 1;
            }
            else
            {
                maximum = Math.Max(iMaxBalance, iMaxEquity) + 1;
                minimum = Math.Min(iMinBalance, iMinEquity) - 1;
            }

            YTop    = border + space;
            YBottom = ClientSize.Height - border - space;
            XLeft   = border;
            XRight  = ClientSize.Width - border - space;
            XScale  = (XRight - XLeft) / (float)chartBars;
            YScale  = (YBottom - YTop) / (float)(maximum - minimum);

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

            apntBalance = new PointF[chartBars];
            apntEquity  = new PointF[chartBars];

            if (Configs.AdditionalStatistics)
            {
                apntLongBalance  = new PointF[chartBars];
                apntShortBalance = new PointF[chartBars];
            }

            int index = 0;

            for (int iBar = firstBar; iBar < bars; iBar++)
            {
                apntBalance[index].X = XLeft + index * XScale;
                apntEquity[index].X  = XLeft + index * XScale;
                if (Configs.AccountInMoney)
                {
                    apntBalance[index].Y = (float)(YBottom - (Backtester.MoneyBalance(iBar) - minimum) * YScale);
                    apntEquity[index].Y  = (float)(YBottom - (Backtester.MoneyEquity(iBar) - minimum) * YScale);
                }
                else
                {
                    apntBalance[index].Y = YBottom - (Backtester.Balance(iBar) - minimum) * YScale;
                    apntEquity[index].Y  = YBottom - (Backtester.Equity(iBar) - minimum) * YScale;
                }

                if (Configs.AdditionalStatistics)
                {
                    apntLongBalance[index].X  = XLeft + index * XScale;
                    apntShortBalance[index].X = XLeft + index * XScale;
                    if (Configs.AccountInMoney)
                    {
                        apntLongBalance[index].Y  = (float)(YBottom - (Backtester.LongMoneyBalance(iBar) - minimum) * YScale);
                        apntShortBalance[index].Y = (float)(YBottom - (Backtester.ShortMoneyBalance(iBar) - minimum) * YScale);
                    }
                    else
                    {
                        apntLongBalance[index].Y  = YBottom - (Backtester.LongBalance(iBar) - minimum) * YScale;
                        apntShortBalance[index].Y = YBottom - (Backtester.ShortBalance(iBar) - minimum) * YScale;
                    }
                }

                index++;
            }
        }
        /// <summary>
        /// Paints the journal
        /// </summary>
        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g = e.Graphics;

            int hScrll = -HScrollBar.Value;
            var size   = new Size(_visibalWidth, _rowHeight);
            var sf     = new StringFormat {
                Alignment = StringAlignment.Center
            };

            // Caption background
            var rectfCaption = new RectangleF(0, 0, ClientSize.Width, 2 * _rowHeight);

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

            var colorBack        = LayoutColors.ColorControlBack;
            var brushCaptionText = new SolidBrush(LayoutColors.ColorCaptionText);
            var brushEvenRowBack = new SolidBrush(LayoutColors.ColorEvenRowBack);
            var brushRowText     = new SolidBrush(LayoutColors.ColorControlText);
            var penLines         = new Pen(LayoutColors.ColorJournalLines);
            var penBorder        = new Pen(Data.GetGradientColor(LayoutColors.ColorCaptionBack, -LayoutColors.DepthCaption), Border);
            var font             = new Font(Font.FontFamily, 9);

            // Print the journal caption
            string caption = Language.T("Positions During the Bar") + (Configs.AccountInMoney ? " [" + Configs.AccountCurrency + "]" : " [" + Language.T("pips") + "]");

            g.DrawString(caption, font, brushCaptionText, new RectangleF(Point.Empty, size), sf);
            g.SetClip(new RectangleF(Border, _rowHeight, ClientSize.Width - 2 * Border, _rowHeight));
            if (Configs.AccountInMoney)
            {
                for (int i = 0; i < _columns; i++)
                {
                    g.DrawString(_titlesMoney[i], font, brushCaptionText, hScrll + (_xScaled[i] + _xScaled[i + 1]) / 2, _rowHeight, sf);
                }
            }
            else
            {
                for (int i = 0; i < _columns; i++)
                {
                    g.DrawString(_titlesPips[i], font, brushCaptionText, hScrll + (_xScaled[i] + _xScaled[i + 1]) / 2, _rowHeight, sf);
                }
            }
            g.ResetClip();

            // Paints the journal's data field
            var rectField = new RectangleF(Border, 2 * _rowHeight, ClientSize.Width - 2 * Border, ClientSize.Height - 2 * _rowHeight - Border);

            g.FillRectangle(new SolidBrush(colorBack), rectField);

            size = new Size(ClientSize.Width - VScrollBar.Width - 2 * Border, _rowHeight);

            // Prints the journal data
            for (int pos = _firstPos; pos < _firstPos + _shownPos; pos++)
            {
                int row   = pos - _firstPos;
                int y     = (row + 2) * _rowHeight;
                var point = new Point(Border, y);

                // Even row
                if (Math.Abs(row % 2f - 0) > 0.0001)
                {
                    g.FillRectangle(brushEvenRowBack, new Rectangle(point, size));
                }

                // Draw the position icon
                int iImgY = y + (int)Math.Floor((_rowHeight - 16) / 2.0);
                g.DrawImage(_positionIcons[pos - _firstPos], hScrll + 2, iImgY, 16, 16);

                // Prints the data
                g.DrawString(_journalData[row, 0], font, brushRowText, hScrll + (16 + _xScaled[1]) / 2, (row + 2) * _rowHeight, sf);
                for (int i = 1; i < _columns; i++)
                {
                    g.DrawString(_journalData[row, i], font, brushRowText, hScrll + (_xScaled[i] + _xScaled[i + 1]) / 2, (row + 2) * _rowHeight, sf);
                }
            }

            for (int i = 1; i < _columns; i++)
            {
                g.DrawLine(penLines, _xScaled[i] + hScrll, 2 * _rowHeight, _xScaled[i] + hScrll, ClientSize.Height);
            }

            // Border
            g.DrawLine(penBorder, 1, 2 * _rowHeight, 1, ClientSize.Height);
            g.DrawLine(penBorder, ClientSize.Width - Border + 1, 2 * _rowHeight, ClientSize.Width - Border + 1, ClientSize.Height);
            g.DrawLine(penBorder, 0, ClientSize.Height - Border + 1, ClientSize.Width, ClientSize.Height - Border + 1);
        }
Esempio n. 12
0
        /// <summary>
        /// Panel Slot Paint
        /// </summary>
        private void PnlSlotPaint(object sender, PaintEventArgs e)
        {
            var       pnl      = (ContextPanel)sender;
            Graphics  g        = e.Graphics;
            var       slot     = (int)pnl.Tag;
            int       width    = pnl.ClientSize.Width;
            SlotTypes slotType = _strategy.GetSlotType(slot);

            Color colorBackground             = LayoutColors.ColorSlotBackground;
            Color colorCaptionText            = LayoutColors.ColorSlotCaptionText;
            Color colorCaptionBackOpen        = LayoutColors.ColorSlotCaptionBackOpen;
            Color colorCaptionBackOpenFilter  = LayoutColors.ColorSlotCaptionBackOpenFilter;
            Color colorCaptionBackClose       = LayoutColors.ColorSlotCaptionBackClose;
            Color colorCaptionBackCloseFilter = LayoutColors.ColorSlotCaptionBackCloseFilter;
            Color colorIndicatorNameText      = LayoutColors.ColorSlotIndicatorText;
            Color colorLogicText = LayoutColors.ColorSlotLogicText;
            Color colorParamText = LayoutColors.ColorSlotParamText;
            Color colorValueText = LayoutColors.ColorSlotValueText;
            Color colorDash      = LayoutColors.ColorSlotDash;

            // Caption
            string stringCaptionText = string.Empty;
            Color  colorCaptionBack  = LayoutColors.ColorSignalRed;

            switch (slotType)
            {
            case SlotTypes.Open:
                stringCaptionText = Language.T("Opening Point of the Position");
                colorCaptionBack  = colorCaptionBackOpen;
                break;

            case SlotTypes.OpenFilter:
                stringCaptionText = Language.T("Opening Logic Condition");
                colorCaptionBack  = colorCaptionBackOpenFilter;
                break;

            case SlotTypes.Close:
                stringCaptionText = Language.T("Closing Point of the Position");
                colorCaptionBack  = colorCaptionBackClose;
                break;

            case SlotTypes.CloseFilter:
                stringCaptionText = Language.T("Closing Logic Condition");
                colorCaptionBack  = colorCaptionBackCloseFilter;
                break;
            }

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

            var   fontCaptionText     = new Font(Font.FontFamily, 9);
            float captionHeight       = Math.Max(fontCaptionText.Height, 18);
            float captionWidth        = width;
            Brush brushCaptionText    = new SolidBrush(colorCaptionText);
            var   stringFormatCaption = new StringFormat
            {
                LineAlignment = StringAlignment.Center,
                Trimming      = StringTrimming.EllipsisCharacter,
                FormatFlags   = StringFormatFlags.NoWrap,
                Alignment     = StringAlignment.Center
            };

            var rectfCaption = new RectangleF(0, 0, captionWidth, captionHeight);

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

            if (ShowRemoveSlotButtons && slot != _strategy.OpenSlot && slot != _strategy.CloseSlot)
            {
                int   buttonDimentions = (int)captionHeight - 2;
                int   buttonX          = width - buttonDimentions - 1;
                float captionTextWidth = g.MeasureString(stringCaptionText, fontCaptionText).Width;
                float captionTextX     = Math.Max((captionWidth - captionTextWidth) / 2f, 0);
                var   pfCaptionText    = new PointF(captionTextX, 0);
                var   sfCaptionText    = new SizeF(buttonX - captionTextX, captionHeight);
                rectfCaption = new RectangleF(pfCaptionText, sfCaptionText);
                stringFormatCaption.Alignment = StringAlignment.Near;
            }
            g.DrawString(stringCaptionText, fontCaptionText, brushCaptionText, rectfCaption, stringFormatCaption);

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

            // Paints the panel
            var rectfPanel = new RectangleF(Border, captionHeight, pnl.Width - 2 * Border,
                                            pnl.Height - captionHeight - Border);

            Data.GradientPaint(g, rectfPanel, colorBackground, LayoutColors.DepthControl);

            int vPosition = (int)captionHeight + 3;

            // Padlock image
            if (ShowPadlockImg)
            {
                if (_strategy.Slot[slot].SlotStatus == StrategySlotStatus.Locked)
                {
                    g.DrawImage(Resources.padlock_img, 1, 1, 16, 16);
                }
                else if (_strategy.Slot[slot].SlotStatus == StrategySlotStatus.Open)
                {
                    g.DrawImage(Resources.open_padlock, 1, 1, 16, 16);
                }
                else if (_strategy.Slot[slot].SlotStatus == StrategySlotStatus.Linked)
                {
                    g.DrawImage(Resources.linked, 1, 1, 16, 16);
                }
            }

            // Indicator name
            var stringFormatIndicatorName = new StringFormat
            {
                Alignment     = StringAlignment.Center,
                LineAlignment = StringAlignment.Center,
                FormatFlags   = StringFormatFlags.NoWrap
            };

            var   fontIndicator = new Font(Font.FontFamily, 11f, FontStyle.Regular);
            Brush brushIndName  = new SolidBrush(colorIndicatorNameText);
            float indNameHeight = fontIndicator.Height;
            float fGroupWidth   = 0;

            if (Configs.UseLogicalGroups && (slotType == SlotTypes.OpenFilter || slotType == SlotTypes.CloseFilter))
            {
                string sLogicalGroup = "[" + _strategy.Slot[slot].LogicalGroup + "]";
                fGroupWidth = g.MeasureString(sLogicalGroup, fontIndicator).Width;
                var rectGroup = new RectangleF(0, vPosition, fGroupWidth, indNameHeight);
                g.DrawString(sLogicalGroup, fontIndicator, brushIndName, rectGroup, stringFormatIndicatorName);
            }
            stringFormatIndicatorName.Trimming = StringTrimming.EllipsisCharacter;
            string indicatorName = _strategy.Slot[slot].IndicatorName;
            float  nameWidth     = g.MeasureString(indicatorName, fontIndicator).Width;

            RectangleF rectIndName = width >= 2 * fGroupWidth + nameWidth
                                         ? new RectangleF(0, vPosition, width, indNameHeight)
                                         : new RectangleF(fGroupWidth, vPosition, width - fGroupWidth, indNameHeight);

            g.DrawString(indicatorName, fontIndicator, brushIndName, rectIndName, stringFormatIndicatorName);
            vPosition += (int)indNameHeight;


            if (slotType == SlotTypes.OpenFilter || slotType == SlotTypes.CloseFilter)
            {
                pnl.CloseButton.ColorBack = colorCaptionBack;
                pnl.CloseButton.ColorFore = colorCaptionText;
                pnl.CloseButton.Visible   = ShowRemoveSlotButtons;
            }

            if (SlotMinMidMax == SlotSizeMinMidMax.min)
            {
                return;
            }

            // Logic
            var stringFormatLogic = new StringFormat
            {
                Alignment     = StringAlignment.Center,
                LineAlignment = StringAlignment.Center,
                Trimming      = StringTrimming.EllipsisCharacter,
                FormatFlags   = StringFormatFlags.NoClip
            };
            float padding = Space;

            if (_strategy.Slot[slot].IndParam.ListParam[0].Enabled)
            {
                string value      = _strategy.Slot[slot].IndParam.ListParam[0].Text;
                var    fontLogic  = new Font(Font.FontFamily, 10.5f, FontStyle.Regular);
                SizeF  sizeValue  = g.MeasureString(value, fontLogic, (int)(width - 2 * padding), stringFormatLogic);
                var    rectValue  = new RectangleF(padding, vPosition, width - 2 * padding, sizeValue.Height);
                Brush  brushLogic = new SolidBrush(colorLogicText);

                g.DrawString(value, fontLogic, brushLogic, rectValue, stringFormatLogic);
                vPosition += (int)sizeValue.Height;
            }

            if (SlotMinMidMax == SlotSizeMinMidMax.mid)
            {
                return;
            }

            // Parameters
            var stringFormat = new StringFormat {
                Trimming = StringTrimming.EllipsisCharacter, FormatFlags = StringFormatFlags.NoWrap
            };
            var   fontParam  = new Font(Font.FontFamily, 9f, FontStyle.Regular);
            var   fontValue  = new Font(Font.FontFamily, 9f, FontStyle.Regular);
            Brush brushParam = new SolidBrush(colorParamText);
            Brush brushValue = new SolidBrush(colorValueText);
            var   penDash    = new Pen(colorDash);

            // Find Maximum width of the strings
            float maxParamWidth = 0;
            float maxValueWidth = 0;

            for (int i = 1; i < 5; i++)
            {
                if (!_strategy.Slot[slot].IndParam.ListParam[i].Enabled)
                {
                    continue;
                }

                string caption   = _strategy.Slot[slot].IndParam.ListParam[i].Caption;
                string value     = _strategy.Slot[slot].IndParam.ListParam[i].Text;
                SizeF  sizeParam = g.MeasureString(caption, fontParam);
                SizeF  sizeValue = g.MeasureString(value, fontValue);

                if (maxParamWidth < sizeParam.Width)
                {
                    maxParamWidth = sizeParam.Width;
                }

                if (maxValueWidth < sizeValue.Width)
                {
                    maxValueWidth = sizeValue.Width;
                }
            }

            foreach (NumericParam numericParam in _strategy.Slot[slot].IndParam.NumParam)
            {
                if (!numericParam.Enabled)
                {
                    continue;
                }

                string caption   = numericParam.Caption;
                string value     = numericParam.ValueToString;
                SizeF  sizeParam = g.MeasureString(caption, fontParam);
                SizeF  sizeValue = g.MeasureString(value, fontValue);

                if (maxParamWidth < sizeParam.Width)
                {
                    maxParamWidth = sizeParam.Width;
                }

                if (maxValueWidth < sizeValue.Width)
                {
                    maxValueWidth = sizeValue.Width;
                }
            }

            foreach (CheckParam checkParam in _strategy.Slot[slot].IndParam.CheckParam)
            {
                if (!checkParam.Enabled)
                {
                    continue;
                }

                string param     = checkParam.Caption;
                string value     = checkParam.Checked ? "Yes" : "No";
                SizeF  sizeParam = g.MeasureString(param, fontParam);
                SizeF  sizeValue = g.MeasureString(value, fontValue);

                if (maxParamWidth < sizeParam.Width)
                {
                    maxParamWidth = sizeParam.Width;
                }

                if (maxValueWidth < sizeValue.Width)
                {
                    maxValueWidth = sizeValue.Width;
                }
            }

            // Padding Parameter Padding Dash Padding Value Padding
            const float dashWidth      = 5;
            float       necessaryWidth = 4 * padding + maxParamWidth + maxValueWidth + dashWidth;

            padding = width > necessaryWidth
                          ? Math.Max((pnl.ClientSize.Width - maxParamWidth - maxValueWidth - dashWidth) / 6, padding)
                          : 2;

            float tabParam = 2 * padding;
            float tabDash  = tabParam + maxParamWidth + padding;
            float tabValue = tabDash + dashWidth + padding;

            // List Parameters
            for (int i = 1; i < 5; i++)
            {
                if (!_strategy.Slot[slot].IndParam.ListParam[i].Enabled)
                {
                    continue;
                }

                string caption    = _strategy.Slot[slot].IndParam.ListParam[i].Caption;
                string value      = _strategy.Slot[slot].IndParam.ListParam[i].Text;
                var    pointParam = new PointF(tabParam, vPosition);
                var    pointDash1 = new PointF(tabDash, vPosition + fontParam.Height / 2 + 2);
                var    pointDash2 = new PointF(tabDash + dashWidth, vPosition + fontParam.Height / 2 + 2);
                var    pointValue = new PointF(tabValue, vPosition);
                var    sizefValue = new SizeF(Math.Max(width - tabValue, 0), fontValue.Height + 2);
                var    rectfValue = new RectangleF(pointValue, sizefValue);

                g.DrawString(caption, fontParam, brushParam, pointParam);
                g.DrawLine(penDash, pointDash1, pointDash2);
                g.DrawString(value, fontValue, brushValue, rectfValue, stringFormat);
                vPosition += fontValue.Height;
            }

            // Num Parameters
            foreach (NumericParam numericParam in _strategy.Slot[slot].IndParam.NumParam)
            {
                if (!numericParam.Enabled)
                {
                    continue;
                }

                string caption    = numericParam.Caption;
                string value      = numericParam.ValueToString;
                var    pointParam = new PointF(tabParam, vPosition);
                var    pointDash1 = new PointF(tabDash, vPosition + fontParam.Height / 2 + 2);
                var    pointDash2 = new PointF(tabDash + dashWidth, vPosition + fontParam.Height / 2 + 2);
                var    pointValue = new PointF(tabValue, vPosition);
                var    sizefValue = new SizeF(Math.Max(width - tabValue, 0), fontValue.Height + 2);
                var    rectfValue = new RectangleF(pointValue, sizefValue);

                g.DrawString(caption, fontParam, brushParam, pointParam);
                g.DrawLine(penDash, pointDash1, pointDash2);
                g.DrawString(value, fontValue, brushValue, rectfValue, stringFormat);
                vPosition += fontValue.Height;
            }

            // Check Parameters
            foreach (CheckParam checkParam in _strategy.Slot[slot].IndParam.CheckParam)
            {
                if (!checkParam.Enabled)
                {
                    continue;
                }

                string param      = checkParam.Caption;
                string salue      = checkParam.Checked ? "Yes" : "No";
                var    pointParam = new PointF(tabParam, vPosition);
                var    pointDash1 = new PointF(tabDash, vPosition + fontParam.Height / 2 + 2);
                var    pointDash2 = new PointF(tabDash + dashWidth, vPosition + fontParam.Height / 2 + 2);
                var    pointValue = new PointF(tabValue, vPosition);
                var    sizefValue = new SizeF(Math.Max(width - tabValue, 0), fontValue.Height + 2);
                var    rectfValue = new RectangleF(pointValue, sizefValue);

                g.DrawString(param, fontParam, brushParam, pointParam);
                g.DrawLine(penDash, pointDash1, pointDash2);
                g.DrawString(salue, fontValue, brushValue, rectfValue, stringFormat);
                vPosition += fontValue.Height;
            }
        }
Esempio n. 13
0
        /// <summary>
        /// Paints panel pnlInfo
        /// </summary>
        private void PnlInfoPaint(object sender, PaintEventArgs e)
        {
            // ---------------------------------------------------------------------+
            // |                          Way points description                    |
            // |--------------------------------------------------------------------+
            // | Number | Description | Price | Direction | Lots | Position | Order |
            // |--------------------------------------------------------------------+
            //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;
            string ff   = Data.FF; // Format modifier to print the floats
            var    size = new Size(_aiX[_columns] - _aiX[0], _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, 2 * _infoRowHeight);
            var   rectfCaption = new RectangleF(pntStart, szfCaption);

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

            // Caption Text
            var stringFormat = new StringFormat
            {
                LineAlignment = StringAlignment.Center,
                Trimming      = StringTrimming.EllipsisCharacter,
                FormatFlags   = StringFormatFlags.NoWrap,
                Alignment     = StringAlignment.Near
            };
            string stringCaptionText = Language.T("Way Points Description");
            float  captionWidth      = Math.Min(_pnlInfo.ClientSize.Width, _aiX[_columns] - _aiX[0]);
            float  fCaptionTextWidth = g.MeasureString(stringCaptionText, _fontInfo).Width;
            float  fCaptionTextX     = Math.Max((captionWidth - fCaptionTextWidth) / 2f, 0);
            var    pfCaptionText     = new PointF(fCaptionTextX, 0);
            var    sfCaptionText     = new SizeF(captionWidth - fCaptionTextX, _infoRowHeight);

            rectfCaption = new RectangleF(pfCaptionText, sfCaptionText);

            // First caption raw
            g.DrawString(stringCaptionText, _fontInfo, _brushCaptionText, rectfCaption, stringFormat);

            // Second caption raw
            for (int i = 0; i < _columns; i++)
            {
                g.DrawString(_asTitles[i], _fontInfo, _brushCaptionText, (_aiX[i] + _aiX[i + 1]) / 2f, _infoRowHeight, sf);
            }

            Brush brush = new SolidBrush(LayoutColors.ColorControlText);

            for (int pnt = 0; pnt < Backtester.WayPoints(_barCurrent); pnt++)
            {
                int y     = (pnt + 2) * _infoRowHeight;
                var point = new Point(_aiX[0], y);

                // Even row
                if (Math.Abs(pnt % 2f - 0) > 0.00001)
                {
                    g.FillRectangle(_brushEvenRow, new Rectangle(point, size));
                }

                int          positionNumber = Backtester.WayPoint(_barCurrent, pnt).PosNumb;
                WayPointType wpType         = Backtester.WayPoint(_barCurrent, pnt).WPType;
                PosDirection posDirection   = Backtester.PosFromNumb(positionNumber).PosDir;
                double       posLots        = Backtester.PosFromNumb(positionNumber).PosLots;
                int          ordNumber      = Backtester.WayPoint(_barCurrent, pnt).OrdNumb;

                g.DrawString((pnt + 1).ToString(CultureInfo.InvariantCulture), _fontInfo, brush, (_aiX[0] + _aiX[1]) / 2f,
                             y, sf);
                g.DrawString(Language.T(WayPoint.WPTypeToString(wpType)), _fontInfo, brush, _aiX[1] + 2, y);
                g.DrawString(Backtester.WayPoint(_barCurrent, pnt).Price.ToString(ff), _fontInfo, brush,
                             (_aiX[3] + _aiX[2]) / 2f, y, sf);

                if (positionNumber > -1)
                {
                    g.DrawString(Language.T(posDirection.ToString()), _fontInfo, brush, (_aiX[4] + _aiX[3]) / 2f, y, sf);
                    g.DrawString(posLots.ToString(CultureInfo.InvariantCulture), _fontInfo, brush,
                                 (_aiX[5] + _aiX[4]) / 2f, y, sf);
                    g.DrawString((positionNumber + 1).ToString(CultureInfo.InvariantCulture), _fontInfo, brush,
                                 (_aiX[6] + _aiX[5]) / 2f, y, sf);
                }

                if (ordNumber > -1)
                {
                    g.DrawString((ordNumber + 1).ToString(CultureInfo.InvariantCulture), _fontInfo, brush,
                                 (_aiX[7] + _aiX[6]) / 2f, y, sf);
                }
            }

            // Vertical lines
            var penLine = new Pen(LayoutColors.ColorJournalLines);

            for (int i = 1; i < _columns; i++)
            {
                g.DrawLine(penLine, _aiX[i], 2 * _infoRowHeight, _aiX[i], ClientSize.Height - Border);
            }

            // 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);
        }
Esempio n. 14
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(DataPeriods)).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);

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

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

                var    period      = (DataPeriods)Enum.GetValues(typeof(DataPeriods)).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);
        }
        /// <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>
 /// Sets the panel colors
 /// </summary>
 private void SetColors()
 {
     _colorCaptionBack = LayoutColors.ColorCaptionBack;
     _brushCaption     = new SolidBrush(LayoutColors.ColorCaptionText);
     _penBorder        = new Pen(Data.GetGradientColor(LayoutColors.ColorCaptionBack, -LayoutColors.DepthCaption), Border);
 }
Esempio n. 17
0
        /// <summary>
        /// Sets the chart params
        /// </summary>
        public void InitChart()
        {
            // Chart Title
            strChartTitle                     = Language.T("Balance / Equity Chart") + " [" + (Configs.AccountInMoney ? Configs.AccountCurrency + "]" : Language.T("pips") + "]");
            font                              = new Font(Font.FontFamily, 9);
            captionHeight                     = (float)Math.Max(font.Height, 18);
            rectfCaption                      = new RectangleF(0, 0, ClientSize.Width, captionHeight);
            stringFormatCaption               = new StringFormat();
            stringFormatCaption.Alignment     = StringAlignment.Center;
            stringFormatCaption.LineAlignment = StringAlignment.Center;
            stringFormatCaption.Trimming      = StringTrimming.EllipsisCharacter;
            stringFormatCaption.FormatFlags   = StringFormatFlags.NoWrap;

            brushFore           = new SolidBrush(LayoutColors.ColorChartFore);
            penGrid             = new Pen(LayoutColors.ColorChartGrid);
            penGrid.DashStyle   = DashStyle.Dash;
            penGrid.DashPattern = new float [] { 4, 2 };
            penBorder           = new Pen(Data.GetGradientColor(LayoutColors.ColorCaptionBack, -LayoutColors.DepthCaption), border);

            if (isNotPaint)
            {
                return;
            }

            YTop    = (int)captionHeight + 2 * space + 1;
            YBottom = ClientSize.Height - 2 * space - 1 - border;

            Graphics g = CreateGraphics();

            labelWidth = (int)Math.Max(g.MeasureString(minimum.ToString(), Font).Width, g.MeasureString(maximum.ToString(), Font).Width);
            g.Dispose();

            labelWidth = Math.Max(labelWidth, 30);
            XLeft      = border + space;
            XRight     = ClientSize.Width - border - space - labelWidth;
            XScale     = (XRight - 2 * space - border) / (float)chartBars;

            countLabels = (int)Math.Max((YBottom - YTop) / 20, 1);
            delta       = (float)Math.Max(Math.Round((maximum - minimum) / (float)countLabels), 10);
            step        = (int)Math.Ceiling(delta / 10) * 10;
            countLabels = (int)Math.Ceiling((maximum - minimum) / (float)step);
            maximum     = minimum + countLabels * step;
            YScale      = (YBottom - YTop) / (countLabels * (float)step);

            apntBalance = new PointF[chartBars];
            apntEquity  = new PointF[chartBars];

            if (Configs.AdditionalStatistics)
            {
                apntLongBalance  = new PointF[chartBars];
                apntShortBalance = new PointF[chartBars];
            }

            apntClosePrice = new PointF[chartBars];

            // Close Price
            if (showPriceLine)
            {
                YPriceScale = (float)((YBottom - YTop) / (dataMaxPrice - dataMinPrice));
            }

            int index = 0;

            for (int bar = firstBar; bar < bars; bar++)
            {
                apntBalance[index].X = XLeft + index * XScale;
                apntEquity[index].X  = XLeft + index * XScale;
                if (Configs.AccountInMoney)
                {
                    apntBalance[index].Y = (float)(YBottom - (backtesterMoneyBalance[bar] - minimum) * YScale);
                    apntEquity[index].Y  = (float)(YBottom - (backtesterMoneyEquity[bar] - minimum) * YScale);
                }
                else
                {
                    apntBalance[index].Y = YBottom - (backtesterBalance[bar] - minimum) * YScale;
                    apntEquity[index].Y  = YBottom - (backtesterEquity[bar] - minimum) * YScale;
                }

                if (Configs.AdditionalStatistics)
                {
                    apntLongBalance[index].X  = XLeft + index * XScale;
                    apntShortBalance[index].X = XLeft + index * XScale;
                    if (Configs.AccountInMoney)
                    {
                        apntLongBalance[index].Y  = (float)(YBottom - (backtesterLongMoneyBalance[bar] - minimum) * YScale);
                        apntShortBalance[index].Y = (float)(YBottom - (backtesterShortMoneyBalance[bar] - minimum) * YScale);
                    }
                    else
                    {
                        apntLongBalance[index].Y  = YBottom - (backtesterLongBalance[bar] - minimum) * YScale;
                        apntShortBalance[index].Y = YBottom - (backtesterShortBalance[bar] - minimum) * YScale;
                    }
                }

                if (showPriceLine)
                {
                    apntClosePrice[index].X = XLeft + index * XScale;
                    apntClosePrice[index].Y = YBottom - (float)(dataClose[bar] - dataMinPrice) * YPriceScale;
                }
                index++;
            }

            // Margin Call
            if (marginCallBar >= firstBar)
            {
                XMarginCallBar = XLeft + (marginCallBar - firstBar) * XScale;
            }
            else
            {
                XMarginCallBar = 0;
            }

            //OOS
            if (isOOS && barOOS > firstBar)
            {
                XOOSBar = XLeft + (barOOS - firstBar) * XScale;
            }
            else
            {
                XOOSBar = 0;
            }

            YBalance = YBottom - (balance - minimum) * YScale;

            isHideScanningLine = false;
            modellingQuolity   = " MQ " + Data.ModellingQuality.ToString("N2") + "%";
        }
        /// <summary>
        /// Sets the chart parameters
        /// </summary>
        public void InitChart()
        {
            // Chart Title
            _chartTitle          = Language.T("Balance / Equity Chart") + " [" + (Configs.AccountInMoney ? Configs.AccountCurrency + "]" : Language.T("pips") + "]");
            _font                = new Font(Font.FontFamily, 9);
            _captionHeight       = Math.Max(_font.Height, 18);
            _rectfCaption        = new RectangleF(0, 0, ClientSize.Width, _captionHeight);
            _stringFormatCaption = new StringFormat
            {
                Alignment     = StringAlignment.Center,
                LineAlignment = StringAlignment.Center,
                Trimming      = StringTrimming.EllipsisCharacter,
                FormatFlags   = StringFormatFlags.NoWrap
            };
            _brushFore = new SolidBrush(LayoutColors.ColorChartFore);
            _penGrid   = new Pen(LayoutColors.ColorChartGrid)
            {
                DashStyle = DashStyle.Dash, DashPattern = new float[] { 4, 2 }
            };
            _penBorder = new Pen(Data.GetGradientColor(LayoutColors.ColorCaptionBack, -LayoutColors.DepthCaption), Border);

            if (_isNotPaint)
            {
                return;
            }

            _yTop    = (int)_captionHeight + 2 * Space + 1;
            _yBottom = ClientSize.Height - 2 * Space - 1 - Border;

            Graphics g            = CreateGraphics();
            float    widthMinimum = g.MeasureString(_data.Minimum.ToString(CultureInfo.InvariantCulture), Font).Width;
            float    widthMaximum = g.MeasureString(_data.Maximum.ToString(CultureInfo.InvariantCulture), Font).Width;

            _labelWidth = (int)Math.Max(widthMinimum, widthMaximum);
            _labelWidth = Math.Max(_labelWidth, 30);
            g.Dispose();

            _xLeft  = Border + Space;
            _xRight = ClientSize.Width - Border - Space - _labelWidth;
            _xScale = (_xRight - 2 * Space - Border) / (float)_chartBars;

            _countLabels = (int)Math.Max((_yBottom - _yTop) / 20.0, 1);
            _delta       = (float)Math.Max(Math.Round((_data.Maximum - _data.Minimum) / (float)_countLabels), 10);
            _labelStep   = (int)Math.Ceiling(_delta / 10) * 10;
            _countLabels = (int)Math.Ceiling((_data.Maximum - _data.Minimum) / (float)_labelStep);
            _yScale      = (_yBottom - _yTop) / (_countLabels * (float)_labelStep);

            _balancePoints = new PointF[_chartBars];
            _equityPoints  = new PointF[_chartBars];

            if (Configs.AdditionalStatistics)
            {
                _longBalancePoints  = new PointF[_chartBars];
                _shortBalancePoints = new PointF[_chartBars];
            }

            _closePricePoints = new PointF[_chartBars];

            // Close Price
            if (_showPriceLine)
            {
                _yPriceScale = (float)((_yBottom - _yTop) / (_data.DataMaxPrice - _data.DataMinPrice));
            }

            for (int bar = _data.FirstBar; bar < _data.Bars; bar++)
            {
                int index = bar - _data.FirstBar;
                _balancePoints[index].X = _xLeft + index * _xScale;
                _equityPoints[index].X  = _xLeft + index * _xScale;
                if (Configs.AccountInMoney)
                {
                    _balancePoints[index].Y = (float)(_yBottom - (_data.MoneyBalance[bar] - _data.Minimum) * _yScale);
                    _equityPoints[index].Y  = (float)(_yBottom - (_data.MoneyEquity[bar] - _data.Minimum) * _yScale);
                }
                else
                {
                    _balancePoints[index].Y = _yBottom - (_data.Balance[bar] - _data.Minimum) * _yScale;
                    _equityPoints[index].Y  = _yBottom - (_data.Equity[bar] - _data.Minimum) * _yScale;
                }

                if (Configs.AdditionalStatistics)
                {
                    _longBalancePoints[index].X  = _xLeft + index * _xScale;
                    _shortBalancePoints[index].X = _xLeft + index * _xScale;
                    if (Configs.AccountInMoney)
                    {
                        _longBalancePoints[index].Y  = (float)(_yBottom - (_data.LongMoneyBalance[bar] - _data.Minimum) * _yScale);
                        _shortBalancePoints[index].Y = (float)(_yBottom - (_data.ShortMoneyBalance[bar] - _data.Minimum) * _yScale);
                    }
                    else
                    {
                        _longBalancePoints[index].Y  = _yBottom - (_data.LongBalance[bar] - _data.Minimum) * _yScale;
                        _shortBalancePoints[index].Y = _yBottom - (_data.ShortBalance[bar] - _data.Minimum) * _yScale;
                    }
                }

                if (_showPriceLine)
                {
                    _closePricePoints[index].X = _xLeft + index * _xScale;
                    _closePricePoints[index].Y = _yBottom - (float)(_data.ClosePrice[bar] - _data.DataMinPrice) * _yPriceScale;
                }
            }

            // Margin Call
            _xMarginCallBar = _data.MarginCallBar >= _data.FirstBar ? _xLeft + (_data.MarginCallBar - _data.FirstBar) * _xScale : 0;

            //OOS
            if (IsOOS && OOSBar > _data.FirstBar)
            {
                _xOOSBar = _xLeft + (OOSBar - _data.FirstBar) * _xScale;
            }
            else
            {
                _xOOSBar = 0;
            }

            _yBalance = _yBottom - (_data.NetBalance - _data.Minimum) * _yScale;

            _isHideScanningLine    = false;
            _data.ModellingQuolity = " MQ " + Data.ModellingQuality.ToString("N2") + "%";

            ButtonsColorBack     = LayoutColors.ColorCaptionBack;
            ButtonColorFore      = LayoutColors.ColorCaptionText;
            ContextMenuColorBack = LayoutColors.ColorControlBack;
            ContextMenuColorFore = LayoutColors.ColorControlText;
        }
        /// <summary>
        /// Initialize the form and controls
        /// </summary>
        public Bar_Explorer(int iBarNumber)
        {
            pnlChart = new Panel();
            pnlInfo  = new Panel();
            toolTip  = new ToolTip();

            bar = iBarNumber < Data.FirstBar ? Data.FirstBar : iBarNumber;

            this.Text            = Language.T("Bar Explorer");
            this.BackColor       = LayoutColors.ColorFormBack;
            this.FormBorderStyle = FormBorderStyle.FixedDialog;
            this.Icon            = Data.Icon;
            this.MaximizeBox     = false;
            this.MinimizeBox     = false;
            this.ShowInTaskbar   = false;

            fontInfo      = new Font(Font.FontFamily, 9);
            infoRowHeight = (int)Math.Max(fontInfo.Height, 18);

            barInfo = Language.T("Bar") + ": " + (bar + 1).ToString() + " " +
                      Data.Time[bar].ToString(Data.DF) + " " +
                      Data.Time[bar].ToString("HH:mm") + "; " +
                      Language.T("Interpolation method") + ": " +
                      Backtester.InterpolationMethodToString();

            pnlChart.Parent = this;
            pnlChart.Paint += new PaintEventHandler(PnlChart_Paint);

            pnlInfo.Parent = this;
            pnlInfo.Paint += new PaintEventHandler(PnlInfo_Paint);

            btnNavigate = new Button[4];
            string [] btnNavigateText = new string [4] {
                "< !", "<", ">", "! >"
            };
            string[] btnNavigateTips = new string [4] {
                Language.T("Previous ambiguous bar."),
                Language.T("Previous bar."),
                Language.T("Next bar."),
                Language.T("Next ambiguous bar.")
            };

            for (int i = 0; i < 4; i++)
            {
                btnNavigate[i]             = new Button();
                btnNavigate[i].Parent      = this;
                btnNavigate[i].Text        = btnNavigateText[i];
                btnNavigate[i].Name        = btnNavigateText[i];
                btnNavigate[i].Click      += new EventHandler(BtnNavigate_Click);
                btnNavigate[i].MouseWheel += new MouseEventHandler(Bar_Explorer_MouseWheel);
                btnNavigate[i].UseVisualStyleBackColor = true;
                toolTip.SetToolTip(btnNavigate[i], btnNavigateTips[i]);
            }

            btnNavigate[0].Enabled = Backtester.AmbiguousBars > 0;
            btnNavigate[3].Enabled = Backtester.AmbiguousBars > 0;

            nudGo           = new NumericUpDown();
            nudGo.Parent    = this;
            nudGo.TextAlign = HorizontalAlignment.Center;
            nudGo.BeginInit();
            nudGo.Minimum   = Data.FirstBar + 1;
            nudGo.Maximum   = Data.Bars;
            nudGo.Increment = 1;
            nudGo.Value     = bar + 1;
            nudGo.EndInit();

            btnGo        = new Button();
            btnGo.Parent = this;
            btnGo.Name   = "Go";
            btnGo.Text   = Language.T("Go");
            btnGo.UseVisualStyleBackColor = true;
            btnGo.Click      += new EventHandler(BtnNavigate_Click);
            btnGo.MouseWheel += new MouseEventHandler(Bar_Explorer_MouseWheel);
            toolTip.SetToolTip(btnGo, Language.T("Go to the chosen bar."));

            //Button Close
            btnClose                         = new Button();
            btnClose.Parent                  = this;
            btnClose.Text                    = Language.T("Close");
            btnClose.DialogResult            = DialogResult.Cancel;
            btnClose.UseVisualStyleBackColor = true;

            // Colors
            brushRed = new SolidBrush(LayoutColors.ColorSignalRed);

            brushCaptionBack = new SolidBrush(LayoutColors.ColorCaptionBack);
            brushCaptionText = new SolidBrush(LayoutColors.ColorCaptionText);
            brushEvenRow     = new SolidBrush(LayoutColors.ColorEvenRowBack);
            brushBack        = new SolidBrush(LayoutColors.ColorControlBack);
            brushGridText    = new SolidBrush(LayoutColors.ColorChartFore);
            brushBarWhite    = new SolidBrush(LayoutColors.ColorBarWhite);
            brushBarBlack    = new SolidBrush(LayoutColors.ColorBarBlack);
            brushTradeLong   = new SolidBrush(LayoutColors.ColorTradeLong);
            brushTradeShort  = new SolidBrush(LayoutColors.ColorTradeShort);
            brushTradeClose  = new SolidBrush(LayoutColors.ColorTradeClose);

            penGrid             = new Pen(LayoutColors.ColorChartGrid);
            penGrid.DashStyle   = DashStyle.Dash;
            penGrid.DashPattern = new float[] { 4, 2 };
            penGridSolid        = new Pen(LayoutColors.ColorChartGrid);
            penAxes             = new Pen(LayoutColors.ColorChartFore);
            penCross            = new Pen(LayoutColors.ColorChartCross);
            penBarBorder        = new Pen(LayoutColors.ColorBarBorder);

            colorBarWight1 = Data.GetGradientColor(LayoutColors.ColorBarWhite, 30);
            colorBarWight2 = Data.GetGradientColor(LayoutColors.ColorBarWhite, -30);
            colorBarBlack1 = Data.GetGradientColor(LayoutColors.ColorBarBlack, 30);
            colorBarBlack2 = Data.GetGradientColor(LayoutColors.ColorBarBlack, -30);

            colorLongTrade1   = Data.GetGradientColor(LayoutColors.ColorTradeLong, 30);
            colorLongTrade2   = Data.GetGradientColor(LayoutColors.ColorTradeLong, -30);
            colorShortTrade1  = Data.GetGradientColor(LayoutColors.ColorTradeShort, 30);
            colorShortTrade2  = Data.GetGradientColor(LayoutColors.ColorTradeShort, -30);
            colorClosedTrade1 = Data.GetGradientColor(LayoutColors.ColorTradeClose, 30);
            colorClosedTrade2 = Data.GetGradientColor(LayoutColors.ColorTradeClose, -30);

            SetJournalPoints();

            return;
        }
        /// <summary>
        /// Paints panel pnlInfo
        /// </summary>
        void PnlInfo_Paint(object sender, PaintEventArgs e)
        {
            // ---------------------------------------------------------------------+
            // |                          Way points description                    |
            // |--------------------------------------------------------------------+
            // | Number | Description | Price | Direction | Lots | Position | Order |
            // |--------------------------------------------------------------------+
            //xp0      xp1           xp2     xp3         xp4    xp5        xp6     xp7

            Graphics g = e.Graphics;

            g.Clear(LayoutColors.ColorControlBack);

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

            Panel  pnl   = (Panel)sender;
            Brush  brush = Brushes.White;
            string FF    = Data.FF;   // Format modifier to print the floats

            Size size = new Size(aiX[columns] - aiX[0], infoRowHeight);

            StringFormat sf = new StringFormat();

            sf.Alignment     = StringAlignment.Center;
            sf.LineAlignment = StringAlignment.Near;

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

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

            // Caption Text
            StringFormat stringFormatCaption = new StringFormat();

            stringFormatCaption.LineAlignment = StringAlignment.Center;
            stringFormatCaption.Trimming      = StringTrimming.EllipsisCharacter;
            stringFormatCaption.FormatFlags   = StringFormatFlags.NoWrap;
            stringFormatCaption.Alignment     = StringAlignment.Near;
            string stringCaptionText = Language.T("Way Points Description");
            float  fCaptionWidth     = (float)Math.Min(pnlInfo.ClientSize.Width, aiX[columns] - aiX[0]);
            float  fCaptionTextWidth = g.MeasureString(stringCaptionText, fontInfo).Width;
            float  fCaptionTextX     = (float)Math.Max((fCaptionWidth - fCaptionTextWidth) / 2f, 0);
            PointF pfCaptionText     = new PointF(fCaptionTextX, 0);
            SizeF  sfCaptionText     = new SizeF(fCaptionWidth - fCaptionTextX, infoRowHeight);

            rectfCaption = new RectangleF(pfCaptionText, sfCaptionText);

            // First caption raw
            g.DrawString(stringCaptionText, fontInfo, brushCaptionText, rectfCaption, stringFormatCaption);

            // Second caption raw
            for (int i = 0; i < columns; i++)
            {
                g.DrawString(asTitles[i], fontInfo, brushCaptionText, (aiX[i] + aiX[i + 1]) / 2, infoRowHeight, sf);
            }

            brush = new SolidBrush(LayoutColors.ColorControlText);

            for (int pnt = 0; pnt < Backtester.WayPoints(bar); pnt++)
            {
                int   y     = (pnt + 2) * infoRowHeight;
                Point point = new Point(aiX[0], y);

                // Even row
                if (pnt % 2f != 0)
                {
                    g.FillRectangle(brushEvenRow, new Rectangle(point, size));
                }

                int          positionNumber = Backtester.WayPoint(bar, pnt).PosNumb;
                WayPointType wpType         = Backtester.WayPoint(bar, pnt).WPType;
                PosDirection posDirection   = Backtester.PosFromNumb(positionNumber).PosDir;
                double       posLots        = Backtester.PosFromNumb(positionNumber).PosLots;
                int          ordNumber      = Backtester.WayPoint(bar, pnt).OrdNumb;

                g.DrawString((pnt + 1).ToString(), fontInfo, brush, (aiX[0] + aiX[1]) / 2, y, sf);
                g.DrawString(Language.T(Way_Point.WPTypeToString(wpType)), fontInfo, brush, aiX[1] + 2, y);
                g.DrawString(Backtester.WayPoint(bar, pnt).Price.ToString(FF), fontInfo, brush, (aiX[3] + aiX[2]) / 2, y, sf);

                if (positionNumber > -1)
                {
                    g.DrawString(Language.T(posDirection.ToString()), fontInfo, brush, (aiX[4] + aiX[3]) / 2, y, sf);
                    g.DrawString(posLots.ToString(), fontInfo, brush, (aiX[5] + aiX[4]) / 2, y, sf);
                    g.DrawString((positionNumber + 1).ToString(), fontInfo, brush, (aiX[6] + aiX[5]) / 2, y, sf);
                }

                if (ordNumber > -1)
                {
                    g.DrawString((ordNumber + 1).ToString(), fontInfo, brush, (aiX[7] + aiX[6]) / 2, y, sf);
                }
            }

            // Vertical lines
            Pen penLine = new Pen(LayoutColors.ColorJournalLines);

            for (int i = 1; i < columns; i++)
            {
                g.DrawLine(penLine, aiX[i], 2 * infoRowHeight, aiX[i], ClientSize.Height - border);
            }

            // Border
            Pen 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);

            return;
        }
Esempio n. 21
0
        /// <summary>
        /// Initialize the form and controls
        /// </summary>
        public BarExplorer(int barNumber)
        {
            _pnlChart = new Panel();
            _pnlInfo  = new Panel();
            _toolTip  = new ToolTip();

            _barCurrent = barNumber < Data.FirstBar ? Data.FirstBar : barNumber;

            Text            = Language.T("Bar Explorer");
            BackColor       = LayoutColors.ColorFormBack;
            FormBorderStyle = FormBorderStyle.FixedDialog;
            Icon            = Data.Icon;
            MaximizeBox     = false;
            MinimizeBox     = false;
            ShowInTaskbar   = false;

            _fontInfo      = new Font(Font.FontFamily, 9);
            _infoRowHeight = Math.Max(_fontInfo.Height, 18);

            _barInfo = Language.T("Bar") + ": " + (_barCurrent + 1) + " " +
                       Data.Time[_barCurrent].ToString(Data.DF) + " " +
                       Data.Time[_barCurrent].ToString("HH:mm") + "; " +
                       Language.T("Interpolation method") + ": " +
                       Backtester.InterpolationMethodToString();

            _pnlChart.Parent = this;
            _pnlChart.Paint += PnlChartPaint;

            _pnlInfo.Parent = this;
            _pnlInfo.Paint += PnlInfoPaint;

            BtnsNavigate = new Button[6];
            var btnNavigateText = new[] { "< !", "<<", "<", ">", ">>", "! >" };
            var btnNavigateTips = new[]
            {
                Language.T("Previous ambiguous bar."),
                Language.T("Previous deal."),
                Language.T("Previous bar."),
                Language.T("Next bar."),
                Language.T("Next deal."),
                Language.T("Next ambiguous bar.")
            };

            for (int i = 0; i < 6; i++)
            {
                BtnsNavigate[i] = new Button {
                    Parent = this, Text = btnNavigateText[i], Name = btnNavigateText[i]
                };
                BtnsNavigate[i].Click      += BtnNavigateClick;
                BtnsNavigate[i].MouseWheel += BarExplorerMouseWheel;
                BtnsNavigate[i].KeyUp      += BtnNavigateKeyUp;
                BtnsNavigate[i].UseVisualStyleBackColor = true;
                _toolTip.SetToolTip(BtnsNavigate[i], btnNavigateTips[i]);
            }

            BtnsNavigate[0].Enabled = Backtester.AmbiguousBars > 0;
            BtnsNavigate[1].Enabled = Backtester.PositionsTotal > 0;
            BtnsNavigate[4].Enabled = Backtester.PositionsTotal > 0;
            BtnsNavigate[5].Enabled = Backtester.AmbiguousBars > 0;

            NUDGo = new NumericUpDown {
                Parent = this, TextAlign = HorizontalAlignment.Center
            };
            NUDGo.BeginInit();
            NUDGo.Minimum   = Data.FirstBar + 1;
            NUDGo.Maximum   = Data.Bars;
            NUDGo.Increment = 1;
            NUDGo.Value     = _barCurrent + 1;
            NUDGo.KeyUp    += BtnNavigateKeyUp;
            NUDGo.EndInit();

            BtnGo = new Button {
                Parent = this, Name = "Go", Text = Language.T("Go"), UseVisualStyleBackColor = true
            };
            BtnGo.Click      += BtnNavigateClick;
            BtnGo.MouseWheel += BarExplorerMouseWheel;
            BtnGo.KeyUp      += BtnNavigateKeyUp;
            _toolTip.SetToolTip(BtnGo, Language.T("Go to the chosen bar."));

            //Button Close
            BtnClose = new Button
            {
                Parent                  = this,
                Text                    = Language.T("Close"),
                DialogResult            = DialogResult.Cancel,
                UseVisualStyleBackColor = true
            };

            // Colors
            _brushRed = new SolidBrush(LayoutColors.ColorSignalRed);

            _brushCaptionText = new SolidBrush(LayoutColors.ColorCaptionText);
            _brushEvenRow     = new SolidBrush(LayoutColors.ColorEvenRowBack);
            _brushGridText    = new SolidBrush(LayoutColors.ColorChartFore);

            _penGrid = new Pen(LayoutColors.ColorChartGrid)
            {
                DashStyle = DashStyle.Dash, DashPattern = new float[] { 4, 2 }
            };
            _penAxes      = new Pen(LayoutColors.ColorChartFore);
            _penCross     = new Pen(LayoutColors.ColorChartCross);
            _penBarBorder = new Pen(LayoutColors.ColorBarBorder);

            _colorBarWight1 = Data.GetGradientColor(LayoutColors.ColorBarWhite, 30);
            _colorBarWight2 = Data.GetGradientColor(LayoutColors.ColorBarWhite, -30);
            _colorBarBlack1 = Data.GetGradientColor(LayoutColors.ColorBarBlack, 30);
            _colorBarBlack2 = Data.GetGradientColor(LayoutColors.ColorBarBlack, -30);

            _colorLongTrade1   = Data.GetGradientColor(LayoutColors.ColorTradeLong, 30);
            _colorLongTrade2   = Data.GetGradientColor(LayoutColors.ColorTradeLong, -30);
            _colorShortTrade1  = Data.GetGradientColor(LayoutColors.ColorTradeShort, 30);
            _colorShortTrade2  = Data.GetGradientColor(LayoutColors.ColorTradeShort, -30);
            _colorClosedTrade1 = Data.GetGradientColor(LayoutColors.ColorTradeClose, 30);
            _colorClosedTrade2 = Data.GetGradientColor(LayoutColors.ColorTradeClose, -30);

            SetJournalPoints();
        }
Esempio n. 22
0
        /// <summary>
        /// Panel properties Paint
        /// </summary>
        private void PnlPropertiesPaint(object sender, PaintEventArgs e)
        {
            var      pnl   = (Panel)sender;
            Graphics g     = e.Graphics;
            int      width = pnl.ClientSize.Width;

            Color colorCaptionBack = LayoutColors.ColorSlotCaptionBackAveraging;
            Color colorCaptionText = LayoutColors.ColorSlotCaptionText;
            Color colorBackground  = LayoutColors.ColorSlotBackground;
            Color colorLogicText   = LayoutColors.ColorSlotLogicText;
            Color colorDash        = LayoutColors.ColorSlotDash;

            // Caption
            string stringCaptionText   = Language.T("Strategy Properties");
            var    fontCaptionText     = new Font(Font.FontFamily, 9);
            float  captionHeight       = Math.Max(fontCaptionText.Height, 18);
            float  captionWidth        = width;
            Brush  brushCaptionText    = new SolidBrush(colorCaptionText);
            var    stringFormatCaption = new StringFormat
            {
                LineAlignment = StringAlignment.Center,
                Trimming      = StringTrimming.EllipsisCharacter,
                FormatFlags   = StringFormatFlags.NoWrap,
                Alignment     = StringAlignment.Center
            };

            var rectfCaption = new RectangleF(0, 0, captionWidth, captionHeight);

            Data.GradientPaint(g, rectfCaption, colorCaptionBack, LayoutColors.DepthCaption);
            g.DrawString(stringCaptionText, fontCaptionText, brushCaptionText, rectfCaption, stringFormatCaption);

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

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

            // Paint the panel's background
            var rectfPanel = new RectangleF(Border, captionHeight, pnl.Width - 2 * Border,
                                            pnl.Height - captionHeight - Border);

            Data.GradientPaint(g, rectfPanel, colorBackground, LayoutColors.DepthControl);

            int vPosition = (int)captionHeight + 2;

            // Padlock image
            if (ShowPadlockImg)
            {
                if (_strategy.PropertiesStatus == StrategySlotStatus.Locked)
                {
                    g.DrawImage(Resources.padlock_img, 1, 1, 16, 16);
                }
                else if (_strategy.PropertiesStatus == StrategySlotStatus.Open)
                {
                    g.DrawImage(Resources.open_padlock, 1, 1, 16, 16);
                }
                else if (_strategy.PropertiesStatus == StrategySlotStatus.Linked)
                {
                    g.DrawImage(Resources.linked, 1, 1, 16, 16);
                }
            }

            var stringFormat = new StringFormat
            {
                Trimming = StringTrimming.EllipsisCharacter, FormatFlags = StringFormatFlags.NoWrap
            };
            var   fontParam  = new Font(Font.FontFamily, 9f, FontStyle.Regular);
            var   fontValue  = new Font(Font.FontFamily, 9f, FontStyle.Regular);
            Brush brushParam = new SolidBrush(colorLogicText);
            Brush brushValue = new SolidBrush(colorLogicText);
            var   penDash    = new Pen(colorDash);

            string strPermaSL = _strategy.UsePermanentSL
                                    ? (Data.Strategy.PermanentSLType == PermanentProtectionType.Absolute ? "(Abs) " : "") +
                                _strategy.PermanentSL.ToString(CultureInfo.InvariantCulture)
                                    : Language.T("None");
            string strPermaTP = _strategy.UsePermanentTP
                                    ? (Data.Strategy.PermanentTPType == PermanentProtectionType.Absolute ? "(Abs) " : "") +
                                _strategy.PermanentTP.ToString(CultureInfo.InvariantCulture)
                                    : Language.T("None");
            string strBreakEven = _strategy.UseBreakEven
                                      ? _strategy.BreakEven.ToString(CultureInfo.InvariantCulture)
                                      : Language.T("None");

            if (SlotMinMidMax == SlotSizeMinMidMax.min)
            {
                string param = Language.T(_strategy.SameSignalAction.ToString()) + "; " +
                               Language.T(_strategy.OppSignalAction.ToString()) + "; " +
                               "SL-" + strPermaSL + "; " +
                               "TP-" + strPermaTP + "; " +
                               "BE-" + strBreakEven;

                SizeF sizeParam     = g.MeasureString(param, fontParam);
                float maxParamWidth = sizeParam.Width;

                // Padding Param Padding Dash Padding Value Padding
                float padding        = Space;
                float necessaryWidth = 2 * padding + maxParamWidth;
                padding = width > necessaryWidth?Math.Max((pnl.ClientSize.Width - maxParamWidth) / 2, padding) : 2;

                float tabParam = padding;

                var pointParam = new PointF(tabParam, vPosition);
                g.DrawString(param, fontParam, brushParam, pointParam);
            }
            else
            {
                // Find Maximum width of the strings
                var asParams = new[]
                {
                    Language.T("Same direction signal"),
                    Language.T("Opposite direction signal"),
                    Language.T("Permanent Stop Loss"),
                    Language.T("Permanent Take Profit"),
                    Language.T("Break Even")
                };

                var asValues = new[]
                {
                    Language.T(_strategy.SameSignalAction.ToString()),
                    Language.T(_strategy.OppSignalAction.ToString()),
                    strPermaSL,
                    strPermaTP,
                    strBreakEven
                };

                float maxParamWidth = 0;
                foreach (string param in asParams)
                {
                    if (g.MeasureString(param, fontParam).Width > maxParamWidth)
                    {
                        maxParamWidth = g.MeasureString(param, fontParam).Width;
                    }
                }

                float maxValueWidth = 0;
                foreach (string value in asValues)
                {
                    if (g.MeasureString(value, fontParam).Width > maxValueWidth)
                    {
                        maxValueWidth = g.MeasureString(value, fontParam).Width;
                    }
                }

                // Padding Param Padding Dash Padding Value Padding
                float       padding        = Space;
                const float dashWidth      = 5;
                float       necessaryWidth = 4 * padding + maxParamWidth + maxValueWidth + dashWidth;
                padding = width > necessaryWidth
                              ? Math.Max((pnl.ClientSize.Width - maxParamWidth - maxValueWidth - dashWidth) / 6, padding)
                              : 2;

                float tabParam = 2 * padding;
                float tabDash  = tabParam + maxParamWidth + padding;
                float tabValue = tabDash + dashWidth + padding;

                // Same direction
                string parameter  = Language.T("Same direction signal");
                string text       = Language.T(_strategy.SameSignalAction.ToString());
                var    pointParam = new PointF(tabParam, vPosition);
                var    pointDash1 = new PointF(tabDash, vPosition + fontParam.Height / 2 + 2);
                var    pointDash2 = new PointF(tabDash + dashWidth, vPosition + fontParam.Height / 2 + 2);
                var    pointValue = new PointF(tabValue, vPosition);
                var    sizefValue = new SizeF(Math.Max(width - tabValue, 0), fontValue.Height + 2);
                var    rectfValue = new RectangleF(pointValue, sizefValue);
                g.DrawString(parameter, fontParam, brushParam, pointParam);
                g.DrawLine(penDash, pointDash1, pointDash2);
                g.DrawString(text, fontValue, brushValue, rectfValue, stringFormat);
                vPosition += fontValue.Height + 2;

                // Opposite direction
                parameter  = Language.T("Opposite direction signal");
                text       = Language.T(_strategy.OppSignalAction.ToString());
                pointParam = new PointF(tabParam, vPosition);
                pointDash1 = new PointF(tabDash, vPosition + fontParam.Height / 2 + 2);
                pointDash2 = new PointF(tabDash + dashWidth, vPosition + fontParam.Height / 2 + 2);
                pointValue = new PointF(tabValue, vPosition);
                sizefValue = new SizeF(Math.Max(width - tabValue, 0), fontValue.Height + 2);
                rectfValue = new RectangleF(pointValue, sizefValue);
                g.DrawString(parameter, fontParam, brushParam, pointParam);
                g.DrawLine(penDash, pointDash1, pointDash2);
                g.DrawString(text, fontValue, brushValue, rectfValue, stringFormat);
                vPosition += fontValue.Height + 2;

                // Permanent Stop Loss
                parameter  = Language.T("Permanent Stop Loss");
                text       = strPermaSL;
                pointParam = new PointF(tabParam, vPosition);
                pointDash1 = new PointF(tabDash, vPosition + fontParam.Height / 2 + 2);
                pointDash2 = new PointF(tabDash + dashWidth, vPosition + fontParam.Height / 2 + 2);
                pointValue = new PointF(tabValue, vPosition);
                sizefValue = new SizeF(Math.Max(width - tabValue, 0), fontValue.Height + 2);
                rectfValue = new RectangleF(pointValue, sizefValue);
                g.DrawString(parameter, fontParam, brushParam, pointParam);
                g.DrawLine(penDash, pointDash1, pointDash2);
                g.DrawString(text, fontValue, brushValue, rectfValue, stringFormat);
                vPosition += fontValue.Height + 2;

                // Permanent Take Profit
                parameter  = Language.T("Permanent Take Profit");
                text       = strPermaTP;
                pointParam = new PointF(tabParam, vPosition);
                pointDash1 = new PointF(tabDash, vPosition + fontParam.Height / 2 + 2);
                pointDash2 = new PointF(tabDash + dashWidth, vPosition + fontParam.Height / 2 + 2);
                pointValue = new PointF(tabValue, vPosition);
                sizefValue = new SizeF(Math.Max(width - tabValue, 0), fontValue.Height + 2);
                rectfValue = new RectangleF(pointValue, sizefValue);
                g.DrawString(parameter, fontParam, brushParam, pointParam);
                g.DrawLine(penDash, pointDash1, pointDash2);
                g.DrawString(text, fontValue, brushValue, rectfValue, stringFormat);
                vPosition += fontValue.Height;

                // Break Even
                parameter  = Language.T("Break Even");
                text       = strBreakEven;
                pointParam = new PointF(tabParam, vPosition);
                pointDash1 = new PointF(tabDash, vPosition + fontParam.Height / 2 + 2);
                pointDash2 = new PointF(tabDash + dashWidth, vPosition + fontParam.Height / 2 + 2);
                pointValue = new PointF(tabValue, vPosition);
                sizefValue = new SizeF(Math.Max(width - tabValue, 0), fontValue.Height + 2);
                rectfValue = new RectangleF(pointValue, sizefValue);
                g.DrawString(parameter, fontParam, brushParam, pointParam);
                g.DrawLine(penDash, pointDash1, pointDash2);
                g.DrawString(text, fontValue, brushValue, rectfValue, stringFormat);
            }
        }
Esempio n. 23
0
        /// <summary>
        /// Paints panel pnlChart
        /// </summary>
        private void PnlChartPaint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;

            g.Clear(LayoutColors.ColorChartBack);

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

            var pnl   = (Panel)sender;
            int width = pnl.ClientSize.Width;

            // Caption background
            var   pntStart     = new PointF(0, 0);
            SizeF szfCaption   = new Size(width, _infoRowHeight);
            var   rectfCaption = new RectangleF(pntStart, szfCaption);

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

            // Caption Text
            var stringFormat = new StringFormat
            {
                LineAlignment = StringAlignment.Center,
                Trimming      = StringTrimming.EllipsisCharacter,
                FormatFlags   = StringFormatFlags.NoWrap,
                Alignment     = StringAlignment.Center
            };
            string stringCaptionText = Language.T("Price Route Inside the Bar");

            rectfCaption = new RectangleF(Border, 0, pnl.ClientSize.Width - 2 * Border, _infoRowHeight);
            g.DrawString(stringCaptionText, _fontInfo, _brushCaptionText, rectfCaption, stringFormat);

            // Paint the panel background
            var rectClient = new RectangleF(0, _infoRowHeight, pnl.ClientSize.Width, pnl.Height - _infoRowHeight);

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

            // Paint bar info
            var rectBarInfo = new RectangleF(Border, _infoRowHeight + 1, pnl.ClientSize.Width - 2 * Border, _infoRowHeight);

            g.DrawString(_barInfo, _fontInfo, _brushGridText, rectBarInfo, stringFormat);

            // Searching the min and the max price and volume
            width = pnl.ClientSize.Width - 2 * Border;
            double    maxPrice  = Data.High[_barCurrent];
            double    minPrice  = Data.Low[_barCurrent];
            const int space     = 8;
            int       spcRight  = _szPrice.Width + 4;
            const int xLeft     = Border + space;
            int       xRight    = width - spcRight;
            int       yTop      = 2 * _infoRowHeight + 6;
            int       yBottom   = pnl.ClientSize.Height - 22;
            int       barPixels = _maxWayPoints < 10 ? 28 : _maxWayPoints < 15 ? 24 : 20;
            const int spcLeft   = 3;
            int       x         = barPixels + spcLeft;

            int       pointLeft   = x + barPixels + 30;
            int       pointRight  = xRight - 20;
            int       points      = Backtester.WayPoints(_barCurrent);
            const int pointRadius = 3;

            // Grid
            var    iCntLabels = (int)Math.Max((yBottom - yTop) / 30d, 1);
            double deltaPoint = (Data.InstrProperties.Digits == 5 || Data.InstrProperties.Digits == 3)
                                    ? Data.InstrProperties.Point * 100
                                    : Data.InstrProperties.Point * 10;
            double delta =
                Math.Max(Math.Round((maxPrice - minPrice) / iCntLabels, Data.InstrProperties.Point < 0.001 ? 3 : 1),
                         deltaPoint);

            minPrice   = Math.Round(minPrice, Data.InstrProperties.Point < 0.001f ? 3 : 1) - Data.InstrProperties.Point * 10;
            minPrice  -= delta;
            maxPrice  += delta;
            iCntLabels = (int)Math.Ceiling((maxPrice - minPrice) / delta);
            maxPrice   = minPrice + iCntLabels * delta;

            double scaleY = (yBottom - yTop) / (iCntLabels * delta);
            var    yOpen  = (int)(yBottom - (Data.Open[_barCurrent] - minPrice) * scaleY);
            var    yHigh  = (int)(yBottom - (Data.High[_barCurrent] - minPrice) * scaleY);
            var    yLow   = (int)(yBottom - (Data.Low[_barCurrent] - minPrice) * scaleY);
            var    yClose = (int)(yBottom - (Data.Close[_barCurrent] - minPrice) * scaleY);

            // Find the price distance
            double priceDistance = 0;

            for (int point = 1; point < points; point++)
            {
                priceDistance +=
                    Math.Abs(Backtester.WayPoint(_barCurrent, point).Price -
                             Backtester.WayPoint(_barCurrent, point - 1).Price);
            }
            double dPriceForAPixel = (pointRight - pointLeft) / priceDistance;

            // Points X
            var aiPointX = new int[points];

            aiPointX[0] = pointLeft;
            for (int point = 1; point < points - 1; point++)
            {
                var iDistance =
                    (int)
                    (Math.Abs(Backtester.WayPoint(_barCurrent, point).Price -
                              Backtester.WayPoint(_barCurrent, point - 1).Price) * dPriceForAPixel);
                aiPointX[point] = aiPointX[point - 1] + iDistance;
            }
            aiPointX[points - 1] = pointRight;
            for (int point = 1; point < points - 1; point++)
            {
                if (aiPointX[point] - aiPointX[point - 1] < barPixels + 1)
                {
                    aiPointX[point] = aiPointX[point - 1] + barPixels + 1;
                }
            }
            for (int point = points - 2; point > 0; point--)
            {
                if (aiPointX[point + 1] - aiPointX[point] < barPixels + 1)
                {
                    aiPointX[point] = aiPointX[point + 1] - barPixels - 1;
                }
            }

            // Find coordinates of the Way Points
            var pntWay = new Point[points];

            for (int point = 0; point < points; point++)
            {
                var pointY = (int)(yBottom - (Backtester.WayPoint(_barCurrent, point).Price - minPrice) * scaleY);
                pntWay[point] = new Point(aiPointX[point], pointY);
            }

            // Horizontal grid and Price labels
            for (double label = minPrice; label <= maxPrice + Data.InstrProperties.Point; label += delta)
            {
                var labelY = (int)(yBottom - (label - minPrice) * scaleY);
                g.DrawString(label.ToString(Data.FF), Font, _brushGridText, xRight, labelY - Font.Height / 2 - 1);
                g.DrawLine(_penGrid, Border + space, labelY, xRight, labelY);
            }

            // Vertical Grid
            g.DrawLine(_penGrid, x + barPixels / 2 - 1, yTop, x + barPixels / 2 - 1, yBottom + 2);
            for (int point = 0; point < points; point++)
            {
                var pt1 = new Point(pntWay[point].X, yTop);
                var pt2 = new Point(pntWay[point].X, yBottom + 2);
                var pt3 = new Point(pntWay[point].X - 5, yBottom + 4);
                g.DrawLine(_penGrid, pt1, pt2);
                g.DrawString((point + 1).ToString(CultureInfo.InvariantCulture), Font, _brushGridText, pt3);
            }

            // Bar Number
            string barNumber = (_barCurrent + 1).ToString(CultureInfo.InvariantCulture);
            int    stringX   = x + barPixels / 2 - 1 - g.MeasureString(barNumber, Font).ToSize().Width / 2;
            Brush  barBrush  = Backtester.BackTestEval(_barCurrent) == BacktestEval.Ambiguous ? _brushRed : _brushGridText;

            g.DrawString(barNumber, Font, barBrush, stringX, yBottom + 4);

            // Draw the bar
            g.DrawLine(_penBarBorder, x + barPixels / 2 - 1, yLow, x + barPixels / 2 - 1, yHigh);
            if (yClose < yOpen) // White bar
            {
                var rect    = new Rectangle(x, yClose, barPixels - 2, yOpen - yClose);
                var lgBrush = new LinearGradientBrush(rect, _colorBarWight1, _colorBarWight2, 5f);
                g.FillRectangle(lgBrush, rect);
                g.DrawRectangle(_penBarBorder, x, yClose, barPixels - 2, yOpen - yClose);
            }
            else if (yClose > yOpen) // Black bar
            {
                var rect    = new Rectangle(x, yOpen, barPixels - 2, yClose - yOpen);
                var lgBrush = new LinearGradientBrush(rect, _colorBarBlack1, _colorBarBlack2, 5f);
                g.FillRectangle(lgBrush, rect);
                g.DrawRectangle(_penBarBorder, x, yOpen, barPixels - 2, yClose - yOpen);
            }
            else // Cross
            {
                g.DrawLine(_penBarBorder, x, yClose, x + barPixels - 2, yClose);
            }

            // Draw cancelled orders
            for (int orderIndex = 0; orderIndex < Backtester.Orders(_barCurrent); orderIndex++)
            {
                int   ordNumber = Backtester.OrdNumb(_barCurrent, orderIndex);
                Order order     = Backtester.OrdFromNumb(ordNumber);
                if (order.OrdStatus != OrderStatus.Cancelled)
                {
                    continue;
                }

                if (order.OrdPrice > Data.High[_barCurrent] || order.OrdPrice < Data.Low[_barCurrent])
                {
                    continue;
                }

                int d     = barPixels / 2 - 1;
                int x1    = x + d;
                int x2    = x + barPixels - 2;
                var yDeal = (int)(yBottom - (order.OrdPrice - minPrice) * scaleY);
                var pen   = new Pen(LayoutColors.ColorChartGrid, 2);

                if (order.OrdDir == OrderDirection.Buy)
                {
                    g.DrawLine(pen, x, yDeal, x1, yDeal);
                    g.DrawLine(pen, x1, yDeal, x2, yDeal - d);
                    g.DrawLine(pen, x2 + 1, yDeal - d + 1, x1 + d / 2 + 1, yDeal - d + 1);
                    g.DrawLine(pen, x2, yDeal - d, x2, yDeal - d / 2);
                }
                else if (order.OrdDir == OrderDirection.Sell)
                {
                    g.DrawLine(pen, x, yDeal + 1, x1 + 1, yDeal + 1);
                    g.DrawLine(pen, x1, yDeal, x2, yDeal + d);
                    g.DrawLine(pen, x1 + d / 2 + 1, yDeal + d, x2, yDeal + d);
                    g.DrawLine(pen, x2, yDeal + d, x2, yDeal + d / 2 + 1);
                }
            }

            // Draw the deals on the bar
            for (int pos = 0; pos < Backtester.Positions(_barCurrent); pos++)
            {
                if (Backtester.PosTransaction(_barCurrent, pos) == Transaction.Transfer)
                {
                    continue;
                }

                var yDeal = (int)(yBottom - (Backtester.PosOrdPrice(_barCurrent, pos) - minPrice) * scaleY);

                if (Backtester.PosDir(_barCurrent, pos) == PosDirection.Long ||
                    Backtester.PosDir(_barCurrent, pos) == PosDirection.Short)
                {
                    int d  = barPixels / 2 - 1;
                    int x1 = x + d;
                    int x2 = x + barPixels - 2;
                    if (Backtester.OrdFromNumb(Backtester.PosOrdNumb(_barCurrent, pos)).OrdDir == OrderDirection.Buy)
                    {
                        // Buy
                        var pen = new Pen(LayoutColors.ColorTradeLong, 2);
                        g.DrawLine(pen, x, yDeal, x1, yDeal);
                        g.DrawLine(pen, x1, yDeal, x2, yDeal - d);
                        g.DrawLine(pen, x2 + 1, yDeal - d + 1, x1 + d / 2 + 1, yDeal - d + 1);
                        g.DrawLine(pen, x2, yDeal - d, x2, yDeal - d / 2);
                    }
                    else
                    {
                        // Sell
                        var pen = new Pen(LayoutColors.ColorTradeShort, 2);
                        g.DrawLine(pen, x, yDeal + 1, x1 + 1, yDeal + 1);
                        g.DrawLine(pen, x1, yDeal, x2, yDeal + d);
                        g.DrawLine(pen, x1 + d / 2 + 1, yDeal + d, x2, yDeal + d);
                        g.DrawLine(pen, x2, yDeal + d, x2, yDeal + d / 2 + 1);
                    }
                }
                else if (Backtester.PosDir(_barCurrent, pos) == PosDirection.Closed)
                {
                    // Close position
                    int d   = barPixels / 2 - 1;
                    int x1  = x + d;
                    int x2  = x + barPixels - 3;
                    var pen = new Pen(LayoutColors.ColorTradeClose, 2);
                    g.DrawLine(pen, x, yDeal, x1, yDeal);
                    g.DrawLine(pen, x1, yDeal + d / 2, x2, yDeal - d / 2);
                    g.DrawLine(pen, x1, yDeal - d / 2, x2, yDeal + d / 2);
                }
            }

            // Draw position lots
            for (int point = 0; point < points; point++)
            {
                int posNumber = Backtester.WayPoint(_barCurrent, point).PosNumb;
                if (posNumber == -1)
                {
                    continue;
                }

                Position     position     = Backtester.PosFromNumb(posNumber);
                double       posLots      = position.PosLots;
                PosDirection posDirection = position.PosDir;
                WayPointType wpType       = Backtester.WayPoint(_barCurrent, point).WPType;

                var hight  = (int)(Math.Max(posLots * 2, 2));
                int lenght = barPixels;
                int posX   = pntWay[point].X - (barPixels - 1) / 2;
                int posY   = yBottom - hight;

                if (point < points - 1)
                {
                    lenght = pntWay[point + 1].X - pntWay[point].X + 1;
                }

                if (posDirection == PosDirection.Long)
                {
                    // Long
                    var rect    = new Rectangle(posX - 1, posY - 1, lenght, hight + 2);
                    var lgBrush = new LinearGradientBrush(rect, _colorLongTrade1, _colorLongTrade2,
                                                          LinearGradientMode.Vertical);
                    rect = new Rectangle(posX - 1, posY, lenght, hight);
                    g.FillRectangle(lgBrush, rect);
                }
                else if (posDirection == PosDirection.Short)
                {
                    // Short
                    var rect    = new Rectangle(posX - 1, posY - 1, lenght, hight + 2);
                    var lgBrush = new LinearGradientBrush(rect, _colorShortTrade1, _colorShortTrade2,
                                                          LinearGradientMode.Vertical);
                    rect = new Rectangle(posX - 1, posY, lenght, hight);
                    g.FillRectangle(lgBrush, rect);
                }
                else if (posDirection == PosDirection.Closed && wpType == WayPointType.Exit)
                {
                    // Closed
                    var rect    = new Rectangle(posX - 1, yBottom - 2, barPixels + 1, 2);
                    var lgBrush = new LinearGradientBrush(rect, _colorClosedTrade1, _colorClosedTrade2,
                                                          LinearGradientMode.Vertical);
                    rect = new Rectangle(posX, yBottom - 2, barPixels - 1, 2);
                    g.FillRectangle(lgBrush, rect);
                }
            }

            // Draw the Beziers
            for (int point = 1; point < points; point++)
            {
                Point ptKnot1 = pntWay[point - 1];
                Point ptKnot2 = pntWay[point];

                int ctrlX1 = (ptKnot1.X + ptKnot2.X) / 2;
                int ctrlX2 = (ptKnot1.X + ptKnot2.X) / 2;

                int ctrlY1 = ptKnot1.Y;
                int ctrlY2 = ptKnot2.Y;

                if (point > 1)
                {
                    if (pntWay[point - 2].Y > pntWay[point - 1].Y && pntWay[point - 1].Y > pntWay[point].Y ||
                        pntWay[point - 2].Y < pntWay[point - 1].Y && pntWay[point - 1].Y < pntWay[point].Y)
                    {
                        ctrlY1 = (pntWay[point - 1].Y + pntWay[point].Y) / 2;
                    }
                }
                if (point < points - 1)
                {
                    if (pntWay[point - 1].Y > pntWay[point].Y && pntWay[point].Y > pntWay[point + 1].Y ||
                        pntWay[point - 1].Y < pntWay[point].Y && pntWay[point].Y < pntWay[point + 1].Y)
                    {
                        ctrlY2 = (pntWay[point - 1].Y + pntWay[point].Y) / 2;
                    }
                }

                if (point == 1)
                {
                    ctrlX1 = ptKnot1.X;
                    ctrlY1 = ptKnot1.Y;
                }
                if (point == points - 1)
                {
                    ctrlX2 = ptKnot2.X;
                    ctrlY2 = ptKnot2.Y;
                }

                var ptControl1 = new Point(ctrlX1, ctrlY1);
                var ptControl2 = new Point(ctrlX2, ctrlY2);

                g.DrawBezier(_penCross, ptKnot1, ptControl1, ptControl2, ptKnot2);
            }

            // Draw the WayPoints
            Brush brushWeyPnt = new SolidBrush(LayoutColors.ColorChartBack);

            for (int point = 0; point < points; point++)
            {
                g.FillEllipse(brushWeyPnt, pntWay[point].X - pointRadius, pntWay[point].Y - pointRadius, 2 * pointRadius,
                              2 * pointRadius);
                g.DrawEllipse(_penCross, pntWay[point].X - pointRadius, pntWay[point].Y - pointRadius, 2 * pointRadius,
                              2 * pointRadius);
            }

            // Draw O, H, L, C labels
            for (int point = 0; point < points; point++)
            {
                WayPointType wpType = Backtester.WayPoint(_barCurrent, point).WPType;
                if (wpType != WayPointType.Open && wpType != WayPointType.High &&
                    wpType != WayPointType.Low && wpType != WayPointType.Close)
                {
                    continue;
                }

                string label = "?";
                switch (wpType)
                {
                case WayPointType.Open:
                    label = "O";
                    break;

                case WayPointType.High:
                    label = "H";
                    break;

                case WayPointType.Low:
                    label = "L";
                    break;

                case WayPointType.Close:
                    label = "C";
                    break;
                }

                int xPoint = pntWay[point].X;
                int yPoint = pntWay[point].Y - Font.Height - 3;

                var stringFormatLabel = new StringFormat {
                    Alignment = StringAlignment.Center
                };
                g.DrawString(label, Font, _brushGridText, xPoint, yPoint, stringFormatLabel);
            }

            // Draw the deals on the route
            for (int point = 0; point < points; point++)
            {
                int posNumber = Backtester.WayPoint(_barCurrent, point).PosNumb;
                int ordNumber = Backtester.WayPoint(_barCurrent, point).OrdNumb;

                if (posNumber < 0 || ordNumber < 0)
                {
                    continue;
                }

                PosDirection   posDirection = Backtester.PosFromNumb(posNumber).PosDir;
                OrderDirection ordDirection = Backtester.OrdFromNumb(ordNumber).OrdDir;
                WayPointType   wpType       = Backtester.WayPoint(_barCurrent, point).WPType;

                if (wpType == WayPointType.None || wpType == WayPointType.Open || wpType == WayPointType.High ||
                    wpType == WayPointType.Low || wpType == WayPointType.Close)
                {
                    continue;
                }

                int yDeal = pntWay[point].Y;

                if (posDirection == PosDirection.Long || posDirection == PosDirection.Short ||
                    wpType == WayPointType.Cancel)
                {
                    int d = barPixels / 2 - 1;
                    x = pntWay[point].X - d;
                    int x1 = pntWay[point].X;
                    int x2 = x + barPixels - 2;
                    if (ordDirection == OrderDirection.Buy)
                    {
                        // Buy
                        var pen = new Pen(LayoutColors.ColorTradeLong, 2);
                        if (wpType == WayPointType.Cancel)
                        {
                            pen = new Pen(LayoutColors.ColorChartGrid, 2);
                        }
                        g.DrawLine(pen, x, yDeal, x1, yDeal);
                        g.DrawLine(pen, x1, yDeal, x2, yDeal - d);
                        g.DrawLine(pen, x2 + 1, yDeal - d + 1, x1 + d / 2 + 1, yDeal - d + 1);
                        g.DrawLine(pen, x2, yDeal - d, x2, yDeal - d / 2);
                    }
                    else
                    {
                        // Sell
                        var pen = new Pen(LayoutColors.ColorTradeShort, 2);
                        if (wpType == WayPointType.Cancel)
                        {
                            pen = new Pen(LayoutColors.ColorChartGrid, 2);
                        }
                        g.DrawLine(pen, x, yDeal + 1, x1 + 1, yDeal + 1);
                        g.DrawLine(pen, x1, yDeal, x2, yDeal + d);
                        g.DrawLine(pen, x1 + d / 2 + 1, yDeal + d, x2, yDeal + d);
                        g.DrawLine(pen, x2, yDeal + d, x2, yDeal + d / 2 + 1);
                    }
                }

                if (posDirection == PosDirection.Closed)
                {
                    // Close position
                    int d = barPixels / 2 - 1;
                    x = pntWay[point].X - d;
                    int x1  = pntWay[point].X;
                    int x2  = x + barPixels - 3;
                    var pen = new Pen(LayoutColors.ColorTradeClose, 2);
                    g.DrawLine(pen, x, yDeal, x1, yDeal);
                    g.DrawLine(pen, x1, yDeal + d / 2, x2, yDeal - d / 2);
                    g.DrawLine(pen, x1, yDeal - d / 2, x2, yDeal + d / 2);
                }
            }

            // Coordinate axes
            g.DrawLine(_penAxes, xLeft, yTop - 4, xLeft, yBottom); // Vertical left line
            g.DrawLine(_penAxes, xLeft, yBottom, xRight, yBottom);

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

            g.DrawLine(penBorder, 1, _infoRowHeight, 1, pnl.ClientSize.Height);
            g.DrawLine(penBorder, pnl.ClientSize.Width - Border + 1, _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);
        }
        /// <summary>
        /// Paints the journal
        /// </summary>
        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g       = e.Graphics;
            int      iHScrll = -HScrollBar.Value;
            var      sf      = new StringFormat {
                Alignment = StringAlignment.Center
            };

            // Caption background
            var rectfCaption = new RectangleF(0, 0, ClientSize.Width, 2 * _rowHeight);

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

            var   font                 = new Font(Font.FontFamily, 9);
            Color colorBack            = LayoutColors.ColorControlBack;
            var   brushCaptionText     = new SolidBrush(LayoutColors.ColorCaptionText);
            var   brushEvenRowBack     = new SolidBrush(LayoutColors.ColorEvenRowBack);
            var   brushSelectedRowBack = new SolidBrush(LayoutColors.ColorSelectedRowBack);
            var   brushSelectedRowText = new SolidBrush(LayoutColors.ColorSelectedRowText);
            var   brushRowText         = new SolidBrush(LayoutColors.ColorControlText);
            var   brushWarningBack     = new SolidBrush(LayoutColors.ColorWarningRowBack);
            var   brushWarningText     = new SolidBrush(LayoutColors.ColorWarningRowText);
            var   penLines             = new Pen(LayoutColors.ColorJournalLines);
            var   penBorder            = new Pen(Data.GetGradientColor(LayoutColors.ColorCaptionBack, -LayoutColors.DepthCaption),
                                                 Border);

            // Print the journal caption
            string unit = Configs.AccountInMoney
                              ? " [" + Configs.AccountCurrency + "]"
                              : " [" + Language.T("pips") + "]";
            string accUnit = " [" + Configs.AccountCurrency + "]";

            g.SetClip(new RectangleF(Border, 0, ClientSize.Width - 2 * Border, 2 * _rowHeight));
            g.DrawString(Language.T("Market Data"), font, brushCaptionText, iHScrll + (_xScaled[8] + _xScaled[0]) / 2, 0,
                         sf);
            g.DrawString(Language.T("Summary") + unit, font, brushCaptionText, iHScrll + (_xScaled[14] + _xScaled[8]) / 2,
                         0, sf);
            g.DrawString(Language.T("Account") + unit, font, brushCaptionText, iHScrll + (_xScaled[16] + _xScaled[14]) / 2,
                         0, sf);
            g.DrawString(Language.T("Margin") + accUnit, font, brushCaptionText,
                         iHScrll + (_xScaled[18] + _xScaled[16]) / 2, 0, sf);
            g.DrawString(Language.T("Backtest"), font, brushCaptionText, iHScrll + (_xScaled[19] + _xScaled[18]) / 2, 0,
                         sf);
            if (Configs.AccountInMoney)
            {
                for (int i = 0; i < _columns; i++)
                {
                    g.DrawString(_titlesInMoney[i], font, brushCaptionText, iHScrll + (_xScaled[i] + _xScaled[i + 1]) / 2,
                                 _rowHeight, sf);
                }
            }
            else
            {
                for (int i = 0; i < _columns; i++)
                {
                    g.DrawString(_titlesInPips[i], font, brushCaptionText, iHScrll + (_xScaled[i] + _xScaled[i + 1]) / 2,
                                 _rowHeight, sf);
                }
            }
            g.ResetClip();

            var rectField = new RectangleF(Border, 2 * _rowHeight, ClientSize.Width - 2 * Border,
                                           ClientSize.Height - 2 * _rowHeight - Border);

            g.FillRectangle(new SolidBrush(colorBack), rectField);

            var size = new Size(ClientSize.Width - VScrollBar.Width - 2 * Border, _rowHeight);

            // Prints the journal data
            for (int bar = _firstBar; bar < _firstBar + _shownBars; bar++)
            {
                int y     = (bar - _firstBar + 2) * _rowHeight;
                var point = new Point(Border, y);

                // Even row
                if (Math.Abs((bar - _firstBar) % 2f - 0) > 0.0001)
                {
                    g.FillRectangle(brushEvenRowBack, new Rectangle(point, size));
                }

                // Warning row
                bool isWarningRow = false;
                if (_journalData[bar - _firstBar, _columns - 1] == Language.T("Ambiguous"))
                {
                    g.FillRectangle(brushWarningBack, new Rectangle(point, size));
                    isWarningRow = true;
                }

                // Selected row
                Brush brush;
                if (bar - _firstBar == _selectedRow)
                {
                    g.FillRectangle(brushSelectedRowBack, new Rectangle(point, size));
                    brush = brushSelectedRowText;
                }
                else
                {
                    brush = isWarningRow ? brushWarningText : brushRowText;
                }

                int index = bar - _firstBar;

                // Draw the position icon
                int imgY = y + (int)Math.Floor((_rowHeight - 16) / 2.0);
                g.DrawImage(_positionIcons[index], iHScrll + 2, imgY, 16, 16);

                // Prints the data
                g.DrawString(_journalData[index, 0], font, brush, iHScrll + (16 + _xScaled[1]) / 2, (index + 2) * _rowHeight,
                             sf);
                for (int i = 1; i < _columns; i++)
                {
                    g.DrawString(_journalData[index, i], font, brush, iHScrll + (_xScaled[i] + _xScaled[i + 1]) / 2,
                                 (index + 2) * _rowHeight, sf);
                }
            }

            // Vertical grid lines
            for (int i = 1; i < _columns; i++)
            {
                if (i == 8 || i == 14 || i == 16 || i == 18)
                {
                    var rectfSeparator = new RectangleF(_xScaled[i] + iHScrll, (float)(_rowHeight / 2.0), 1,
                                                        (float)(3 * _rowHeight / 2.0));
                    Data.GradientPaint(g, rectfSeparator, LayoutColors.ColorCaptionBack, -2 * LayoutColors.DepthCaption);
                }
                g.DrawLine(penLines, _xScaled[i] + iHScrll, 2 * _rowHeight, _xScaled[i] + iHScrll, ClientSize.Height);
            }

            // Borders
            g.DrawLine(penBorder, 1, 2 * _rowHeight, 1, ClientSize.Height);
            g.DrawLine(penBorder, ClientSize.Width - Border + 1, 2 * _rowHeight, ClientSize.Width - Border + 1,
                       ClientSize.Height);
            g.DrawLine(penBorder, 0, ClientSize.Height - Border + 1, ClientSize.Width, ClientSize.Height - Border + 1);

            OnSelectedBarChange(new EventArgs());
        }
 /// <summary>
 /// Sets the panel colors
 /// </summary>
 public void SetColors()
 {
     colorCaptionBack = LayoutColors.ColorCaptionBack;
     brushCaption     = new SolidBrush(LayoutColors.ColorCaptionText);
     penBorder        = new Pen(Data.GetGradientColor(LayoutColors.ColorCaptionBack, -LayoutColors.DepthCaption), border);
 }
Esempio n. 26
0
        /// <summary>
        /// Sets the chart parameters
        /// </summary>
        private void InitChart(int width, int height)
        {
            Chart = new Bitmap(width, height);

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

            const int border = 1;
            const int space  = 2;

            int maximum;
            int minimum;

            int firstBar   = Data.FirstBar;
            int bars       = Data.Bars;
            int chartBars  = Data.Bars - firstBar;
            int maxBalance = Configs.AccountInMoney ? (int)Backtester.MaxMoneyBalance : Backtester.MaxBalance;
            int minBalance = Configs.AccountInMoney ? (int)Backtester.MinMoneyBalance : Backtester.MinBalance;
            int maxEquity  = Configs.AccountInMoney ? (int)Backtester.MaxMoneyEquity : Backtester.MaxEquity;
            int minEquity  = Configs.AccountInMoney ? (int)Backtester.MinMoneyEquity : Backtester.MinEquity;

            if (Configs.AdditionalStatistics)
            {
                int maxLongBalance  = Configs.AccountInMoney ? (int)Backtester.MaxLongMoneyBalance : Backtester.MaxLongBalance;
                int minLongBalance  = Configs.AccountInMoney ? (int)Backtester.MinLongMoneyBalance : Backtester.MinLongBalance;
                int maxShortBalance = Configs.AccountInMoney ? (int)Backtester.MaxShortMoneyBalance : Backtester.MaxShortBalance;
                int minShortBalance = Configs.AccountInMoney ? (int)Backtester.MinShortMoneyBalance : Backtester.MinShortBalance;
                int maxLSBalance    = Math.Max(maxLongBalance, maxShortBalance);
                int minLSBalance    = Math.Min(minLongBalance, minShortBalance);

                maximum = Math.Max(Math.Max(maxBalance, maxEquity), maxLSBalance) + 1;
                minimum = Math.Min(Math.Min(minBalance, minEquity), minLSBalance) - 1;
            }
            else
            {
                maximum = Math.Max(maxBalance, maxEquity) + 1;
                minimum = Math.Min(minBalance, minEquity) - 1;
            }

            const int yTop    = border + space;
            int       yBottom = height - border - space;
            const int xLeft   = border;
            int       xRight  = width - border - space;
            float     xScale  = (xRight - xLeft) / (float)chartBars;
            float     yScale  = (yBottom - yTop) / (float)(maximum - minimum);

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

            var balancePoints      = new PointF[chartBars];
            var equityPoints       = new PointF[chartBars];
            var longBalancePoints  = new PointF[chartBars];
            var shortBalancePoints = new PointF[chartBars];

            int index = 0;

            for (int bar = firstBar; bar < bars; bar++)
            {
                balancePoints[index].X = xLeft + index * xScale;
                equityPoints[index].X  = xLeft + index * xScale;
                if (Configs.AccountInMoney)
                {
                    balancePoints[index].Y = (float)(yBottom - (Backtester.MoneyBalance(bar) - minimum) * yScale);
                    equityPoints[index].Y  = (float)(yBottom - (Backtester.MoneyEquity(bar) - minimum) * yScale);
                }
                else
                {
                    balancePoints[index].Y = yBottom - (Backtester.Balance(bar) - minimum) * yScale;
                    equityPoints[index].Y  = yBottom - (Backtester.Equity(bar) - minimum) * yScale;
                }

                if (Configs.AdditionalStatistics)
                {
                    longBalancePoints[index].X  = xLeft + index * xScale;
                    shortBalancePoints[index].X = xLeft + index * xScale;
                    if (Configs.AccountInMoney)
                    {
                        longBalancePoints[index].Y  = (float)(yBottom - (Backtester.LongMoneyBalance(bar) - minimum) * yScale);
                        shortBalancePoints[index].Y = (float)(yBottom - (Backtester.ShortMoneyBalance(bar) - minimum) * yScale);
                    }
                    else
                    {
                        longBalancePoints[index].Y  = yBottom - (Backtester.LongBalance(bar) - minimum) * yScale;
                        shortBalancePoints[index].Y = yBottom - (Backtester.ShortBalance(bar) - minimum) * yScale;
                    }
                }

                index++;
            }

            Graphics g = Graphics.FromImage(Chart);

            // Paints the background by gradient
            var rectField = new RectangleF(1, 1, width - 2, height - 2);

            g.FillRectangle(new SolidBrush(LayoutColors.ColorChartBack), rectField);

            // Border
            g.DrawRectangle(penBorder, 0, 0, width - 1, height - 1);

            // 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);
            }

            // Draw the balance line
            g.DrawLines(new Pen(LayoutColors.ColorChartBalanceLine), balancePoints);
        }
Esempio n. 27
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>
        /// Sets the chart params
        /// </summary>
        void InitChart(int width, int height)
        {
            chart = new Bitmap(width, height);

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

            int border = 1;
            int space  = 2;

            int   XLeft, XRight, YTop, YBottom;
            float XScale, YScale;

            int bars;
            int chartBars;
            int maximum;
            int minimum;
            int firstBar;
            Pen penBorder;

            PointF[] apntBalance;
            PointF[] apntEquity;
            PointF[] apntLongBalance;
            PointF[] apntShortBalance;

            firstBar  = Data.FirstBar;
            bars      = Data.Bars;
            chartBars = Data.Bars - firstBar;
            int iMaxBalance = Configs.AccountInMoney ? (int)Backtester.MaxMoneyBalance : Backtester.MaxBalance;
            int iMinBalance = Configs.AccountInMoney ? (int)Backtester.MinMoneyBalance : Backtester.MinBalance;
            int iMaxEquity  = Configs.AccountInMoney ? (int)Backtester.MaxMoneyEquity : Backtester.MaxEquity;
            int iMinEquity  = Configs.AccountInMoney ? (int)Backtester.MinMoneyEquity : Backtester.MinEquity;

            if (Configs.AdditionalStatistics)
            {
                int iMaxLongBalance  = Configs.AccountInMoney ? (int)Backtester.MaxLongMoneyBalance : Backtester.MaxLongBalance;
                int iMinLongBalance  = Configs.AccountInMoney ? (int)Backtester.MinLongMoneyBalance : Backtester.MinLongBalance;
                int iMaxShortBalance = Configs.AccountInMoney ? (int)Backtester.MaxShortMoneyBalance : Backtester.MaxShortBalance;
                int iMinShortBalance = Configs.AccountInMoney ? (int)Backtester.MinShortMoneyBalance : Backtester.MinShortBalance;
                int iMaxLSBalance    = Math.Max(iMaxLongBalance, iMaxShortBalance);
                int iMinLSBalance    = Math.Min(iMinLongBalance, iMinShortBalance);

                maximum = Math.Max(Math.Max(iMaxBalance, iMaxEquity), iMaxLSBalance) + 1;
                minimum = Math.Min(Math.Min(iMinBalance, iMinEquity), iMinLSBalance) - 1;
            }
            else
            {
                maximum = Math.Max(iMaxBalance, iMaxEquity) + 1;
                minimum = Math.Min(iMinBalance, iMinEquity) - 1;
            }

            YTop    = border + space;
            YBottom = height - border - space;
            XLeft   = border;
            XRight  = width - border - space;
            XScale  = (XRight - XLeft) / (float)chartBars;
            YScale  = (YBottom - YTop) / (float)(maximum - minimum);

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

            apntBalance      = new PointF[chartBars];
            apntEquity       = new PointF[chartBars];
            apntLongBalance  = new PointF[chartBars];
            apntShortBalance = new PointF[chartBars];

            int index = 0;

            for (int iBar = firstBar; iBar < bars; iBar++)
            {
                apntBalance[index].X = XLeft + index * XScale;
                apntEquity[index].X  = XLeft + index * XScale;
                if (Configs.AccountInMoney)
                {
                    apntBalance[index].Y = (float)(YBottom - (Backtester.MoneyBalance(iBar) - minimum) * YScale);
                    apntEquity[index].Y  = (float)(YBottom - (Backtester.MoneyEquity(iBar) - minimum) * YScale);
                }
                else
                {
                    apntBalance[index].Y = YBottom - (Backtester.Balance(iBar) - minimum) * YScale;
                    apntEquity[index].Y  = YBottom - (Backtester.Equity(iBar) - minimum) * YScale;
                }

                if (Configs.AdditionalStatistics)
                {
                    apntLongBalance[index].X  = XLeft + index * XScale;
                    apntShortBalance[index].X = XLeft + index * XScale;
                    if (Configs.AccountInMoney)
                    {
                        apntLongBalance[index].Y  = (float)(YBottom - (Backtester.LongMoneyBalance(iBar) - minimum) * YScale);
                        apntShortBalance[index].Y = (float)(YBottom - (Backtester.ShortMoneyBalance(iBar) - minimum) * YScale);
                    }
                    else
                    {
                        apntLongBalance[index].Y  = YBottom - (Backtester.LongBalance(iBar) - minimum) * YScale;
                        apntShortBalance[index].Y = YBottom - (Backtester.ShortBalance(iBar) - minimum) * YScale;
                    }
                }

                index++;
            }

            Graphics g = Graphics.FromImage(chart);

            // Paints the background by gradient
            RectangleF rectField = new RectangleF(1, 1, width - 2, height - 2);

            g.FillRectangle(new SolidBrush(LayoutColors.ColorChartBack), rectField);

            // Border
            g.DrawRectangle(penBorder, 0, 0, width - 1, height - 1);

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

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

            // Draw the balance line
            g.DrawLines(new Pen(LayoutColors.ColorChartBalanceLine), apntBalance);
        }
        /// <summary>
        /// Paints panel pnlOptions
        /// </summary>
        private void PnlOptionsPaint(object sender, PaintEventArgs e)
        {
            var       pnl    = (Panel)sender;
            Graphics  g      = e.Graphics;
            const int border = 2;

            // Chart Title
            string str                 = Language.T("Interpolation Methods");
            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.ColorControlBack, 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);

            int       positionX = (PnlOptions.ClientSize.Width - 10) / 3;
            const int positionY = 35;
            int       num       = 0;

            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    if (num < _countMethods)
                    {
                        var pt1 = new Point(j * positionX + 10, i * 30 + positionY);
                        var pt2 = new Point(j * positionX + 30, i * 30 + positionY);
                        var pen = new Pen(Color.Red);
                        switch ((InterpolationMethod)AchboxMethods[num].Tag)
                        {
                        case InterpolationMethod.Pessimistic:
                            pen = new Pen(LayoutColors.ComparatorChartPessimisticLine);
                            break;

                        case InterpolationMethod.Shortest:
                            pen = new Pen(LayoutColors.ComparatorChartShortestLine);
                            break;

                        case InterpolationMethod.Nearest:
                            pen = new Pen(LayoutColors.ComparatorChartNearestLine);
                            break;

                        case InterpolationMethod.Optimistic:
                            pen = new Pen(LayoutColors.ComparatorChartOptimisticLine);
                            break;

                        case InterpolationMethod.Random:
                            var   pntRnd1  = new Point(j * positionX + 10, i * 30 + positionY - 6);
                            var   pntRnd2  = new Point(j * positionX + 30, i * 30 + positionY - 6);
                            var   pntRnd3  = new Point(j * positionX + 10, i * 30 + positionY + 6);
                            var   pntRnd4  = new Point(j * positionX + 30, i * 30 + positionY + 6);
                            var   penRnd   = new Pen(LayoutColors.ComparatorChartRandomBands, 2);
                            Brush brushRnd = new SolidBrush(LayoutColors.ComparatorChartRandomArea);
                            g.FillRectangle(brushRnd,
                                            new Rectangle(pntRnd1.X, pntRnd1.Y, pntRnd2.X - pntRnd1.X,
                                                          pntRnd4.Y - pntRnd2.Y));
                            g.DrawLine(penRnd, pntRnd1, pntRnd2);
                            g.DrawLine(penRnd, pntRnd3, pntRnd4);
                            pen = new Pen(LayoutColors.ComparatorChartRandomLine);
                            break;
                        }
                        pen.Width = 2;
                        g.DrawLine(pen, pt1, pt2);
                    }
                    else
                    {
                        var pt1 = new Point(j * positionX + 10, i * 30 + positionY);
                        var pt2 = new Point(j * positionX + 30, i * 30 + positionY);
                        var pen = new Pen(LayoutColors.ComparatorChartBalanceLine)
                        {
                            Width = 3
                        };
                        g.DrawLine(pen, pt1, pt2);
                    }

                    num++;
                }
            }
        }