예제 #1
0
        // TODO:  Disabled for now, need sure recntangels are drawn historically and for all price zones
        private void RenderPriceZoneAreas(ChartControl chartControl, ChartScale chartScale, int barIndex, int plotIndex)
        {
            SharpDX.RectangleF rectangleF = new SharpDX.RectangleF();

            DateTime tm = ChartBars.GetTimeByBarIdx(chartControl, barIndex).Date;

            PriceZone zone = zonesList[tm];


            rectangleF.Top    = chartScale.GetYByValue(zone.ZoneStrong);
            rectangleF.Bottom = chartScale.GetYByValue(zone.ZoneWeak);
            rectangleF.Left   = chartControl.GetXByTime(zone.StartTime);
            rectangleF.Right  = ChartControl.GetXByTime(zone.EndTime);

            Brush tmpBrush = Plots[plotIndex].Brush.Clone();

            tmpBrush.Opacity = .05;
            tmpBrush.Freeze();
            RenderTarget.FillRectangle(rectangleF, tmpBrush.ToDxBrush(RenderTarget));
        }
예제 #2
0
        protected override Point[] OnGetSelectionPoints(ChartControl chartControl, ChartScale chartScale)
        {
            if (!IsSelected || Count == 0 || Plots[0].Brush.IsTransparent() || startIndex == int.MinValue)
            {
                return(new System.Windows.Point[0]);
            }

            List <System.Windows.Point> points = new List <System.Windows.Point>();

            int lastIndex = Calculate == NinjaTrader.NinjaScript.Calculate.OnBarClose ? ChartBars.ToIndex - 1 : ChartBars.ToIndex - 2;

            for (int i = Math.Max(0, ChartBars.FromIndex - Displacement); i <= Math.Max(lastIndex, Math.Min(Bars.Count - (Calculate == NinjaTrader.NinjaScript.Calculate.OnBarClose ? 2 : 1), lastIndex - Displacement)); i++)
            {
                int x = (chartControl.BarSpacingType == BarSpacingType.TimeBased || chartControl.BarSpacingType == BarSpacingType.EquidistantMulti && i + Displacement >= ChartBars.Count
                                        ? chartControl.GetXByTime(ChartBars.GetTimeByBarIdx(chartControl, i + Displacement))
                                        : chartControl.GetXByBarIndex(ChartBars, i + Displacement));

                if (Value.IsValidDataPointAt(i))
                {
                    points.Add(new System.Windows.Point(x, chartScale.GetYByValue(Value.GetValueAt(i))));
                }
            }
            return(points.ToArray());
        }
