public override void Draw(GraphicsWrapper g, PointF?mousePosition, RectangleF clippingRectangle, RectangleF drawingSpace)
        {
            if (Visible == false)
            {
                return;
            }

            if (_controlPoints.Count < 1)
            {
                return;
            }

            PointF point1 = _controlPoints[0];
            PointF point2;

            if (_controlPoints.Count < 2)
            {
                point2 = mousePosition.Value;
            }
            else
            {
                point2 = _controlPoints[1];
            }

            // Clipping opitmization.
            RectangleF rectangle = new RectangleF(
                Math.Min(point1.X, point2.X), Math.Min(point1.Y, point2.Y),
                Math.Abs(point2.X - point1.X), Math.Abs(point2.Y - point1.Y));

            if (rectangle.IntersectsWith(clippingRectangle) == false)
            {
                return;
            }

            // Draw base line.
            g.DrawLine(_dashedLinePen, point1, point2);

            float baseLevel = point1.Y;
            float height    = point2.Y - point1.Y;

            // Draw fibbonacci levels.
            float[] levels = new float[] { 0, 23.6f, 38.2f, 50, 61.8f, 100 };
            for (int i = 0; i < levels.Length; i++)
            {
                float actualLevel = baseLevel + height * levels[i] / 100f;
                g.DrawLine(_solidLinePen, point1.X, actualLevel, point2.X, actualLevel);
                g.DrawString(levels[i].ToString(), DefaultDynamicObjectFont, Brushes.White, point1.X, actualLevel);
            }



            if (Selected)
            {
                DrawControlPoints(g);
            }
        }
Beispiel #2
0
        protected void DrawLine(GraphicsWrapper g, Pen linePen, float[] values, int unitsUnification, RectangleF clippingRectangle, float itemWidth, float itemMargin)
        {
            PointF drawingPoint = new PointF();

            int startIndex, endIndex;

            GetDrawingRangeIndecesFromClippingRectange(clippingRectangle, drawingPoint, unitsUnification, out startIndex, out endIndex, itemWidth, itemMargin);

            for (int i = startIndex + unitsUnification; i < endIndex && i < values.Length + unitsUnification - 1; i += unitsUnification)
            {
                int actualIndex         = i;
                int actualPreviousIndex = i - unitsUnification;

                if (actualIndex >= values.Length)
                {
                    actualIndex = values.Length - 1;
                }

                float previousValue = (float)values[actualPreviousIndex];
                float value         = (float)values[actualIndex];

                if (float.IsNaN(previousValue) == false && float.IsNaN(value) == false)
                {
                    g.DrawLine(linePen, drawingPoint.X, drawingPoint.Y + previousValue, drawingPoint.X + itemMargin + itemWidth, drawingPoint.Y + value);
                }

                drawingPoint.X = i * (itemMargin + itemWidth);
            }
        }
        /// <summary>
        /// Enter locked.
        /// </summary>
        void DrawBar(GraphicsWrapper g, ref PointF startingPoint, BarData barData, float itemWidth, float itemMargin, int itemUnitification)
        {
            float xMiddle    = startingPoint.X + itemWidth / 2;
            float xHalfWidth = itemWidth / 2;

            Pen pen = _risingBarPen;

            if (barData.BarIsRising == false)
            {
                pen = _fallingBarPen;
            }

            if (pen == null)
            {
                return;
            }

            float yDisplacement = startingPoint.Y;

            g.DrawLine(pen, xMiddle, yDisplacement + (float)barData.Low, xMiddle, yDisplacement + (float)barData.High);
            g.DrawLine(pen, xMiddle, yDisplacement + (float)barData.Open, xMiddle - xHalfWidth, yDisplacement + (float)barData.Open);
            g.DrawLine(pen, xMiddle, yDisplacement + (float)barData.Close, xMiddle + xHalfWidth, yDisplacement + (float)barData.Close);
        }
        public override void Draw(GraphicsWrapper g, PointF? mousePosition, RectangleF clippingRectangle, RectangleF drawingSpace)
        {
            if (Visible == false)
            {
                return;
            }

            foreach (double level in _levels)
            {
                if (level >= drawingSpace.Y && level <= drawingSpace.Y + drawingSpace.Height)
                {
                    g.DrawLine(_pen, drawingSpace.X, (float)level, drawingSpace.X + drawingSpace.Width, (float)level);
                }
            }
        }
Beispiel #5
0
        public override void Draw(GraphicsWrapper g, PointF?mousePosition, RectangleF clippingRectangle, RectangleF drawingSpace)
        {
            if (Visible == false)
            {
                return;
            }

            foreach (double level in _levels)
            {
                if (level >= drawingSpace.Y && level <= drawingSpace.Y + drawingSpace.Height)
                {
                    g.DrawLine(_pen, drawingSpace.X, (float)level, drawingSpace.X + drawingSpace.Width, (float)level);
                }
            }
        }
Beispiel #6
0
        protected void DrawColorAreaItem(GraphicsWrapper g, ref PointF drawingPoint, float[] values, Pen pen, Brush fill,
                                         int index, int previousItemIndex, float itemWidth, float itemMargin)
        {
            float indexValue             = values[index];
            float previousItemIndexValue = values[previousItemIndex];

            int unificationCount = index - previousItemIndex;

            for (int i = previousItemIndex; i <= index; i++)
            {
                if (float.IsNaN(previousItemIndexValue))
                {
                    previousItemIndexValue = values[i];
                }
                else if (float.IsNaN(indexValue))
                {
                    indexValue = values[i];
                }
            }

            if (float.IsNaN(indexValue) || float.IsNaN(previousItemIndexValue))
            {// Failed to find reasonable values to draw.
                return;
            }

            if (fill != null)
            {
                g.FillPolygon(fill, new PointF[] {
                    drawingPoint,
                    new PointF(drawingPoint.X + (itemMargin + itemWidth) * unificationCount, drawingPoint.Y),
                    new PointF(drawingPoint.X + (itemMargin + itemWidth) * unificationCount, drawingPoint.Y + indexValue),
                    new PointF(drawingPoint.X, drawingPoint.Y + previousItemIndexValue)
                });
            }

            if (pen != null)
            {
                g.DrawLine(pen, drawingPoint.X, drawingPoint.Y + previousItemIndexValue,
                           drawingPoint.X + (itemMargin + itemWidth) * unificationCount, drawingPoint.Y + indexValue);
            }
        }
