Forex_Strategy_Builder.Chart.PnlPrice_Paint C# (CSharp) Method

PnlPrice_Paint() private method

Paints the panel PnlPrice
private PnlPrice_Paint ( object sender, PaintEventArgs e ) : void
sender object
e PaintEventArgs
return void
        void PnlPrice_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;

            g.Clear(LayoutColors.ColorChartBack);

            if (chartBars == 0) return;

            // Searching the min and the max price and volume
            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];
            }

            double pricePixel = (maxPrice - minPrice) / (YBottom - YTop);
            if (isVolumeShown)
                minPrice -= pricePixel * 30;
            else if (isPositionLotsShown)
                minPrice -= pricePixel * 10;

            maxPrice += pricePixel * verticalScale;
            minPrice -= pricePixel * verticalScale;

            // Grid
            int countLabels = (int)Math.Max((YBottom - YTop) / 30, 1);
            double deltaPoint = (Data.InstrProperties.Digits == 5 || Data.InstrProperties.Digits == 3) ? Data.InstrProperties.Point * 100 : Data.InstrProperties.Point * 10;
            double deltaLabel = Math.Max(Math.Round((maxPrice - minPrice) / countLabels, Data.InstrProperties.Point < 0.001 ? 3 : 1), deltaPoint);
            minPrice = Math.Round(minPrice, Data.InstrProperties.Point < 0.001 ? 3 : 1) - deltaPoint;
            countLabels = (int)Math.Ceiling((maxPrice - minPrice) / deltaLabel);
            maxPrice  = minPrice + countLabels * deltaLabel;
            YScale    = (YBottom - YTop) / (countLabels * deltaLabel);
            YVolScale = maxVolume > 0 ? 40.0f / maxVolume : 0f; // 40 - the highest volume line

            // Price labels
            for (double label = minPrice; label <= maxPrice + Data.InstrProperties.Point; label += deltaLabel)
            {
                int iLabelY = (int)Math.Round(YBottom - (label - minPrice) * YScale);
                g.DrawString(label.ToString(Data.FF), Font, brushFore, XRight, iLabelY - Font.Height / 2 - 1);
                if (isGridShown || label == minPrice)
                    g.DrawLine(penGrid, spcLeft, iLabelY, XRight, iLabelY);
                else
                    g.DrawLine(penGrid, XRight - 5, iLabelY, XRight, iLabelY);
            }
            // Date labels
            for (int iVertLineBar = lastBar; iVertLineBar > firstBar; iVertLineBar -= (int)Math.Round((szDate.Width + 10.0) / barPixels + 1))
            {
                int iXVertLine = (iVertLineBar - firstBar) * barPixels + spcLeft + barPixels / 2 - 1;
                if (isGridShown)
                    g.DrawLine(penGrid, iXVertLine, YTop, iXVertLine, YBottom + 2);
                string date = String.Format("{0} {1}", Data.Time[iVertLineBar].ToString(Data.DFS), Data.Time[iVertLineBar].ToString("HH:mm"));
                g.DrawString(date, font, brushFore, iXVertLine - szDate.Width / 2, YBottomText);
            }

            // Cross
            if (isCrossShown && mouseX > XLeft - 1 && mouseX < XRight  + 1)
            {
                Point point;
                Rectangle rec;
                int crossBar;

                crossBar = (mouseX - spcLeft) / barPixels;
                crossBar = Math.Max(0, crossBar);
                crossBar = Math.Min(chartBars - 1, crossBar);
                crossBar += firstBar;
                crossBar = Math.Min(Data.Bars - 1, crossBar);

                // Vertical positions
                point = new Point(mouseX - szDateL.Width / 2, YBottomText);
                rec   = new Rectangle(point, szDateL);

                // Vertical line
                if (isMouseInPriceChart && mouseY > YTop - 1 && mouseY < YBottom + 1)
                {
                    g.DrawLine(penCross, mouseX, YTop, mouseX, mouseY - 10);
                    g.DrawLine(penCross, mouseX, mouseY + 10, mouseX, YBottomText);
                }
                else if (isMouseInPriceChart || isMouseInIndicatorChart)
                {
                    g.DrawLine(penCross, mouseX, YTop, mouseX, YBottomText);
                }

                // Date Window
                if (isMouseInPriceChart || isMouseInIndicatorChart)
                {
                    g.FillRectangle(brushLabelBkgrd, rec);
                    g.DrawRectangle(penCross, rec);
                    string sDate = Data.Time[crossBar].ToString(Data.DF) + " " + Data.Time[crossBar].ToString("HH:mm");
                    g.DrawString(sDate, font, brushLabelFore, point);
                }

                if (isMouseInPriceChart && mouseY > YTop - 1 && mouseY < YBottom + 1)
                {
                    //Horizontal positions
                    point = new Point(XRight, mouseY - szPrice.Height / 2);
                    rec   = new Rectangle(point, szPrice);
                    // Horizontal line
                    g.DrawLine(penCross, XLeft, mouseY, mouseX - 10, mouseY);
                    g.DrawLine(penCross, mouseX + 10, mouseY, XRight, mouseY);
                    // Price Window
                    g.FillRectangle(brushLabelBkgrd, rec);
                    g.DrawRectangle(penCross, rec);
                    string sPrice = ((YBottom - mouseY) / YScale + minPrice).ToString(Data.FF);
                    g.DrawString(sPrice, font, brushLabelFore, point);
                }
            }

            // Draws Volume, Lots and Bars
            for (int bar = firstBar; bar <= lastBar; bar++)
            {
                int x       = (bar - firstBar) * barPixels + spcLeft;
                int yOpen   = (int)Math.Round(YBottom - (Data.Open[bar]   - minPrice) * YScale);
                int yHigh   = (int)Math.Round(YBottom - (Data.High[bar]   - minPrice) * YScale);
                int yLow    = (int)Math.Round(YBottom - (Data.Low[bar]    - minPrice) * YScale);
                int yClose  = (int)Math.Round(YBottom - (Data.Close[bar]  - minPrice) * YScale);
                int yVolume = (int)Math.Round(YBottom -  Data.Volume[bar] * YVolScale);

                // Draw the volume
                if (isVolumeShown && yVolume != YBottom)
                    g.DrawLine(penVolume, x + barPixels / 2 - 1, yVolume, x + barPixels / 2 - 1, YBottom);

                // Draw position lots
                if (isPositionLotsShown && Backtester.IsPos(bar))
                {
                    int iPosHight = (int)Math.Round(Math.Max(Backtester.SummaryLots(bar) * 2, 2));
                    int iPosY     = YBottom - iPosHight + 1;

                    if (Backtester.SummaryDir(bar) == PosDirection.Long)
                    {   // Long
                        Rectangle rect = new Rectangle(x - 1, iPosY, barPixels + 1, iPosHight);
                        LinearGradientBrush lgBrush = new LinearGradientBrush(rect, colorLongTrade1, colorLongTrade2, 0f);
                        rect = new Rectangle(x, iPosY, barPixels - 1, iPosHight);
                        g.FillRectangle(lgBrush, rect);
                    }
                    else if (Backtester.SummaryDir(bar) == PosDirection.Short)
                    {   // Short
                        Rectangle rect = new Rectangle(x - 1, iPosY, barPixels + 1, iPosHight);
                        LinearGradientBrush lgBrush = new LinearGradientBrush(rect, colorShortTrade1, colorShortTrade2, 0f);
                        rect = new Rectangle(x, iPosY, barPixels - 1, iPosHight);
                        g.FillRectangle(lgBrush, rect);
                    }
                    else
                    {   // Closed
                        Rectangle rect = new Rectangle(x - 1, 2, barPixels + 1, 2);
                        LinearGradientBrush lgBrush = new LinearGradientBrush(rect, colorClosedTrade1, colorClosedTrade2, 0f);
                        rect = new Rectangle(x, YBottom - 1, barPixels - 1, 2);
                        g.FillRectangle(lgBrush, rect);
                    }
                }

                // Draw the bar
                if (isCandleChart)
                {
                    if (barPixels < 25)
                        g.DrawLine(penBarBorder, x + barPixels / 2 - 1, yLow, x + barPixels / 2 - 1, yHigh);
                    else
                        g.DrawLine(penBarThick, x + barPixels / 2 - 1, yLow, x + barPixels / 2 - 1, yHigh);

                    if (barPixels == 2)
                        g.DrawLine(penBarBorder, x, yClose, x + 1, yClose);
                    else
                    {
                        if (yClose < yOpen)
                        {   // White bar
                            Rectangle rect = new Rectangle(x, yClose, barPixels - 2, yOpen - yClose);
                            LinearGradientBrush lgBrush = new LinearGradientBrush(rect, colorBarWhite1, colorBarWhite2, 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, rect);
                        }
                        else
                        {   // Cross
                            if (barPixels < 25)
                                g.DrawLine(penBarBorder, x, yClose, x + barPixels - 2, yClose);
                            else
                                g.DrawLine(penBarThick, x, yClose, x + barPixels - 2, yClose);
                        }
                    }
                }
                else
                {
                    if (barPixels == 2)
                    {
                        g.DrawLine(penBarBorder, x, yClose, x + 1, yClose);
                        g.DrawLine(penBarBorder, x + barPixels / 2 - 1, yLow, x + barPixels / 2 - 1, yHigh);
                    }
                    else if (barPixels <= 16)
                    {
                        g.DrawLine(penBarBorder, x + barPixels / 2 - 1, yLow, x + barPixels / 2 - 1, yHigh);
                        if (yClose != yOpen)
                        {
                            g.DrawLine(penBarBorder, x, yOpen, x + barPixels / 2 - 1, yOpen);
                            g.DrawLine(penBarBorder, x + barPixels / 2 - 1, yClose, x + barPixels - 2, yClose);
                        }
                        else
                        {
                            g.DrawLine(penBarBorder, x, yClose, x + barPixels - 2, yClose);
                        }
                    }
                    else
                    {
                        g.DrawLine(penBarThick, x + barPixels / 2 - 1, yLow + 2, x + barPixels / 2 - 1, yHigh - 1);
                        if (yClose != yOpen)
                        {
                            g.DrawLine(penBarThick, x + 1, yOpen, x + barPixels / 2 - 1, yOpen);
                            g.DrawLine(penBarThick, x + barPixels / 2, yClose, x + barPixels - 2, yClose);
                        }
                        else
                        {
                            g.DrawLine(penBarThick, x, yClose, x + barPixels - 2, yClose);
                        }
                    }
                }
            }

            // Drawing the indicators in the chart
            g.SetClip(new RectangleF(0, YTop, XRight, YBottom - YTop));
            for (int slot = 0; slot < Data.Strategy.Slots && isIndicatorsShown; slot++)
            {
                if (Data.Strategy.Slot[slot].SeparatedChart || repeatedIndicator[slot]) continue;

                int cloudUp   = 0; // For Ichimoku and similar
                int cloudDown = 0; // For Ichimoku and similar

                bool isIndicatorValueAtClose = true;
                int  indicatorValueShift = 1;
                foreach (ListParam listParam in Data.Strategy.Slot[slot].IndParam.ListParam)
                    if (listParam.Caption == "Base price" && listParam.Text == "Open")
                    {
                        isIndicatorValueAtClose = false;
                        indicatorValueShift = 0;
                    }

                for (int comp = 0; comp < Data.Strategy.Slot[slot].Component.Length; comp++)
                {
                    Pen pen   = new Pen(Data.Strategy.Slot[slot].Component[comp].ChartColor);
                    Pen penTC = new Pen(Data.Strategy.Slot[slot].Component[comp].ChartColor);
                    penTC.DashStyle   = DashStyle.Dash;
                    penTC.DashPattern = new float[] { 2, 1 };

                    if (Data.Strategy.Slot[slot].Component[comp].ChartType == IndChartType.Line)
                    {   // Line
                        if (isTrueChartsShown)
                        {   // True Charts
                            Point[] point = new Point[lastBar - firstBar + 1];
                            for (int bar = firstBar; bar <= lastBar; bar++)
                            {
                                double value = Data.Strategy.Slot[slot].Component[comp].Value[bar];
                                int x = spcLeft + (bar - firstBar) * barPixels + indicatorValueShift * (barPixels - 2);
                                int y = (int)Math.Round(YBottom - (value - minPrice) * YScale);

                                if (value == 0)
                                    point[bar - firstBar] = point[Math.Max(bar - firstBar - 1, 0)];
                                else
                                    point[bar - firstBar] = new Point(x, y);
                            }

                            for (int bar = firstBar; bar <= lastBar; bar++)
                            {   // All bars except the last one
                                int i = bar - firstBar;

                                // The indicator value point
                                g.DrawLine(pen, point[i].X - 1, point[i].Y, point[i].X + 1, point[i].Y);
                                g.DrawLine(pen, point[i].X, point[i].Y - 1, point[i].X, point[i].Y + 1);

                                if (bar == firstBar && isIndicatorValueAtClose)
                                {   // First bar
                                    double value = Data.Strategy.Slot[slot].Component[comp].Value[bar - 1];
                                    int x = spcLeft + (bar - firstBar) * barPixels;
                                    int y = (int)Math.Round(YBottom - (value - minPrice) * YScale);

                                    int deltaY = Math.Abs(y - point[i].Y);
                                    if (barPixels > 3)
                                    {   // Horizontal part
                                        if (deltaY == 0)
                                            g.DrawLine(pen, x + 1, y, x + barPixels - 5, y);
                                        else if (deltaY < 3)
                                            g.DrawLine(pen, x + 1, y, x + barPixels - 4, y);
                                        else
                                            g.DrawLine(pen, x + 1, y, x + barPixels - 2, y);
                                    }
                                    if (deltaY > 4)
                                    {   // Vertical part
                                        if (point[i].Y > y)
                                            g.DrawLine(penTC, x + barPixels - 2, y + 2, x + barPixels - 2, point[i].Y - 2);
                                        else
                                            g.DrawLine(penTC, x + barPixels - 2, y - 2, x + barPixels - 2, point[i].Y + 2);
                                    }
                                }

                                if (bar < lastBar)
                                {
                                    int deltaY = Math.Abs(point[i + 1].Y - point[i].Y);

                                    if (barPixels > 3)
                                    {   // Horizontal part
                                        if (deltaY == 0)
                                            g.DrawLine(pen, point[i].X + 3, point[i].Y, point[i + 1].X - 3, point[i].Y);
                                        else if (deltaY < 3)
                                            g.DrawLine(pen, point[i].X + 3, point[i].Y, point[i + 1].X - 2, point[i].Y);
                                        else
                                            g.DrawLine(pen, point[i].X + 3, point[i].Y, point[i + 1].X, point[i].Y);
                                    }
                                    if (deltaY > 4)
                                    {   // Vertical part
                                        if (point[i + 1].Y > point[i].Y)
                                            g.DrawLine(penTC, point[i + 1].X, point[i].Y + 2, point[i + 1].X, point[i + 1].Y - 2);
                                        else
                                            g.DrawLine(penTC, point[i + 1].X, point[i].Y - 2, point[i + 1].X, point[i + 1].Y + 2);
                                    }
                                }

                                if (bar == lastBar && !isIndicatorValueAtClose && barPixels > 3)
                                {   // Last bar
                                    g.DrawLine(pen, point[i].X + 3, point[i].Y, point[i].X + barPixels - 2, point[i].Y);
                                }
                            }
                        }
                        else
                        {   // Regular Charts
                            Point[] aPoint = new Point[lastBar - firstBar + 1];
                            for (int bar = firstBar; bar <= lastBar; bar++)
                            {
                                double dValue = Data.Strategy.Slot[slot].Component[comp].Value[bar];
                                int x = spcLeft + (bar - firstBar) * barPixels + barPixels / 2 - 1;
                                int y = (int)Math.Round(YBottom - (dValue - minPrice) * YScale);

                                if (dValue == 0)
                                    aPoint[bar - firstBar] = aPoint[Math.Max(bar - firstBar - 1, 0)];
                                else
                                    aPoint[bar - firstBar] = new Point(x, y);
                            }
                            g.DrawLines(pen, aPoint);
                        }
                    }
                    else if (Data.Strategy.Slot[slot].Component[comp].ChartType == IndChartType.Dot)
                    {   // Dots
                        for (int bar = firstBar; bar <= lastBar; bar++)
                        {
                            double dValue = Data.Strategy.Slot[slot].Component[comp].Value[bar];
                            int x = (bar - firstBar) * barPixels + barPixels / 2 - 1 + spcLeft;
                            int y = (int)Math.Round(YBottom - (dValue - minPrice) * YScale);
                            if (barPixels == 2)
                                g.FillRectangle(pen.Brush, x, y, 1, 1);
                            else
                            {
                                g.DrawLine(pen, x - 1, y, x + 1, y);
                                g.DrawLine(pen, x, y - 1, x, y + 1);
                            }
                        }
                    }
                    else if (Data.Strategy.Slot[slot].Component[comp].ChartType == IndChartType.Level)
                    {   // Level
                        for (int bar = firstBar; bar <= lastBar; bar++)
                        {
                            double dValue = Data.Strategy.Slot[slot].Component[comp].Value[bar];
                            int x = (bar - firstBar) * barPixels + spcLeft;
                            int y = (int)Math.Round(YBottom - (dValue - minPrice) * YScale);
                            g.DrawLine(pen, x, y, x + barPixels - 1, y);
                        }
                    }
                    else if (Data.Strategy.Slot[slot].Component[comp].ChartType == IndChartType.CloudUp)
                    {
                        cloudUp = comp;
                    }
                    else if (Data.Strategy.Slot[slot].Component[comp].ChartType == IndChartType.CloudDown)
                    {
                        cloudDown = comp;
                    }
                }

                // Clouds
                if (cloudUp > 0 && cloudDown > 0)
                {
                    PointF[] apntUp   = new PointF[lastBar - firstBar + 1];
                    PointF[] apntDown = new PointF[lastBar - firstBar + 1];
                    for (int bar = firstBar; bar <= lastBar; bar++)
                    {
                        double dValueUp   = Data.Strategy.Slot[slot].Component[cloudUp].Value[bar];
                        double dValueDown = Data.Strategy.Slot[slot].Component[cloudDown].Value[bar];
                        apntUp[bar - firstBar].X = (bar - firstBar) * barPixels + barPixels / 2 - 1 + spcLeft;
                        apntUp[bar - firstBar].Y = (int)Math.Round(YBottom - (dValueUp - minPrice) * YScale);
                        apntDown[bar - firstBar].X = (bar - firstBar) * barPixels + barPixels / 2 - 1 + spcLeft;
                        apntDown[bar - firstBar].Y = (int)Math.Round(YBottom - (dValueDown - minPrice) * YScale);
                    }

                    GraphicsPath pathUp = new GraphicsPath();
                    pathUp.AddLine(new PointF(apntUp[0].X, 0), apntUp[0]);
                    pathUp.AddLines(apntUp);
                    pathUp.AddLine(apntUp[lastBar - firstBar], new PointF(apntUp[lastBar - firstBar].X, 0));
                    pathUp.AddLine(new PointF(apntUp[lastBar - firstBar].X, 0), new PointF(apntUp[0].X, 0));

                    GraphicsPath pathDown = new GraphicsPath();
                    pathDown.AddLine(new PointF(apntDown[0].X, 0), apntDown[0]);
                    pathDown.AddLines(apntDown);
                    pathDown.AddLine(apntDown[lastBar - firstBar], new PointF(apntDown[lastBar - firstBar].X, 0));
                    pathDown.AddLine(new PointF(apntDown[lastBar - firstBar].X, 0), new PointF(apntDown[0].X, 0));

                    Color colorUp   = Color.FromArgb(50, Data.Strategy.Slot[slot].Component[cloudUp].ChartColor);
                    Color colorDown = Color.FromArgb(50, Data.Strategy.Slot[slot].Component[cloudDown].ChartColor);

                    Pen penUp   = new Pen(Data.Strategy.Slot[slot].Component[cloudUp].ChartColor);
                    Pen penDown = new Pen(Data.Strategy.Slot[slot].Component[cloudDown].ChartColor);

                    penUp.DashStyle   = DashStyle.Dash;
                    penDown.DashStyle = DashStyle.Dash;

                    Brush brushUp   = new SolidBrush(colorUp);
                    Brush brushDown = new SolidBrush(colorDown);

                    System.Drawing.Region regionUp = new Region(pathUp);
                    regionUp.Exclude(pathDown);
                    g.FillRegion(brushDown, regionUp);

                    System.Drawing.Region regionDown = new Region(pathDown);
                    regionDown.Exclude(pathUp);
                    g.FillRegion(brushUp, regionDown);

                    g.DrawLines(penUp,   apntUp);
                    g.DrawLines(penDown, apntDown);
                }

            }
            g.ResetClip();

            // Draws position price, deals and Ambiguous note
            for (int bar = firstBar; bar <= lastBar; bar++)
            {
                int x     = (bar - firstBar) * barPixels + spcLeft;
                int yHigh = (int)Math.Round(YBottom - (Data.High[bar] - minPrice) * YScale);

                // Draw the corrected position price
                for (int iPos = 0; iPos < Backtester.Positions(bar) && isPositionPriceShown; iPos++)
                {
                    int yPrice = (int)Math.Round(YBottom - (Backtester.SummaryPrice(bar) - minPrice) * YScale);

                    if (yPrice >= YBottom || yPrice <= YTop) continue;

                    if (Backtester.SummaryDir(bar) == PosDirection.Long)
                    {   // Long
                        g.DrawLine(penTradeLong, x, yPrice, x + barPixels - 2, yPrice);
                    }
                    else if (Backtester.SummaryDir(bar) == PosDirection.Short)
                    {   // Short
                        g.DrawLine(penTradeShort, x, yPrice, x + barPixels - 2, yPrice);
                    }
                    else if (Backtester.SummaryDir(bar) == PosDirection.Closed)
                    {   // Closed
                        g.DrawLine(penTradeClose, x, yPrice, x + barPixels - 2, yPrice);
                    }
                }

                //// Draw Permanent SL and TP
                //for (int iPos = 0; iPos < Backtester.Positions(bar) && isPositionPriceShown; iPos++)
                //{
                //    int yAbsSL = (int)Math.Round(YBottom - (Backtester.SummaryAbsoluteSL(bar) - minPrice) * YScale);
                //    int yAbsTP = (int)Math.Round(YBottom - (Backtester.SummaryAbsoluteTP(bar) - minPrice) * YScale);

                //    if (yAbsTP < YBottom && yAbsTP > YTop)
                //        g.DrawLine(penTradeLong, x, yAbsTP, x + barPixels - 2, yAbsTP);
                //    if (yAbsSL < YBottom && yAbsSL > YTop)
                //        g.DrawLine(penTradeShort, x, yAbsSL, x + barPixels - 2, yAbsSL);
                //}

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

                    int yDeal = (int)Math.Round(YBottom - (Backtester.PosOrdPrice(bar, iPos) - minPrice) * YScale);

                    if (Backtester.PosDir(bar, iPos) == PosDirection.Long ||
                        Backtester.PosDir(bar, iPos) == PosDirection.Short)
                    {
                        if (Backtester.OrdFromNumb(Backtester.PosOrdNumb(bar, iPos)).OrdDir == OrderDirection.Buy)
                        {   // Buy
                            Pen pen = new Pen(brushTradeLong, 2);
                            if (barPixels < 8)
                            {
                                g.DrawLine(pen, x, yDeal, x + barPixels - 1, yDeal);
                            }
                            else if (barPixels == 8)
                            {
                                g.DrawLine(pen, x, yDeal, x + 4, yDeal);
                                pen.EndCap = LineCap.DiamondAnchor;
                                g.DrawLine(pen, x + 2, yDeal, x + 5, yDeal - 3);
                            }
                            else if (barPixels > 8)
                            {
                                int d = barPixels / 2 - 1;
                                int x1 = x + d;
                                int x2 = x + barPixels - 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(brushTradeShort, 2);
                            if (barPixels < 8)
                            {
                                g.DrawLine(pen, x, yDeal, x + barPixels - 1, yDeal);
                            }
                            else if (barPixels == 8)
                            {
                                g.DrawLine(pen, x, yDeal + 1, x + 4, yDeal + 1);
                                pen.EndCap = LineCap.DiamondAnchor;
                                g.DrawLine(pen, x + 2, yDeal, x + 5, yDeal + 3);
                            }
                            else if (barPixels > 8)
                            {
                                int d = barPixels / 2 - 1;
                                int x1 = x + d;
                                int x2 = x + barPixels - 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, iPos) == PosDirection.Closed)
                    {   // Close
                        Pen pen = new Pen(brushTradeClose, 2);
                        if (barPixels < 8)
                        {
                            g.DrawLine(pen, x, yDeal, x + barPixels - 1, yDeal);
                        }
                        else if (barPixels == 8)
                        {
                            g.DrawLine(pen, x, yDeal, x + 7, yDeal);
                            g.DrawLine(pen, x + 5, yDeal - 2, x + 5, yDeal + 2);
                        }
                        else if (barPixels > 8)
                        {
                            int d = barPixels / 2 - 1;
                            int x1 = x + d;
                            int x2 = x + barPixels - 3;
                            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);
                        }
                    }
                }

                // Ambiguous note
                if (isAmbiguousBarsShown && Backtester.BackTestEval(bar) == "Ambiguous")
                    g.DrawString("!", Font, brushSignalRed, x + barPixels / 2 - 4, yHigh - 20);
            }

            // Chart title
            g.DrawString(chartTitle, font, brushFore, spcLeft, 0);

            return;
        }