예제 #3
0
        protected override void OnBarUpdate()
        {
            if (CurrentBar < 0)
            {
                return;
            }

            // High Trend Line
            int swingHighBar = swing.SwingHighBar(0, 1, Strength + 1);

            if (swingHighBar != -1)
            {
                double swingHighPrice = !(Input is PriceSeries || Input is Bars) ? Input[swingHighBar] : High[swingHighBar];

                if (swingHighPrice < lastHighPrice && lastHighBar > -1)
                {
                    highTrend = new TrendRay(lastHighBar, lastHighPrice, CurrentBar - swingHighBar, swingHighPrice)
                    {
                        IsHigh = true
                    };
                    trendLines.Enqueue(highTrend);
                    highTrendIsActive = true;
                    alertIsArmed      = true;
                }

                lastHighBar   = CurrentBar - swingHighBar;
                lastHighPrice = swingHighPrice;
            }

            // Low Trend Line
            int swingLowBar = swing.SwingLowBar(0, 1, Strength + 1);

            if (swingLowBar != -1)
            {
                double swingLowPrice = !(Input is PriceSeries || Input is Bars) ? Input[swingLowBar] : Low[swingLowBar];

                if (swingLowPrice > lastLowPrice && lastLowBar > -1)
                {
                    lowTrend = new TrendRay(lastLowBar, lastLowPrice, CurrentBar - swingLowBar, swingLowPrice);
                    trendLines.Enqueue(lowTrend);
                    highTrendIsActive = false;
                    alertIsArmed      = true;
                }

                lastLowBar   = CurrentBar - swingLowBar;
                lastLowPrice = swingLowPrice;
            }

            if (highTrendIsActive.HasValue)
            {
                if (ChartControl == null || ChartControl.BarSpacingType == BarSpacingType.TimeBased)
                {
                    if (highTrendIsActive.Value)
                    {
                        double slope = (highTrend.EndPrice - highTrend.StartPrice) / (highTrend.EndBar - highTrend.StartBar);
                        Values[0][0] = slope * CurrentBar - (slope * highTrend.StartBar - highTrend.StartPrice);
                    }
                    else
                    {
                        double slope = (lowTrend.EndPrice - lowTrend.StartPrice) / (lowTrend.EndBar - lowTrend.StartBar);
                        Values[0][0] = slope * CurrentBar - (slope * lowTrend.StartBar - lowTrend.StartPrice);
                    }
                }
                else
                {
                    if (highTrendIsActive.Value)
                    {
                        double startSlotIndex = ChartControl.GetSlotIndexByTime(ChartBars.GetTimeByBarIdx(ChartControl, highTrend.StartBar));
                        double endSlotIndex   = ChartControl.GetSlotIndexByTime(ChartBars.GetTimeByBarIdx(ChartControl, highTrend.EndBar));
                        double curSlotIndex   = ChartControl.GetSlotIndexByTime(Time[0]);
                        double slope          = (highTrend.EndPrice - highTrend.StartPrice) / (endSlotIndex - startSlotIndex);
                        Values[0][0] = slope * curSlotIndex - (slope * startSlotIndex - highTrend.StartPrice);
                    }
                    else
                    {
                        double startSlotIndex = ChartControl.GetSlotIndexByTime(ChartBars.GetTimeByBarIdx(ChartControl, lowTrend.StartBar));
                        double endSlotIndex   = ChartControl.GetSlotIndexByTime(ChartBars.GetTimeByBarIdx(ChartControl, lowTrend.EndBar));
                        double curSlotIndex   = ChartControl.GetSlotIndexByTime(Time[0]);
                        double slope          = (lowTrend.EndPrice - lowTrend.StartPrice) / (endSlotIndex - startSlotIndex);
                        Values[0][0] = slope * curSlotIndex - (slope * startSlotIndex - lowTrend.StartPrice);
                    }
                }

                if (State == State.Realtime && AlertOnBreak && alertIsArmed)
                {
                    if (CrossAbove(Input, Values[0][0], 1) || CrossBelow(Input, Values[0][0], 1))
                    {
                        Alert(string.Empty, Priority.High, string.Format(NinjaTrader.Custom.Resource.TrendLinesTrendLineBroken,
                                                                         highTrendIsActive.Value ? NinjaTrader.Custom.Resource.TrendLinesTrendLineHigh: NinjaTrader.Custom.Resource.TrendLinesTrendLineLow),
                              AlertOnBreakSound, 0, Brushes.Transparent, highTrendIsActive.Value ? TrendLineHighStroke.Brush : TrendLineLowStroke.Brush);

                        alertIsArmed = false;
                    }
                }
            }
        }
