예제 #1
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);
                }
            }
        }
예제 #2
0
        public override void OnRender(ChartControl chartControl, ChartScale chartScale)
        {
            if (!IsVisible)
            {
                return;
            }
            if (Anchors.All(a => a.IsEditing))
            {
                return;
            }

            // this will be true right away to fix a restoral issue, so check if we really want to set reward
            if (needsRatioUpdate && DrawTarget)
            {
                SetReward();
            }

            ChartPanel chartPanel  = chartControl.ChartPanels[PanelIndex];
            Point      entryPoint  = EntryAnchor.GetPoint(chartControl, chartPanel, chartScale);
            Point      stopPoint   = RiskAnchor.GetPoint(chartControl, chartPanel, chartScale);
            Point      targetPoint = RewardAnchor.GetPoint(chartControl, chartPanel, chartScale);

            AnchorLineStroke.RenderTarget = RenderTarget;
            EntryLineStroke.RenderTarget  = RenderTarget;
            StopLineStroke.RenderTarget   = RenderTarget;

            // first of all, turn on anti-aliasing to smooth out our line
            RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive;
            RenderTarget.DrawLine(entryPoint.ToVector2(), stopPoint.ToVector2(), AnchorLineStroke.BrushDX, AnchorLineStroke.Width, AnchorLineStroke.StrokeStyle);

            double anchorMinX = DrawTarget ? new[] { entryPoint.X, stopPoint.X, targetPoint.X }.Min() : new[] { entryPoint.X, stopPoint.X }.Min();
            double anchorMaxX = DrawTarget ? new[] { entryPoint.X, stopPoint.X, targetPoint.X }.Max() : new[] { entryPoint.X, stopPoint.X }.Max();
            double lineStartX = IsExtendedLinesLeft ? chartPanel.X : anchorMinX;
            double lineEndX   = IsExtendedLinesRight ? chartPanel.X + chartPanel.W : anchorMaxX;

            SharpDX.Vector2 entryStartVector = new SharpDX.Vector2((float)lineStartX, (float)entryPoint.Y);
            SharpDX.Vector2 entryEndVector   = new SharpDX.Vector2((float)lineEndX, (float)entryPoint.Y);
            SharpDX.Vector2 stopStartVector  = new SharpDX.Vector2((float)lineStartX, (float)stopPoint.Y);
            SharpDX.Vector2 stopEndVector    = new SharpDX.Vector2((float)lineEndX, (float)stopPoint.Y);

            // don't try and draw the target stuff until we have calculated the target
            SharpDX.Direct2D1.Brush tmpBrush = IsInHitTest ? chartControl.SelectionBrush : AnchorLineStroke.BrushDX;
            if (DrawTarget)
            {
                AnchorLineStroke.RenderTarget = RenderTarget;
                RenderTarget.DrawLine(entryPoint.ToVector2(), targetPoint.ToVector2(), tmpBrush, AnchorLineStroke.Width, AnchorLineStroke.StrokeStyle);

                TargetLineStroke.RenderTarget = RenderTarget;
                SharpDX.Vector2 targetStartVector = new SharpDX.Vector2((float)lineStartX, (float)targetPoint.Y);
                SharpDX.Vector2 targetEndVector   = new SharpDX.Vector2((float)lineEndX, (float)targetPoint.Y);

                tmpBrush = IsInHitTest ? chartControl.SelectionBrush : TargetLineStroke.BrushDX;
                RenderTarget.DrawLine(targetStartVector, targetEndVector, tmpBrush, TargetLineStroke.Width, TargetLineStroke.StrokeStyle);
                DrawPriceText(RewardAnchor, targetPoint, targetPrice, chartControl, chartPanel, chartScale);
            }

            tmpBrush = IsInHitTest ? chartControl.SelectionBrush : EntryLineStroke.BrushDX;
            RenderTarget.DrawLine(entryStartVector, entryEndVector, tmpBrush, EntryLineStroke.Width, EntryLineStroke.StrokeStyle);
            DrawPriceText(EntryAnchor, entryPoint, entryPrice, chartControl, chartPanel, chartScale);

            tmpBrush = IsInHitTest ? chartControl.SelectionBrush : StopLineStroke.BrushDX;
            RenderTarget.DrawLine(stopStartVector, stopEndVector, tmpBrush, StopLineStroke.Width, StopLineStroke.StrokeStyle);
            DrawPriceText(RiskAnchor, stopPoint, stopPrice, chartControl, chartPanel, chartScale);
        }
예제 #3
0
        public override void OnMouseDown(ChartControl chartControl, ChartPanel chartPanel, ChartScale chartScale, ChartAnchor dataPoint)
        {
            switch (DrawingState)
            {
            case DrawingState.Building:
                if (StartAnchor.IsEditing)
                {
                    dataPoint.CopyDataValues(StartAnchor);
                    // Give end anchor something to start with so we dont try to render it with bad values right away
                    dataPoint.CopyDataValues(EndAnchor);
                    StartAnchor.IsEditing = false;
                }
                else if (EndAnchor.IsEditing)
                {
                    dataPoint.CopyDataValues(EndAnchor);
                    // Give extension anchor something nearby to start with
                    dataPoint.CopyDataValues(ExtensionAnchor);
                    EndAnchor.IsEditing = false;
                }
                else if (ExtensionAnchor.IsEditing)
                {
                    dataPoint.CopyDataValues(ExtensionAnchor);
                    ExtensionAnchor.IsEditing = false;
                }

                // Is initial building done (all anchors set)
                if (Anchors.All(a => !a.IsEditing))
                {
                    DrawingState = DrawingState.Normal;
                    IsSelected   = false;
                }
                break;

            case DrawingState.Normal:
                Point point = dataPoint.GetPoint(chartControl, chartPanel, chartScale);
                editingAnchor = GetClosestAnchor(chartControl, chartPanel, chartScale, cursorSensitivity, point);
                if (editingAnchor != null)
                {
                    editingAnchor.IsEditing = true;
                    DrawingState            = DrawingState.Editing;
                }
                else
                {
                    if (GetCursor(chartControl, chartPanel, chartScale, point) == Cursors.SizeAll)
                    {
                        DrawingState = DrawingState.Moving;
                    }
                    else if (GetCursor(chartControl, chartPanel, chartScale, point) == Cursors.SizeNESW ||
                             GetCursor(chartControl, chartPanel, chartScale, point) == Cursors.SizeNWSE)
                    {
                        DrawingState = DrawingState.Editing;
                    }
                    else if (GetCursor(chartControl, chartPanel, chartScale, point) == Cursors.Arrow)
                    {
                        DrawingState = DrawingState.Editing;
                    }
                    else if (GetCursor(chartControl, chartPanel, chartScale, point) == null)
                    {
                        IsSelected = false;
                    }
                }
                break;
            }
        }