Forex_Strategy_Builder.Chart.PnlInd_Paint C# (CSharp) Method

PnlInd_Paint() private method

Paints the panel PnlInd
private PnlInd_Paint ( object sender, PaintEventArgs e ) : void
sender object
e PaintEventArgs
return void
        void PnlInd_Paint(object sender, PaintEventArgs e)
        {
            if (!isIndicatorsShown) return;

            Panel pnl = (Panel)sender;
            Graphics g = e.Graphics;

            int slot = (int)pnl.Tag;

            int topSpace    = font.Height / 2 + 2;
            int bottomSpace = font.Height / 2;

            double minValue = double.MaxValue;
            double maxValue = double.MinValue;

            g.Clear(LayoutColors.ColorChartBack);

            if (chartBars == 0) return;

            foreach(IndicatorComp component in Data.Strategy.Slot[slot].Component)
                if (component.ChartType != IndChartType.NoChart)
                    for (int bar = Math.Max(firstBar - 1, component.FirstBar); bar <= lastBar; bar++)
                    {
                        double value = component.Value[bar];
                        if (value > maxValue) maxValue = value;
                        if (value < minValue) minValue = value;
                    }

            minValue = Math.Min(minValue, Data.Strategy.Slot[slot].MinValue);
            maxValue = Math.Max(maxValue, Data.Strategy.Slot[slot].MaxValue);

            foreach (double value in Data.Strategy.Slot[slot].SpecValue)
                if (value == 0)
                {
                    minValue = Math.Min(minValue, 0);
                    maxValue = Math.Max(maxValue, 0);
                }

            double scale = (pnl.ClientSize.Height - topSpace - bottomSpace) / (Math.Max(maxValue - minValue, 0.0001));

            // Grid
            double label;
            int    labelY;
            String strFormat;
            double labelAbs;
            int    XGridRight = pnl.ClientSize.Width - spcRight + 2;

            label = 0; // Zero line
            int labelYZero = (int)Math.Round(pnl.ClientSize.Height - bottomSpace - (label - minValue) * scale);
            if (label >= minValue && label <= maxValue)
            {
                labelAbs = Math.Abs(label);
                strFormat = labelAbs < 10 ? "F4" : labelAbs < 100 ? "F3" : labelAbs < 1000 ? "F2" : labelAbs < 10000 ? "F1" : "F0";
                g.DrawString(label.ToString(strFormat), font, brushFore, XRight, labelYZero - font.Height / 2 - 1);
                g.DrawLine(penGridSolid, spcLeft, labelYZero, XGridRight, labelYZero);
            }

            label = minValue; // Bottom line
            int labelYMin = (int)Math.Round(pnl.ClientSize.Height - bottomSpace - (label - minValue) * scale);
            if (Math.Abs(labelYZero - labelYMin) >= font.Height)
            {
                labelAbs = Math.Abs(label);
                strFormat = labelAbs < 10 ? "F4" : labelAbs < 100 ? "F3" : labelAbs < 1000 ? "F2" : labelAbs < 10000 ? "F1" : "F0";
                g.DrawString(label.ToString(strFormat), font, brushFore, XRight, labelYMin - font.Height / 2 - 1);
                if (isGridShown)
                    g.DrawLine(penGrid, spcLeft, labelYMin, XGridRight, labelYMin);
                else
                    g.DrawLine(penGrid, XGridRight - 5, labelYMin, XGridRight, labelYMin);
            }

            label = maxValue; // Top line
            int labelYMax = (int)Math.Round(pnl.ClientSize.Height - bottomSpace - (label - minValue) * scale);
            if (Math.Abs(labelYZero - labelYMax) >= font.Height)
            {
                labelAbs = Math.Abs(label);
                strFormat = labelAbs < 10 ? "F4" : labelAbs < 100 ? "F3" : labelAbs < 1000 ? "F2" : labelAbs < 10000 ? "F1" : "F0";
                g.DrawString(label.ToString(strFormat), font, brushFore, XRight, labelYMax - font.Height / 2 - 1);
                if (isGridShown)
                    g.DrawLine(penGrid, spcLeft, labelYMax, XGridRight, labelYMax);
                else
                    g.DrawLine(penGrid, XGridRight - 5, labelYMax, XGridRight, labelYMax);
            }

            if (Data.Strategy.Slot[slot].SpecValue != null)
                for (int i = 0; i < Data.Strategy.Slot[slot].SpecValue.Length; i++)
                {
                    label = Data.Strategy.Slot[slot].SpecValue[i];
                    if (label <= maxValue && label >= minValue)
                    {
                        labelY = (int)Math.Round(pnl.ClientSize.Height - bottomSpace - (label - minValue) * scale);
                        if (Math.Abs(labelY - labelYZero) < font.Height) continue;
                        if (Math.Abs(labelY - labelYMin)  < font.Height) continue;
                        if (Math.Abs(labelY - labelYMax)  < font.Height) continue;
                        labelAbs = Math.Abs(label);
                        strFormat = labelAbs < 10 ? "F4" : labelAbs < 100 ? "F3" : labelAbs < 1000 ? "F2" : labelAbs < 10000 ? "F1" : "F0";
                        g.DrawString(label.ToString(strFormat), font, brushFore, XRight, labelY - font.Height / 2 - 1);
                        if (isGridShown)
                            g.DrawLine(penGrid, spcLeft, labelY, XGridRight, labelY);
                        else
                            g.DrawLine(penGrid, XGridRight - 5, labelY, XGridRight, labelY);
                    }
                }

            // Vertical line
            if (isGridShown)
            {
                string date = Data.Time[firstBar].ToString("dd.MM") + " " + Data.Time[firstBar].ToString("HH:mm");
                int dateWidth = (int)g.MeasureString(date, font).Width;
                for (int vertLineBar = lastBar; vertLineBar > firstBar; vertLineBar -= (int)Math.Round((dateWidth + 10.0) / barPixels + 1))
                {
                    int XVertLine = (vertLineBar - firstBar) * barPixels + barPixels / 2 - 1 + spcLeft;
                    g.DrawLine(penGrid, XVertLine, topSpace, XVertLine, pnl.ClientSize.Height - bottomSpace);
                }
            }

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

            // Indicator chart
            foreach (IndicatorComp component in Data.Strategy.Slot[slot].Component)
            {
                if (component.ChartType == IndChartType.Histogram)
                {   // Histogram
                    double zero = 0;
                    if (zero < minValue) zero = minValue;
                    if (zero > maxValue) zero = maxValue;
                    int y0 = (int)Math.Round(pnl.ClientSize.Height - 5 - (zero - minValue) * scale);

                    Rectangle rect;
                    LinearGradientBrush lgBrush;
                    Pen penGreen = new Pen(LayoutColors.ColorTradeLong);
                    Pen penRed   = new Pen(LayoutColors.ColorTradeShort);

                    bool isPrevBarGreen = false;

                    if (isTrueChartsShown)
                    {
                        if (isIndicatorValueAtClose)
                        {
                            for (int bar = firstBar; bar <= lastBar; bar++)
                            {
                                double value     = component.Value[bar - 1];
                                double prevValue = component.Value[bar - 2];
                                int x = spcLeft + (bar - firstBar) * barPixels + barPixels / 2 - 1;
                                int y = (int)Math.Round(pnl.ClientSize.Height - 7 - (value - minValue) * scale);

                                if (value > prevValue || value == prevValue && isPrevBarGreen)
                                {
                                    if (y != y0)
                                    {
                                        if (y > y0)
                                            g.DrawLine(penGreen, x, y0, x, y);
                                        else if (y < y0 - 2)
                                            g.DrawLine(penGreen, x, y0 - 2, x, y);
                                        isPrevBarGreen = true;
                                    }
                                }
                                else
                                {
                                    if (y != y0)
                                    {
                                        if (y > y0)
                                            g.DrawLine(penRed, x, y0, x, y);
                                        else if (y < y0 - 2)
                                            g.DrawLine(penRed, x, y0 - 2, x, y);
                                        isPrevBarGreen = false;
                                    }
                                }
                            }
                            for (int bar = firstBar; bar <= lastBar; bar++)
                            {
                                double value     = component.Value[bar];
                                double prevValue = component.Value[bar - 1];
                                int x = spcLeft + (bar - firstBar) * barPixels + barPixels - 2;
                                int y = (int)Math.Round(pnl.ClientSize.Height - 7 - (value - minValue) * scale);

                                if (value > prevValue || value == prevValue && isPrevBarGreen)
                                {
                                    g.DrawLine(penGreen, x, y + 1, x, y - 1);
                                    g.DrawLine(penGreen, x - 1, y, x + 1, y);
                                    isPrevBarGreen = true;
                                }
                                else
                                {
                                    g.DrawLine(penRed, x, y + 1, x, y - 1);
                                    g.DrawLine(penRed, x - 1, y, x + 1, y);
                                    isPrevBarGreen = false;
                                }
                            }

                        }
                        else
                        {
                            for (int bar = firstBar; bar <= lastBar; bar++)
                            {
                                double value     = component.Value[bar];
                                double prevValue = component.Value[bar - 1];
                                int x = spcLeft + (bar - firstBar) * barPixels + barPixels / 2 - 1;
                                int y = (int)Math.Round(pnl.ClientSize.Height - 7 - (value - minValue) * scale);

                                if (value > prevValue || value == prevValue && isPrevBarGreen)
                                {
                                    g.DrawLine(penGreen, x, y + 1, x, y - 1);
                                    g.DrawLine(penGreen, x - 1, y, x + 1, y);
                                    if (y != y0)
                                    {
                                        if (y > y0 + 3)
                                            g.DrawLine(penGreen, x, y0, x, y - 3);
                                        else if (y < y0 - 5)
                                            g.DrawLine(penGreen, x, y0 - 2, x, y + 3);
                                        isPrevBarGreen = true;
                                    }
                                }
                                else
                                {
                                    g.DrawLine(penRed, x, y + 1, x, y - 1);
                                    g.DrawLine(penRed, x - 1, y, x + 1, y);
                                    if (y != y0)
                                    {
                                        if (y > y0 + 3)
                                            g.DrawLine(penRed, x, y0, x, y - 3);
                                        else if (y < y0 - 5)
                                            g.DrawLine(penRed, x, y0 - 2, x, y + 3);
                                        isPrevBarGreen = false;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        for (int bar = firstBar; bar <= lastBar; bar++)
                        {
                            double value     = component.Value[bar];
                            double prevValue = component.Value[bar - 1];
                            int x = (bar - firstBar) * barPixels + spcLeft;
                            int y = (int)Math.Round(pnl.ClientSize.Height - 7 - (value - minValue) * scale);

                            if (value > prevValue || value == prevValue && isPrevBarGreen)
                            {
                                if (y > y0)
                                {
                                    rect = new Rectangle(x - 1, y0, barPixels + 1, y - y0);
                                    lgBrush = new LinearGradientBrush(rect, colorLongTrade1, colorLongTrade2, 0f);
                                    rect = new Rectangle(x, y0, barPixels - 1, y - y0);
                                }
                                else if (y < y0)
                                {
                                    rect = new Rectangle(x - 1, y, barPixels + 1, y0 - y);
                                    lgBrush = new LinearGradientBrush(rect, colorLongTrade1, colorLongTrade2, 0f);
                                    rect = new Rectangle(x, y, barPixels - 1, y0 - y);
                                }
                                else
                                    continue;
                                g.FillRectangle(lgBrush, rect);
                                isPrevBarGreen = true;
                            }
                            else
                            {
                                if (y > y0)
                                {
                                    rect = new Rectangle(x - 1, y0, barPixels + 1, y - y0);
                                    lgBrush = new LinearGradientBrush(rect, colorShortTrade1, colorShortTrade2, 0f);
                                    rect = new Rectangle(x, y0, barPixels - 1, y - y0);
                                }
                                else if (y < y0)
                                {
                                    rect = new Rectangle(x - 1, y, barPixels + 1, y0 - y);
                                    lgBrush = new LinearGradientBrush(rect, colorShortTrade1, colorShortTrade2, 0f);
                                    rect = new Rectangle(x, y, barPixels - 1, y0 - y);
                                }
                                else
                                    continue;
                                g.FillRectangle(lgBrush, rect);
                                isPrevBarGreen = false;
                            }
                        }
                    }
                }

                if (component.ChartType == IndChartType.Line)
                {   // Line
                    Pen pen   = new Pen(component.ChartColor);
                    Pen penTC = new Pen(component.ChartColor);
                    penTC.DashStyle   = DashStyle.Dash;
                    penTC.DashPattern = new float[] { 2, 1 };

                    int YIndChart = pnl.ClientSize.Height - 7;

                    if (isTrueChartsShown)
                    {   // True Charts
                        Point[] point = new Point[lastBar - firstBar + 1];
                        for (int bar = firstBar; bar <= lastBar; bar++)
                        {
                            double value = component.Value[bar];
                            int x = spcLeft + (bar - firstBar + indicatorValueShift) * barPixels - 2 * indicatorValueShift;
                            int y = (int)Math.Round(YIndChart - (value - minValue) * scale);

                            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 = component.Value[bar - 1];
                                int x = spcLeft + (bar - firstBar) * barPixels;
                                int y = (int)Math.Round(YIndChart - (value - minValue) * scale);

                                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 value = component.Value[bar];
                            int x = (bar - firstBar) * barPixels + barPixels / 2 - 1 + spcLeft;
                            int y = (int)Math.Round(YIndChart - (value - minValue) * scale);
                            aPoint[bar - firstBar] = new Point(x, y);
                        }
                        g.DrawLines(pen, aPoint);
                    }
                }
            }

            // Vertical cross line
            if (isCrossShown && mouseX > XLeft - 1 && mouseX < XRight + 1)
                g.DrawLine(penCross, mouseX, 0, mouseX, pnl.ClientSize.Height);

            // Chart title
            Indicator indicator = Indicator_Store.ConstructIndicator(Data.Strategy.Slot[slot].IndicatorName, Data.Strategy.Slot[slot].SlotType);
            indicator.IndParam = Data.Strategy.Slot[slot].IndParam;
            string indicatorText = indicator.ToString();
            Size sizeTitle = g.MeasureString(indicatorText, Font).ToSize();
            g.FillRectangle(brushBack, new Rectangle(spcLeft, 0, sizeTitle.Width, sizeTitle.Height));
            g.DrawString(indicatorText, Font, brushFore, spcLeft, 0);

            return;
        }