Beispiel #7
0
        public override void Draw(GraphicsWrapper g, PointF?mousePosition, RectangleF clippingRectangle, RectangleF drawingSpace)
        {
            if (Visible == false || _controlPoints.Count < 1)
            {
                return;
            }

            if (clippingRectangle.Contains(_controlPoints[0]) == false)
            {// Clipping opitmization.
                return;
            }

            SizeF size = g.MeasureString(_text, DefaultDynamicObjectFont);

            if (size.Height < 0)
            {
                _rectangle = new RectangleF(_controlPoints[0].X, _controlPoints[0].Y + size.Height, size.Width, -size.Height);
            }
            else
            {
                _rectangle = new RectangleF(_controlPoints[0].X, _controlPoints[0].Y, size.Width, size.Height);
            }

            g.DrawString(_text, DefaultDynamicObjectFont, _brush, _controlPoints[0]);

            if (Selected || IsBuilding)
            {
                g.DrawLine(Pens.Red, _rectangle.Location, new PointF(_rectangle.X + _rectangle.Width, _rectangle.Y));
            }

            // Rounding rectangle.
            //g.DrawRectangle(Pens.White, _rectangle);

            if (Selected)
            {
                DrawControlPoints(g);
            }
        }
        public override void Draw(GraphicsWrapper g, PointF? mousePosition, RectangleF clippingRectangle, RectangleF drawingSpace)
        {
            if (Visible == false)
            {
                return;
            }

            if (_controlPoints.Count < 1)
            {
                return;
            }

            if (_mode == ModeEnum.HorizontalLine || _mode == ModeEnum.VerticalLine)
            {
                PointF point1 = _controlPoints[0];
                PointF point2 = new PointF(drawingSpace.X + drawingSpace.Width, _controlPoints[0].Y);

                if (_mode == ModeEnum.VerticalLine)
                {
                    point2 = new PointF(_controlPoints[0].X, drawingSpace.Y + drawingSpace.Height);
                }

                StretchSegmentToDrawingSpace(ref point1, ref point2, drawingSpace);
                g.DrawLine(_pen, point1, point2);

                if (Selected)
                {
                    DrawControlPoints(g);
                }
            }
            else
            if (_controlPoints.Count == 1 && mousePosition.HasValue)
            {
                PointF point1 = _controlPoints[0];
                PointF point2 = mousePosition.Value;

                if (_mode == ModeEnum.Line)
                {
                    StretchSegmentToDrawingSpace(ref point1, ref point2, drawingSpace);
                }
                g.DrawLine(_pen, point1, point2);
            }
            else if (_controlPoints.Count == 2)
            {
                PointF point1 = _controlPoints[0];
                PointF point2 = _controlPoints[1];

                if (_mode == ModeEnum.Line)
                {
                    StretchSegmentToDrawingSpace(ref point1, ref point2, drawingSpace);
                }

                // Clipping opitmization.
                RectangleF rectangle = new RectangleF(
                    Math.Min(point1.X, point2.X), Math.Min(point1.Y, point2.Y),
                    Math.Abs(point2.X - point1.X), Math.Abs(point2.Y - point1.Y));
                if (rectangle.IntersectsWith(clippingRectangle) == false)
                {
                    return;
                }

                //if (_isSegment == false)
                //{// Draw the central line piece separately.
                    //g.DrawLine(_pen, _controlPoints[0], _controlPoints[1]);
                //}

                g.DrawLine(_pen, point1, point2);
                if (Selected)
                {
                    DrawControlPoints(g);
                }

            }
        }
        public override void Draw(GraphicsWrapper g, PointF?mousePosition, RectangleF clippingRectangle, RectangleF drawingSpace)
        {
            if (Visible == false)
            {
                return;
            }

            if (_controlPoints.Count < 1)
            {
                return;
            }

            if (_mode == ModeEnum.HorizontalLine || _mode == ModeEnum.VerticalLine)
            {
                PointF point1 = _controlPoints[0];
                PointF point2 = new PointF(drawingSpace.X + drawingSpace.Width, _controlPoints[0].Y);

                if (_mode == ModeEnum.VerticalLine)
                {
                    point2 = new PointF(_controlPoints[0].X, drawingSpace.Y + drawingSpace.Height);
                }

                StretchSegmentToDrawingSpace(ref point1, ref point2, drawingSpace);
                g.DrawLine(_pen, point1, point2);

                if (Selected)
                {
                    DrawControlPoints(g);
                }
            }
            else
            if (_controlPoints.Count == 1 && mousePosition.HasValue)
            {
                PointF point1 = _controlPoints[0];
                PointF point2 = mousePosition.Value;

                if (_mode == ModeEnum.Line)
                {
                    StretchSegmentToDrawingSpace(ref point1, ref point2, drawingSpace);
                }
                g.DrawLine(_pen, point1, point2);
            }
            else if (_controlPoints.Count == 2)
            {
                PointF point1 = _controlPoints[0];
                PointF point2 = _controlPoints[1];

                if (_mode == ModeEnum.Line)
                {
                    StretchSegmentToDrawingSpace(ref point1, ref point2, drawingSpace);
                }

                // Clipping opitmization.
                RectangleF rectangle = new RectangleF(
                    Math.Min(point1.X, point2.X), Math.Min(point1.Y, point2.Y),
                    Math.Abs(point2.X - point1.X), Math.Abs(point2.Y - point1.Y));
                if (rectangle.IntersectsWith(clippingRectangle) == false)
                {
                    return;
                }

                //if (_isSegment == false)
                //{// Draw the central line piece separately.
                //g.DrawLine(_pen, _controlPoints[0], _controlPoints[1]);
                //}

                g.DrawLine(_pen, point1, point2);
                if (Selected)
                {
                    DrawControlPoints(g);
                }
            }
        }
        public override void Draw(GraphicsWrapper g, PointF? mousePosition, RectangleF clippingRectangle, RectangleF drawingSpace)
        {
            if (Visible == false || _controlPoints.Count < 1)
            {
                return;
            }

            if (clippingRectangle.Contains(_controlPoints[0]) == false)
            {// Clipping opitmization.
                return;
            }

            SizeF size = g.MeasureString(_text, DefaultDynamicObjectFont);
            if (size.Height < 0)
            {
                _rectangle = new RectangleF(_controlPoints[0].X, _controlPoints[0].Y + size.Height, size.Width, -size.Height);
            }
            else
            {
                _rectangle = new RectangleF(_controlPoints[0].X, _controlPoints[0].Y, size.Width, size.Height);
            }

            g.DrawString(_text, DefaultDynamicObjectFont, _brush, _controlPoints[0]);

            if (Selected || IsBuilding)
            {
                g.DrawLine(Pens.Red, _rectangle.Location, new PointF(_rectangle.X + _rectangle.Width, _rectangle.Y));
            }

            // Rounding rectangle.
            //g.DrawRectangle(Pens.White, _rectangle);

            if (Selected)
            {
                DrawControlPoints(g);
            }
        }
        void DrawOrder(GraphicsWrapper g, ref PointF updatedImageDrawingPoint, Order order, float itemWidth, float itemMargin,
            float yToXScaling, BarData orderBarData, float lastBarX, bool drawOpening)
        {
            Image image = _imageUp;
            Brush brush = Brushes.Green;
            Pen dashedPen = _buyDashedPen;
            Pen pen = Pens.GreenYellow;
            if (order.IsBuy == false)
            {
                image = _imageDown;
                brush = Brushes.Red;
                pen = Pens.Red;
                dashedPen = _sellDashedPen;
            }

            if (drawOpening == false)
            {
                image = _imageCross;
            }

            float price = (float)order.OpenPrice;
            if (drawOpening == false)
            {
                price = (float)order.ClosePrice;
            }

            if (drawOpening && _showPendingOrdersTracing && order.IsOpen)
            {// Open orders tracking line.
                PointF point1 = new PointF(updatedImageDrawingPoint.X + itemWidth / 2f, updatedImageDrawingPoint.Y + price);
                float sellPrice = (float)_dataProvider.Bid;
                if (order.IsBuy == false)
                {
                    sellPrice = (float)_dataProvider.Ask;
                }
                PointF point2 = new PointF(lastBarX - itemWidth / 2f, updatedImageDrawingPoint.Y + sellPrice);
                g.DrawLine(dashedPen, point1, point2);
            }

            //if (drawOpening && _showClosedOrdersTracing && order.IsOpen == false)
            //{// Closed order tracking.
            // Close order tracing is implemented in main draw function.
            //}

            if (_showOrderSpot)
            {
                PointF basePoint = new PointF(updatedImageDrawingPoint.X, updatedImageDrawingPoint.Y + price);
                float height = (yToXScaling * itemWidth);
                if (order.IsBuy == false)
                {
                    height = -height;
                }

                if (drawOpening)
                {
                    g.FillPolygon(brush, new PointF[] { basePoint, new PointF(basePoint.X + itemWidth, basePoint.Y),
                        new PointF(basePoint.X + (itemWidth / 2f), basePoint.Y + height) });
                    g.DrawPolygon(Pens.White, new PointF[] { basePoint, new PointF(basePoint.X + itemWidth, basePoint.Y),
                        new PointF(basePoint.X + (itemWidth / 2f), basePoint.Y + height) });

                    // Take profit level.
                    if (double.IsInfinity(order.SourceTakeProfit) == false
                        && double.IsNaN(order.SourceTakeProfit) == false
                        && order.SourceTakeProfit != 0)
                    {
                        g.DrawLine(pen, updatedImageDrawingPoint.X, updatedImageDrawingPoint.Y + (float)order.SourceTakeProfit,
                            updatedImageDrawingPoint.X + itemWidth, updatedImageDrawingPoint.Y + (float)order.SourceTakeProfit);

                        g.DrawLine(pen, updatedImageDrawingPoint.X + itemWidth / 2f, updatedImageDrawingPoint.Y + (float)order.SourceTakeProfit,
                            updatedImageDrawingPoint.X + itemWidth / 2f, updatedImageDrawingPoint.Y + (float)order.SourceTakeProfit - height);
                    }

                    // Stop loss level.
                    if (double.IsInfinity(order.SourceStopLoss) == false
                        && double.IsNaN(order.SourceStopLoss) == false
                        && order.SourceStopLoss != 0)
                    {
                        g.DrawLine(pen, updatedImageDrawingPoint.X, updatedImageDrawingPoint.Y + (float)order.SourceStopLoss,
                            updatedImageDrawingPoint.X + itemWidth, updatedImageDrawingPoint.Y + (float)order.SourceStopLoss);

                        g.DrawLine(pen, updatedImageDrawingPoint.X + itemWidth / 2f, updatedImageDrawingPoint.Y + (float)order.SourceStopLoss,
                            updatedImageDrawingPoint.X + itemWidth / 2f, updatedImageDrawingPoint.Y + (float)order.SourceStopLoss + height);
                    }
                }
                else
                {
                    g.DrawRectangle(Pens.White, basePoint.X, basePoint.Y,
                        itemWidth, yToXScaling * itemWidth);
                }

            }

            float imageHeight = 2 * (yToXScaling * itemWidth);
            if (_showOrderArrow)
            {
                // Draw up image.

                g.DrawImage(image, updatedImageDrawingPoint.X - (itemWidth / 2f), updatedImageDrawingPoint.Y +
                    (float)orderBarData.Low - (yToXScaling * itemWidth), 2 * itemWidth, -imageHeight);

                updatedImageDrawingPoint.Y -= 1.2f * imageHeight;
            }
        }
        public override void Draw(GraphicsWrapper g, PointF? mousePosition, RectangleF clippingRectangle, RectangleF drawingSpace)
        {
            if (Visible == false)
            {
                return;
            }

            if (_controlPoints.Count < 1)
            {
                return;
            }

            PointF point1 = _controlPoints[0];
            PointF point2;
            if (_controlPoints.Count < 2)
            {
                point2 = mousePosition.Value;
            }
            else
            {
                point2 = _controlPoints[1];
            }

            // Clipping opitmization.
            RectangleF rectangle = new RectangleF(
                Math.Min(point1.X, point2.X), Math.Min(point1.Y, point2.Y),
                Math.Abs(point2.X - point1.X), Math.Abs(point2.Y - point1.Y));

            if (rectangle.IntersectsWith(clippingRectangle) == false)
            {
                return;
            }

            // Draw base line.
            g.DrawLine(_dashedLinePen, point1, point2);

            float baseLevel = point1.Y;
            float height = point2.Y - point1.Y;

            // Draw fibbonacci levels.
            float[] levels = new float[] { 0, 23.6f, 38.2f, 50, 61.8f, 100 };
            for (int i = 0; i < levels.Length; i++)
            {
                float actualLevel = baseLevel + height * levels[i] / 100f;
                g.DrawLine(_solidLinePen, point1.X, actualLevel, point2.X, actualLevel);
                g.DrawString(levels[i].ToString(), DefaultDynamicObjectFont, Brushes.White, point1.X, actualLevel);
            }

            if (Selected)
            {
                DrawControlPoints(g);
            }
        }
        protected virtual void DrawInitialActualSpaceOverlays(GraphicsWrapper g, ChartSeries timeBasedSeries)
        {
            {// X Axis labels.
                float totalItemWidth = _seriesItemWidth + _seriesItemMargin;
                float actualXSpacing = _xAxisLabelSpacing * totalItemWidth;
                if (_considerAxisLabelsSpacingScale)
                {
                    int xScaling = Math.Abs((int)(1 / _graphicsWrapper.DrawingSpaceTransform.Elements[0]));
                    if (xScaling > 1)
                    {
                        actualXSpacing = actualXSpacing * xScaling;
                    }
                }

                // Set starting to the closes compatible positionactualXSpacing
                // TODO : this can be optimized further by narrowing the range of xStart to end
                float xStart = (int)(_drawingSpaceDisplayLimit.X / actualXSpacing);
                xStart = xStart * actualXSpacing;

                for (float i = xStart; i < _drawingSpaceDisplayLimit.X + _drawingSpaceDisplayLimit.Width; i += actualXSpacing)
                {
                    PointF point = GraphicsWrapper.DrawingSpaceToActualSpace(new PointF(i, 0), true);
                    if (point.X > _actualDrawingSpaceArea.X - 10
                        && point.X < _actualDrawingSpaceArea.X + _actualDrawingSpaceArea.Width)
                    {
                        int index = (int)(i / totalItemWidth);
                        string message = string.Empty;
                        if (timeBasedSeries != null)
                        {// If there is a leading dateAssignedSeries show labels based on its timing.
                            if (timeBasedSeries.MaximumIndex > index)
                            {
                                message = GeneralHelper.GetShortDateTime(timeBasedSeries.GetTimeAtIndex(index));

                            }
                        }
                        else
                        {
                            message = index.ToString(_xAxisLabelsFormat);
                        }

                        if (_axisLabelsFont != null && _xAxisLabelsFontBrush != null)
                        {
                            g.DrawString(message, _axisLabelsFont, _xAxisLabelsFontBrush, point.X, _actualDrawingSpaceArea.Y + _actualDrawingSpaceArea.Height);
                        }

                        // Draw the small line indicating where the string applies for.
                        g.DrawLine(_actualDrawingSpaceAreaBorderPen, point.X, _actualDrawingSpaceArea.Y + _actualDrawingSpaceArea.Height, point.X, _actualDrawingSpaceArea.Y + _actualDrawingSpaceArea.Height + 5);
                    }
                }
            }

            if (_axisLabelsFont != null && _xAxisLabelsFontBrush != null)
            {
                _actualDrawingSpaceAreaMarginBottom = 20;
            }
            else
            {
                _actualDrawingSpaceAreaMarginBottom = 8;
            }

            {// Y Axis labels.

                int? yAxisLabelsWidth = null;

                float actualYSpacing = _yAxisLabelSpacing;
                if (_considerAxisLabelsSpacingScale)
                {
                    int yScaling = Math.Abs((int)(1 / _graphicsWrapper.DrawingSpaceTransform.Elements[3]));
                    if (yScaling > 1)
                    {
                        actualYSpacing = actualYSpacing * yScaling;
                    }
                }

                // Set starting to the closes compatible positionactualXSpacing
                int maxDecimalPlaces = actualYSpacing.ToString().Length - 1;
                float yStart = (int)(_drawingSpaceDisplayLimit.Y / actualYSpacing);
                yStart = yStart * actualYSpacing;
                // Round off to a fixed number of post decimal point digits, will only work for values under 1
                yStart = (float)Math.Round(yStart, maxDecimalPlaces);

                {
                    //float minLabelValue = yStart;
                    //float maxLabelValue = _drawingSpaceDisplayLimit.Y + _drawingSpaceDisplayLimit.Height;
                    // Harry--Modified
                    // This must auto adjust to format the number properly and always fit in 6 spaces.

                    // Specify positive, negative and zero formats.

                        _yAxisLabelsFormat = " #0.#####;-#0.#####; Zero";

                    //_yAxisLabelsFormat = " #0.##;-#0.##; Zero";
                    // original
                    //_yAxisLabelsFormat = " #0.#####;-#0.#####; Zero";
                    //_yAxisLabelsFormat = " 0.000;-0.000;Zero";

                    // The default is 6 positions total for the y axis labels.
                    yAxisLabelsWidth = ((int)g.MeasureString("00.00000", _axisLabelsFont).Width);
                    //yAxisLabelsWidth = ((int)g.MeasureString("00.00", _axisLabelsFont).Width);
                }

                if (yAxisLabelsWidth.HasValue)
                {// Calculate the current margin and confirm with any controling subscriber.
                    _actualDrawingSpaceAreaMarginLeft = yAxisLabelsWidth.Value + 5;
                    if (ActualDrawingSpaceMarginLeftUpdateEvent != null)
                    {
                        _actualDrawingSpaceAreaMarginLeft = ActualDrawingSpaceMarginLeftUpdateEvent(this, _actualDrawingSpaceAreaMarginLeft);
                    }
                }

                // Pass 2 - actually draw the labels and label lines at the established and confirmed location.
                for (float i = yStart; i < _drawingSpaceDisplayLimit.Y + _drawingSpaceDisplayLimit.Height; i += actualYSpacing)
                {
                    i = (float)Math.Round(i, maxDecimalPlaces);
                    PointF point = GraphicsWrapper.DrawingSpaceToActualSpace(new PointF(0, i), true);
                    if (point.Y > _actualDrawingSpaceArea.Y &&
                        point.Y < _actualDrawingSpaceArea.Y + _actualDrawingSpaceArea.Height)
                    {
                        if (_axisLabelsFont != null && _yAxisLabelsFontBrush != null)
                        {
                            g.DrawString((i).ToString(_yAxisLabelsFormat), _axisLabelsFont, _yAxisLabelsFontBrush, _actualDrawingSpaceAreaMarginLeft - yAxisLabelsWidth.Value - 3, point.Y);
                        }

                        // Draw the small line indicating where the string applies for.
                        g.DrawLine(_actualDrawingSpaceAreaBorderPen, _actualDrawingSpaceAreaMarginLeft - 5, point.Y, _actualDrawingSpaceAreaMarginLeft, point.Y);
                    }
                }

            }

            if (ShowSeriesLabels)
            {
                _actualDrawingSpaceAreaMarginTop = 30;
            }
            else
            {
                _actualDrawingSpaceAreaMarginTop = 5;
            }

            UpdateActualDrawingSpaceArea();

            // Actual space, drawing area, grid.
            _actualSpaceGrid.Draw(g, _actualDrawingSpaceArea, _actualDrawingSpaceArea, 1);

            if (ShowSeriesLabels)
            {
                DrawGraphicSeriesLabels(g, _actualDrawingSpaceArea.Left);
            }

            // Show
            if (_customObjectsManager.IsBuildingObject)
            {
                g.DrawImageUnscaledAndClipped(_customObjectDrawingImage, new Rectangle(4, (int)LabelsTopMargin, _customObjectDrawingImage.Width, _customObjectDrawingImage.Height));
            }
        }
        protected void DrawColorAreaItem(GraphicsWrapper g, ref PointF drawingPoint, float[] values, Pen pen, Brush fill, 
            int index, int previousItemIndex, float itemWidth, float itemMargin)
        {
            float indexValue = values[index];
            float previousItemIndexValue = values[previousItemIndex];

            int unificationCount = index - previousItemIndex;

            for (int i = previousItemIndex; i <= index; i++)
            {
                if (float.IsNaN(previousItemIndexValue))
                {
                    previousItemIndexValue = values[i];
                } else if (float.IsNaN(indexValue))
                {
                    indexValue = values[i];
                }
            }

            if (float.IsNaN(indexValue) || float.IsNaN(previousItemIndexValue))
            {// Failed to find reasonable values to draw.
                return;
            }

            if (fill != null)
            {
                g.FillPolygon(fill, new PointF[] {
                    drawingPoint,
                    new PointF(drawingPoint.X + (itemMargin + itemWidth) * unificationCount, drawingPoint.Y),
                    new PointF(drawingPoint.X + (itemMargin + itemWidth) * unificationCount, drawingPoint.Y + indexValue),
                    new PointF(drawingPoint.X, drawingPoint.Y + previousItemIndexValue) });
            }

            if (pen != null)
            {
                g.DrawLine(pen, drawingPoint.X, drawingPoint.Y + previousItemIndexValue,
                    drawingPoint.X + (itemMargin + itemWidth) * unificationCount, drawingPoint.Y + indexValue);
            }
        }
