示例#1
0
        public override Cursor GetCursor(ChartControl chartControl, ChartPanel chartPanel, ChartScale chartScale, Point point)
        {
            switch (DrawingState)
            {
            case DrawingState.Building:     return(Cursors.Pen);

            case DrawingState.Moving:       return(IsLocked ? Cursors.No : Cursors.SizeAll);

            case DrawingState.Editing:
                if (IsLocked)
                {
                    return(Cursors.No);
                }
                if (editingAnchor == TextAnchor)
                {
                    return(Cursors.SizeNESW);
                }
                return(editingAnchor == StartAnchor ? Cursors.SizeNESW : Cursors.SizeNWSE);

            default:
                // see if we are near an anchor right away. this is is cheap so no big deal to do often
                ChartAnchor closest = GetClosestAnchor(chartControl, chartPanel, chartScale, cursorSensitivity, point);
                if (closest != null)
                {
                    if (IsLocked)
                    {
                        return(Cursors.Arrow);
                    }
                    return(closest == StartAnchor ? Cursors.SizeNESW : Cursors.SizeNWSE);
                }
                // draw move cursor if cursor is near line path anywhere
                Point  startAnchorPoint = StartAnchor.GetPoint(chartControl, chartPanel, chartScale);
                Point  endAnchorPoint   = EndAnchor.GetPoint(chartControl, chartPanel, chartScale);
                Point  txtAnchorPoint   = TextAnchor.GetPoint(chartControl, chartPanel, chartScale);
                Vector startEndVector   = endAnchorPoint - startAnchorPoint;
                Vector endToTextVector  = txtAnchorPoint - endAnchorPoint;

                //Text Outline Box Path as well
                Point bottomLeft = new Point(txtAnchorPoint.X - textLayout.MaxWidth - textMargin, txtAnchorPoint.Y);
                Point topLeft    = new Point(bottomLeft.X, txtAnchorPoint.Y - textLayout.MaxHeight - 2 * textMargin);
                Point topRight   = new Point(txtAnchorPoint.X, txtAnchorPoint.Y - textLayout.MaxHeight - 2 * textMargin);

                Vector txtBottomLeft     = bottomLeft - txtAnchorPoint;
                Vector bottomLeftTopLeft = topLeft - bottomLeft;
                Vector topLeftTopRight   = topRight - topLeft;
                Vector topRightTxt       = txtAnchorPoint - topRight;

                if (MathHelper.IsPointAlongVector(point, startAnchorPoint, startEndVector, cursorSensitivity) ||
                    MathHelper.IsPointAlongVector(point, endAnchorPoint, endToTextVector, cursorSensitivity) ||
                    MathHelper.IsPointAlongVector(point, txtAnchorPoint, txtBottomLeft, cursorSensitivity) ||
                    MathHelper.IsPointAlongVector(point, bottomLeft, bottomLeftTopLeft, cursorSensitivity) ||
                    MathHelper.IsPointAlongVector(point, topLeft, topLeftTopRight, cursorSensitivity) ||
                    MathHelper.IsPointAlongVector(point, topRight, topRightTxt, cursorSensitivity))
                {
                    return(IsLocked ? Cursors.Arrow : Cursors.SizeAll);
                }
                return(null);
            }
        }
示例#2
0
        public override void OnRender(ChartControl chartControl, ChartScale chartScale)
        {
            LineColor.RenderTarget = RenderTarget;

            // first of all, turn on anti-aliasing to smooth out our line
            RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive;

            ChartPanel panel = chartControl.ChartPanels[chartScale.PanelIndex];

            // draw a line from start measure point to end measure point.
            Point lineStartPoint = StartAnchor.GetPoint(chartControl, panel, chartScale);
            Point lineEndPoint   = EndAnchor.GetPoint(chartControl, panel, chartScale);

            // align to full pixel to avoid unneeded aliasing
            double strokePixAdjust    = (LineColor.Width % 2).ApproxCompare(0) == 0 ? 0.5d : 0d;
            Vector strokePixAdjustVec = new Vector(strokePixAdjust, strokePixAdjust);

            SharpDX.Vector2         endVec   = (lineEndPoint + strokePixAdjustVec).ToVector2();
            SharpDX.Direct2D1.Brush tmpBrush = IsInHitTest ? chartControl.SelectionBrush : LineColor.BrushDX;
            RenderTarget.DrawLine((lineStartPoint + strokePixAdjustVec).ToVector2(), endVec, tmpBrush, LineColor.Width, LineColor.StrokeStyle);

            if (ShouldDrawText)
            {
                UpdateTextLayout(chartControl, ChartPanel, chartScale);
                textDeviceBrush.RenderTarget = RenderTarget;
                // Text rec uses same settings as mini data box
                textBackgroundDeviceBrush.Brush        = Application.Current.FindResource("ChartControl.DataBoxBackground") as Brush;
                textBackgroundDeviceBrush.RenderTarget = RenderTarget;

                Brush  borderBrush       = Application.Current.FindResource("BorderThinBrush") as Brush;
                object thicknessResource = Application.Current.FindResource("BorderThinThickness");
                double thickness         = thicknessResource as double? ?? 1;
                Stroke textBorderStroke  = new Stroke(borderBrush ?? LineColor.Brush, DashStyleHelper.Solid, Convert.ToSingle(thickness))
                {
                    RenderTarget = RenderTarget
                };

                Point           textEndPoint = TextAnchor.GetPoint(chartControl, panel, chartScale);
                SharpDX.Vector2 textEndVec   = (textEndPoint + strokePixAdjustVec).ToVector2();

                RenderTarget.DrawLine(endVec, textEndVec, LineColor.BrushDX, LineColor.Width, LineColor.StrokeStyle);

                float rectPixAdjust     = (float)(strokePixAdjust / 2f);
                SharpDX.RectangleF rect = new SharpDX.RectangleF((float)(textEndPoint.X - textLayout.MaxWidth - textMargin + rectPixAdjust),
                                                                 (float)(textEndPoint.Y - textLayout.MaxHeight - textMargin + rectPixAdjust),
                                                                 textLayout.MaxWidth + textMargin * 2f, textLayout.MaxHeight + textMargin);

                if (textBackgroundDeviceBrush.BrushDX != null && !IsInHitTest)
                {
                    RenderTarget.FillRectangle(rect, textBackgroundDeviceBrush.BrushDX);
                }
                RenderTarget.DrawRectangle(rect, textBorderStroke.BrushDX, textBorderStroke.Width, textBorderStroke.StrokeStyle);

                if (textDeviceBrush.BrushDX != null && !IsInHitTest)
                {
                    RenderTarget.DrawTextLayout(new SharpDX.Vector2((float)(rect.X + textMargin + strokePixAdjust), (float)(rect.Y + textMargin + strokePixAdjust)), textLayout, textDeviceBrush.BrushDX);
                }
            }
        }
示例#3
0
        public override Cursor GetCursor(ChartControl chartControl, ChartPanel chartPanel, ChartScale chartScale, Point point)
        {
            if (!IsVisible)
            {
                return(null);
            }

            switch (DrawingState)
            {
            case DrawingState.Building: return(Cursors.Pen);

            case DrawingState.Moving: return(IsLocked ? Cursors.No : Cursors.SizeAll);

            case DrawingState.Editing:
                if (IsLocked)
                {
                    return(Cursors.No);
                }
                return(editingAnchor == StartAnchor ? Cursors.SizeNESW : Cursors.SizeNWSE);

            default:
                Point startAnchorPixelPoint = StartAnchor.GetPoint(chartControl, chartPanel, chartScale);

                ChartAnchor closest = GetClosestAnchor(chartControl, chartPanel, chartScale, cursorSensitivity, point);
                if (closest != null)
                {
                    if (IsLocked)
                    {
                        return(Cursors.Arrow);
                    }
                    return(closest == StartAnchor ? Cursors.SizeNESW : Cursors.SizeNWSE);
                }

                // Check the anchor lines for cursor
                Point  endAnchorPixelPoint = EndAnchor.GetPoint(chartControl, chartPanel, chartScale);
                Point  extAnchorPixelPoint = ExtensionAnchor.GetPoint(chartControl, chartPanel, chartScale);
                Point  midAnchorPixelPoint = new Point((endAnchorPixelPoint.X + extAnchorPixelPoint.X) / 2, (endAnchorPixelPoint.Y + extAnchorPixelPoint.Y) / 2);
                Vector startToEndVec       = endAnchorPixelPoint - startAnchorPixelPoint;
                Vector endToExtVec         = extAnchorPixelPoint - endAnchorPixelPoint;
                Vector startToMidVec       = midAnchorPixelPoint - startAnchorPixelPoint;

                foreach (Tuple <Point, Point> endPoint in GetAndrewsEndPoints(chartControl, chartScale))
                {
                    Vector andrewVector = endPoint.Item1 - endPoint.Item2;
                    if (MathHelper.IsPointAlongVector(point, endPoint.Item2, andrewVector, cursorSensitivity))
                    {
                        return(IsLocked ? Cursors.Arrow : Cursors.SizeAll);
                    }
                }

                return(MathHelper.IsPointAlongVector(point, startAnchorPixelPoint, startToEndVec, cursorSensitivity) ||
                       MathHelper.IsPointAlongVector(point, endAnchorPixelPoint, endToExtVec, cursorSensitivity) ||
                       MathHelper.IsPointAlongVector(point, startAnchorPixelPoint, startToMidVec, cursorSensitivity) ?
                       (IsLocked ? Cursors.Arrow : Cursors.SizeAll) : null);
            }
        }