예제 #4
0
        protected override void OnRender(Gui.Chart.ChartControl chartControl, Gui.Chart.ChartScale chartScale)
        {
            if (Bars == null || chartControl == null || startIndex == int.MinValue)
            {
                return;
            }

            IsValidDataPointAt(Bars.Count - 1 - (Calculate == NinjaTrader.NinjaScript.Calculate.OnBarClose ? 1 : 0));             // Make sure indicator is calculated until last (existing) bar
            int preDiff = 1;

            for (int i = ChartBars.FromIndex - 1; i >= 0; i--)
            {
                if (i - Displacement < startIndex || i - Displacement > Bars.Count - 1 - (Calculate == NinjaTrader.NinjaScript.Calculate.OnBarClose ? 1 : 0))
                {
                    break;
                }

                bool isHigh = zigZagHighZigZags.IsValidDataPointAt(i - Displacement);
                bool isLow  = zigZagLowZigZags.IsValidDataPointAt(i - Displacement);

                if (isHigh || isLow)
                {
                    break;
                }

                preDiff++;
            }

            preDiff -= (Displacement < 0 ? Displacement : 0 - Displacement);

            int postDiff = 0;

            for (int i = ChartBars.ToIndex; i <= zigZagHighZigZags.Count; i++)
            {
                if (i - Displacement < startIndex || i - Displacement > Bars.Count - 1 - (Calculate == NinjaTrader.NinjaScript.Calculate.OnBarClose ? 1 : 0))
                {
                    break;
                }

                bool isHigh = zigZagHighZigZags.IsValidDataPointAt(i - Displacement);
                bool isLow  = zigZagLowZigZags.IsValidDataPointAt(i - Displacement);

                if (isHigh || isLow)
                {
                    break;
                }

                postDiff++;
            }

            postDiff += (Displacement < 0 ? 0 - Displacement : Displacement);

            int    lastIdx   = -1;
            double lastValue = -1;

            SharpDX.Direct2D1.PathGeometry g    = null;
            SharpDX.Direct2D1.GeometrySink sink = null;

            for (int idx = ChartBars.FromIndex - preDiff; idx <= ChartBars.ToIndex + postDiff; idx++)
            {
                if (idx < startIndex || idx > Bars.Count - (Calculate == NinjaTrader.NinjaScript.Calculate.OnBarClose ? 2 : 1) || idx < Math.Max(BarsRequiredToPlot - Displacement, Displacement))
                {
                    continue;
                }

                bool isHigh = zigZagHighZigZags.IsValidDataPointAt(idx);
                bool isLow  = zigZagLowZigZags.IsValidDataPointAt(idx);

                if (!isHigh && !isLow)
                {
                    continue;
                }

                double value = isHigh ? zigZagHighZigZags.GetValueAt(idx) : zigZagLowZigZags.GetValueAt(idx);

                if (lastIdx >= startIndex)
                {
                    float x1 = (chartControl.BarSpacingType == BarSpacingType.TimeBased || chartControl.BarSpacingType == BarSpacingType.EquidistantMulti && idx + Displacement >= ChartBars.Count
                                                ? chartControl.GetXByTime(ChartBars.GetTimeByBarIdx(chartControl, idx + Displacement))
                                                : chartControl.GetXByBarIndex(ChartBars, idx + Displacement));
                    float y1 = chartScale.GetYByValue(value);

                    if (sink == null)
                    {
                        float x0 = (chartControl.BarSpacingType == BarSpacingType.TimeBased || chartControl.BarSpacingType == BarSpacingType.EquidistantMulti && lastIdx + Displacement >= ChartBars.Count
                                                ? chartControl.GetXByTime(ChartBars.GetTimeByBarIdx(chartControl, lastIdx + Displacement))
                                                : chartControl.GetXByBarIndex(ChartBars, lastIdx + Displacement));
                        float y0 = chartScale.GetYByValue(lastValue);
                        g    = new SharpDX.Direct2D1.PathGeometry(Core.Globals.D2DFactory);
                        sink = g.Open();
                        sink.BeginFigure(new SharpDX.Vector2(x0, y0), SharpDX.Direct2D1.FigureBegin.Hollow);
                    }
                    sink.AddLine(new SharpDX.Vector2(x1, y1));
                }

                // Save as previous point
                lastIdx   = idx;
                lastValue = value;
            }

            if (sink != null)
            {
                sink.EndFigure(SharpDX.Direct2D1.FigureEnd.Open);
                sink.Close();
            }

            if (g != null)
            {
                var oldAntiAliasMode = RenderTarget.AntialiasMode;
                RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive;
                RenderTarget.DrawGeometry(g, Plots[0].BrushDX, Plots[0].Width, Plots[0].StrokeStyle);
                RenderTarget.AntialiasMode = oldAntiAliasMode;
                g.Dispose();
                RemoveDrawObject("NinjaScriptInfo");
            }
            else
            {
                Draw.TextFixed(this, "NinjaScriptInfo", NinjaTrader.Custom.Resource.ZigZagDeviationValueError, TextPosition.BottomRight);
            }
        }