Beispiel #15
0
        public void Draw(GraphicsWrapper g, RectangleF clipping, RectangleF space, float totalItemWidth)
        {
            if (Visible == false)
            {
                return;
            }
            _pen.DashStyle = DashStyle.Dash;

            Console.WriteLine(" space ************************************************** " + space);
            Console.WriteLine(" clipping ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ " + clipping);
            if (VerticalLineSpacing.HasValue)
            {
                float actualSpacing = _verticalLineSpacing.Value * totalItemWidth;
                if (ConsiderScale)
                {
                    int xScaling = Math.Abs((int)(1 / g.DrawingSpaceTransform.Elements[0]));
                    if (xScaling > 1)
                    {
                        actualSpacing = actualSpacing * xScaling;
                    }
                }

                // Set starting to the closes compatible position.
                float starting = (int)(space.Left / actualSpacing);
                starting = starting * actualSpacing;

                for (float x = starting; x <= space.Right; x += actualSpacing)
                {// Vertical lines.
                    if (x >= clipping.X && x <= clipping.X + clipping.Width + actualSpacing)
                    {
                        g.DrawLine(_pen, x, Math.Max(space.Top, clipping.Top), x, Math.Min(space.Bottom, clipping.Bottom));
                    }
                }
            }

            if (HorizontalLineSpacing.HasValue)
            {
                float actualSpacing = _horizontalLineSpacing.Value;
                //Console.WriteLine(" actualSpacing ************************************************** " + actualSpacing);
                if (ConsiderScale)
                {
                    int yScaling = Math.Abs((int)(1 / g.DrawingSpaceTransform.Elements[3]));
                    Console.WriteLine(" yScaling ************************************************** " + yScaling);
                    if (yScaling > 1)
                    {
                        actualSpacing = actualSpacing * yScaling;
                        Console.WriteLine(" actualSpacing ************************************************** " + actualSpacing);
                    }
                }


                // Set starting to the closes compatible position.
                float starting = (int)(space.Top / actualSpacing);
                starting = starting * actualSpacing;
                //actualSpacing = actualSpacing * 0.5f;
                for (float y = starting; y <= space.Bottom; y += actualSpacing)
                {// Horizontal lines.
                    if (y >= clipping.Y && y <= clipping.Y + clipping.Height)
                    {
                        g.DrawLine(_pen, Math.Min(space.Left, clipping.Left), y, Math.Max(space.Right, clipping.Right), y);
                        //g.DrawLine(_pen, Math.Max(space.Left, clipping.Left), y, Math.Min(space.Right, clipping.Right), y);
                    }
                }
            }
        }
        protected void DrawLine(GraphicsWrapper g, Pen linePen, float[] values, int unitsUnification, RectangleF clippingRectangle, float itemWidth, float itemMargin)
        {
            PointF drawingPoint = new PointF();

            int startIndex, endIndex;
            GetDrawingRangeIndecesFromClippingRectange(clippingRectangle, drawingPoint, unitsUnification, out startIndex, out endIndex, itemWidth, itemMargin);

            for (int i = startIndex + unitsUnification; i < endIndex && i < values.Length + unitsUnification - 1; i += unitsUnification)
            {
                int actualIndex = i;
                int actualPreviousIndex = i - unitsUnification;

                if (actualIndex >= values.Length)
                {
                    actualIndex = values.Length - 1;
                }

                float previousValue = (float)values[actualPreviousIndex];
                float value = (float)values[actualIndex];

                if (float.IsNaN(previousValue) == false && float.IsNaN(value) == false)
                {
                    g.DrawLine(linePen, drawingPoint.X, drawingPoint.Y + previousValue, drawingPoint.X + itemMargin + itemWidth, drawingPoint.Y + value);
                }

                drawingPoint.X = i * (itemMargin + itemWidth);
            }
        }
        public override void Draw(GraphicsWrapper g, int unitsUnification,
                                  RectangleF clippingRectangle, float itemWidth, float itemMargin)
        {
            base.Draw(g, unitsUnification, clippingRectangle, itemWidth, itemMargin);

            if (Visible == false)
            {
                return;
            }

            // Draw ask line.
            if (_dataProvider != null && _drawCurrentPriceLevel)  //&& _dataProvider.OperationalState == OperationalStateEnum.Operational)
            {
                float price = (float)_dataProvider.Bid;
                g.DrawLine(_priceLevelPen, clippingRectangle.X, price, clippingRectangle.X + clippingRectangle.Width, price);
            }

            List <Order> ordersOpening;

            // Draw orders locations on chart.
            lock (this)
            {
                if (_orderExecutionProvider == null)
                {
                    return;
                }

                // Render orders.
                ordersOpening = new List <Order>(_orderExecutionProvider.Orders);
            }

            // Use for orders closes.
            List <Order> ordersClosing = new List <Order>();

            foreach (Order order in ordersOpening)
            {
                if (order.IsOpen == false)
                {// Only add orders already closed.
                    ordersClosing.Add(order);
                }
            }

            // This is used later on, since ordersClosing is modified.
            List <Order> ordersClosed = new List <Order>(ordersClosing);

            // Orders opening at current bar.
            List <Order> pendingOpeningOrders = new List <Order>();
            // Order closing at current bar.
            List <Order> pendingClosingOrders = new List <Order>();

            PointF drawingPoint = new PointF();
            int    startIndex, endIndex;

            GetDrawingRangeIndecesFromClippingRectange(clippingRectangle, drawingPoint, unitsUnification, out startIndex, out endIndex, itemWidth, itemMargin);

            lock (this)
            {
                float lastBarX = (itemMargin + itemWidth) * _dataBars.Count;
                for (int i = startIndex; i < endIndex && i < _dataBars.Count &&
                     (ordersOpening.Count > 0 || ordersClosing.Count > 0); i++)
                {             // Foreach bar, draw orders (and volume).
                    while (ordersOpening.Count > 0)
                    {         // All orders before now.
                        if (ordersOpening[0].SourceOpenTime < (_dataBars[i].DateTime - _dataProvider.TimeInterval))
                        {     // Order before time period.
                            if (ordersOpening[0].IsOpen && _showPendingOrdersTracing)
                            { // Since it is an open pending order, we shall also need to draw it as well.
                                pendingOpeningOrders.Add(ordersOpening[0]);
                            }
                            ordersOpening.RemoveAt(0);
                            continue;
                        }

                        if (ordersOpening[0].SourceOpenTime > _dataBars[i].DateTime)
                        {// Order after time period - look no further.
                            break;
                        }

                        // Order open is within the current period.
                        // Only if order is part of the current period - add to pending.
                        pendingOpeningOrders.Add(ordersOpening[0]);
                        ordersOpening.RemoveAt(0);
                    }

                    for (int j = ordersClosing.Count - 1; j >= 0; j--)
                    {
                        if (ordersClosing[j].SourceCloseTime >= (_dataBars[i].DateTime - _dataProvider.TimeInterval) &&
                            ordersClosing[j].SourceCloseTime <= _dataBars[i].DateTime)
                        {// Order close is within the current period.
                            pendingClosingOrders.Add(ordersClosing[j]);
                            ordersClosing.RemoveAt(j);
                        }
                    }

                    drawingPoint.X = i * (itemMargin + itemWidth);
                    DrawOrders(g, i, drawingPoint, itemWidth, itemMargin, pendingOpeningOrders, pendingClosingOrders, _dataProvider.DataUnits[i], lastBarX);
                    pendingOpeningOrders.Clear();
                    pendingClosingOrders.Clear();
                }

                if (_showClosedOrdersTracing && _dataBars.Count > 0 && startIndex < _dataBars.Count)
                {// Since a closed order may be before or after (or during) the curren set of periods - make a special search and render for them.
                    endIndex = Math.Max(0, endIndex);
                    endIndex = Math.Min(_dataBars.Count - 1, endIndex);

                    foreach (Order order in ordersClosed)
                    {
                        if (order.SourceOpenTime <= _dataBars[endIndex].DateTime &&
                            order.SourceCloseTime >= _dataBars[startIndex].DateTime - _dataProvider.TimeInterval)
                        {
                            int openIndex  = _dataProvider.GetBarIndexAtTime(order.SourceOpenTime);
                            int closeIndex = _dataProvider.GetBarIndexAtTime(order.SourceCloseTime);

                            Pen pen = _buyDashedPen;
                            if (order.IsBuy == false)
                            {
                                pen = _sellDashedPen;
                            }

                            g.DrawLine(pen, new PointF(openIndex * (itemWidth + itemMargin), (float)order.OpenPrice),
                                       new PointF(closeIndex * (itemWidth + itemMargin), (float)order.ClosePrice));
                        }
                    }
                }
            } // Lock
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="g"></param>
        /// <param name="unitsUnification">Draw a few units as one. Used when zooming is too big to show each unit - so unify them. 1 means no unification, 10 means unify 10 units together</param>
        /// <param name="clippingRectangle"></param>
        /// <param name="itemWidth"></param>
        /// <param name="itemMargin"></param>
        public override void Draw(GraphicsWrapper g, int unitsUnification, RectangleF clippingRectangle, float itemWidth, float itemMargin)
        {
            if (Visible == false)
            {
                return;
            }

            PointF drawingPoint = new PointF();

            lock (this)
            {
                if (_chartType == ChartTypeEnum.Line)
                {
                    SetChartType(SimpleChartSeries.ChartTypeEnum.Line);
                    base.Draw(g, unitsUnification, clippingRectangle, itemWidth, itemMargin);
                }
                else if (_chartType == ChartTypeEnum.Histogram)
                {
                    SetChartType(SimpleChartSeries.ChartTypeEnum.Histogram);
                    base.Draw(g, unitsUnification, clippingRectangle, itemWidth, itemMargin);
                }
                else if (_chartType == ChartTypeEnum.ColoredArea)
                {
                    SetChartType(SimpleChartSeries.ChartTypeEnum.ColoredArea);
                    base.Draw(g, unitsUnification, clippingRectangle, itemWidth, itemMargin);
                }
                else if (_chartType == ChartTypeEnum.CandleStick || _chartType == ChartTypeEnum.BarChart)
                {// Unit unification is done trough combining many bars together.
                    List <BarData> combinationDatas = new List <BarData>();
                    bool           timeGapFound     = false;

                    int startIndex, endIndex;
                    GetDrawingRangeIndecesFromClippingRectange(clippingRectangle, drawingPoint, unitsUnification, out startIndex, out endIndex, itemWidth, itemMargin);

                    float  volumeDisplayRange         = clippingRectangle.Height / 4f;
                    double volumeDisplayMultiplicator = volumeDisplayRange / _maxVolume;

                    for (int i = startIndex; i < endIndex && i < _dataBars.Count; i++)
                    {
                        combinationDatas.Add(_dataBars[i]);

                        if (unitsUnification == 1 && ShowTimeGaps && i > 0 && _dataBars[i].DateTime - _dataBars[i - 1].DateTime != _period)
                        {
                            timeGapFound = true;
                        }

                        if (i % unitsUnification == 0)
                        {
                            BarData combinedData = BarData.CombinedBar(combinationDatas.ToArray());

                            if (i == _dataBars.Count - 1)
                            {
                                Console.WriteLine("  LAST  combinedData ######  " + combinedData);
                            }
                            combinationDatas.Clear();
                            if (combinedData.HasDataValues)
                            //&& drawingPoint.X >= clippingRectangle.X
                            //&& drawingPoint.X <= clippingRectangle.X + clippingRectangle.Width)
                            {
                                if (timeGapFound && ShowTimeGaps && _timeGapsLinePen != null)
                                {// Draw time gap.
                                    timeGapFound = false;
                                    g.DrawLine(_timeGapsLinePen, new PointF(drawingPoint.X, clippingRectangle.Y), new PointF(drawingPoint.X, clippingRectangle.Y + clippingRectangle.Height));

                                    //g.DrawLine(_timeGapsLinePen, new PointF(drawingPoint.X, clippingRectangle.Y), new PointF(drawingPoint.X, (float)(data.High)));
                                    //g.DrawLine(_timeGapsLinePen, new PointF(drawingPoint.X, (float)(data.High + data.BarTotalLength / 2f)), new PointF(drawingPoint.X, clippingRectangle.Y + clippingRectangle.Height));
                                }

                                if (_chartType == ChartTypeEnum.CandleStick)
                                {
                                    if (i > 0 && combinedData.Open > _dataBars[i - 1].Close)
                                    {
                                        combinedData.IsHigherPrev = true;
                                    }

                                    DrawCandleStick(g, ref drawingPoint, combinedData, itemWidth, itemMargin, unitsUnification);
                                }
                                else
                                {
                                    DrawBar(g, ref drawingPoint, combinedData, itemWidth, itemMargin, unitsUnification);
                                }

                                // Draw volume for this bar.
                                if (_showVolume)
                                {
                                    float actualHeight = (float)(combinedData.Volume * volumeDisplayMultiplicator);
                                    g.DrawLine(_volumePen, drawingPoint.X, clippingRectangle.Y, drawingPoint.X, clippingRectangle.Y + actualHeight);
                                }

                                if (combinedData.Sar != 0)
                                {
                                    float dy = drawingPoint.Y;
                                    float y  = (drawingPoint.Y + (float)combinedData.Sar);

                                    float yts = Math.Abs(g.DrawingSpaceTransform.Elements[0] / g.DrawingSpaceTransform.Elements[3]);
                                    float x   = drawingPoint.X + (1 + yts) * itemWidth * 3f / 16f;
                                    //float x = drawingPoint.X + (1 + yts) * itemWidth * 3f / 8f;
                                    if (combinedData.Sar >= combinedData.Low && combinedData.High >= combinedData.Sar)
                                    {
                                        g.DrawEllipse(new Pen(Color.White), x, y, yts * itemWidth / 2f, yts * itemWidth / 2f);
                                    }
                                    else
                                    {
                                        g.DrawEllipse(new Pen(Color.White), x, y, yts * itemWidth / 2f, yts * itemWidth / 2f);
                                    }

                                    if (combinedData.Boll != null)
                                    {
                                        float uy = dy + (float)combinedData.Boll[BOLL.UPPER];
                                        float my = dy + (float)combinedData.Boll[BOLL.MID];
                                        float ly = dy + (float)combinedData.Boll[BOLL.LOWER];
                                        g.DrawEllipse(new Pen(Color.Cyan), x, uy, yts * itemWidth / 2f, yts * itemWidth / 2f);
                                        g.DrawEllipse(new Pen(Color.Cyan), x, my, yts * itemWidth / 2f, yts * itemWidth / 2f);
                                        g.DrawEllipse(new Pen(Color.Cyan), x, ly, yts * itemWidth / 2f, yts * itemWidth / 2f);
                                    }
                                }

                                // Harry  --- Draw Signal
                                //_dataBars[i].RefreshExValues();


                                float   actualImageHeight     = _imageDown.Height / Math.Abs(g.DrawingSpaceTransform.Elements[3]);
                                float   yToXScaling           = Math.Abs(g.DrawingSpaceTransform.Elements[0] / g.DrawingSpaceTransform.Elements[3]);
                                PointF  upImageDrawingPoint   = drawingPoint;
                                PointF  downImageDrawingPoint = drawingPoint;
                                Order   order        = new Order();
                                BarData orderBarData = _dataBars[i];
                                float   lastBarX     = (itemMargin + itemWidth) * _dataBars.Count;

                                if (_dataBars[i].SignalList != null && _dataBars[i].SignalList.Count > 0)
                                {
                                    foreach (CandleSignal cs in _dataBars[i].SignalList)
                                    {
                                        cs.BarData = orderBarData;
                                        if (cs.Code == 1)
                                        {
                                            DrawSignal(g, ref downImageDrawingPoint, order, itemWidth, itemMargin, yToXScaling, cs, lastBarX, false);
                                        }

                                        if (cs.Code == -1)
                                        {
                                            DrawSignal(g, ref upImageDrawingPoint, order, itemWidth, itemMargin, yToXScaling, cs, lastBarX, false);
                                        }

                                        if (cs.Code == 2)
                                        {
                                            DrawGainTip(g, ref upImageDrawingPoint, order, itemWidth, itemMargin, yToXScaling, cs, lastBarX, false);
                                        }

                                        if (cs.Code == -2)
                                        {
                                            DrawGainTip(g, ref downImageDrawingPoint, order, itemWidth, itemMargin, yToXScaling, cs, lastBarX, false);
                                        }

                                        if (cs.Code == 3)
                                        {
                                            DrawStopLoss(g, ref downImageDrawingPoint, order, itemWidth, itemMargin, yToXScaling, cs, lastBarX, false);
                                        }

                                        if (cs.Code == -3)
                                        {
                                            DrawStopLoss(g, ref upImageDrawingPoint, order, itemWidth, itemMargin, yToXScaling, cs, lastBarX, false);
                                        }

                                        if (cs.Code == 4)
                                        {
                                            DrawStopGain(g, ref upImageDrawingPoint, order, itemWidth, itemMargin, yToXScaling, cs, lastBarX, false);
                                        }

                                        if (cs.Code == -4)
                                        {
                                            DrawStopGain(g, ref downImageDrawingPoint, order, itemWidth, itemMargin, yToXScaling, cs, lastBarX, false);
                                        }
                                    }
                                }
                            }
                            drawingPoint.X = (i + 1) * (itemMargin + itemWidth);
                        }
                    }
                }
            }
        }
        void DrawOrder(GraphicsWrapper g, ref PointF updatedImageDrawingPoint, Order order, float itemWidth, float itemMargin,
                       float yToXScaling, BarData orderBarData, float lastBarX, bool drawOpening)
        {
            Image image     = _imageUp;
            Brush brush     = Brushes.Green;
            Pen   dashedPen = _buyDashedPen;
            Pen   pen       = Pens.GreenYellow;

            if (order.IsBuy == false)
            {
                image     = _imageDown;
                brush     = Brushes.Red;
                pen       = Pens.Red;
                dashedPen = _sellDashedPen;
            }

            if (drawOpening == false)
            {
                image = _imageCross;
            }

            float price = (float)order.OpenPrice;

            if (drawOpening == false)
            {
                price = (float)order.ClosePrice;
            }

            if (drawOpening && _showPendingOrdersTracing && order.IsOpen)
            {// Open orders tracking line.
                PointF point1    = new PointF(updatedImageDrawingPoint.X + itemWidth / 2f, updatedImageDrawingPoint.Y + price);
                float  sellPrice = (float)_dataProvider.Bid;
                if (order.IsBuy == false)
                {
                    sellPrice = (float)_dataProvider.Ask;
                }
                PointF point2 = new PointF(lastBarX - itemWidth / 2f, updatedImageDrawingPoint.Y + sellPrice);
                g.DrawLine(dashedPen, point1, point2);
            }

            //if (drawOpening && _showClosedOrdersTracing && order.IsOpen == false)
            //{// Closed order tracking.
            // Close order tracing is implemented in main draw function.
            //}

            if (_showOrderSpot)
            {
                PointF basePoint = new PointF(updatedImageDrawingPoint.X, updatedImageDrawingPoint.Y + price);
                float  height    = (yToXScaling * itemWidth);
                if (order.IsBuy == false)
                {
                    height = -height;
                }

                if (drawOpening)
                {
                    g.FillPolygon(brush, new PointF[] { basePoint, new PointF(basePoint.X + itemWidth, basePoint.Y),
                                                        new PointF(basePoint.X + (itemWidth / 2f), basePoint.Y + height) });
                    g.DrawPolygon(Pens.White, new PointF[] { basePoint, new PointF(basePoint.X + itemWidth, basePoint.Y),
                                                             new PointF(basePoint.X + (itemWidth / 2f), basePoint.Y + height) });

                    // Take profit level.
                    if (double.IsInfinity(order.SourceTakeProfit) == false &&
                        double.IsNaN(order.SourceTakeProfit) == false &&
                        order.SourceTakeProfit != 0)
                    {
                        g.DrawLine(pen, updatedImageDrawingPoint.X, updatedImageDrawingPoint.Y + (float)order.SourceTakeProfit,
                                   updatedImageDrawingPoint.X + itemWidth, updatedImageDrawingPoint.Y + (float)order.SourceTakeProfit);

                        g.DrawLine(pen, updatedImageDrawingPoint.X + itemWidth / 2f, updatedImageDrawingPoint.Y + (float)order.SourceTakeProfit,
                                   updatedImageDrawingPoint.X + itemWidth / 2f, updatedImageDrawingPoint.Y + (float)order.SourceTakeProfit - height);
                    }

                    // Stop loss level.
                    if (double.IsInfinity(order.SourceStopLoss) == false &&
                        double.IsNaN(order.SourceStopLoss) == false &&
                        order.SourceStopLoss != 0)
                    {
                        g.DrawLine(pen, updatedImageDrawingPoint.X, updatedImageDrawingPoint.Y + (float)order.SourceStopLoss,
                                   updatedImageDrawingPoint.X + itemWidth, updatedImageDrawingPoint.Y + (float)order.SourceStopLoss);

                        g.DrawLine(pen, updatedImageDrawingPoint.X + itemWidth / 2f, updatedImageDrawingPoint.Y + (float)order.SourceStopLoss,
                                   updatedImageDrawingPoint.X + itemWidth / 2f, updatedImageDrawingPoint.Y + (float)order.SourceStopLoss + height);
                    }
                }
                else
                {
                    g.DrawRectangle(Pens.White, basePoint.X, basePoint.Y,
                                    itemWidth, yToXScaling * itemWidth);
                }
            }

            float imageHeight = 2 * (yToXScaling * itemWidth);

            if (_showOrderArrow)
            {
                // Draw up image.

                g.DrawImage(image, updatedImageDrawingPoint.X - (itemWidth / 2f), updatedImageDrawingPoint.Y +
                            (float)orderBarData.Low - (yToXScaling * itemWidth), 2 * itemWidth, -imageHeight);

                updatedImageDrawingPoint.Y -= 1.2f * imageHeight;
            }
        }
        /// <summary>
        /// Enter locked.
        /// </summary>
        void DrawCandleStick(GraphicsWrapper g, ref PointF startingPoint, BarData barData, float itemWidth, float itemMargin, int itemUnitification)
        {
            if (barData.BarIsRising || (barData.IsHigherPrev && barData.BarBodyLength == 0))
            {
                if (_risingBarFill != null)
                {
                    g.FillRectangle(_risingBarFill, startingPoint.X, startingPoint.Y + (float)barData.Open, itemWidth, (float)barData.BarBodyLength);
                }

                if (_risingBarPen != null)
                {
                    if (itemWidth > 4)
                    {
                        g.DrawRectangle(_risingBarPen, startingPoint.X, startingPoint.Y + (float)barData.Open, itemWidth, (float)barData.BarBodyLength);
                        // Harry -- Draw a line for open = = close
                        if ((float)barData.BarBodyLength <= 0)
                        {
                            g.DrawLine(_risingBarPen,
                                       startingPoint.X,
                                       startingPoint.Y + (float)barData.Close,
                                       startingPoint.X + itemWidth,
                                       startingPoint.Y + (float)barData.Close);
                        }
                    }
                    else
                    {
                        g.FillRectangle(Brushes.Green, startingPoint.X, startingPoint.Y + (float)barData.Open, itemWidth, (float)barData.BarBodyLength);
                    }

                    // Lower shadow
                    g.DrawLine(_risingBarPen,
                               startingPoint.X + itemWidth / 2,
                               startingPoint.Y + (float)barData.Low,
                               startingPoint.X + itemWidth / 2,
                               startingPoint.Y + (float)barData.Open);

                    // Upper shadow
                    g.DrawLine(_risingBarPen,
                               startingPoint.X + itemWidth / 2,
                               (float)(startingPoint.Y + barData.High),
                               startingPoint.X + itemWidth / 2,
                               (float)(startingPoint.Y + barData.Close));
                    //Console.WriteLine("  startingPoint.X    " + startingPoint.X + "   startingPoint.Y " + startingPoint.Y + "  (float)barData.Low " + (float)barData.Low + "  (float)barData.Close  " + (float)barData.Close + "  (float)barData.High " + (float)barData.High + "  (float)barData.Open  " + (float)barData.Open);
                }
            }
            else
            {
                if (_fallingBarFill != null)
                {
                    g.FillRectangle(_fallingBarFill, startingPoint.X, startingPoint.Y + (float)barData.Close, itemWidth, (float)barData.BarBodyLength);
                    // Harry -- Draw a line for open = = close
                    if ((float)barData.BarBodyLength <= 0)
                    {
                        g.DrawLine(_fallingBarPen,
                                   startingPoint.X,
                                   startingPoint.Y + (float)barData.Close,
                                   startingPoint.X + itemWidth,
                                   startingPoint.Y + (float)barData.Close);
                    }
                }

                if (_fallingBarPen != null)
                {
                    if (itemWidth >= 4)
                    {// Only if an item is clearly visible, show the border, otherwise, hide to improver overal visibility.
                        // Showing this border adds nice detail on close zooming, but not useful otherwise.
                        g.DrawRectangle(_fallingBarPen, startingPoint.X, startingPoint.Y + (float)barData.Close, itemWidth, (float)barData.BarBodyLength);
                    }

                    // Lower shadow
                    g.DrawLine(_fallingBarPen,
                               startingPoint.X + itemWidth / 2,
                               startingPoint.Y + (float)barData.Low,
                               startingPoint.X + itemWidth / 2,
                               startingPoint.Y + (float)barData.Close);

                    // Upper shadow
                    g.DrawLine(_fallingBarPen,
                               startingPoint.X + itemWidth / 2,
                               (float)(startingPoint.Y + barData.High),
                               startingPoint.X + itemWidth / 2,
                               (float)(startingPoint.Y + barData.Open));
                }
            }
        }
        public override void Draw(GraphicsWrapper g, int unitsUnification, 
            RectangleF clippingRectangle, float itemWidth, float itemMargin)
        {
            base.Draw(g, unitsUnification, clippingRectangle, itemWidth, itemMargin);

            if (Visible == false)
            {
                return;
            }

            // Draw ask line.
            if (_dataProvider != null && _drawCurrentPriceLevel ) //&& _dataProvider.OperationalState == OperationalStateEnum.Operational)
            {
                float price = (float)_dataProvider.Bid;
                g.DrawLine(_priceLevelPen, clippingRectangle.X, price, clippingRectangle.X + clippingRectangle.Width, price);
            }

            List<Order> ordersOpening;

            // Draw orders locations on chart.
            lock(this)
            {
                if (_orderExecutionProvider == null)
                {
                    return;
                }

                // Render orders.
                ordersOpening = new List<Order>(_orderExecutionProvider.Orders);
            }

            // Use for orders closes.
            List<Order> ordersClosing = new List<Order>();
            foreach (Order order in ordersOpening)
            {
                if (order.IsOpen == false)
                {// Only add orders already closed.
                    ordersClosing.Add(order);
                }
            }

            // This is used later on, since ordersClosing is modified.
            List<Order> ordersClosed = new List<Order>(ordersClosing);

            // Orders opening at current bar.
            List<Order> pendingOpeningOrders = new List<Order>();
            // Order closing at current bar.
            List<Order> pendingClosingOrders = new List<Order>();

            PointF drawingPoint = new PointF();
            int startIndex, endIndex;
            GetDrawingRangeIndecesFromClippingRectange(clippingRectangle, drawingPoint, unitsUnification, out startIndex, out endIndex, itemWidth, itemMargin);

            lock (this)
            {
                float lastBarX = (itemMargin + itemWidth) * _dataBars.Count;
                for (int i = startIndex; i < endIndex && i < _dataBars.Count
                    && (ordersOpening.Count > 0 || ordersClosing.Count > 0); i++)
                {// Foreach bar, draw orders (and volume).

                    while (ordersOpening.Count > 0)
                    {// All orders before now.
                        if (ordersOpening[0].SourceOpenTime < (_dataBars[i].DateTime - _dataProvider.TimeInterval))
                        {// Order before time period.
                            if (ordersOpening[0].IsOpen && _showPendingOrdersTracing)
                            {// Since it is an open pending order, we shall also need to draw it as well.
                                pendingOpeningOrders.Add(ordersOpening[0]);
                            }
                            ordersOpening.RemoveAt(0);
                            continue;
                        }

                        if (ordersOpening[0].SourceOpenTime > _dataBars[i].DateTime)
                        {// Order after time period - look no further.
                            break;
                        }

                        // Order open is within the current period.
                        // Only if order is part of the current period - add to pending.
                        pendingOpeningOrders.Add(ordersOpening[0]);
                        ordersOpening.RemoveAt(0);
                    }

                    for (int j = ordersClosing.Count - 1; j >= 0; j--)
                    {
                        if (ordersClosing[j].SourceCloseTime >= (_dataBars[i].DateTime - _dataProvider.TimeInterval) &&
                            ordersClosing[j].SourceCloseTime <= _dataBars[i].DateTime)
                        {// Order close is within the current period.
                            pendingClosingOrders.Add(ordersClosing[j]);
                            ordersClosing.RemoveAt(j);
                        }
                    }

                    drawingPoint.X = i * (itemMargin + itemWidth);
                    DrawOrders(g, i, drawingPoint, itemWidth, itemMargin, pendingOpeningOrders, pendingClosingOrders, _dataProvider.DataUnits[i], lastBarX);
                    pendingOpeningOrders.Clear();
                    pendingClosingOrders.Clear();
                }

                if (_showClosedOrdersTracing && _dataBars.Count > 0 && startIndex < _dataBars.Count)
                {// Since a closed order may be before or after (or during) the curren set of periods - make a special search and render for them.
                    endIndex = Math.Max(0, endIndex);
                    endIndex = Math.Min(_dataBars.Count - 1, endIndex);

                    foreach (Order order in ordersClosed)
                    {
                        if (order.SourceOpenTime <= _dataBars[endIndex].DateTime
                            && order.SourceCloseTime >= _dataBars[startIndex].DateTime - _dataProvider.TimeInterval)
                        {
                            int openIndex = _dataProvider.GetBarIndexAtTime(order.SourceOpenTime);
                            int closeIndex = _dataProvider.GetBarIndexAtTime(order.SourceCloseTime);

                            Pen pen = _buyDashedPen;
                            if (order.IsBuy == false)
                            {
                                pen = _sellDashedPen;
                            }

                            g.DrawLine(pen, new PointF(openIndex * (itemWidth + itemMargin), (float)order.OpenPrice),
                                new PointF(closeIndex * (itemWidth + itemMargin), (float)order.ClosePrice));
                        }
                    }
                }

            } // Lock
        }