示例#4
0
        public override bool IsVisibleOnChart(ChartControl chartControl, ChartScale chartScale, DateTime firstTimeOnChart, DateTime lastTimeOnChart)
        {
            // First check any of the actual anchors are visible, we are immediately done
            foreach (ChartAnchor anchor in Anchors)
            {
                if (anchor.IsEditing || anchor.Time >= firstTimeOnChart && anchor.Time <= lastTimeOnChart)
                {
                    return(true);
                }
            }

            // Calculate extensions and see if they extend into our visible times
            ChartPanel chartPanel           = chartControl.ChartPanels[PanelIndex];
            Point      anchorStartPoint     = StartAnchor.GetPoint(chartControl, chartPanel, chartScale);
            Point      anchorEndPoint       = EndAnchor.GetPoint(chartControl, chartPanel, chartScale);
            Point      anchorExtensionPoint = ExtensionAnchor.GetPoint(chartControl, chartPanel, chartScale);
            Point      midPointExtension    = new Point((anchorExtensionPoint.X + anchorEndPoint.X) / 2, (anchorExtensionPoint.Y + anchorEndPoint.Y) / 2);

            if (CalculationMethod == AndrewsPitchforkCalculationMethod.Schiff)
            {
                anchorStartPoint = new Point(anchorStartPoint.X, (anchorStartPoint.Y + anchorEndPoint.Y) / 2);
            }
            else if (CalculationMethod == AndrewsPitchforkCalculationMethod.ModifiedSchiff)
            {
                anchorStartPoint = new Point((anchorEndPoint.X + anchorStartPoint.X) / 2, (anchorEndPoint.Y + anchorStartPoint.Y) / 2);
            }

            double totalPriceRange = EndAnchor.Price - ExtensionAnchor.Price;
            double startPrice      = ExtensionAnchor.Price;

            foreach (PriceLevel priceLevel in PriceLevels.Where(pl => pl.IsVisible && pl.Stroke != null))
            {
                double levelPrice = (startPrice + ((priceLevel.Value / 100) * totalPriceRange));
                float  pixelY     = chartScale.GetYByValue(levelPrice);
                float  pixelX     = anchorExtensionPoint.X > anchorEndPoint.X ?
                                    (float)(anchorExtensionPoint.X - (Math.Abs((anchorEndPoint.X - anchorExtensionPoint.X) * (priceLevel.Value / 100)))) :
                                    (float)(anchorExtensionPoint.X + ((anchorEndPoint.X - anchorExtensionPoint.X) * (priceLevel.Value / 100)));

                Point startPoint    = new Point(pixelX, pixelY);
                Point endPoint      = new Point(startPoint.X + (midPointExtension.X - anchorStartPoint.X), startPoint.Y + (midPointExtension.Y - anchorStartPoint.Y));
                Point maxLevelPoint = GetExtendedPoint(startPoint, endPoint);

                double padding = 5d;
                foreach (Point chkPoint in new[] { startPoint, maxLevelPoint, endPoint })
                {
                    if (chkPoint.X >= chartPanel.X - padding && chkPoint.X <= chartPanel.W + chartPanel.X + padding &&
                        chkPoint.Y >= chartPanel.Y - padding && chkPoint.Y <= chartPanel.Y + chartPanel.H + padding)
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
示例#5
0
        public override Cursor GetCursor(ChartControl chartControl, ChartPanel chartPanel, ChartScale chartScale, Point point)
        {
            switch (DrawingState)
            {
            case DrawingState.Building:     return(Cursors.Pen);

            case DrawingState.Moving:       return(IsLocked ? Cursors.No : Cursors.SizeAll);

            case DrawingState.Editing:
                if (IsLocked)
                {
                    return(Cursors.No);
                }

                return(editingAnchor == StartAnchor ? Cursors.SizeNESW : Cursors.SizeNWSE);

            default:
                // draw move cursor if cursor is near line path anywhere
                Point startPoint = StartAnchor.GetPoint(chartControl, chartPanel, chartScale);

                ChartAnchor closest = GetClosestAnchor(chartControl, chartPanel, chartScale, cursorSensitivity, point);
                if (closest != null)
                {
                    if (IsLocked)
                    {
                        return(Cursors.Arrow);
                    }
                    return(closest == StartAnchor ? Cursors.SizeNESW : Cursors.SizeNWSE);
                }

                Point endPoint = EndAnchor.GetPoint(chartControl, chartPanel, chartScale);
                Point minPoint = startPoint;
                Point maxPoint = endPoint;



                /*Vector	totalVector	= maxPoint - minPoint;
                 * return MathHelper.IsPointAlongVector(point, minPoint, totalVector, cursorSensitivity) ?
                 *      IsLocked ? Cursors.Arrow : Cursors.SizeAll : null;*/
                Vector DelVector1 = maxPoint - new Point(minPoint.X, maxPoint.Y);
                Vector DelVector2 = maxPoint - new Point(maxPoint.X, minPoint.Y);
                Vector DelVector3 = minPoint - new Point(maxPoint.X, minPoint.Y);
                Vector DelVector4 = minPoint - new Point(minPoint.X, maxPoint.Y);
                return                          /*MathHelper.IsPointAlongVector(point, minPoint, totalVector, cursorSensitivity)||*/

                       /*MathHelper.IsPointAlongVector(point, minPoint, DelVector1, cursorSensitivity)||
                        * MathHelper.IsPointAlongVector(point, minPoint, DelVector2, cursorSensitivity)||
                        * MathHelper.IsPointAlongVector(point, maxPoint, DelVector3, cursorSensitivity)||
                        * MathHelper.IsPointAlongVector(point, maxPoint, DelVector4, cursorSensitivity)*/
                       (MathHelper.IsPointInsideTriangle(point, minPoint, maxPoint, new Point(minPoint.X, maxPoint.Y)) ||
                        MathHelper.IsPointInsideTriangle(point, minPoint, maxPoint, new Point(maxPoint.X, minPoint.Y))?
                        IsLocked ? Cursors.Arrow : Cursors.SizeAll : null);
            }
        }
示例#6
0
        public sealed override Point[] GetSelectionPoints(ChartControl chartControl, ChartScale chartScale)
        {
            ChartPanel chartPanel = chartControl.ChartPanels[chartScale.PanelIndex];
            Point      startPoint = StartAnchor.GetPoint(chartControl, chartPanel, chartScale);
            Point      endPoint   = EndAnchor.GetPoint(chartControl, chartPanel, chartScale);

            int totalWidth  = chartPanel.W + chartPanel.X;
            int totalHeight = chartPanel.Y + chartPanel.H;

            //Vector strokeAdj = new Vector(Stroke.Width / 2, Stroke.Width / 2);
            //Point midPoint = startPoint + ((endPoint - startPoint) / 2);
            return(new[] { startPoint /*, midPoint*/, endPoint });
        }
示例#7
0
        public override bool IsAlertConditionTrue(AlertConditionItem conditionItem, Condition condition, ChartAlertValue[] values,
                                                  ChartControl chartControl, ChartScale chartScale)
        {
            ChartPanel chartPanel = chartControl.ChartPanels[PanelIndex];
            double     barX       = chartControl.GetXByTime(values[0].Time);
            double     barY       = chartScale.GetYByValue(values[0].Value);
            Point      startPoint = StartAnchor.GetPoint(chartControl, chartPanel, chartScale);
            Point      endPoint   = EndAnchor.GetPoint(chartControl, chartPanel, chartScale);
            Point      barPoint   = new Point(barX, barY);

            if (arcGeometry == null || arcGeometry.IsDisposed)
            {
                UpdateArcGeometry(chartControl, chartPanel, chartScale);
            }

            // Bars have not yet reached edge of drawing tool
            if (barX < Math.Min(startPoint.X, endPoint.X))
            {
                return(false);
            }

            // Do two things, make sure the point is on the right side of the line (the side arc is sweeped into),
            // and if it is, then check if it is in arc geo
            MathHelper.PointLineLocation ptLineLocation = MathHelper.GetPointLineLocation(startPoint, endPoint, barPoint);
            // If its not right/above , its past the line the arc sweeps on, so ignore
            if (ptLineLocation != MathHelper.PointLineLocation.RightOrBelow)
            {
                return(false);
            }

            // Our only conditions are cross inside/outside
            Predicate <ChartAlertValue> arcPredicate = v =>
            {
                if (v.Time == Core.Globals.MinDate || v.Time == Core.Globals.MaxDate)
                {
                    return(false);
                }
                if (v.Value == double.MinValue)
                {
                    return(false);
                }

                double bX      = chartControl.GetXByTime(v.Time);
                double bY      = chartScale.GetYByValue(v.Value);
                Point  bp      = new Point(bX, bY);
                bool   isInGeo = arcGeometry.FillContainsPoint(bp.ToVector2());
                return(condition == Condition.CrossInside ? isInGeo : !isInGeo);
            };

            return(MathHelper.DidPredicateCross(values, arcPredicate));
        }
示例#8
0
        public override Point[] GetSelectionPoints(ChartControl chartControl, ChartScale chartScale)
        {
            if (!IsVisible)
            {
                return(new Point[0]);
            }

            ChartPanel chartPanel = chartControl.ChartPanels[PanelIndex];
            Point      startPoint = StartAnchor.GetPoint(chartControl, chartPanel, chartScale);
            Point      endPoint   = EndAnchor.GetPoint(chartControl, chartPanel, chartScale);
            Point      midPoint   = new Point((startPoint.X + endPoint.X) / 2, (startPoint.Y + endPoint.Y) / 2);
            Point      extPoint   = ExtensionAnchor.GetPoint(chartControl, chartPanel, chartScale);

            return(new[] { startPoint, midPoint, endPoint, extPoint });
        }
示例#9
0
        public sealed override Point[] GetSelectionPoints(ChartControl chartControl, ChartScale chartScale)
        {
            ChartPanel chartPanel = chartControl.ChartPanels[chartScale.PanelIndex];
            Point      startPoint = StartAnchor.GetPoint(chartControl, chartPanel, chartScale);
            Point      endPoint   = EndAnchor.GetPoint(chartControl, chartPanel, chartScale);

            if (!ShouldDrawText)
            {
                return new[] { startPoint, endPoint }
            }
            ;
            Point textPoint = TextAnchor.GetPoint(chartControl, chartPanel, chartScale);

            return(new[] { startPoint, textPoint, endPoint });
        }
示例#10
0
        public override bool IsVisibleOnChart(ChartControl chartControl, ChartScale chartScale, DateTime firstTimeOnChart, DateTime lastTimeOnChart)
        {
            if (DrawingState == DrawingState.Building)
            {
                return(true);
            }

            DateTime minTime = Core.Globals.MaxDate;
            DateTime maxTime = Core.Globals.MinDate;

            Point minPoint;
            Point maxPoint;

            // here we'll get extended point and see if they're on scale
            ChartPanel panel      = chartControl.ChartPanels[PanelIndex];
            Point      startPoint = StartAnchor.GetPoint(chartControl, panel, chartScale);
            Point      endPoint   = EndAnchor.GetPoint(chartControl, panel, chartScale);

            minPoint = startPoint;
            maxPoint = GetExtendedPoint(chartControl, panel, chartScale, StartAnchor, EndAnchor);

            foreach (Point pt in new[] { minPoint, maxPoint })
            {
                DateTime time = chartControl.GetTimeByX((int)pt.X);
                if (time > maxTime)
                {
                    maxTime = time;
                }
                if (time < minTime)
                {
                    minTime = time;
                }
            }

            if ((minTime >= firstTimeOnChart && minTime <= maxTime) || (maxTime >= firstTimeOnChart && maxTime <= lastTimeOnChart))
            {
                return(true);
            }

            return(true);
        }
示例#11
0
        public override Cursor GetCursor(ChartControl chartControl, ChartPanel chartPanel, ChartScale chartScale, Point point)
        {
            switch (DrawingState)
            {
            case DrawingState.Building:     return(Cursors.Pen);

            case DrawingState.Moving:       return(IsLocked ? Cursors.No : Cursors.SizeAll);

            case DrawingState.Editing:
                if (IsLocked)
                {
                    return(Cursors.No);
                }
                return(editingAnchor == StartAnchor ? Cursors.SizeNESW : Cursors.SizeNWSE);

            default:
                // draw move cursor if cursor is near line path anywhere
                Point startPoint = StartAnchor.GetPoint(chartControl, chartPanel, chartScale);

                ChartAnchor closest = GetClosestAnchor(chartControl, chartPanel, chartScale, cursorSensitivity, point);
                if (closest != null)
                {
                    if (IsLocked)
                    {
                        return(Cursors.Arrow);
                    }
                    return(closest == StartAnchor ? Cursors.SizeNESW : Cursors.SizeNWSE);
                }

                Point endPoint = EndAnchor.GetPoint(chartControl, chartPanel, chartScale);
                Point minPoint = startPoint;
                Point maxPoint = endPoint;


                maxPoint = GetExtendedPoint(startPoint, endPoint);

                Vector totalVector = maxPoint - minPoint;
                return(MathHelper.IsPointAlongVector(point, minPoint, totalVector, cursorSensitivity) ?
                       IsLocked ? Cursors.Arrow : Cursors.SizeAll : null);
            }
        }
示例#12
0
        public override void OnRender(ChartControl chartControl, ChartScale chartScale)
        {
            Stroke.RenderTarget = RenderTarget;

            // first of all, turn on anti-aliasing to smooth out our line
            RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive;

            ChartPanel panel = chartControl.ChartPanels[chartScale.PanelIndex];

            Point startPoint = StartAnchor.GetPoint(chartControl, panel, chartScale);

            // align to full pixel to avoid unneeded aliasing
            double strokePixAdj   = Stroke.Width % 2 == 0 ? 0.5d : 0d;
            Vector pixelAdjustVec = new Vector(strokePixAdj, strokePixAdj);

            Point endPoint = EndAnchor.GetPoint(chartControl, panel, chartScale);

            // convert our start / end pixel points to directx 2d vectors
            Point startPointAdjusted = startPoint + pixelAdjustVec;
            Point endPointAdjusted   = endPoint + pixelAdjustVec;

            SharpDX.Vector2         startVec = startPointAdjusted.ToVector2();
            SharpDX.Vector2         endVec   = endPointAdjusted.ToVector2();
            SharpDX.Direct2D1.Brush tmpBrush = IsInHitTest ? chartControl.SelectionBrush : Stroke.BrushDX;

            // if a plain ol' line, then we're all done
            // if we're an arrow line, make sure to draw the actual line. for extended lines, only a single
            // line to extended points is drawn below, to avoid unneeded multiple DrawLine calls
            RenderTarget.DrawLine(startVec, endVec, tmpBrush, Stroke.Width, Stroke.StrokeStyle);
            // we have a line type with extensions (ray / extended line) or additional drawing needed
            // create a line vector to easily calculate total length
            Vector lineVector = endPoint - startPoint;

            lineVector.Normalize();

            Point minPoint = startPointAdjusted;
            Point maxPoint = GetExtendedPoint(chartControl, panel, chartScale, StartAnchor, EndAnchor);            //GetExtendedPoint(startPoint, endPoint); //

            RenderTarget.DrawLine(endPointAdjusted.ToVector2(), maxPoint.ToVector2(), tmpBrush, Stroke.Width, Stroke.StrokeStyle);
        }
示例#13
0
        private void UpdateArcGeometry(ChartControl chartControl, ChartPanel chartPanel, ChartScale chartScale)
        {
            Point startPoint = StartAnchor.GetPoint(chartControl, chartPanel, chartScale);
            Point endPoint   = EndAnchor.GetPoint(chartControl, chartPanel, chartScale);

            if (arcGeometry != null && startPoint == cachedStartPoint && endPoint == cachedEndPoint)
            {
                return;
            }

            cachedEndPoint   = endPoint;
            cachedStartPoint = startPoint;

            if (arcGeometry != null && !arcGeometry.IsDisposed)
            {
                arcGeometry.Dispose();
            }

            Vector lineVec = endPoint - startPoint;
            float  width   = Math.Abs((float)lineVec.X);
            float  height  = Math.Abs((float)lineVec.Y);

            SharpDX.Direct2D1.ArcSegment arcSegment = new SharpDX.Direct2D1.ArcSegment
            {
                ArcSize        = SharpDX.Direct2D1.ArcSize.Small,
                Point          = new SharpDX.Vector2((float)endPoint.X, (float)endPoint.Y),
                SweepDirection = SharpDX.Direct2D1.SweepDirection.CounterClockwise,
                Size           = new SharpDX.Size2F(width, height)
            };

            // Create the arc between the line two end points
            arcGeometry = new SharpDX.Direct2D1.PathGeometry(Core.Globals.D2DFactory);
            SharpDX.Direct2D1.GeometrySink geometrySink = arcGeometry.Open();
            geometrySink.BeginFigure(new SharpDX.Vector2((float)startPoint.X, (float)startPoint.Y), SharpDX.Direct2D1.FigureBegin.Filled);
            geometrySink.AddArc(arcSegment);
            geometrySink.EndFigure(SharpDX.Direct2D1.FigureEnd.Open);
            geometrySink.Close();
        }
示例#14
0
        private IEnumerable <Tuple <Point, Point> > GetAndrewsEndPoints(ChartControl chartControl, ChartScale chartScale)
        {
            ChartPanel panel                = chartControl.ChartPanels[PanelIndex];
            double     totalPriceRange      = EndAnchor.Price - ExtensionAnchor.Price;
            double     startPrice           = ExtensionAnchor.Price;
            Point      anchorExtensionPoint = ExtensionAnchor.GetPoint(chartControl, panel, chartScale);
            Point      anchorStartPoint     = StartAnchor.GetPoint(chartControl, panel, chartScale);
            Point      anchorEndPoint       = EndAnchor.GetPoint(chartControl, panel, chartScale);
            Point      midPointExtension    = new Point((anchorExtensionPoint.X + anchorEndPoint.X) / 2, (anchorExtensionPoint.Y + anchorEndPoint.Y) / 2);

            foreach (PriceLevel pl in PriceLevels.Where(pl => pl.IsVisible))
            {
                double levelPrice = (startPrice + ((pl.Value / 100) * totalPriceRange));
                float  pixelY     = chartScale.GetYByValue(levelPrice);
                float  pixelX     = anchorExtensionPoint.X > anchorEndPoint.X ?
                                    (float)(anchorExtensionPoint.X - (Math.Abs((anchorEndPoint.X - anchorExtensionPoint.X) * (pl.Value / 100)))) :
                                    (float)(anchorExtensionPoint.X + ((anchorEndPoint.X - anchorExtensionPoint.X) * (pl.Value / 100)));

                Point startPoint    = new Point(pixelX, pixelY);
                Point endPoint      = new Point(startPoint.X + (midPointExtension.X - anchorStartPoint.X), startPoint.Y + (midPointExtension.Y - anchorStartPoint.Y));
                Point maxLevelPoint = GetExtendedPoint(startPoint, endPoint);
                yield return(new Tuple <Point, Point>(new Point(Math.Max(maxLevelPoint.X, 1), Math.Max(maxLevelPoint.Y, 1)), startPoint));
            }
        }
示例#15
0
        private void UpdateTextLayout(ChartControl chartControl, ChartPanel chartPanel, ChartScale chartScale)
        {
            if (isTextCreated && textLayout != null && !textLayout.IsDisposed)
            {
                return;
            }

            if (textFormat != null && !textFormat.IsDisposed)
            {
                textFormat.Dispose();
            }
            if (textLayout != null && !textLayout.IsDisposed)
            {
                textLayout.Dispose();
            }

            ChartBars chartBars = GetAttachedToChartBars();

            // bars can be null while chart is initializing
            if (chartBars == null)
            {
                return;
            }

            double yDiffPrice = AttachedTo.Instrument.MasterInstrument.RoundToTickSize(EndAnchor.Price - StartAnchor.Price);
            double yDiffTicks = yDiffPrice / AttachedTo.Instrument.MasterInstrument.TickSize;

            switch (YValueDisplayUnit)
            {
            case ValueUnit.Price: yValueString = chartBars.Bars.Instrument.MasterInstrument.FormatPrice(yDiffPrice); break;

            case ValueUnit.Currency:
                yValueString = AttachedTo.Instrument.MasterInstrument.InstrumentType == InstrumentType.Forex
                                                ? Core.Globals.FormatCurrency((int)Math.Abs(yDiffTicks) * Account.All[0].ForexLotSize * (AttachedTo.Instrument.MasterInstrument.TickSize * AttachedTo.Instrument.MasterInstrument.PointValue))
                                                : Core.Globals.FormatCurrency((int)Math.Abs(yDiffTicks) * (AttachedTo.Instrument.MasterInstrument.TickSize * AttachedTo.Instrument.MasterInstrument.PointValue));
                break;

            case ValueUnit.Percent: yValueString = (yDiffPrice / AttachedTo.Instrument.MasterInstrument.RoundToTickSize(StartAnchor.Price)).ToString("P", Core.Globals.GeneralOptions.CurrentCulture); break;

            case ValueUnit.Ticks: yValueString = yDiffTicks.ToString("F0"); break;

            case ValueUnit.Pips:
                // show tenth pips (if available)
                double pips        = Math.Abs(yDiffTicks / 10);
                char   decimalChar = Char.Parse(Core.Globals.GeneralOptions.CurrentCulture.NumberFormat.NumberDecimalSeparator);
                yValueString = Int32.Parse(pips.ToString("F1").Split(decimalChar)[1]) > 0 ? pips.ToString("F1").Replace(decimalChar, '\'') : pips.ToString("F0");
                break;
            }

            TimeSpan timeDiff = EndAnchor.Time - StartAnchor.Time;

            // trim off millis/ticks, match NT7 time formatting
            timeDiff = new TimeSpan(timeDiff.Days, timeDiff.Hours, timeDiff.Minutes, timeDiff.Seconds);

            bool isMultiDay = Math.Abs(timeDiff.TotalHours) >= 24;

            if (chartBars.Bars.BarsPeriod.BarsPeriodType == BarsPeriodType.Day)
            {
                int timeDiffDay = Math.Abs(timeDiff.Days);
                timeText = timeDiffDay > 1 ? Math.Abs(timeDiff.Days) + " " + Custom.Resource.Days  : Math.Abs(timeDiff.Days) + " " + Custom.Resource.Day;
            }
            else
            {
                timeText = isMultiDay ? string.Format("{0}\n{1,25}",
                                                      string.Format(Custom.Resource.NinjaScriptDrawingToolRulerDaysFormat, Math.Abs(timeDiff.Days)),
                                                      timeDiff.Subtract(new TimeSpan(timeDiff.Days, 0, 0, 0)).Duration().ToString()) : timeDiff.Duration().ToString();
            }

            Point startPoint = StartAnchor.GetPoint(chartControl, chartPanel, chartScale);
            Point endPoint   = EndAnchor.GetPoint(chartControl, chartPanel, chartScale);
            int   startIdx   = chartBars.GetBarIdxByX(chartControl, (int)startPoint.X);
            int   endIdx     = chartBars.GetBarIdxByX(chartControl, (int)endPoint.X);
            int   numBars    = endIdx - startIdx;

            SimpleFont wpfFont = chartControl.Properties.LabelFont ?? new SimpleFont();

            textFormat = wpfFont.ToDirectWriteTextFormat();
            textFormat.TextAlignment = SharpDX.DirectWrite.TextAlignment.Leading;
            textFormat.WordWrapping  = SharpDX.DirectWrite.WordWrapping.NoWrap;
            // format text to our text rectangle bounds (it will wrap to these constraints), nt7 format
            // NOTE: Environment.NewLine doesnt work right here
            string text = string.Format("{0}\n{1,-11}{2,-11}\n{3,-11}{4,-11}\n{5,-10}{6,-10}",
                                        AttachedTo.DisplayName,
                                        Custom.Resource.NinjaScriptDrawingToolRulerNumberBarsText, numBars,
                                        Custom.Resource.NinjaScriptDrawingToolRulerTimeText, timeText,
                                        Custom.Resource.NinjaScriptDrawingToolRulerYValueText, yValueString);

            // give big values for max width/height, we will trim to actual used
            textLayout = new SharpDX.DirectWrite.TextLayout(Core.Globals.DirectWriteFactory, text, textFormat, 600, 600);
            // use measured max width/height
            textLayout.MaxWidth  = textLayout.Metrics.Width;
            textLayout.MaxHeight = textLayout.Metrics.Height;
            isTextCreated        = true;
        }
示例#16
0
        public override void OnRender(ChartControl chartControl, ChartScale chartScale)
        {
            try
            {
                if (!model.parent.Input_TickAggregator_OnOff)
                {
                    Dispose();
                    return;
                }
                if (model != null)
                {
                    SharpDX.Direct2D1.AntialiasMode oldAntialiasMode = RenderTarget.AntialiasMode;
                    RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive;

                    ChartPanel panel = chartControl.ChartPanels[chartScale.PanelIndex];

                    Point startPoint = StartAnchor.GetPoint(chartControl, panel, chartScale);

                    // align to full pixel to avoid unneeded aliasing
                    double strokePixAdj   = ((double)(1 % 2)).ApproxCompare(0) == 0 ? 0.5d : 0d;
                    Vector pixelAdjustVec = new Vector(strokePixAdj, strokePixAdj);

                    //Point					endPoint			= EndAnchor.GetPoint(chartControl, panel, chartScale);

                    // convert our start / end pixel points to directx 2d vectors
                    Point startPointAdjusted = startPoint + pixelAdjustVec;

                    SharpDX.Vector2 startVec = startPointAdjusted.ToVector2();

                    // if a plain ol' line, then we're all done
                    // if we're an arrow line, make sure to draw the actual line. for extended lines, only a single
                    // line to extended points is drawn below, to avoid unneeded multiple DrawLine calls
                    // RenderTarget.DrawLine(startVec, endVec, tmpBrush, LineStroke.Width, LineStroke.StrokeStyle);
                    brush0DX         = new SharpDX.Direct2D1.SolidColorBrush(RenderTarget, SharpDX.Color.WhiteSmoke);
                    brush1DX         = model.parent.Input_TickAggregator_AskColor.ToDxBrush(RenderTarget);
                    brush1DX.Opacity = (float)0.3;
                    brush2DX         = model.parent.Input_TickAggregator_BidColor.ToDxBrush(RenderTarget);
                    brush2DX.Opacity = (float)0.3;
                    brush3DX         = model.parent.Input_TickAggregator_AskColor.ToDxBrush(RenderTarget);
                    brush4DX         = model.parent.Input_TickAggregator_BidColor.ToDxBrush(RenderTarget);
                    brush5DX         = new SharpDX.Direct2D1.SolidColorBrush(RenderTarget, SharpDX.Color.Black);
                    brush5DX.Opacity = (float)0.01;
                    brush6DX         = new SharpDX.Direct2D1.SolidColorBrush(RenderTarget, SharpDX.Color.White);
                    brush6DX.Opacity = (float)0.3;
                    brush7DX         = new SharpDX.Direct2D1.SolidColorBrush(RenderTarget, SharpDX.Color.White);

                    SharpDX.Direct2D1.Ellipse el = new SharpDX.Direct2D1.Ellipse(startVec, Radius, Radius);

                    int Position_Y1 = chartScale.GetYByValue(TickAggregatorData.TopPrice) - model.Claster_Height / 2;
                    int Position_Y2 = chartScale.GetYByValue(TickAggregatorData.LowPrice);
                    int Delta_Y     = Position_Y2 - Position_Y1 + model.Claster_Height / 2;
                    if (Delta_Y < 1)
                    {
                        Delta_Y = model.Claster_Height;
                    }


                    int max = model.parent.Input_TickAggregator_Distance;

                    int Position_X1 = chartControl.GetXByTime(TickAggregatorData.Time);
                    int Delta_X     = TickAggregatorData.Volume * max / model.MaxTickAggregatorVolume;
                    int Delta_X_Ask = TickAggregatorData.Volume_Ask * Delta_X / 100;
                    int Delta_X_Bid = Delta_X - Delta_X_Ask;



                    if (IsSelected)
                    {
                        SharpDX.DirectWrite.TextFormat Claster_textFormat = chartControl.Properties.LabelFont.ToDirectWriteTextFormat();
                        string str = "Volume: " + TickAggregatorData.Volume.ToString() + " =";      //+" - "+TickAggregatorData.Volume_Ask.ToString()+" - "+TickAggregatorData.Volume_Bid.ToString();
                        //string str ="";
                        bool tmpFirst = true;
                        foreach (Model.Print p in TickAggregatorData.PrintList)
                        {
                            if (p.Volume >= model.parent.Input_TickAggregator_TickShow)
                            {
                                if (tmpFirst)
                                {
                                    str     += " " + p.Volume;
                                    tmpFirst = false;
                                }
                                else
                                {
                                    str += " + " + p.Volume;
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                        string str1 = "Time: " + TickAggregatorData.Time.ToLongTimeString() + " MaxPrice: " + TickAggregatorData.TopPrice.ToString() + " MinPrice: " + TickAggregatorData.LowPrice.ToString() + " Ask: " + TickAggregatorData.Volume_Ask.ToString() + "% Bid:" + TickAggregatorData.Volume_Bid.ToString() + "% Delta: " + TickAggregatorData.Volume_Delta.ToString() + "%";



                        if (model.parent.Input_TickAggregator_Standart)
                        {
                            RenderTarget.DrawText(str1, Claster_textFormat, new SharpDX.RectangleF(startVec.X + 5, startVec.Y - Radius - 23, str1.Length * 8, 10), brush0DX);
                            RenderTarget.DrawText(str, Claster_textFormat, new SharpDX.RectangleF(startVec.X + 5, startVec.Y - Radius - 12, str.Length * 8, 10), brush0DX);
                        }
                        else
                        {
                            RenderTarget.DrawText(str1, Claster_textFormat, new SharpDX.RectangleF(startVec.X + 5, Position_Y1 - 23, str1.Length * 8, 10), brush0DX);
                            RenderTarget.DrawText(str, Claster_textFormat, new SharpDX.RectangleF(startVec.X + 5, Position_Y1 - 12, str.Length * 8, 10), brush0DX);
                        }
                        Claster_textFormat.Dispose();
                    }

                    if (model.parent.Input_TickAggregator_Standart)
                    {
                        if (TickAggregatorData.Volume_Ask > TickAggregatorData.Volume_Bid)
                        {
                            RenderTarget.DrawEllipse(el, brush3DX);
                            if (IsSelected)
                            {
                                RenderTarget.FillEllipse(el, brush1DX);
                            }
                        }
                        else if (TickAggregatorData.Volume_Ask < TickAggregatorData.Volume_Bid)
                        {
                            RenderTarget.DrawEllipse(el, brush4DX);
                            if (IsSelected)
                            {
                                RenderTarget.FillEllipse(el, brush2DX);
                            }
                        }
                        else if (TickAggregatorData.Volume_Ask == TickAggregatorData.Volume_Bid)
                        {
                            RenderTarget.DrawEllipse(el, brush7DX);
                            if (IsSelected)
                            {
                                RenderTarget.FillEllipse(el, brush6DX);
                            }
                        }

                        if (!IsSelected)
                        {
                            RenderTarget.FillEllipse(el, brush5DX);
                        }
                    }
                    else
                    {
                        RenderTarget.FillRectangle(new SharpDX.RectangleF(Position_X1, Position_Y1, Delta_X_Ask, Delta_Y), brush1DX);
                        RenderTarget.FillRectangle(new SharpDX.RectangleF(Position_X1 + Delta_X_Ask, Position_Y1, Delta_X_Bid, Delta_Y), brush2DX);
                    }
                    RenderTarget.AntialiasMode = oldAntialiasMode;
                    if (brush0DX != null)
                    {
                        brush0DX.Dispose();
                    }
                    if (brush1DX != null)
                    {
                        brush1DX.Dispose();
                    }
                    if (brush2DX != null)
                    {
                        brush2DX.Dispose();
                    }
                    if (brush3DX != null)
                    {
                        brush3DX.Dispose();
                    }
                    if (brush4DX != null)
                    {
                        brush4DX.Dispose();
                    }
                    if (brush5DX != null)
                    {
                        brush5DX.Dispose();
                    }
                    if (brush6DX != null)
                    {
                        brush6DX.Dispose();
                    }
                    if (brush7DX != null)
                    {
                        brush7DX.Dispose();
                    }
                }
            }
            catch (Exception ex) { Print("MR CustomEllipse 417: " + ex); }
            return;
        }
示例#17
0
        public override Cursor GetCursor(ChartControl chartControl, ChartPanel chartPanel, ChartScale chartScale, Point point)
        {
            switch (DrawingState)
            {
            case DrawingState.Building:     return(Cursors.Pen);

            case DrawingState.Moving:       return(IsLocked ? Cursors.No : Cursors.SizeAll);

            case DrawingState.Editing:
                if (IsLocked)
                {
                    return(Cursors.No);
                }

                return(editingAnchor == StartAnchor ? Cursors.SizeNESW : Cursors.SizeNWSE);

            default:
                // draw move cursor if cursor is near line path anywhere
                Point startPoint = StartAnchor.GetPoint(chartControl, chartPanel, chartScale);

                ChartAnchor closest = GetClosestAnchor(chartControl, chartPanel, chartScale, cursorSensitivity, point);
                if (closest != null)
                {
                    if (IsLocked)
                    {
                        return(Cursors.Arrow);
                    }
                    return(closest == StartAnchor ? Cursors.SizeNESW : Cursors.SizeNWSE);
                }

                int Position_Y1 = chartScale.GetYByValue(TickAggregatorData.TopPrice) - model.Claster_Height / 2;
                int Position_Y2 = chartScale.GetYByValue(TickAggregatorData.LowPrice);
                int Delta_Y     = Position_Y2 - Position_Y1 + model.Claster_Height / 2;
                if (Delta_Y < 1)
                {
                    Delta_Y = model.Claster_Height;
                }


                int max = model.parent.Input_TickAggregator_Distance;

                int Position_X1 = chartControl.GetXByTime(TickAggregatorData.Time);
                int Delta_X     = TickAggregatorData.Volume * max / model.MaxTickAggregatorVolume;



                //Point	endPoint		= EndAnchor.GetPoint(chartControl, chartPanel, chartScale);
                Point TopLeft  = new Point(Position_X1, Position_Y1);
                Point TopRight = new Point(Position_X1 + Delta_X, Position_Y1);
                Point BotRight = new Point(Position_X1 + Delta_X, Position_Y1 + Delta_Y);
                Point BotLeft  = new Point(Position_X1, Position_Y1 + Delta_Y);
                //Point	maxPoint		= endPoint;

                Vector totalVector = startPoint - point;

                if (model.parent.Input_TickAggregator_Standart)
                {
                    return(Math.Abs(totalVector.Length) <= Radius + cursorSensitivity?
                           IsLocked ? Cursors.Arrow : Cursors.SizeAll : null);
                }
                else
                {
                    return(MathHelper.IsPointInsideTriangle(point, TopLeft, TopRight, BotLeft) ||
                           MathHelper.IsPointInsideTriangle(point, BotLeft, TopRight, BotRight)?
                           IsLocked ? Cursors.Arrow : Cursors.SizeAll : null);
                }
            }
        }
示例#18
0
        public override void OnRender(ChartControl chartControl, ChartScale chartScale)
        {
            if (firstTime && DrawingState == DrawingState.Normal)
            {
                firstTime = false;
                Cbi.License.Log("TimeCycles");
            }

            ChartPanel chartPanel = chartControl.ChartPanels[PanelIndex];
            int        startX     = Convert.ToInt32(StartAnchor.GetPoint(chartControl, chartPanel, chartScale).X);

            diameter = Math.Abs(startX - Convert.ToInt32(EndAnchor.GetPoint(chartControl, chartPanel, chartScale).X));
            radius   = Convert.ToInt32(diameter / 2.0);

            if (radius <= 0)
            {
                return;
            }

            UpdateAnchors(chartControl, startX);

            if (anchorBars.Count <= 2)
            {
                return;
            }

            RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive;
            Stroke outlineStroke = OutlineStroke;

            outlineStroke.RenderTarget = RenderTarget;

            // dont bother with an area brush if we're doing a hit test (software) render pass. we do not render area then.
            // this allows us to select something behind our area brush (like NT7)
            bool renderArea = false;

            if (!IsInHitTest && AreaBrush != null)
            {
                if (areaBrushDevice.Brush == null)
                {
                    Brush brushCopy = areaBrush.Clone();
                    brushCopy.Opacity     = areaOpacity / 100d;
                    areaBrushDevice.Brush = brushCopy;
                }

                areaBrushDevice.RenderTarget = RenderTarget;
                renderArea = true;
            }
            else
            {
                areaBrushDevice.RenderTarget = null;
                areaBrushDevice.Brush        = null;
            }

            for (int i = 0; i < anchorBars.Count - 1; i++)
            {
                SharpDX.Direct2D1.Ellipse ellipse = new SharpDX.Direct2D1.Ellipse(new SharpDX.Vector2(anchorBars[i] + radius, chartPanel.Y + chartPanel.H), radius, radius);

                if (renderArea)
                {
                    RenderTarget.FillEllipse(ellipse, areaBrushDevice.BrushDX);
                }

                SharpDX.Direct2D1.Brush tmpBrush = IsInHitTest ? chartControl.SelectionBrush : outlineStroke.BrushDX;
                RenderTarget.DrawEllipse(ellipse, tmpBrush);
            }
        }
示例#19
0
        public override void OnRender(ChartControl chartControl, ChartScale chartScale)
        {
            try
            {
                if (model != null)
                {
                    SharpDX.Direct2D1.AntialiasMode oldAntialiasMode = RenderTarget.AntialiasMode;
                    RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive;

                    ChartPanel panel = chartControl.ChartPanels[chartScale.PanelIndex];

                    Point startPoint = StartAnchor.GetPoint(chartControl, panel, chartScale);

                    // align to full pixel to avoid unneeded aliasing
                    double strokePixAdj   = ((double)(1 % 2)).ApproxCompare(0) == 0 ? 0.5d : 0d;
                    Vector pixelAdjustVec = new Vector(strokePixAdj, strokePixAdj);

                    Point endPoint = EndAnchor.GetPoint(chartControl, panel, chartScale);

                    // convert our start / end pixel points to directx 2d vectors
                    Point           startPointAdjusted = startPoint + pixelAdjustVec;
                    Point           endPointAdjusted   = endPoint + pixelAdjustVec;
                    SharpDX.Vector2 startVec           = startPointAdjusted.ToVector2();
                    SharpDX.Vector2 endVec             = endPointAdjusted.ToVector2();
                    //SharpDX.Direct2D1.Brush	tmpBrush			= chartControl.SelectionBrush;
                    SharpDX.Vector2 tmpVect = startVec - endVec;

                    brush0DX          = new SharpDX.Direct2D1.SolidColorBrush(RenderTarget, SharpDX.Color.Black);
                    brush0DX.Opacity  = (float)0.01;
                    brush1DX          = model.Input_ProfileRange_Border_Color.ToDxBrush(RenderTarget);
                    brush2DX          = model.Input_ProfileRange_Inside_Color.ToDxBrush(RenderTarget);
                    brush2DX.Opacity  = model.Profile_Opacity / (float)100d;
                    brush3DX          = model.Input_ProfileRange_POC_Color.ToDxBrush(RenderTarget);
                    brush3DX.Opacity  = model.Profile_Opacity / (float)100d;
                    brush4DX          = model.Range_Profile_Text_Color.ToDxBrush(RenderTarget);
                    brush4DX.Opacity  = model.Profile_Text_Opacity / (float)100d;
                    brush5DX          = model.Input_ProfileRange_Inside_Bid_Color.ToDxBrush(RenderTarget);
                    brush5DX.Opacity  = model.Profile_Opacity / (float)100d;
                    brush6DX          = model.Input_ProfileRange_Inside_Ask_Color.ToDxBrush(RenderTarget);
                    brush6DX.Opacity  = model.Profile_Opacity / (float)100d;
                    brush7DX          = new SharpDX.Direct2D1.SolidColorBrush(RenderTarget, SharpDX.Color.WhiteSmoke);
                    brush8DX          = new SharpDX.Direct2D1.SolidColorBrush(RenderTarget, SharpDX.Color.Gray);
                    brush9DX          = new SharpDX.Direct2D1.SolidColorBrush(RenderTarget, SharpDX.Color.Gray);
                    brush9DX.Opacity  = (float)0.5;
                    brush10DX         = model.Input_ProfileRange_POC_Color.ToDxBrush(RenderTarget);
                    brush10DX.Opacity = model.Profile_Text_Opacity / (float)100d;
                    // if a plain ol' line, then we're all done
                    // if we're an arrow line, make sure to draw the actual line. for extended lines, only a single
                    // line to extended points is drawn below, to avoid unneeded multiple DrawLine calls
                    //RenderTarget.DrawLine(startVec, endVec, model.Input_ProfileRange_Inside_Color.ToDxBrush(RenderTarget), 2);

                    RenderTarget.DrawRectangle(new SharpDX.RectangleF(endVec.X, endVec.Y, tmpVect.X, tmpVect.Y), brush1DX, (float)1);
                    RenderTarget.FillRectangle(new SharpDX.RectangleF(endVec.X, endVec.Y, tmpVect.X, tmpVect.Y), brush0DX);

                    //int firstindex = ((int)model.parent.ChartControl.GetSlotIndexByTime(StartAnchor.Time));
                    //int lastIndex = ((int)model.parent.ChartControl.GetSlotIndexByTime(EndAnchor.Time));
                    int firstindex = model.parent.ChartBars.GetBarIdxByTime(chartControl, StartAnchor.Time);            //Edited by PD
                    int lastIndex  = model.parent.ChartBars.GetBarIdxByTime(chartControl, EndAnchor.Time);              //Edited by PD
                    Model.HistogrammClass profile = new Model.HistogrammClass();
                    int count = 0;

                    IEnumerable <Model.Bar> bars;
                    if (firstindex <= lastIndex)
                    {
                        bars = model.GetBarRange(firstindex, lastIndex);
                    }
                    else
                    {
                        bars = model.GetBarRange(lastIndex, firstindex);
                    }

                    int leftPosition = 0;
                    int topPosition  = 0;
                    if (startVec.X < endVec.X)
                    {
                        leftPosition = (int)startVec.X;
                    }
                    else
                    {
                        leftPosition = (int)endVec.X;
                    }
                    if (startVec.Y < endVec.Y)
                    {
                        topPosition = (int)startVec.Y;
                    }
                    else
                    {
                        topPosition = (int)endVec.Y;
                    }

                    foreach (Model.Bar bar in bars)
                    {
                        IEnumerable <KeyValuePair <double, Model.Claster> > clasters;
                        if (StartAnchor.Price >= EndAnchor.Price)
                        {
                            clasters = bar.ListOfClasters.Where(c => c.Key <= StartAnchor.Price && c.Key >= EndAnchor.Price);
                        }
                        else
                        {
                            clasters = bar.ListOfClasters.Where(c => c.Key >= StartAnchor.Price && c.Key <= EndAnchor.Price);
                        }

                        foreach (KeyValuePair <double, Model.Claster> claster in clasters)
                        {
                            profile.AddPrintToHistogramm(claster.Key, claster.Value.Volume_Ask_sum, PrintType.ASK);
                            profile.AddPrintToHistogramm(claster.Key, claster.Value.Volume_Bid_sum, PrintType.BID);
                        }
                    }

                    //textToRender+=" : "+profile.ListOfCurrentBar.Count.ToString();
                    Dictionary <double, int> deltaProfile = new Dictionary <double, int>();
                    double maxDeltaPrice = int.MinValue;
                    int    prevdelta     = 0;
                    int    volumeSum     = 0;

                    foreach (KeyValuePair <double, Model.CurrentClaster> claster in profile.ListOfCurrentBar)
                    {
                        volumeSum += claster.Value.Volume_sum;
                        int delta = Math.Abs(claster.Value.Volume_Bid_sum - claster.Value.Volume_Ask_sum);
                        deltaProfile.Add(claster.Key, delta);
                        if (prevdelta <= delta)
                        {
                            prevdelta     = delta;
                            maxDeltaPrice = claster.Key;
                        }
                    }

                    SharpDX.DirectWrite.TextFormat Claster_textFormat = chartControl.Properties.LabelFont.ToDirectWriteTextFormat();
                    Claster_textFormat.ParagraphAlignment = SharpDX.DirectWrite.ParagraphAlignment.Center;
                    int vol1 = ProfileType != 1 ? (int)Math.Abs(tmpVect.X) : (int)Math.Abs(tmpVect.X / 2);

                    float fontSize1 = Math.Max(7, Math.Min(vol1 / 2, Math.Min(14, model.Claster_Height - 1)));
                    SharpDX.DirectWrite.TextFormat Claster_textFormatEach = new SharpDX.DirectWrite.TextFormat(Core.Globals.DirectWriteFactory, "Arial", SharpDX.DirectWrite.FontWeight.Normal, SharpDX.DirectWrite.FontStyle.Normal, fontSize1);
                    Claster_textFormatEach.TextAlignment      = SharpDX.DirectWrite.TextAlignment.Leading;
                    Claster_textFormatEach.ParagraphAlignment = SharpDX.DirectWrite.ParagraphAlignment.Center;
                    Claster_textFormatEach.WordWrapping       = SharpDX.DirectWrite.WordWrapping.NoWrap;

                    if (ProfileType == 1 || ProfileType == 0)
                    {
                        foreach (KeyValuePair <double, Model.CurrentClaster> claster in profile.ListOfCurrentBar)
                        {
                            int Y_histogramm = chartScale.GetYByValue(claster.Key) - model.Claster_Height / 2;

                            int vol = claster.Value.Volume_sum * (int)Math.Abs(tmpVect.X) / profile.ListOfCurrentBar[profile.pocPrice].Volume_sum;

                            if (ProfileType == 0)
                            {
                                if (claster.Key == profile.pocPrice)
                                {
                                    if (ExtendedLine)
                                    {
                                        vol = (int)ChartPanel.MaxWidth - Math.Abs(leftPosition);
                                    }
                                    RenderTarget.FillRectangle(new SharpDX.RectangleF(leftPosition, Y_histogramm, vol, model.Claster_Height), brush3DX);

                                    int text_Y     = chartScale.GetYByValue(profile.pocPrice) - model.Claster_Height / 2;
                                    int text_width = profile.pocPrice.ToString().Length *7;
                                    RenderTarget.DrawText(profile.pocPrice.ToString(), Claster_textFormat,
                                                          new SharpDX.RectangleF(leftPosition - text_width, text_Y, text_width, model.Claster_Height), brush10DX);

                                    //RenderTarget.DrawRectangle(new SharpDX.RectangleF(leftPosition-text_width, text_Y,text_width ,model.Claster_Height), Brushes.Red.ToDxBrush(RenderTarget), 1f); //
                                }
                                else
                                {
                                    RenderTarget.FillRectangle(new SharpDX.RectangleF(leftPosition, Y_histogramm, vol, model.Claster_Height), brush2DX);
                                }

                                if (model.Range_Profile_Text_OnOff && vol1 > 10 && model.Claster_Height > 5)
                                {
                                    SharpDX.RectangleF rectText = new SharpDX.RectangleF(leftPosition + 2, Y_histogramm, vol1, model.Claster_Height);
                                    //RenderTarget.DrawRectangle(rectText, model.Range_Profile_Text_Color.ToDxBrush(RenderTarget), 1f);
                                    RenderTarget.DrawText(claster.Value.Volume_sum.ToString(), Claster_textFormatEach, rectText, brush4DX);
                                }
                            }
                            if (ProfileType == 1)
                            {
                                int vol_bid = claster.Value.Volume_Bid_sum * vol / claster.Value.Volume_sum;
                                RenderTarget.FillRectangle(new SharpDX.RectangleF(leftPosition, Y_histogramm, vol_bid, model.Claster_Height), brush5DX);
                                RenderTarget.FillRectangle(new SharpDX.RectangleF(leftPosition + vol_bid, Y_histogramm, vol - vol_bid, model.Claster_Height), brush6DX);

                                if (claster.Key == profile.pocPrice && ExtendedLine)
                                {
                                    RenderTarget.FillRectangle(new SharpDX.RectangleF(leftPosition + vol, Y_histogramm, (int)ChartPanel.MaxWidth - Math.Abs(leftPosition + vol), model.Claster_Height), brush3DX);
                                }
                                if (claster.Key == profile.pocPrice)
                                {
                                    int text_Y     = chartScale.GetYByValue(profile.pocPrice) - model.Claster_Height / 2;
                                    int text_width = profile.pocPrice.ToString().Length *7;
                                    RenderTarget.DrawText(profile.pocPrice.ToString(), Claster_textFormat,
                                                          new SharpDX.RectangleF(leftPosition - text_width, text_Y, text_width, model.Claster_Height), brush10DX);
                                    //RenderTarget.DrawRectangle(new SharpDX.RectangleF(leftPosition-text_width, text_Y,text_width ,model.Claster_Height), Brushes.Red.ToDxBrush(RenderTarget), 1f);
                                }
                                if (model.Range_Profile_Text_OnOff && vol1 > 10 && model.Claster_Height > 5)
                                {
                                    SharpDX.RectangleF rectText = new SharpDX.RectangleF(leftPosition + 2, Y_histogramm, vol1, model.Claster_Height);
                                    //RenderTarget.DrawRectangle(rectText, model.Range_Profile_Text_Color.ToDxBrush(RenderTarget), 1f);
                                    RenderTarget.DrawText(claster.Value.Volume_Bid_sum.ToString() + " x " + claster.Value.Volume_Ask_sum.ToString(), Claster_textFormatEach, rectText, brush4DX);
                                }
                            }
                        }
                    }
                    if (ProfileType == 2)
                    {
                        foreach (KeyValuePair <double, int> claster in deltaProfile)
                        {
                            int Y_histogramm = chartScale.GetYByValue(claster.Key) - model.Claster_Height / 2;

                            int vol_delta = claster.Value * (int)Math.Abs(tmpVect.X) / (int)prevdelta;

                            if (profile.ListOfCurrentBar[claster.Key].Volume_Bid_sum == profile.ListOfCurrentBar[claster.Key].Volume_Ask_sum)
                            {
                                vol_delta = 0;
                            }
                            else if (profile.ListOfCurrentBar[claster.Key].Volume_Bid_sum > profile.ListOfCurrentBar[claster.Key].Volume_Ask_sum)
                            {
                                RenderTarget.FillRectangle(new SharpDX.RectangleF(leftPosition, Y_histogramm, vol_delta, model.Claster_Height), brush5DX);
                            }
                            else if (profile.ListOfCurrentBar[claster.Key].Volume_Bid_sum < profile.ListOfCurrentBar[claster.Key].Volume_Ask_sum)
                            {
                                RenderTarget.FillRectangle(new SharpDX.RectangleF(leftPosition, Y_histogramm, vol_delta, model.Claster_Height), brush6DX);
                            }

                            if (model.Range_Profile_Text_OnOff && vol1 > 10 && model.Claster_Height > 5)
                            {
                                SharpDX.RectangleF rectText = new SharpDX.RectangleF(leftPosition + 2, Y_histogramm, vol1, model.Claster_Height);
                                //RenderTarget.DrawRectangle(rectText, model.Range_Profile_Text_Color.ToDxBrush(RenderTarget), 1f);
                                RenderTarget.DrawText((profile.ListOfCurrentBar[claster.Key].Volume_Ask_sum - profile.ListOfCurrentBar[claster.Key].Volume_Bid_sum).ToString(),
                                                      Claster_textFormatEach, rectText, brush4DX);
                            }
                        }
                        int text_Y     = chartScale.GetYByValue(maxDeltaPrice) - model.Claster_Height / 2;
                        int text_width = maxDeltaPrice.ToString().Length *7;
                        RenderTarget.DrawText(maxDeltaPrice.ToString(), Claster_textFormat, new SharpDX.RectangleF(leftPosition - text_width, text_Y, text_width, model.Claster_Height), brush10DX);
                    }

                    RenderTarget.DrawText("Σ " + volumeSum.ToString(), Claster_textFormat, new SharpDX.RectangleF(leftPosition, topPosition + Math.Abs(tmpVect.Y) + 3, volumeSum.ToString().Length *8 + 10, 10), brush10DX);
                    if (Claster_textFormat != null)
                    {
                        Claster_textFormat.Dispose();
                    }
                    if (Claster_textFormatEach != null)
                    {
                        Claster_textFormatEach.Dispose();
                    }

                    if (IsSelected)
                    {
                        SharpDX.Vector2 tempVector1 = new Point(leftPosition + 2, topPosition + 2 - 20).ToVector2();
                        SharpDX.Vector2 tempVector2 = new Point(leftPosition - 2 + 15, topPosition - 2 - 20 + 15).ToVector2();
                        RenderTarget.DrawLine(tempVector1, tempVector2, brush8DX, 2);
                        tempVector1.X += 11;
                        tempVector2.X -= 11;
                        RenderTarget.DrawLine(tempVector1, tempVector2, brush8DX, 2);
                        RenderTarget.DrawRectangle(new SharpDX.RectangleF(leftPosition, topPosition - 20, 15, 15), brush8DX, (float)1);

                        RenderTarget.DrawRectangle(new SharpDX.RectangleF(leftPosition + 20, topPosition - 20, 15, 15), brush8DX, (float)1);
                        string str = "";
                        switch (ProfileType)
                        {
                        case 0: str = "V"; break;

                        case 1: str = "P"; break;

                        case 2: str = "D"; break;
                        }

                        SharpDX.DirectWrite.Factory    fontFactory = new SharpDX.DirectWrite.Factory();
                        SharpDX.DirectWrite.TextFormat textFormat  = new SharpDX.DirectWrite.TextFormat(fontFactory, "Segoe UI", 15);
                        RenderTarget.DrawText(str, textFormat, new SharpDX.RectangleF(leftPosition + 23, topPosition - 23, 15, 15), brush7DX);
                        fontFactory.Dispose();
                        textFormat.Dispose();
                        if (ExtendedLine)
                        {
                            RenderTarget.FillRectangle(new SharpDX.RectangleF(leftPosition + 42, topPosition - 18, 11, 11), brush9DX);
                        }
                        RenderTarget.DrawRectangle(new SharpDX.RectangleF(leftPosition + 40, topPosition - 20, 15, 15), brush8DX, (float)1);
                    }
                    RenderTarget.AntialiasMode = oldAntialiasMode;
                    if (brush0DX != null)
                    {
                        brush0DX.Dispose();
                    }
                    if (brush1DX != null)
                    {
                        brush1DX.Dispose();
                    }
                    if (brush2DX != null)
                    {
                        brush2DX.Dispose();
                    }
                    if (brush3DX != null)
                    {
                        brush3DX.Dispose();
                    }
                    if (brush4DX != null)
                    {
                        brush4DX.Dispose();
                    }
                    if (brush5DX != null)
                    {
                        brush5DX.Dispose();
                    }
                    if (brush6DX != null)
                    {
                        brush6DX.Dispose();
                    }
                    if (brush7DX != null)
                    {
                        brush7DX.Dispose();
                    }
                    if (brush8DX != null)
                    {
                        brush8DX.Dispose();
                    }
                    if (brush9DX != null)
                    {
                        brush9DX.Dispose();
                    }
                    if (brush10DX != null)
                    {
                        brush10DX.Dispose();
                    }
                }
            }
            catch (Exception ex) { Print("Range Profile2 OnRender 663: " + ex); }
            return;
        }
示例#20
0
        public override bool IsAlertConditionTrue(AlertConditionItem conditionItem, Condition condition, ChartAlertValue[] values, ChartControl chartControl, ChartScale chartScale)
        {
            if (values.Length < 1)
            {
                return(false);
            }

            ChartPanel chartPanel = chartControl.ChartPanels[PanelIndex];

            // get start / end points of what is absolutely shown for our vector
            Point lineStartPoint = StartAnchor.GetPoint(chartControl, chartPanel, chartScale);
            Point lineEndPoint   = EndAnchor.GetPoint(chartControl, chartPanel, chartScale);

            double minLineX = double.MaxValue;
            double maxLineX = double.MinValue;

            foreach (Point point in new[] { lineStartPoint, lineEndPoint })
            {
                minLineX = Math.Min(minLineX, point.X);
                maxLineX = Math.Max(maxLineX, point.X);
            }

            // first thing, if our smallest x is greater than most recent bar, we have nothing to do yet.
            // do not try to check Y because lines could cross through stuff
            double firstBarX = values[0].ValueType == ChartAlertValueType.StaticValue ? minLineX : chartControl.GetXByTime(values[0].Time);
            double firstBarY = chartScale.GetYByValue(values[0].Value);

            // dont have to take extension into account as its already handled in min/max line x

            // bars completely passed our line
            if (maxLineX < firstBarX)
            {
                return(false);
            }

            // bars not yet to our line
            if (minLineX > firstBarX)
            {
                return(false);
            }

            // NOTE: normalize line points so the leftmost is passed first. Otherwise, our vector
            // math could end up having the line normal vector being backwards if user drew it backwards.
            // but we dont care the order of anchors, we want 'up' to mean 'up'!
            Point leftPoint  = lineStartPoint.X < lineEndPoint.X ? lineStartPoint : lineEndPoint;
            Point rightPoint = lineEndPoint.X > lineStartPoint.X ? lineEndPoint : lineStartPoint;

            Point barPoint = new Point(firstBarX, firstBarY);

            // NOTE: 'left / right' is relative to if line was vertical. it can end up backwards too
            MathHelper.PointLineLocation pointLocation = MathHelper.GetPointLineLocation(leftPoint, rightPoint, barPoint);
            // for vertical things, think of a vertical line rotated 90 degrees to lay flat, where it's normal vector is 'up'
            switch (condition)
            {
            case Condition.Greater:                 return(pointLocation == MathHelper.PointLineLocation.LeftOrAbove);

            case Condition.GreaterEqual:    return(pointLocation == MathHelper.PointLineLocation.LeftOrAbove || pointLocation == MathHelper.PointLineLocation.DirectlyOnLine);

            case Condition.Less:                    return(pointLocation == MathHelper.PointLineLocation.RightOrBelow);

            case Condition.LessEqual:               return(pointLocation == MathHelper.PointLineLocation.RightOrBelow || pointLocation == MathHelper.PointLineLocation.DirectlyOnLine);

            case Condition.Equals:                  return(pointLocation == MathHelper.PointLineLocation.DirectlyOnLine);

            case Condition.NotEqual:                return(pointLocation != MathHelper.PointLineLocation.DirectlyOnLine);

            case Condition.CrossAbove:
            case Condition.CrossBelow:
                Predicate <ChartAlertValue> predicate = v =>
                {
                    double barX         = chartControl.GetXByTime(v.Time);
                    double barY         = chartScale.GetYByValue(v.Value);
                    Point  stepBarPoint = new Point(barX, barY);
                    MathHelper.PointLineLocation ptLocation = MathHelper.GetPointLineLocation(leftPoint, rightPoint, stepBarPoint);
                    if (condition == Condition.CrossAbove)
                    {
                        return(ptLocation == MathHelper.PointLineLocation.LeftOrAbove);
                    }
                    return(ptLocation == MathHelper.PointLineLocation.RightOrBelow);
                };
                return(MathHelper.DidPredicateCross(values, predicate));
            }

            return(false);
        }
示例#21
0
        public override bool IsAlertConditionTrue(AlertConditionItem conditionItem, Condition condition, ChartAlertValue[] values,
                                                  ChartControl chartControl, ChartScale chartScale)
        {
            PriceLevel priceLevel = conditionItem.Tag as PriceLevel;

            if (priceLevel == null)
            {
                return(false);
            }

            ChartPanel chartPanel           = chartControl.ChartPanels[PanelIndex];
            Point      anchorStartPoint     = StartAnchor.GetPoint(chartControl, chartPanel, chartScale);
            Point      anchorEndPoint       = EndAnchor.GetPoint(chartControl, chartPanel, chartScale);
            Point      anchorExtensionPoint = ExtensionAnchor.GetPoint(chartControl, chartPanel, chartScale);
            Point      midPointExtension    = new Point((anchorExtensionPoint.X + anchorEndPoint.X) / 2, (anchorExtensionPoint.Y + anchorEndPoint.Y) / 2);

            if (CalculationMethod == AndrewsPitchforkCalculationMethod.Schiff)
            {
                anchorStartPoint = new Point(anchorStartPoint.X, (anchorStartPoint.Y + anchorEndPoint.Y) / 2);
            }
            else if (CalculationMethod == AndrewsPitchforkCalculationMethod.ModifiedSchiff)
            {
                anchorStartPoint = new Point((anchorEndPoint.X + anchorStartPoint.X) / 2, (anchorEndPoint.Y + anchorStartPoint.Y) / 2);
            }

            double totalPriceRange = EndAnchor.Price - ExtensionAnchor.Price;
            double startPrice      = ExtensionAnchor.Price;

            double levelPrice = (startPrice + ((priceLevel.Value / 100) * totalPriceRange));
            float  pixelY     = chartScale.GetYByValue(levelPrice);
            float  pixelX     = anchorExtensionPoint.X > anchorEndPoint.X ?
                                (float)(anchorExtensionPoint.X - (Math.Abs((anchorEndPoint.X - anchorExtensionPoint.X) * (priceLevel.Value / 100)))) :
                                (float)(anchorExtensionPoint.X + ((anchorEndPoint.X - anchorExtensionPoint.X) * (priceLevel.Value / 100)));

            Point alertStartPoint = new Point(pixelX, pixelY);
            Point endPoint        = new Point(alertStartPoint.X + (midPointExtension.X - anchorStartPoint.X), alertStartPoint.Y + (midPointExtension.Y - anchorStartPoint.Y));
            Point alertEndPoint   = GetExtendedPoint(alertStartPoint, endPoint);

            double firstBarX = values[0].ValueType == ChartAlertValueType.StaticValue ? pixelX : chartControl.GetXByTime(values[0].Time);
            double firstBarY = chartScale.GetYByValue(values[0].Value);
            Point  barPoint  = new Point(firstBarX, firstBarY);

            // Check bars are not yet to our drawing tool
            if (firstBarX < alertStartPoint.X || firstBarX > alertEndPoint.X)
            {
                return(false);
            }

            // NOTE: 'left / right' is relative to if line was vertical. It can end up backwards too
            MathHelper.PointLineLocation pointLocation = MathHelper.GetPointLineLocation(alertStartPoint, alertEndPoint, barPoint);
            // For vertical things, think of a vertical line rotated 90 degrees to lay flat, where it's normal vector is 'up'
            switch (condition)
            {
            case Condition.Greater:                 return(pointLocation == MathHelper.PointLineLocation.LeftOrAbove);

            case Condition.GreaterEqual:    return(pointLocation == MathHelper.PointLineLocation.LeftOrAbove || pointLocation == MathHelper.PointLineLocation.DirectlyOnLine);

            case Condition.Less:                    return(pointLocation == MathHelper.PointLineLocation.RightOrBelow);

            case Condition.LessEqual:               return(pointLocation == MathHelper.PointLineLocation.RightOrBelow || pointLocation == MathHelper.PointLineLocation.DirectlyOnLine);

            case Condition.Equals:                  return(pointLocation == MathHelper.PointLineLocation.DirectlyOnLine);

            case Condition.NotEqual:                return(pointLocation != MathHelper.PointLineLocation.DirectlyOnLine);

            case Condition.CrossAbove:
            case Condition.CrossBelow:
                Predicate <ChartAlertValue> predicate = v =>
                {
                    double barX         = chartControl.GetXByTime(v.Time);
                    double barY         = chartScale.GetYByValue(v.Value);
                    Point  stepBarPoint = new Point(barX, barY);
                    // NOTE: 'left / right' is relative to if line was vertical. It can end up backwards too
                    MathHelper.PointLineLocation ptLocation = MathHelper.GetPointLineLocation(alertStartPoint, alertEndPoint, stepBarPoint);
                    if (condition == Condition.CrossAbove)
                    {
                        return(ptLocation == MathHelper.PointLineLocation.LeftOrAbove);
                    }
                    return(ptLocation == MathHelper.PointLineLocation.RightOrBelow);
                };
                return(MathHelper.DidPredicateCross(values, predicate));
            }

            return(false);
        }
示例#22
0
        public override void OnRender(ChartControl chartControl, ChartScale chartScale)
        {
            if (Anchors.All(a => a.IsEditing))
            {
                return;
            }

            RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive;

            ChartPanel chartPanel           = chartControl.ChartPanels[PanelIndex];
            Point      anchorStartPoint     = StartAnchor.GetPoint(chartControl, chartPanel, chartScale);
            Point      anchorEndPoint       = EndAnchor.GetPoint(chartControl, chartPanel, chartScale);
            Point      anchorExtensionPoint = ExtensionAnchor.GetPoint(chartControl, chartPanel, chartScale);
            Point      midPointExtension    = new Point((anchorExtensionPoint.X + anchorEndPoint.X) / 2, (anchorExtensionPoint.Y + anchorEndPoint.Y) / 2);

            if (CalculationMethod == AndrewsPitchforkCalculationMethod.Schiff)
            {
                anchorStartPoint = new Point(anchorStartPoint.X, (anchorStartPoint.Y + anchorEndPoint.Y) / 2);
            }
            else if (CalculationMethod == AndrewsPitchforkCalculationMethod.ModifiedSchiff)
            {
                anchorStartPoint = new Point((anchorEndPoint.X + anchorStartPoint.X) / 2, (anchorEndPoint.Y + anchorStartPoint.Y) / 2);
            }

            AnchorLineStroke.RenderTarget      = RenderTarget;
            RetracementLineStroke.RenderTarget = RenderTarget;

            // Align to full pixel to avoid unneeded aliasing
            double strokePixAdj   = AnchorLineStroke.Width % 2 == 0 ? 0.5d : 0d;
            Vector pixelAdjustVec = new Vector(strokePixAdj, strokePixAdj);

            SharpDX.Vector2         startVec = (anchorStartPoint + pixelAdjustVec).ToVector2();
            SharpDX.Vector2         endVec   = (anchorEndPoint + pixelAdjustVec).ToVector2();
            SharpDX.Direct2D1.Brush tmpBrush = IsInHitTest ? chartControl.SelectionBrush : AnchorLineStroke.BrushDX;

            SharpDX.Vector2 startOriginVec = (StartAnchor.GetPoint(chartControl, chartPanel, chartScale) + pixelAdjustVec).ToVector2();

            RenderTarget.DrawLine(startOriginVec, endVec, tmpBrush, AnchorLineStroke.Width, AnchorLineStroke.StrokeStyle);

            // Is second anchor set yet? Check both so we correctly re-draw during extension anchor editing
            if (ExtensionAnchor.IsEditing && EndAnchor.IsEditing)
            {
                return;
            }

            SharpDX.Vector2 extVector = anchorExtensionPoint.ToVector2();
            tmpBrush = IsInHitTest ? chartControl.SelectionBrush : RetracementLineStroke.BrushDX;
            RenderTarget.DrawLine(endVec, extVector, tmpBrush, RetracementLineStroke.Width, RetracementLineStroke.StrokeStyle);

            // If we're doing a hit test pass, don't draw price levels at all, we dont want those to count for
            // hit testing
            if (IsInHitTest || PriceLevels == null || !PriceLevels.Any())
            {
                return;
            }

            SetAllPriceLevelsRenderTarget();

            // Calculate total y range for % calculation on each level
            double totalPriceRange = EndAnchor.Price - ExtensionAnchor.Price;
            double startPrice      = ExtensionAnchor.Price;
            float  minLevelY       = float.MaxValue;
            float  maxLevelY       = float.MinValue;

            // Store values to use in correct render order
            Point  lastEndPoint   = new Point(0, 0);
            Point  lastStartPoint = new Point(0, 0);
            Stroke lastStroke     = null;
            List <Tuple <PriceLevel, Point> > textPoints = new List <Tuple <PriceLevel, Point> >();

            foreach (PriceLevel priceLevel in PriceLevels.Where(pl => pl.IsVisible && pl.Stroke != null).OrderBy(pl => pl.Value))
            {
                double levelPrice = (startPrice + ((priceLevel.Value / 100) * totalPriceRange));
                float  pixelY     = chartScale.GetYByValue(levelPrice);
                float  pixelX     = anchorExtensionPoint.X > anchorEndPoint.X ?
                                    priceLevel.Value >= 0 ? (float)(anchorExtensionPoint.X - (Math.Abs((anchorEndPoint.X - anchorExtensionPoint.X) * (priceLevel.Value / 100)))) : (float)(anchorExtensionPoint.X + ((anchorEndPoint.X - anchorExtensionPoint.X) * (priceLevel.Value / 100))):
                                    priceLevel.Value >= 0 ? (float)(anchorExtensionPoint.X + ((anchorEndPoint.X - anchorExtensionPoint.X) * (priceLevel.Value / 100))) : (float)(anchorExtensionPoint.X - (Math.Abs((anchorEndPoint.X - anchorExtensionPoint.X) * (priceLevel.Value / 100))));
                Point startPoint    = new Point(pixelX, pixelY);
                Point endPoint      = new Point(startPoint.X + (midPointExtension.X - anchorStartPoint.X), startPoint.Y + (midPointExtension.Y - anchorStartPoint.Y));
                Point maxLevelPoint = GetExtendedPoint(startPoint, endPoint);
                if (priceLevel.Value == 50)
                {
                    RenderTarget.DrawLine(startVec, maxLevelPoint.ToVector2(), priceLevel.Stroke.BrushDX, priceLevel.Stroke.Width, priceLevel.Stroke.StrokeStyle);
                }
                else
                {
                    RenderTarget.DrawLine(startPoint.ToVector2(), maxLevelPoint.ToVector2(), priceLevel.Stroke.BrushDX, priceLevel.Stroke.Width, priceLevel.Stroke.StrokeStyle);
                }

                if (lastStroke == null)
                {
                    lastStroke = new Stroke();
                }
                else
                {
                    SharpDX.Direct2D1.PathGeometry lineGeometry = new SharpDX.Direct2D1.PathGeometry(Core.Globals.D2DFactory);
                    SharpDX.Direct2D1.GeometrySink sink         = lineGeometry.Open();
                    sink.BeginFigure(lastEndPoint.ToVector2(), SharpDX.Direct2D1.FigureBegin.Filled);
                    // Does the fill color need to fill a corner?  Check and add a point
                    if (lastEndPoint.Y != maxLevelPoint.Y && lastEndPoint.X != maxLevelPoint.X)
                    {
                        double boundaryX;
                        double boundaryY;

                        if (lastEndPoint.Y <= ChartPanel.Y || lastEndPoint.Y >= ChartPanel.Y + ChartPanel.H)
                        {
                            boundaryY = lastEndPoint.Y;
                            boundaryX = maxLevelPoint.X;
                        }
                        else
                        {
                            boundaryY = maxLevelPoint.Y;
                            boundaryX = lastEndPoint.X;
                        }
                        sink.AddLine(new SharpDX.Vector2((float)boundaryX, (float)boundaryY));
                    }
                    sink.AddLine(maxLevelPoint.ToVector2());
                    sink.AddLine(startPoint.ToVector2());
                    sink.AddLine(lastStartPoint.ToVector2());
                    sink.EndFigure(SharpDX.Direct2D1.FigureEnd.Closed);
                    sink.Close();
                    RenderTarget.FillGeometry(lineGeometry, lastStroke.BrushDX);
                    lineGeometry.Dispose();
                }

                if (IsTextDisplayed)
                {
                    textPoints.Add(new Tuple <PriceLevel, Point>(priceLevel, maxLevelPoint));
                }

                priceLevel.Stroke.CopyTo(lastStroke);
                lastStroke.Opacity = PriceLevelOpacity;
                lastStartPoint     = startPoint;
                lastEndPoint       = maxLevelPoint;
                minLevelY          = Math.Min(pixelY, minLevelY);
                maxLevelY          = Math.Max(pixelY, maxLevelY);
            }

            // Render text last so it's on top of the price level colors
            if (IsTextDisplayed)
            {
                foreach (Tuple <PriceLevel, Point> textPoint in textPoints)
                {
                    DrawPriceLevelText(0, 0, textPoint.Item2, textPoint.Item1, chartPanel);
                }
            }
        }
示例#23
0
        /* Steps:
         *	1. Project start/end points for rays and extended lines
         *	2. Find collitions with ChartPanel for TextBox coordinates
         *	3. Determine price to be appended
         *	4. Create message
         *	5. Draw TextBox
         */

        public override void OnRender(ChartControl chartControl, ChartScale chartScale)
        {
            base.OnRender(chartControl, chartScale);

            Stroke.RenderTarget        = RenderTarget;
            OutlineStroke.RenderTarget = RenderTarget;

            bool             snap           = true;
            bool             startsOnScreen = true;
            bool             priceOffScreen = false;
            double           priceToUse     = 0;
            string           pricetime      = String.Empty;
            string           TextToDisplay  = DisplayText;
            MasterInstrument masterInst     = GetAttachedToChartBars().Bars.Instrument.MasterInstrument;

            Point startPoint = StartAnchor.GetPoint(chartControl, ChartPanel, chartScale);
            Point endPoint   = EndAnchor.GetPoint(chartControl, ChartPanel, chartScale);

            double strokePixAdj   = ((double)(Stroke.Width % 2)).ApproxCompare(0) == 0 ? 0.5d : 0d;
            Vector pixelAdjustVec = new Vector(strokePixAdj, strokePixAdj);

            Point startAdj = (LineType == ChartLineType.HorizontalLine ? new Point(ChartPanel.X, startPoint.Y) : new Point(startPoint.X, ChartPanel.Y)) + pixelAdjustVec;
            Point endAdj   = (LineType == ChartLineType.HorizontalLine ? new Point(ChartPanel.X + ChartPanel.W, startPoint.Y) : new Point(startPoint.X, ChartPanel.Y + ChartPanel.H)) + pixelAdjustVec;

            Vector distVec  = Vector.Divide(Point.Subtract(endPoint, startPoint), 100);
            Vector scalVec  = (LineType == ChartLineType.ExtendedLine || LineType == ChartLineType.Ray || LineType == ChartLineType.HorizontalLine) ? Vector.Multiply(distVec, 10000) : Vector.Multiply(distVec, 100);
            Point  extPoint = Vector.Add(scalVec, startPoint);

            // Project extended line start point if it is off screen
            if (LineType == ChartLineType.ExtendedLine && TextDisplayMode != TextMode.EndPoint)
            {
                startPoint = Point.Subtract(startPoint, scalVec);
            }

            // Project TextBox coordinate for extended lines and rays to get ChartPanel bounds
            if (LineType == ChartLineType.ExtendedLine || LineType == ChartLineType.Ray)
            {
                extPoint = Vector.Add(scalVec, extPoint);
            }

            // Find collisions with ChartPanel bounds for PriceScale bound TextBox coordinates
            if (LineType == ChartLineType.HorizontalLine || LineType == ChartLineType.VerticalLine)
            {
                extPoint   = endAdj;
                startPoint = startAdj;
            }
            else if (TextDisplayMode == TextMode.EndPoint)
            {
                extPoint = endPoint;
                snap     = false;
            }
            else
            {
                if (extPoint.X <= ChartPanel.X || extPoint.Y < ChartPanel.Y || extPoint.X > ChartPanel.W || extPoint.Y > ChartPanel.H)
                {
                    switch (LineIntersectsRect(startPoint, extPoint, new SharpDX.RectangleF(ChartPanel.X, ChartPanel.Y, ChartPanel.W, ChartPanel.H)))
                    {
                    case RectSide.Top:
                        extPoint = FindIntersection(startPoint, extPoint, new Point(ChartPanel.X, ChartPanel.Y), new Point(ChartPanel.W, ChartPanel.Y));
                        break;

                    case RectSide.Bottom:
                        extPoint = FindIntersection(startPoint, extPoint, new Point(ChartPanel.W, ChartPanel.H), new Point(ChartPanel.X, ChartPanel.H));
                        break;

                    case RectSide.Left:
                        extPoint = FindIntersection(startPoint, extPoint, new Point(ChartPanel.X, ChartPanel.H), new Point(ChartPanel.X, ChartPanel.Y));
                        break;

                    case RectSide.Right:
                        extPoint = FindIntersection(startPoint, extPoint, new Point(ChartPanel.W, ChartPanel.Y), new Point(ChartPanel.W, ChartPanel.H));
                        break;

                    default:
                        return;
                    }
                }

                if (startPoint.X <= ChartPanel.X || startPoint.Y < ChartPanel.Y || startPoint.X > ChartPanel.W || startPoint.Y > ChartPanel.H)
                {
                    switch (LineIntersectsRect(extPoint, startPoint, new SharpDX.RectangleF(ChartPanel.X, ChartPanel.Y, ChartPanel.W, ChartPanel.H)))
                    {
                    case RectSide.Top:
                        startPoint = FindIntersection(extPoint, startPoint, new Point(ChartPanel.X, ChartPanel.Y), new Point(ChartPanel.W, ChartPanel.Y));
                        break;

                    case RectSide.Bottom:
                        startPoint = FindIntersection(extPoint, startPoint, new Point(ChartPanel.W, ChartPanel.H), new Point(ChartPanel.X, ChartPanel.H));
                        break;

                    case RectSide.Left:
                        startPoint = FindIntersection(extPoint, startPoint, new Point(ChartPanel.X, ChartPanel.H), new Point(ChartPanel.X, ChartPanel.Y));
                        break;

                    case RectSide.Right:
                        startPoint = FindIntersection(extPoint, startPoint, new Point(ChartPanel.W, ChartPanel.Y), new Point(ChartPanel.W, ChartPanel.H));
                        break;

                    default:
                        return;
                    }
                }

                if (endPoint.X <= ChartPanel.X || endPoint.Y < ChartPanel.Y || endPoint.X > ChartPanel.W || endPoint.Y > ChartPanel.H)
                {
                    priceOffScreen = true;
                }
            }

            // Scale coordinates by HorizontalOffset/VerticalOffset
            distVec     = Point.Subtract(extPoint, startPoint);
            scalVec     = Vector.Multiply(Vector.Divide(distVec, 100), HorizontalOffset);
            extPoint    = Point.Subtract(extPoint, scalVec);
            extPoint.Y -= VerticalOffset;

            // Get a Price or a Timestamp to append to the label
            switch (LineType)
            {
            case ChartLineType.VerticalLine:
                pricetime = StartAnchor.Time.ToString();
                break;

            case ChartLineType.HorizontalLine:
                priceToUse = StartAnchor.Price;
                break;

            case ChartLineType.ExtendedLine:
            case ChartLineType.Ray:
                priceToUse = TextDisplayMode == TextMode.PriceScale
                                                           ? chartScale.GetValueByY(endPoint.X >= startPoint.X
                                                                                                                ? (float)FindIntersection(startPoint, endPoint, new Point(ChartPanel.W, ChartPanel.Y), new Point(ChartPanel.W, ChartPanel.H)).Y
                                                                                                                : (float)FindIntersection(startPoint, endPoint, new Point(ChartPanel.X, ChartPanel.Y), new Point(ChartPanel.X, ChartPanel.H)).Y)
                                                           : EndAnchor.Price;
                break;

            default:
                priceToUse = priceOffScreen && TextDisplayMode == TextMode.PriceScale
                                                           ? chartScale.GetValueByY(endPoint.X >= startPoint.X
                                                                                                                ? (float)FindIntersection(startPoint, endPoint, new Point(ChartPanel.W, ChartPanel.Y), new Point(ChartPanel.W, ChartPanel.H)).Y
                                                                                                                : (float)FindIntersection(startPoint, endPoint, new Point(ChartPanel.X, ChartPanel.Y), new Point(ChartPanel.X, ChartPanel.H)).Y)
                                                           : EndAnchor.Price;
                break;
            }

            // Round the price
            if (LineType != ChartLineType.VerticalLine)
            {
                pricetime = priceToUse <= masterInst.RoundDownToTickSize(priceToUse) + masterInst.TickSize * 0.5
                                                        ? pricetime = masterInst.RoundDownToTickSize(priceToUse).ToString("0.00")
                                                        : pricetime = masterInst.RoundToTickSize(priceToUse).ToString("0.00");
            }

            // Check if we need to append price or time
            if (AppendPriceTime && DisplayText.Length > 0)
            {
                TextToDisplay = String.Format("{0} {1}", DisplayText, pricetime);
            }
            else if (AppendPriceTime)
            {
                TextToDisplay = pricetime;
            }

            // Use Label Font if one is not specified by template
            if (Font == null)
            {
                Font = new NinjaTrader.Gui.Tools.SimpleFont(chartControl.Properties.LabelFont.Family.ToString(), 16);
            }

            // Update DX Brushes
            if (offScreenDXBrushNeedsUpdate)
            {
                offScreenDXBrush.Dispose();
                offScreenDXBrush            = offScreenMediaBrush.ToDxBrush(RenderTarget);
                offScreenDXBrushNeedsUpdate = false;
            }

            if (backgroundDXBrushNeedsUpdate)
            {
                backgroundDXBrush.Dispose();
                backgroundDXBrush            = backgroundMediaBrush.ToDxBrush(RenderTarget);
                backgroundDXBrush.Opacity    = (float)AreaOpacity / 100f;
                backgroundDXBrushNeedsUpdate = false;
            }

            // Draw TextBoxes
            switch (LineType)
            {
            case ChartLineType.VerticalLine:
                DrawTextBox(snap, TextToDisplay, extPoint.X, extPoint.Y, Stroke.BrushDX, backgroundDXBrush, OutlineStroke, 1.5708f);
                break;

            case ChartLineType.HorizontalLine:
                DrawTextBox(snap, TextToDisplay, extPoint.X, extPoint.Y, Stroke.BrushDX, backgroundDXBrush, OutlineStroke, 0);
                break;

            default:
                DrawTextBox(snap, TextToDisplay, extPoint.X, extPoint.Y, priceOffScreen && TextDisplayMode == TextMode.EndPointAtPriceScale ? offScreenDXBrush : Stroke.BrushDX, backgroundDXBrush, OutlineStroke, 0);
                break;
            }
        }
示例#24
0
        public override void OnRender(ChartControl chartControl, ChartScale chartScale)
        {
            if (model == null)
            {
                return;
            }
            try
            {
                // first of all, turn on anti-aliasing to smooth out our line
                RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive;

                ChartPanel panel = chartControl.ChartPanels[chartScale.PanelIndex];

                Point startPoint = StartAnchor.GetPoint(chartControl, panel, chartScale);


                Point endPoint = EndAnchor.GetPoint(chartControl, panel, chartScale);

                // convert our start / end pixel points to directx 2d vectors
                Point           startPointAdjusted = startPoint /*+ pixelAdjustVec*/;
                Point           endPointAdjusted   = endPoint /*+ pixelAdjustVec*/;
                SharpDX.Vector2 startVec           = startPointAdjusted.ToVector2();
                SharpDX.Vector2 endVec             = endPointAdjusted.ToVector2();
                //SharpDX.Direct2D1.Brush	tmpBrush			= IsInHitTest ? chartControl.SelectionBrush : LineStroke.BrushDX;

                SharpDX.Vector2 tmpVect = startVec - endVec;

                SharpDX.Direct2D1.Brush brush = Brushes.Red.ToDxBrush(RenderTarget);
                brush.Opacity = IsSelected ? (float)0.3 : 0;

                RenderTarget.DrawRectangle(new SharpDX.RectangleF(endVec.X, endVec.Y, tmpVect.X, tmpVect.Y), model.Input_ProfileRange_Border_Color.ToDxBrush(RenderTarget), (float)1);
                //RenderTarget.FillRectangle(new SharpDX.RectangleF(endVec.X, endVec.Y, tmpVect.X, tmpVect.Y),brush);

                int firstindex = ((int)model.parent.ChartControl.GetSlotIndexByTime(StartAnchor.Time));
                int lastIndex  = ((int)model.parent.ChartControl.GetSlotIndexByTime(EndAnchor.Time));



                IEnumerable <Model.Bar> bars;
                if (firstindex <= lastIndex)
                {
                    bars = model.GetBarRange(firstindex, lastIndex);
                }
                else
                {
                    bars = model.GetBarRange(lastIndex, firstindex);
                }

                int leftPosition = 0;
                int topPosition  = 0;
                if (startVec.X < endVec.X)
                {
                    leftPosition = (int)startVec.X;
                }
                else
                {
                    leftPosition = (int)endVec.X;
                }
                if (startVec.Y < endVec.Y)
                {
                    topPosition = (int)startVec.Y;
                }
                else
                {
                    topPosition = (int)endVec.Y;
                }


                Model.HistogrammClass profile = new Model.HistogrammClass();

                int count = 0;

                foreach (Model.Bar bar in bars)
                {
                    IEnumerable <KeyValuePair <double, Model.Claster> > clasters;
                    if (StartAnchor.Price >= EndAnchor.Price)
                    {
                        clasters = bar.ListOfClasters.Where(c => c.Key <= StartAnchor.Price && c.Key >= EndAnchor.Price);
                    }
                    else
                    {
                        clasters = bar.ListOfClasters.Where(c => c.Key >= StartAnchor.Price && c.Key <= EndAnchor.Price);
                    }

                    foreach (KeyValuePair <double, Model.Claster> claster in clasters)
                    {
                        profile.AddPrintToHistogramm(claster.Key, claster.Value.Volume_Ask_sum, PrintType.ASK);
                        profile.AddPrintToHistogramm(claster.Key, claster.Value.Volume_Bid_sum, PrintType.BID);
                    }
                }
                //textToRender+=" : "+profile.ListOfCurrentBar.Count.ToString();


                SharpDX.Direct2D1.Brush profile_Claster_Color = model.Input_ProfileRange_Inside_Color.ToDxBrush(RenderTarget);
                profile_Claster_Color.Opacity = (float)0.5;

                int volumeSum = 0;

                foreach (KeyValuePair <double, Model.CurrentClaster> claster in profile.ListOfCurrentBar)
                {
                    int Y_histogramm = chartScale.GetYByValue(claster.Key) - model.Claster_Height / 2;
                    int vol          = claster.Value.Volume_sum * (int)Math.Abs(tmpVect.X) / profile.ListOfCurrentBar[profile.pocPrice].Volume_sum;
                    volumeSum += claster.Value.Volume_sum;
                    if (claster.Key == profile.pocPrice)
                    {
                        RenderTarget.FillRectangle(new SharpDX.RectangleF(leftPosition, Y_histogramm, vol, model.Claster_Height), model.Input_ProfileRange_POC_Color.ToDxBrush(RenderTarget));
                    }
                    else
                    {
                        RenderTarget.FillRectangle(new SharpDX.RectangleF(leftPosition, Y_histogramm, vol, model.Claster_Height), profile_Claster_Color);
                    }
                }

                SharpDX.DirectWrite.TextFormat Claster_textFormat = chartControl.Properties.LabelFont.ToDirectWriteTextFormat();


                RenderTarget.DrawText("Σ " + volumeSum.ToString(), Claster_textFormat, new SharpDX.RectangleF(leftPosition, topPosition + Math.Abs(tmpVect.Y) + 3, volumeSum.ToString().Length *8 + 10, 10), Brushes.WhiteSmoke.ToDxBrush(RenderTarget));

                int text_Y     = chartScale.GetYByValue(profile.pocPrice) - model.Claster_Height / 2;
                int text_width = profile.pocPrice.ToString().Length *7;
                RenderTarget.DrawText(profile.pocPrice.ToString(), Claster_textFormat, new SharpDX.RectangleF(leftPosition - text_width, text_Y, text_width, 10), model.Input_ProfileRange_POC_Color.ToDxBrush(RenderTarget));


                if (false)
                {
                    RenderTarget.DrawRectangle(new SharpDX.RectangleF(leftPosition, topPosition - 20, 15, 15), Brushes.Gray.ToDxBrush(RenderTarget), (float)1);
                }



                return;
            }
            catch (Exception ex) { Print("MR CustomProfile 414: " + ex); }
        }