예제 #5
0
        public override void OnRender(ChartControl chartControl, ChartScale chartScale)
        {
            if (Series1 == null)
            {
                return;
            }

            NinjaScriptBase nsb       = AttachedTo.ChartObject as NinjaScriptBase;
            ChartBars       chartBars = (AttachedTo.ChartObject as Gui.NinjaScript.IChartBars).ChartBars;

            if (nsb == null || chartBars == null || Math.Abs(Series1.Count - chartBars.Count) > 1)
            {
                return;
            }

            int startBarIdx;
            int endBarIdx;

            if (chartControl.BarSpacingType == BarSpacingType.TimeBased)
            {
                startBarIdx = chartBars.GetBarIdxByTime(chartControl, StartAnchor.Time);
                endBarIdx   = chartBars.GetBarIdxByTime(chartControl, EndAnchor.Time);
            }
            else
            {
                startBarIdx = StartAnchor.DrawnOnBar - StartAnchor.BarsAgo;
                endBarIdx   = EndAnchor.DrawnOnBar - EndAnchor.BarsAgo;

                if (startBarIdx == endBarIdx)
                {
                    startBarIdx = chartBars.GetBarIdxByTime(chartControl, StartAnchor.Time);
                    endBarIdx   = chartBars.GetBarIdxByTime(chartControl, EndAnchor.Time);
                }
            }

            int startIdx = Math.Min(startBarIdx, endBarIdx);
            int endIdx   = Math.Max(startBarIdx, endBarIdx);

            // Now cap start/end by visibly painted bars!
            // If you dont do this it will absolutely crush performance on larger regions
            int firstVisibleIdx = Math.Max(nsb.BarsRequiredToPlot + Displacement, chartBars.GetBarIdxByTime(chartControl, chartControl.GetTimeByX(0)) - 1);
            int lastVisibleIdx  = Math.Max(chartBars.ToIndex, chartBars.GetBarIdxByTime(chartControl, chartControl.LastTimePainted)) + 1;

            // Update indicies for displacement
            startIdx = Math.Max(0, Math.Max(firstVisibleIdx, startIdx + Displacement));
            endIdx   = Math.Max(0, Math.Min(endIdx + Displacement, lastVisibleIdx));

            // we're completely not visible
            if (startIdx > lastVisibleIdx || endIdx < firstVisibleIdx)
            {
                return;
            }

            /* NOTE: Calling GetValueAt() on an ISeries<double> interface with a concrete
             * type of NinjaScriptBase will get the *bar* value which is not what we want,
             * in this case, default to first values (indicator) series */
            ISeries <double> series1Adjusted = Series1;
            ISeries <double> series2Adjusted = Series2;

            NinjaScriptBase series1NsBase = Series1 as NinjaScriptBase;

            if (series1NsBase != null)
            {
                series1Adjusted = series1NsBase.Value;
            }

            if (series1Adjusted == null)
            {
                return;
            }

            NinjaScriptBase series2NsBase = Series2 as NinjaScriptBase;

            if (series2NsBase != null)
            {
                series2Adjusted = series2NsBase.Value;
            }

            // take care to wind the points correctly so our geometry builds as a solid, not flipped inside out
            SharpDX.Vector2[] points;
            SharpDX.Vector2[] points2 = new SharpDX.Vector2[0];
            int pointIdx  = 0;
            int pointIdx2 = 0;

            if (series2Adjusted == null)
            {
                points = new SharpDX.Vector2[endIdx - startIdx + 1 + 2];
                for (int i = startIdx; i <= endIdx; ++i)
                {
                    if (i < Math.Max(0, Displacement) || i > Math.Max(chartBars.Count - (nsb.Calculate == Calculate.OnBarClose ? 2 : 1) + Displacement, endIdx))
                    {
                        continue;
                    }

                    int    displacedIndex = Math.Min(chartBars.Count - (nsb.Calculate == Calculate.OnBarClose ? 2 : 1), Math.Max(0, i - Displacement));
                    double seriesValue    = series1Adjusted.GetValueAt(displacedIndex);
                    float  y = chartScale.GetYByValue(seriesValue);
                    float  x = chartControl.BarSpacingType == BarSpacingType.TimeBased || chartControl.BarSpacingType == BarSpacingType.EquidistantMulti && i >= chartBars.Count                                                    //i is already displaced
                                                ? chartControl.GetXByTime(chartBars.GetTimeByBarIdx(chartControl, i))
                                                : chartControl.GetXByBarIndex(chartBars, i);

                    double pixXAdjust     = x % 1 != 0 ? 0 : 0.5d;
                    double pixYAdjust     = y % 1 != 0 ? 0 : 0.5d;
                    Vector pixelAdjustVec = new Vector(pixXAdjust, pixYAdjust);

                    Point adjusted = new Point(x, y) + pixelAdjustVec;
                    points[pointIdx] = adjusted.ToVector2();
                    ++pointIdx;
                }

                // cap it end->start
                points[pointIdx].X = chartControl.BarSpacingType == BarSpacingType.TimeBased || chartControl.BarSpacingType == BarSpacingType.EquidistantMulti && endIdx >= chartBars.Count
                                        ? chartControl.GetXByTime(chartBars.GetTimeByBarIdx(chartControl, endIdx))
                                        : chartControl.GetXByBarIndex(chartBars, endIdx);
                points[pointIdx++].Y = chartScale.GetYByValue(Math.Max(chartScale.MinValue, Math.Min(chartScale.MaxValue, Price)));

                points[pointIdx].X = chartControl.BarSpacingType == BarSpacingType.TimeBased || chartControl.BarSpacingType == BarSpacingType.EquidistantMulti && startIdx >= chartBars.Count
                                        ? chartControl.GetXByTime(chartBars.GetTimeByBarIdx(chartControl, startIdx))
                                        : chartControl.GetXByBarIndex(chartBars, startIdx);
                points[pointIdx++].Y = chartScale.GetYByValue(Math.Max(chartScale.MinValue, Math.Min(chartScale.MaxValue, Price)));
            }
            else
            {
                points  = new SharpDX.Vector2[endIdx - startIdx + 1];
                points2 = new SharpDX.Vector2[endIdx - startIdx + 1];
                // fill clockwise from series1, the	counter clockwise for series 2 for correct point poly winding
                for (int i = startIdx; i <= endIdx; ++i)
                {
                    if (i < Math.Max(0, Displacement) || i > Math.Max(chartBars.Count - (nsb.Calculate == Calculate.OnBarClose ? 2 : 1) + Displacement, endIdx))
                    {
                        continue;
                    }

                    int   displacedIndex = Math.Min(chartBars.Count - (nsb.Calculate == Calculate.OnBarClose ? 2 : 1), Math.Max(0, i - Displacement));
                    float x = chartControl.BarSpacingType == BarSpacingType.TimeBased || chartControl.BarSpacingType == BarSpacingType.EquidistantMulti && i >= chartBars.Count                                                     //i is already displaced
                                                ? chartControl.GetXByTime(chartBars.GetTimeByBarIdx(chartControl, i))
                                                : chartControl.GetXByBarIndex(chartBars, i);
                    if (!series1Adjusted.IsValidDataPointAt(displacedIndex))
                    {
                        continue;
                    }
                    double seriesValue = series1Adjusted.GetValueAt(displacedIndex);
                    float  y           = chartScale.GetYByValue(seriesValue);

                    double pixXAdjust = x % 1 != 0 ? 0 : 0.5d;
                    double pixYAdjust = y % 1 != 0 ? 0 : 0.5d;

                    Vector pixelAdjustVec = new Vector(pixXAdjust, pixYAdjust);

                    Point adjusted = new Point(x, y) + pixelAdjustVec;
                    points[pointIdx] = adjusted.ToVector2();
                    ++pointIdx;
                    if (!series2Adjusted.IsValidDataPointAt(displacedIndex))
                    {
                        continue;
                    }
                    seriesValue        = series2Adjusted.GetValueAt(displacedIndex);
                    y                  = chartScale.GetYByValue(seriesValue);
                    pixYAdjust         = y % 1 != 0 ? 0 : 0.5d;
                    pixelAdjustVec     = new Vector(pixXAdjust, pixYAdjust);
                    adjusted           = new Point(x, y) + pixelAdjustVec;
                    points2[pointIdx2] = adjusted.ToVector2();
                    ++pointIdx2;
                }
            }

            if (pointIdx + pointIdx2 > 2)
            {
                RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive;

                if (OutlineStroke != null)
                {
                    OutlineStroke.RenderTarget = RenderTarget;
                }

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

                SharpDX.Direct2D1.PathGeometry polyGeo = new SharpDX.Direct2D1.PathGeometry(Core.Globals.D2DFactory);
                SharpDX.Direct2D1.GeometrySink geoSink = polyGeo.Open();
                double pixXAdjust     = points[0].X % 1 != 0 ? 0 : 0.5d;
                double pixYAdjust     = points[0].Y % 1 != 0 ? 0 : 0.5d;
                Vector pixelAdjustVec = new Vector(pixXAdjust, pixYAdjust);
                Point  startPt        = new Point(points[0].X, points[0].Y) + pixelAdjustVec;

                geoSink.BeginFigure(startPt.ToVector2(), SharpDX.Direct2D1.FigureBegin.Filled);
                geoSink.SetFillMode(SharpDX.Direct2D1.FillMode.Winding);

                // NOTE: We skip our first point since that is where the path will start
                for (int i = 1; i < pointIdx; i++)
                {
                    geoSink.AddLine(points[i]);
                }
                for (int i = pointIdx2 - 1; i >= 0; i--)
                {
                    geoSink.AddLine(points2[i]);
                }
                geoSink.EndFigure(SharpDX.Direct2D1.FigureEnd.Closed);
                geoSink.Close();

                SharpDX.Direct2D1.Brush tmpBrush = IsInHitTest ? chartControl.SelectionBrush : areaBrushDevice == null ? null : areaBrushDevice.BrushDX;
                if (tmpBrush != null)
                {
                    RenderTarget.FillGeometry(polyGeo, tmpBrush);
                }

                tmpBrush = IsInHitTest ? chartControl.SelectionBrush : OutlineStroke == null ? null : OutlineStroke.BrushDX;
                if (tmpBrush != null)
                {
                    RenderTarget.DrawGeometry(polyGeo, OutlineStroke.BrushDX, OutlineStroke.Width);
                }

                polyGeo.Dispose();
            }
        }