private string GetPriceString(double price, ChartBars chartBars) { string priceString; double yValueEntry = AttachedTo.Instrument.MasterInstrument.RoundToTickSize(EntryAnchor.Price); double tickSize = AttachedTo.Instrument.MasterInstrument.TickSize; double pointValue = AttachedTo.Instrument.MasterInstrument.PointValue; switch (DisplayUnit) { case ValueUnit.Currency: if (AttachedTo.Instrument.MasterInstrument.InstrumentType == InstrumentType.Forex) { priceString = price > yValueEntry? Core.Globals.FormatCurrency(AttachedTo.Instrument.MasterInstrument.RoundToTickSize(price - yValueEntry) / tickSize *(tickSize * pointValue * Account.All[0].ForexLotSize)) : Core.Globals.FormatCurrency(AttachedTo.Instrument.MasterInstrument.RoundToTickSize(yValueEntry - price) / tickSize * (tickSize * pointValue * Account.All[0].ForexLotSize)); } else { priceString = price > yValueEntry? Core.Globals.FormatCurrency(AttachedTo.Instrument.MasterInstrument.RoundToTickSize(price - yValueEntry) / tickSize *(tickSize *pointValue)) : Core.Globals.FormatCurrency(AttachedTo.Instrument.MasterInstrument.RoundToTickSize(yValueEntry - price) / tickSize * (tickSize * pointValue)); } break; case ValueUnit.Percent: priceString = price > yValueEntry ? (AttachedTo.Instrument.MasterInstrument.RoundToTickSize(price - yValueEntry) / yValueEntry).ToString("P", Core.Globals.GeneralOptions.CurrentCulture) : (AttachedTo.Instrument.MasterInstrument.RoundToTickSize(yValueEntry - price) / yValueEntry).ToString("P", Core.Globals.GeneralOptions.CurrentCulture); break; case ValueUnit.Ticks: priceString = price > yValueEntry ? (AttachedTo.Instrument.MasterInstrument.RoundToTickSize(price - yValueEntry) / tickSize).ToString("F0") : (AttachedTo.Instrument.MasterInstrument.RoundToTickSize(yValueEntry - price) / tickSize).ToString("F0"); break; case ValueUnit.Pips: priceString = price > yValueEntry ? (AttachedTo.Instrument.MasterInstrument.RoundToTickSize(price - yValueEntry) / tickSize / 10).ToString("F0") : (AttachedTo.Instrument.MasterInstrument.RoundToTickSize(yValueEntry - price) / tickSize / 10).ToString("F0"); break; default: priceString = chartBars.Bars.Instrument.MasterInstrument.FormatPrice(price); break; } return(priceString); }
// 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)); }
private ChartBars GetChartBars() { if (AttachedTo != null) { ChartBars chartBars = AttachedTo.ChartObject as ChartBars; if (chartBars == null) { Gui.NinjaScript.IChartBars iChartBars = AttachedTo.ChartObject as Gui.NinjaScript.IChartBars; if (iChartBars != null) { chartBars = iChartBars.ChartBars; } } if (chartBars != null) { return(chartBars); } } return(null); }
public void init_or_deinit(object indi_or_strat_, bool init) { log("init_or_deinit1"); if (init && indi_or_strat == null) { // for generic purposes indi_or_strat = (NinjaTrader.NinjaScript.NinjaScriptBase)indi_or_strat_; if (indi_or_strat_ is NinjaTrader.NinjaScript.Indicators.Indicator) { indi = (NinjaTrader.NinjaScript.Indicators.Indicator)indi_or_strat_; chartControl = indi.ChartControl; chartPnl = indi.ChartControl.ChartPanels[0]; chartBars = indi.ChartBars; } else if (indi_or_strat_ is NinjaTrader.NinjaScript.Strategies.Strategy) { strat = (NinjaTrader.NinjaScript.Strategies.Strategy)indi_or_strat_; chartControl = strat.ChartControl; chartPnl = strat.ChartControl.ChartPanels[0]; chartBars = strat.ChartBars; } if (chartControl == null || chartPnl == null) { enabled = false; return; } enabled = true; registerEventHandlers(); } else { checkForDeregister(); } log("init_or_deinit2"); }
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()); }
// drawZones // private void drawZones(ChartControl chartControl, ChartScale chartScale) { if (hideActiveZones && hideBrokenZones) { return; } if (Zones.Count == 0) { return; } SharpDX.Direct2D1.AntialiasMode oldAntialiasMode = RenderTarget.AntialiasMode; RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.Aliased; SharpDX.Direct2D1.Brush demandBrush = demandColor.ToDxBrush(RenderTarget); SharpDX.Direct2D1.Brush supplyBrush = supplyColor.ToDxBrush(RenderTarget); int x1 = 0; int x2 = 0; int y1 = 0; int y2 = 0; int wd = (int)(chartControl.BarWidth / 2.0) + (int)(chartControl.BarMarginLeft / 2.0); for (int i = 0; i < Zones.Count; i++) { if (Zones[i].a == true && hideActiveZones) { continue; } if (Zones[i].a == false && hideBrokenZones) { continue; } if (barIndex == 0) { x1 = ChartControl.GetXByBarIndex(ChartBars, Zones[i].b); x2 = (Zones[i].a == false) ? ChartControl.GetXByBarIndex(ChartBars, Zones[i].e) : (int)(ChartControl.GetXByBarIndex(ChartBars, ChartBars.ToIndex) + wd); x2 = (Zones[i].a == true && extendZones) ? chartControl.CanvasRight: x2; } else { x1 = ChartControl.GetXByBarIndex(ChartBars, findBar(Zones[i])); //x1 = ChartControl.GetXByBarIndex(ChartBars, BarsArray[0].GetBar(BarsArray[1].GetTime(Zones[i].b))); x2 = (Zones[i].a == false) ? ChartControl.GetXByBarIndex(ChartBars, ChartBars.GetBarIdxByTime(chartControl, BarsArray[1].GetTime(Zones[i].e))) : (int)(ChartControl.GetXByBarIndex(ChartBars, ChartBars.ToIndex) + wd); x2 = (Zones[i].a == true && extendZones) ? chartControl.CanvasRight: x2; } if (x2 < x1) { continue; } y1 = chartScale.GetYByValue(Zones[i].h); y2 = chartScale.GetYByValue(Zones[i].l); // area SharpDX.RectangleF rect = new SharpDX.RectangleF(); rect.X = (float)x1; rect.Y = (float)y1; rect.Width = (float)Math.Abs(x2 - x1); rect.Height = (float)Math.Abs(y1 - y2) - 1; if (Zones[i].a == true) { demandBrush.Opacity = activeAreaOpacity; supplyBrush.Opacity = activeAreaOpacity; } else { demandBrush.Opacity = brokenAreaOpacity; supplyBrush.Opacity = brokenAreaOpacity; } if (Zones[i].t == "d") { RenderTarget.FillRectangle(rect, demandBrush); } if (Zones[i].t == "s") { RenderTarget.FillRectangle(rect, supplyBrush); } // line one if (Zones[i].a == true) { demandBrush.Opacity = activeLineOpacity; supplyBrush.Opacity = activeLineOpacity; } else { demandBrush.Opacity = brokenLineOpacity; supplyBrush.Opacity = brokenLineOpacity; } SharpDX.Vector2 pOne = new SharpDX.Vector2(); SharpDX.Vector2 pTwo = new SharpDX.Vector2(); pOne.X = (float)x1; pOne.Y = (float)y1; pTwo.X = (float)x2; pTwo.Y = (float)y1; if (Zones[i].t == "d") { RenderTarget.DrawLine(pOne, pTwo, demandBrush, lineWidth); } if (Zones[i].t == "s") { RenderTarget.DrawLine(pOne, pTwo, supplyBrush, lineWidth); } // line two pOne.X = (float)x1; pOne.Y = (float)y2; pTwo.X = (float)x2; pTwo.Y = (float)y2; if (Zones[i].t == "d") { RenderTarget.DrawLine(pOne, pTwo, demandBrush, lineWidth); } if (Zones[i].t == "s") { RenderTarget.DrawLine(pOne, pTwo, supplyBrush, lineWidth); } } RenderTarget.AntialiasMode = oldAntialiasMode; // --- demandBrush.Dispose(); supplyBrush.Dispose(); }
public override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars chartBars) { if (chartBars.FromIndex > chartBars.ToIndex) { return; } if (chartBars.FromIndex > 0) { chartBars.FromIndex--; } Bars bars = chartBars.Bars; float barWidth = GetBarPaintWidth(BarWidthUI); int sessionStartIndex = chartBars.FromIndex; int thickOffsetTop = (int)(Stroke.Width * 0.5); int thinOffsetTop = (int)(Stroke2.Width * 0.5); Vector2 point0 = new Vector2(); Vector2 point1 = new Vector2(); while (sessionStartIndex > 0 && bars.BarsType.IsIntraday) { if (bars.BarsSeries.GetIsFirstBarOfSession(sessionStartIndex)) { break; } sessionStartIndex--; } if (sessionStartIndex < 0) // Occurs when all bars are off screen { return; } thickLine = bars.GetClose(sessionStartIndex) > bars.GetOpen(sessionStartIndex); //Determine the next bar coming up is thick or thin for (int k = sessionStartIndex + 1; k < chartBars.FromIndex; k++) { double closeTest = bars.GetClose(k); if (closeTest > bars.GetOpen(k)) { if (Math.Max(bars.GetOpen(k - 1), bars.GetClose(k - 1)) < closeTest) { thickLine = true; } } else if (closeTest < Math.Min(bars.GetOpen(k - 1), bars.GetClose(k - 1))) { thickLine = false; } } for (int idx = chartBars.FromIndex; idx <= chartBars.ToIndex; idx++) { Brush overriddenBrush = chartControl.GetBarOverrideBrush(chartBars, idx); double openValue = bars.GetOpen(idx); float open = chartScale.GetYByValue(openValue); double closeValue = bars.GetClose(idx); float close = chartScale.GetYByValue(closeValue); float x = chartControl.GetXByBarIndex(chartBars, idx); double prevOpenValue = idx == 0 ? openValue : bars.GetOpen(idx - 1); double prevCloseValue = idx == 0 ? closeValue : bars.GetClose(idx - 1); float startPosition; if (idx == 0 && chartBars.ToIndex >= 1) { float x0 = chartControl.GetXByBarIndex(chartBars, 0); float x1 = chartControl.GetXByBarIndex(chartBars, 1); float diffX = Math.Max(1, x1 - x0); startPosition = x0 - diffX; } else { startPosition = idx == chartBars.FromIndex ? chartControl.GetXByBarIndex(chartBars, idx) : chartControl.GetXByBarIndex(chartBars, idx - 1); } startPosition = startPosition < 0 ? 0 : startPosition; if (bars.BarsType.IsIntraday && bars.IsResetOnNewTradingDay && bars.BarsSeries.GetIsFirstBarOfSession(idx)) { // First bar if (closeValue > openValue) { point0.X = x; point0.Y = open; point1.X = x; point1.Y = close; TransformBrush(overriddenBrush ?? Stroke.BrushDX, new RectangleF(point0.X, point0.Y - Stroke.Width, barWidth, Stroke.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke.BrushDX, Stroke.Width, Stroke.StrokeStyle); thickLine = true; } else { point0.X = x; point0.Y = open; point1.X = x; point1.Y = close; TransformBrush(overriddenBrush ?? Stroke2.BrushDX, new RectangleF(point0.X, point0.Y - Stroke2.Width, barWidth, Stroke2.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke2.BrushDX, Stroke2.Width, Stroke2.StrokeStyle); thickLine = false; } } else { if (closeValue > openValue) { if (closeValue <= Math.Max(prevCloseValue, prevOpenValue)) { // Maintain previous thickness if (thickLine) { point0.X = x; point0.Y = open + thickOffsetTop; point1.X = x; point1.Y = close - thickOffsetTop; TransformBrush(overriddenBrush ?? Stroke.BrushDX, new RectangleF(point0.X, point0.Y - Stroke.Width, barWidth, Stroke.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke.BrushDX, Stroke.Width, Stroke.StrokeStyle); point0.X = startPosition; point0.Y = open; point1.X = x; point1.Y = open; TransformBrush(overriddenBrush ?? Stroke.BrushDX, new RectangleF(point0.X, point0.Y - Stroke.Width, barWidth, Stroke.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke.BrushDX, Stroke.Width, Stroke.StrokeStyle); } else { point0.X = x; point0.Y = open + thinOffsetTop; point1.X = x; point1.Y = close - thinOffsetTop; TransformBrush(overriddenBrush ?? Stroke2.BrushDX, new RectangleF(point0.X, point0.Y - Stroke2.Width, barWidth, Stroke2.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke2.BrushDX, Stroke2.Width, Stroke2.StrokeStyle); point0.X = startPosition; point0.Y = open; point1.X = x; point1.Y = open; TransformBrush(overriddenBrush ?? Stroke2.BrushDX, new RectangleF(point0.X, point0.Y - Stroke2.Width, barWidth, Stroke2.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke2.BrushDX, Stroke2.Width, Stroke2.StrokeStyle); } } else if (closeValue > Math.Max(prevCloseValue, prevOpenValue)) { double transitionPoint = Math.Max(prevCloseValue, prevOpenValue); point0.X = x; point0.Y = close - thickOffsetTop; point1.X = x; point1.Y = chartScale.GetYByValue(transitionPoint); TransformBrush(overriddenBrush ?? Stroke.BrushDX, new RectangleF(point0.X, point0.Y - Stroke.Width, barWidth, Stroke.Width)); RenderTarget.DrawLine(point0, point1, Stroke.BrushDX, Stroke.Width, Stroke.StrokeStyle); point0.X = x; point0.Y = chartScale.GetYByValue(transitionPoint); point1.X = x; point1.Y = open + (thickLine ? thickOffsetTop : thinOffsetTop); TransformBrush(overriddenBrush ?? (thickLine ? Stroke.BrushDX : Stroke2.BrushDX), new RectangleF(point0.X, point0.Y - (thickLine ? Stroke.Width : Stroke2.Width), barWidth, thickLine ? Stroke.Width : Stroke2.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? (thickLine ? Stroke.BrushDX : Stroke2.BrushDX), thickLine ? Stroke.Width : Stroke2.Width, thickLine ? Stroke.StrokeStyle : Stroke2.StrokeStyle); point0.X = startPosition; point0.Y = open; point1.X = x; point1.Y = open; TransformBrush(overriddenBrush ?? (thickLine ? Stroke.BrushDX : Stroke2.BrushDX), new RectangleF(point0.X, point0.Y - (thickLine ? Stroke.Width : Stroke2.Width), barWidth, thickLine ? Stroke.Width : Stroke2.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? (thickLine ? Stroke.BrushDX : Stroke2.BrushDX), thickLine ? Stroke.Width : Stroke2.Width, thickLine ? Stroke.StrokeStyle : Stroke2.StrokeStyle); thickLine = true; } } else { if (Math.Min(prevCloseValue, prevOpenValue) <= closeValue) { // Maintain previous thickness if (thickLine) { point0.X = x; point0.Y = open - thickOffsetTop; point1.X = x; point1.Y = close + thickOffsetTop; TransformBrush(overriddenBrush ?? Stroke.BrushDX, new RectangleF(point0.X, point0.Y - Stroke.Width, barWidth, Stroke.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke.BrushDX, Stroke.Width, Stroke.StrokeStyle); point0.X = startPosition; point0.Y = open; point1.X = x; point1.Y = open; TransformBrush(overriddenBrush ?? Stroke.BrushDX, new RectangleF(point0.X, point0.Y - Stroke.Width, barWidth, Stroke.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke.BrushDX, Stroke.Width, Stroke.StrokeStyle); } else { point0.X = x; point0.Y = open - thinOffsetTop; point1.X = x; point1.Y = close + thinOffsetTop; TransformBrush(overriddenBrush ?? Stroke2.BrushDX, new RectangleF(point0.X, point0.Y - Stroke2.Width, barWidth, Stroke2.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke2.BrushDX, Stroke2.Width, Stroke2.StrokeStyle); point0.X = startPosition; point0.Y = open; point1.X = x; point1.Y = open; TransformBrush(overriddenBrush ?? Stroke2.BrushDX, new RectangleF(point0.X, point0.Y - Stroke2.Width, barWidth, Stroke2.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke2.BrushDX, Stroke2.Width, Stroke2.StrokeStyle); } } else if (closeValue < Math.Min(prevCloseValue, prevOpenValue)) { double transitionPoint = Math.Min(prevCloseValue, prevOpenValue); point0.X = startPosition; point0.Y = open; point1.X = x; point1.Y = open; TransformBrush(overriddenBrush ?? (thickLine ? Stroke.BrushDX : Stroke2.BrushDX), new RectangleF(point0.X, point0.Y - (thickLine ? Stroke.Width : Stroke2.Width), barWidth, thickLine ? Stroke.Width : Stroke2.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? (thickLine ? Stroke.BrushDX : Stroke2.BrushDX), thickLine ? Stroke.Width : Stroke2.Width, thickLine ? Stroke.StrokeStyle : Stroke2.StrokeStyle); point0.X = x; point0.Y = open - (thickLine ? thickOffsetTop : thinOffsetTop); point1.X = x; point1.Y = chartScale.GetYByValue(transitionPoint); TransformBrush(overriddenBrush ?? (thickLine ? Stroke.BrushDX : Stroke2.BrushDX), new RectangleF(point0.X, point0.Y - (thickLine ? Stroke.Width : Stroke2.Width), barWidth, thickLine ? Stroke.Width : Stroke2.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? (thickLine ? Stroke.BrushDX : Stroke2.BrushDX), thickLine ? Stroke.Width : Stroke2.Width, thickLine ? Stroke.StrokeStyle : Stroke2.StrokeStyle); point0.X = x; point0.Y = chartScale.GetYByValue(transitionPoint); point1.X = x; point1.Y = close + thinOffsetTop; TransformBrush(overriddenBrush ?? Stroke2.BrushDX, new RectangleF(point0.X, point0.Y - Stroke2.Width, barWidth, Stroke2.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke2.BrushDX, Stroke2.Width, Stroke2.StrokeStyle); thickLine = false; } } } } }
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; } } } }
public override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars chartBars) { double boxHeightActual = Math.Floor(10000000.0 * chartBars.Bars.BarsPeriod.Value * chartBars.Bars.Instrument.MasterInstrument.TickSize) / 10000000.0; int boxSize = (int)Math.Round(chartScale.Height.ConvertToVerticalPixels(chartControl.PresentationSource) / Math.Round(chartScale.MaxMinusMin / boxHeightActual, 0)); AntialiasMode oldAliasMode = RenderTarget.AntialiasMode; RenderTarget.AntialiasMode = AntialiasMode.PerPrimitive; trendDetermined = false; for (int idx = chartBars.FromIndex; idx <= chartBars.ToIndex; idx++) { int barWidth = GetBarPaintWidth(BarWidthUI); double closeVal = chartBars.Bars.GetClose(idx); double openVal = chartBars.Bars.GetOpen(idx); int boxDrawCount = openVal == closeVal ? 1 : (int)Math.Round(Math.Abs(openVal - closeVal) / boxHeightActual, 0) + 1; float close = chartScale.GetYByValue(closeVal); float open = chartScale.GetYByValue(openVal); float nextBox = Math.Min(open, close); float x = chartControl.GetXByBarIndex(chartBars, idx); float diff = Math.Abs(open - close) + boxSize - (int)Math.Round((double)(boxSize * boxDrawCount)); if (closeVal == openVal) { if (idx == 0) { RenderTarget.DrawRectangle(new RectangleF(x - barWidth / 2.0f + 1, nextBox - boxSize / 2.0f + 2, barWidth - 1, boxSize - 2), DownBrushDX, Stroke.Width); Vector2 point0; Vector2 point1; point0.X = x - barWidth / 2.0f; point0.Y = nextBox - boxSize / 2.0f; point1.X = x + barWidth / 2.0f; point1.Y = nextBox + boxSize - boxSize / 2.0f; if (!(UpBrushDX is SharpDX.Direct2D1.SolidColorBrush)) { TransformBrush(UpBrushDX, new RectangleF(point0.X, point0.Y - Stroke.Width, barWidth, Stroke.Width)); } RenderTarget.DrawLine(point0, point1, UpBrushDX, Stroke.Width, Stroke.StrokeStyle); point0.X = x - barWidth / 2.0f; point0.Y = nextBox + boxSize - boxSize / 2.0f; point1.X = x + barWidth / 2.0f; point1.Y = nextBox - boxSize / 2.0f; if (!(UpBrushDX is SharpDX.Direct2D1.SolidColorBrush)) { TransformBrush(UpBrushDX, new RectangleF(point0.X, point0.Y - Stroke.Width, barWidth, Stroke.Width)); } RenderTarget.DrawLine(point0, point1, UpBrushDX, Stroke.Width, Stroke.StrokeStyle); continue; } if (!trendDetermined) { if (chartBars.Bars.GetOpen(idx - 1) == chartBars.Bars.GetClose(idx - 1)) { if (chartBars.Bars.GetHigh(idx) < chartBars.Bars.GetHigh(idx - 1)) { isUp = false; } } else { isUp = !(chartBars.Bars.GetOpen(idx - 1) < chartBars.Bars.GetClose(idx - 1)); } trendDetermined = true; } else { isUp = !isUp; } } else { isUp = closeVal > openVal; } for (int k = 0; k < boxDrawCount; k++) { if (diff != 0) { nextBox += diff > 0 ? 1 : -1; diff += diff > 0 ? -1 : 1; } if (!isUp) { Ellipse ellipse; ellipse.Point = new Vector2(x, nextBox); ellipse.RadiusX = barWidth / 2.0f; ellipse.RadiusY = boxSize / 2.0f - 1; if (!(DownBrushDX is SharpDX.Direct2D1.SolidColorBrush)) { TransformBrush(DownBrushDX, new RectangleF(ellipse.Point.X - ellipse.RadiusX, ellipse.Point.Y - ellipse.RadiusY - Stroke.Width, barWidth, Stroke.Width)); } RenderTarget.DrawEllipse(ellipse, DownBrushDX, Stroke.Width); } else { Vector2 point0; Vector2 point1; point0.X = x - barWidth / 2.0f; point0.Y = nextBox - boxSize / 2.0f; point1.X = x + barWidth / 2.0f; point1.Y = nextBox + boxSize - boxSize / 2.0f; if (!(UpBrushDX is SharpDX.Direct2D1.SolidColorBrush)) { TransformBrush(UpBrushDX, new RectangleF(point0.X, point0.Y - Stroke.Width, barWidth, Stroke.Width)); } RenderTarget.DrawLine(point0, point1, UpBrushDX, Stroke.Width, Stroke.StrokeStyle); point0.X = x - barWidth / 2.0f; point0.Y = nextBox + boxSize - boxSize / 2.0f; point1.X = x + barWidth / 2.0f; point1.Y = nextBox - boxSize / 2.0f; if (!(UpBrushDX is SharpDX.Direct2D1.SolidColorBrush)) { TransformBrush(UpBrushDX, new RectangleF(point0.X, point0.Y - Stroke.Width, barWidth, Stroke.Width)); } RenderTarget.DrawLine(point0, point1, UpBrushDX, Stroke.Width, Stroke.StrokeStyle); } nextBox += boxSize; } } RenderTarget.AntialiasMode = oldAliasMode; }
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); } }
protected override void OnBarUpdate() { // Get time of first bar on chart if (isFirstChartBar) { isFirstChartBar = false; chartStartTime = Time[0]; } // Not Enough History to calc rel vol if (Time[0].Date.AddDays(LookBackDays * -1) < chartStartTime.Date) { return; } // Only gather vol history on first tick // of bar since history does not change for // a given bar if (IsFirstTickOfBar) { int skipDays = 0; totalHistPeriodVol = 0; histPeriodVol = new List <double>(LookBackDays); // Loop until all same timeperiod lookback days // are found or lookback exceeds history while (histPeriodVol.Count < LookBackDays) { // Bar target time DateTime tt = Time[0].AddDays((histPeriodVol.Count + 1 + skipDays) * -1); // Bail if target day is before first chart, not enough history if (tt.Date < Time[CurrentBar].Date) { return; } // No weekends if ((tt.DayOfWeek == DayOfWeek.Saturday) || (tt.DayOfWeek == DayOfWeek.Sunday)) { skipDays++; continue; } // Skip over early close days and Holidays if (TradingHours.PartialHolidays.ContainsKey(tt.Date) || TradingHours.Holidays.ContainsKey(tt.Date)) { skipDays++; continue; } // Get Prev day's same time bar int relPrevBar = ChartBars.GetBarIdxByTime(ChartControl, tt); // If the returned bar is not the expected date, a bar with the // timetarget is not on the chart. Dont know why GetBarIdxByTime // does not return something more normal(like a -1) for a GetBarIdxXXX() // miss. Instead it just returns the incorrect bar. // At this point a missing bar is unexpected if (tt != Bars.GetTime(relPrevBar)) { throw new Exception("Missing data error - Target Time: " + tt + " Found Time: " + Bars.GetTime(relPrevBar)); } totalHistPeriodVol += Bars.GetVolume(relPrevBar); histPeriodVol.Add(Bars.GetVolume(relPrevBar)); } histPeriodVolStd = this.getStandardDeviation(histPeriodVol); avgHistPeriodVol = totalHistPeriodVol / LookBackDays; } // Get historical average at time volume from last x days Values[3][0] = avgHistPeriodVol; // Difference between avg period vol and current bars vol double rel_vol_diff = Volume[0] - avgHistPeriodVol; // Std Hi-Low Hash marks Values[1][0] = Math.Max(0.0, avgHistPeriodVol - histPeriodVolStd); Values[2][0] = avgHistPeriodVol + histPeriodVolStd; // Raw period volume bars, color code based on // volume above, below or within 1 std band Values[0][0] = Volume[0]; if (ShowVolumeBars) { // Greater than one std if (Volume[0] > Values[2][0]) { PlotBrushes[0][0] = VolAboveStdBrush; } // Within one std else if (Values[0][0] > Values[1][0]) { PlotBrushes[0][0] = VolWithinStdBrush; } // Less than 1 std else { PlotBrushes[0][0] = VolBelowStdBrush; } } else { PlotBrushes[0][0] = Brushes.Transparent; } }
public override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars chartBars) { Bars bars = chartBars.Bars; float barWidth = GetBarPaintWidth(BarWidthUI); RectangleF rect = new RectangleF(); for (int idx = chartBars.FromIndex; idx <= chartBars.ToIndex; idx++) { Brush overriddenBrush = chartControl.GetBarOverrideBrush(chartBars, idx); Brush overriddenOutlineBrush = chartControl.GetCandleOutlineOverrideBrush(chartBars, idx); double closeValue = bars.GetClose(idx); float close = chartScale.GetYByValue(closeValue); double openValue = bars.GetOpen(idx); float open = chartScale.GetYByValue(openValue); float x = chartControl.GetXByBarIndex(chartBars, idx); Gui.Stroke outlineStroke = closeValue >= openValue ? Stroke : Stroke2; rect.X = x - barWidth * 0.5f + 0.5f; rect.Y = Math.Min(open, close); rect.Width = barWidth - 1; rect.Height = Math.Max(open, close) - Math.Min(open, close); Brush b = overriddenBrush ?? (closeValue >= openValue ? UpBrushDX : DownBrushDX); if (!(b is SolidColorBrush)) { TransformBrush(b, rect); } RenderTarget.FillRectangle(rect, b); b = overriddenBrush ?? outlineStroke.BrushDX; if (!(b is SolidColorBrush)) { TransformBrush(b, rect); } RenderTarget.DrawRectangle(rect, overriddenOutlineBrush ?? outlineStroke.BrushDX, outlineStroke.Width, outlineStroke.StrokeStyle); } }
public override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars chartBars) { Bars bars = chartBars.Bars; float chartMinX = ConvertToHorizontalPixels(chartControl, chartControl.CanvasLeft + chartControl.Properties.BarMarginRight); RectangleF rect = new RectangleF(); int toIndex = chartBars.ToIndex; if (toIndex >= 0 && toIndex < bars.Count - 1) { toIndex++; } for (int idx = chartBars.FromIndex; idx <= toIndex; idx++) { double closeValue = bars.GetClose(idx); float high = chartScale.GetYByValue(bars.GetHigh(idx)); float low = chartScale.GetYByValue(bars.GetLow(idx)); double openValue = bars.GetOpen(idx); Brush overriddenBarBrush = chartControl.GetBarOverrideBrush(chartBars, idx); Brush overriddenOutlineBrush = chartControl.GetCandleOutlineOverrideBrush(chartBars, idx); float x = chartControl.GetXByBarIndex(chartBars, idx); float boxStartPosition; if (idx == chartBars.FromIndex && (toIndex == 0 || idx == 0)) { if (toIndex == 0) { boxStartPosition = chartMinX; } else { boxStartPosition = 2 * x - chartControl.GetXByBarIndex(chartBars, idx + 1); } } else { boxStartPosition = chartControl.GetXByBarIndex(chartBars, idx - 1); } if (Math.Abs(x - boxStartPosition) < 0.2) { continue; } float width = Math.Max(2f, Math.Abs(x - boxStartPosition)); if (closeValue > openValue) { width -= Stroke.Width; rect.X = boxStartPosition; rect.Y = high; rect.Width = width; rect.Height = low - high; TransformBrush(overriddenBarBrush ?? UpBrushDX, rect); TransformBrush(overriddenOutlineBrush ?? Stroke.BrushDX, rect); RenderTarget.FillRectangle(rect, overriddenBarBrush ?? UpBrushDX); RenderTarget.DrawRectangle(rect, overriddenOutlineBrush ?? Stroke.BrushDX, Stroke.Width, Stroke.StrokeStyle); } else { width -= Stroke2.Width; rect.X = boxStartPosition; rect.Y = high; rect.Width = width; rect.Height = low - high; TransformBrush(overriddenBarBrush ?? DownBrushDX, rect); TransformBrush(overriddenOutlineBrush ?? Stroke2.BrushDX, rect); RenderTarget.FillRectangle(rect, overriddenBarBrush ?? DownBrushDX); RenderTarget.DrawRectangle(rect, overriddenOutlineBrush ?? Stroke2.BrushDX, Stroke2.Width, Stroke2.StrokeStyle); } } }
public override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars chartBars) { Bars bars = chartBars.Bars; float lineWidth = (float)Math.Max(1, BarWidth); Vector2 point0 = new Vector2(); Vector2 point1 = new Vector2(); Vector2 point2 = new Vector2(); Vector2 point3 = new Vector2(); Vector2 point4 = new Vector2(); Vector2 point5 = new Vector2(); for (int idx = chartBars.FromIndex; idx <= chartBars.ToIndex; idx++) { SharpDX.Direct2D1.Brush overriddenBrush = chartControl.GetBarOverrideBrush(chartBars, idx); double closeValue = bars.GetClose(idx); float close = chartScale.GetYByValue(closeValue); float high = chartScale.GetYByValue(bars.GetHigh(idx)); float low = chartScale.GetYByValue(bars.GetLow(idx)); double openValue = bars.GetOpen(idx); float open = chartScale.GetYByValue(openValue); float x = chartControl.GetXByBarIndex(chartBars, idx); point0.X = point1.X = x; point0.Y = high - lineWidth * 0.5f; point1.Y = low + lineWidth * 0.5f; SharpDX.Direct2D1.Brush b = overriddenBrush ?? (closeValue >= openValue ? UpBrushDX : DownBrushDX); if (!(b is SharpDX.Direct2D1.SolidColorBrush)) { TransformBrush(b, new RectangleF(point0.X - lineWidth * 1.5f, point0.Y, lineWidth * 3, point1.Y - point0.Y)); } RenderTarget.DrawLine(point0, point1, b, lineWidth); if (!Equals(Mode, OhlcMode.HiLo)) { point2.X = x + lineWidth * 1.5f; point2.Y = close; point3.X = x; point3.Y = close; RenderTarget.DrawLine(point2, point3, b, lineWidth); if (Equals(Mode, OhlcMode.OHLC)) { point4.X = x - lineWidth * 1.5f; point4.Y = open; point5.X = x; point5.Y = open; RenderTarget.DrawLine(point4, point5, b, lineWidth); } } } }
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; }
public override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars chartBars) { Bars bars = chartBars.Bars; if (chartBars.FromIndex > 0) { chartBars.FromIndex--; } SharpDX.Direct2D1.PathGeometry lineGeometry = new SharpDX.Direct2D1.PathGeometry(Core.Globals.D2DFactory); AntialiasMode oldAliasMode = RenderTarget.AntialiasMode; GeometrySink sink = lineGeometry.Open(); sink.BeginFigure(new Vector2(chartControl.GetXByBarIndex(chartBars, chartBars.FromIndex > -1 ? chartBars.FromIndex : 0), chartScale.GetYByValue(bars.GetClose(chartBars.FromIndex > -1 ? chartBars.FromIndex : 0))), FigureBegin.Filled); for (int idx = chartBars.FromIndex + 1; idx <= chartBars.ToIndex; idx++) { double closeValue = bars.GetClose(idx); float close = chartScale.GetYByValue(closeValue); float x = chartControl.GetXByBarIndex(chartBars, idx); sink.AddLine(new Vector2(x, close)); } sink.EndFigure(FigureEnd.Open); sink.Close(); RenderTarget.AntialiasMode = AntialiasMode.PerPrimitive; RenderTarget.DrawGeometry(lineGeometry, UpBrushDX, (float)Math.Max(1, chartBars.Properties.ChartStyle.BarWidth)); lineGeometry.Dispose(); SharpDX.Direct2D1.SolidColorBrush fillOutline = new SharpDX.Direct2D1.SolidColorBrush(RenderTarget, SharpDX.Color.Transparent); SharpDX.Direct2D1.PathGeometry fillGeometry = new SharpDX.Direct2D1.PathGeometry(Core.Globals.D2DFactory); GeometrySink fillSink = fillGeometry.Open(); fillSink.BeginFigure(new Vector2(chartControl.GetXByBarIndex(chartBars, chartBars.FromIndex > -1 ? chartBars.FromIndex : 0), chartScale.GetYByValue(chartScale.MinValue)), FigureBegin.Filled); float fillx = float.NaN; for (int idx = chartBars.FromIndex; idx <= chartBars.ToIndex; idx++) { double closeValue = bars.GetClose(idx); float close = chartScale.GetYByValue(closeValue); fillx = chartControl.GetXByBarIndex(chartBars, idx); fillSink.AddLine(new Vector2(fillx, close)); } if (!double.IsNaN(fillx)) { fillSink.AddLine(new Vector2(fillx, chartScale.GetYByValue(chartScale.MinValue))); } fillSink.EndFigure(FigureEnd.Open); fillSink.Close(); DownBrushDX.Opacity = Opacity / 100f; if (!(DownBrushDX is SharpDX.Direct2D1.SolidColorBrush)) { TransformBrush(DownBrushDX, new RectangleF(0, 0, (float)chartScale.Width, (float)chartScale.Height)); } RenderTarget.FillGeometry(fillGeometry, DownBrushDX); RenderTarget.DrawGeometry(fillGeometry, fillOutline, (float)chartBars.Properties.ChartStyle.BarWidth); fillOutline.Dispose(); RenderTarget.AntialiasMode = oldAliasMode; fillGeometry.Dispose(); }
// Draw objects after any reload of data (if possible) // currently wont restore if one of points is -1 (unfinished bar, when calc per bar close) private void RestoreDrawObjects() { //check all dates for bars to validate they exist. //if(APDate == DateTime.MinValue) return; //works, but could still be older than oldest bar. //make sure All our saved dates are available on chart (null save = 01/01/0001). DateTime oldestDate = Time[CurrentBar]; if (oldestDate > APDate || oldestDate > BPDate || oldestDate > CPDate) { return; } if (Time[0] < APDate || Time[0] < BPDate || Time[0] < CPDate) { return; } swingDir = APVal >= BPVal ? -1 : 1; swingColor = swingDir > 0 ? SwingColorUp : SwingColorDn; //Draw AB line and text, using date info lineAB = Draw.Line(this, "dDwABLine", false, APDate, APVal, BPDate, BPVal, swingColor, DashStyleHelper.Solid, 2); lineBC = Draw.Line(this, "dDwBCLine", false, BPDate, BPVal, CPDate, CPVal, swingColor, DashStyleHelper.Solid, 2); //ChartControl.InvalidateVisual(); ForceRefresh(); //Place 'A' text Draw.Text(this, "dDwALabel", IsAutoScale, "A", APDate, APVal, textOffset2 * swingDir * -1, swingColor, textFontLabel, TextAlignment.Center, Brushes.Transparent, Brushes.Transparent, 0); Draw.Text(this, "dDwAPct", IsAutoScale, APVal.ToString(), APDate, APVal, textOffset * swingDir * -1, swingColor, textFont, TextAlignment.Center, Brushes.Transparent, Brushes.Transparent, 0); //Place 'B' text double moveVal = RoundInst(Math.Abs(APVal - BPVal)); Draw.Text(this, "dDwBLabel", IsAutoScale, "B", BPDate, BPVal, textOffset2 * swingDir, swingColor, textFontLabel, TextAlignment.Center, Brushes.Transparent, Brushes.Transparent, 0); Draw.Text(this, "dDwBPrice", IsAutoScale, moveVal.ToString() + "c - " + BPVal.ToString(), BPDate, BPVal, textOffset * swingDir, swingColor, textFont, TextAlignment.Center, Brushes.Transparent, Brushes.Transparent, 0); //Draw 'C' text moveVal = RoundInst(Math.Abs(BPVal - CPVal)); double movePct = (moveVal / Math.Abs(APVal - BPVal)) * 100; Draw.Text(this, "dDwCLabel", IsAutoScale, "C", CPDate, CPVal, textOffset3 * swingDir * -1, swingColor, textFontLabel, TextAlignment.Center, Brushes.Transparent, Brushes.Transparent, 0); //move point value and % Draw.Text(this, "dDwCPct", IsAutoScale, movePct.ToString("f1") + "%", CPDate, CPVal, textOffset2 * swingDir * -1, swingColor, textFont, TextAlignment.Center, Brushes.Transparent, Brushes.Transparent, 0); Draw.Text(this, "dDwCPrice", IsAutoScale, moveVal.ToString() + "c - " + CPVal.ToString(), CPDate, CPVal, textOffset * swingDir * -1, swingColor, textFont, TextAlignment.Center, Brushes.Transparent, Brushes.Transparent, 0); //setup and call fib draws _ABbarStart = CurrentBar - ChartBars.GetBarIdxByTime(ChartControl, APDate); _ABbarEnd = CurrentBar - ChartBars.GetBarIdxByTime(ChartControl, BPDate); _ABpriceStart = APVal; _ABpriceEnd = BPVal; _BCbarStart = _ABbarEnd; _BCbarEnd = CurrentBar - ChartBars.GetBarIdxByTime(ChartControl, CPDate); _BCpriceStart = BPVal; _BCpriceEnd = CPVal; DoDrawFibs(1, FibABRets, FibABExtends, FibABColor); DoDrawFibs(2, FibBCRets, FibBCExtends, FibBCColor); DoDrawFibs(3, FibMMRets, FibMMExtends, swingColor); }
private void DrawPriceText(ChartAnchor anchor, Point point, double price, ChartControl chartControl, ChartPanel chartPanel, ChartScale chartScale) { if (TextAlignment == TextLocation.Off) { return; } string priceString; ChartBars chartBars = GetAttachedToChartBars(); // bars can be null while chart is initializing if (chartBars == null) { return; } priceString = GetPriceString(price, chartBars); Stroke color; textleftPoint = RiskAnchor.GetPoint(chartControl, chartPanel, chartScale).X; textRightPoint = EntryAnchor.GetPoint(chartControl, chartPanel, chartScale).X; if (anchor == RewardAnchor) { color = TargetLineStroke; } else if (anchor == RiskAnchor) { color = StopLineStroke; } else if (anchor == EntryAnchor) { color = EntryLineStroke; } else { color = AnchorLineStroke; } SimpleFont wpfFont = chartControl.Properties.LabelFont ?? new SimpleFont(); SharpDX.DirectWrite.TextFormat textFormat = wpfFont.ToDirectWriteTextFormat(); textFormat.TextAlignment = SharpDX.DirectWrite.TextAlignment.Leading; textFormat.WordWrapping = SharpDX.DirectWrite.WordWrapping.NoWrap; SharpDX.DirectWrite.TextLayout textLayout = new SharpDX.DirectWrite.TextLayout(Core.Globals.DirectWriteFactory, priceString, textFormat, chartPanel.H, textFormat.FontSize); if (RiskAnchor.Time <= EntryAnchor.Time) { if (!IsExtendedLinesLeft && !IsExtendedLinesRight) { switch (TextAlignment) { case TextLocation.InsideLeft: point.X = textleftPoint; break; case TextLocation.InsideRight: point.X = textRightPoint - textLayout.Metrics.Width; break; case TextLocation.ExtremeLeft: point.X = textleftPoint; break; case TextLocation.ExtremeRight: point.X = textRightPoint - textLayout.Metrics.Width; break; } } else if (IsExtendedLinesLeft && !IsExtendedLinesRight) { switch (TextAlignment) { case TextLocation.InsideLeft: point.X = textleftPoint; break; case TextLocation.InsideRight: point.X = textRightPoint - textLayout.Metrics.Width; break; case TextLocation.ExtremeLeft: point.X = chartPanel.X; break; case TextLocation.ExtremeRight: point.X = textRightPoint - textLayout.Metrics.Width; break; } } else if (!IsExtendedLinesLeft && IsExtendedLinesRight) { switch (TextAlignment) { case TextLocation.InsideLeft: point.X = textleftPoint; break; case TextLocation.InsideRight: point.X = textRightPoint - textLayout.Metrics.Width; break; case TextLocation.ExtremeLeft: point.X = textleftPoint; break; case TextLocation.ExtremeRight: point.X = chartPanel.W - textLayout.Metrics.Width; break; } } else if (IsExtendedLinesLeft && IsExtendedLinesRight) { switch (TextAlignment) { case TextLocation.InsideLeft: point.X = textleftPoint; break; case TextLocation.InsideRight: point.X = textRightPoint - textLayout.Metrics.Width; break; case TextLocation.ExtremeRight: point.X = chartPanel.W - textLayout.Metrics.Width; break; case TextLocation.ExtremeLeft: point.X = chartPanel.X; break; } } } else if (RiskAnchor.Time >= EntryAnchor.Time) { if (!IsExtendedLinesLeft && !IsExtendedLinesRight) { switch (TextAlignment) { case TextLocation.InsideLeft: point.X = textRightPoint; break; case TextLocation.InsideRight: point.X = textleftPoint - textLayout.Metrics.Width; break; case TextLocation.ExtremeLeft: point.X = textRightPoint; break; case TextLocation.ExtremeRight: point.X = textleftPoint - textLayout.Metrics.Width; break; } } else if (IsExtendedLinesLeft && !IsExtendedLinesRight) { switch (TextAlignment) { case TextLocation.InsideLeft: point.X = textRightPoint; break; case TextLocation.InsideRight: point.X = textleftPoint - textLayout.Metrics.Width; break; case TextLocation.ExtremeLeft: point.X = chartPanel.X; break; case TextLocation.ExtremeRight: point.X = textleftPoint - textLayout.Metrics.Width; break; } } else if (!IsExtendedLinesLeft && IsExtendedLinesRight) { switch (TextAlignment) { case TextLocation.InsideLeft: point.X = textRightPoint; break; case TextLocation.InsideRight: point.X = textleftPoint - textLayout.Metrics.Width; break; case TextLocation.ExtremeLeft: point.X = textRightPoint; break; case TextLocation.ExtremeRight: point.X = chartPanel.W - textLayout.Metrics.Width; break; } } else if (IsExtendedLinesLeft && IsExtendedLinesRight) { switch (TextAlignment) { case TextLocation.InsideLeft: point.X = textRightPoint; break; case TextLocation.InsideRight: point.X = textleftPoint - textLayout.Metrics.Width; break; case TextLocation.ExtremeRight: point.X = chartPanel.W - textLayout.Metrics.Width; break; case TextLocation.ExtremeLeft: point.X = chartPanel.X; break; } } } RenderTarget.DrawTextLayout(new SharpDX.Vector2((float)point.X, (float)point.Y), textLayout, color.BrushDX, SharpDX.Direct2D1.DrawTextOptions.NoSnap); }
public override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars chartBars) { Bars bars = chartBars.Bars; float barWidth = GetBarPaintWidth(BarWidthUI); Vector2 point0 = new Vector2(); Vector2 point1 = new Vector2(); RectangleF rect = new RectangleF(); for (int idx = chartBars.FromIndex; idx <= chartBars.ToIndex; idx++) { Brush overriddenBarBrush = chartControl.GetBarOverrideBrush(chartBars, idx); Brush overriddenOutlineBrush = chartControl.GetCandleOutlineOverrideBrush(chartBars, idx); double closeValue = bars.GetClose(idx); int close = chartScale.GetYByValue(closeValue); int high = chartScale.GetYByValue(bars.GetHigh(idx)); int low = chartScale.GetYByValue(bars.GetLow(idx)); double openValue = bars.GetOpen(idx); int open = chartScale.GetYByValue(openValue); int x = chartControl.GetXByBarIndex(chartBars, idx); if (Math.Abs(open - close) < 0.0000001) { // Line point0.X = x - barWidth * 0.5f; point0.Y = close; point1.X = x + barWidth * 0.5f; point1.Y = close; Brush b = overriddenOutlineBrush ?? Stroke.BrushDX; if (!(b is SolidColorBrush)) { TransformBrush(overriddenOutlineBrush ?? Stroke.BrushDX, new RectangleF(point0.X, point0.Y - Stroke.Width, barWidth, Stroke.Width)); } RenderTarget.DrawLine(point0, point1, b, Stroke.Width, Stroke.StrokeStyle); } else { // Candle rect.X = x - barWidth * 0.5f + 0.5f; rect.Y = Math.Min(close, open); rect.Width = barWidth - 1; rect.Height = Math.Max(open, close) - Math.Min(close, open); Brush brush = overriddenBarBrush ?? (closeValue >= openValue ? UpBrushDX : DownBrushDX); if (!(brush is SolidColorBrush)) { TransformBrush(brush, rect); } RenderTarget.FillRectangle(rect, brush); brush = overriddenOutlineBrush ?? Stroke.BrushDX; if (!(brush is SolidColorBrush)) { TransformBrush(brush, rect); } RenderTarget.DrawRectangle(rect, overriddenOutlineBrush ?? Stroke.BrushDX, Stroke.Width, Stroke.StrokeStyle); } Brush br = overriddenOutlineBrush ?? Stroke2.BrushDX; // High wick if (high < Math.Min(open, close)) { point0.X = x; point0.Y = high; point1.X = x; point1.Y = Math.Min(open, close); if (!(br is SolidColorBrush)) { TransformBrush(br, new RectangleF(point0.X - Stroke2.Width, point0.Y, Stroke2.Width, point1.Y - point0.Y)); } RenderTarget.DrawLine(point0, point1, br, Stroke2.Width, Stroke2.StrokeStyle); } // Low wick if (low > Math.Max(open, close)) { point0.X = x; point0.Y = low; point1.X = x; point1.Y = Math.Max(open, close); if (!(br is SolidColorBrush)) { TransformBrush(br, new RectangleF(point1.X - Stroke2.Width, point1.Y, Stroke2.Width, point0.Y - point1.Y)); } RenderTarget.DrawLine(point0, point1, br, Stroke2.Width, Stroke2.StrokeStyle); } } }
public override void OnRender(ChartControl chartControl, ChartScale chartScale) { if (firstTime && DrawingState == DrawingState.Normal) { firstTime = false; Cbi.License.Log("TimeCycles"); } ChartPanel chartPanel = chartControl.ChartPanels[PanelIndex]; ChartBars chartBars = GetChartBars(); 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, chartBars, startX); if (anchorBars.Count <= 2) { return; } RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive; 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); } }
public override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars chartBars) { Bars bars = chartBars.Bars; if (chartBars.FromIndex > 0) { chartBars.FromIndex--; } SharpDX.Direct2D1.PathGeometry lineGeometry = new SharpDX.Direct2D1.PathGeometry(Core.Globals.D2DFactory); GeometrySink sink = lineGeometry.Open(); sink.BeginFigure(new Vector2(chartControl.GetXByBarIndex(chartBars, chartBars.FromIndex > -1 ? chartBars.FromIndex : 0), chartScale.GetYByValue(bars.GetClose(chartBars.FromIndex > -1 ? chartBars.FromIndex : 0))), FigureBegin.Filled); for (int idx = chartBars.FromIndex + 1; idx <= chartBars.ToIndex; idx++) { double closeValue = bars.GetClose(idx); float close = chartScale.GetYByValue(closeValue); float x = chartControl.GetXByBarIndex(chartBars, idx); sink.AddLine(new Vector2(x, close)); } sink.EndFigure(FigureEnd.Open); sink.Close(); AntialiasMode oldAliasMode = RenderTarget.AntialiasMode; RenderTarget.AntialiasMode = AntialiasMode.PerPrimitive; RenderTarget.DrawGeometry(lineGeometry, UpBrushDX, (float)Math.Max(1, chartBars.Properties.ChartStyle.BarWidth)); RenderTarget.AntialiasMode = oldAliasMode; lineGeometry.Dispose(); }
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(); } }