Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Add a calculated values to chart

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Add a calculated values to chart

    I have created an indicator that displays Point Value, ATR and 2 other calculated values on the chart. The point value displays correctly, but the ATR is not calculating correctly (I am comparing it to pre-built ATR Indicator).

    The ATR from the code below is not calculating correctly and I am getting an error stating:
    Error on calling 'OnBarUpdate' method on bar 15 (Gui.Chart): The calling thread cannot access the object because a different thread owns it.

    I would greatly appreciate help in correcting my code to display these values on the chart.

    #region Using declarations
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Xml.Serialization;
    using NinjaTrader.Cbi;
    using NinjaTrader.Gui;
    using NinjaTrader.Gui.Chart;
    using NinjaTrader.Gui.SuperDom;
    using NinjaTrader.Gui.Tools;
    using NinjaTrader.Data;
    using NinjaTrader.NinjaScript;
    using NinjaTrader.Core.FloatingPoint;
    using NinjaTrader.NinjaScript.DrawingTools;
    #endregion

    //This namespace holds Indicators in this folder and is required. Do not change it.
    namespace NinjaTrader.NinjaScript.Indicators
    {
    public class IndicatorLegend : Indicator
    {
    private double atrValue = 0;
    private double riskperlot = 0;
    private double stop = 0;

    protected override void OnStateChange()
    {
    if (State == State.SetDefaults)
    {
    Description = @"Displays PV, Risk/Lot, Stop";
    Name = "IndicatorLegend";
    IsOverlay = true;
    DisplayInDataBox = true;
    DrawOnPricePanel = true;
    Calculate = Calculate.OnBarClose;
    //Disable this property if your indicator requires custom values that cumulate with each new market data event.
    //See Help Guide for additional information.
    IsSuspendedWhileInactive = true;
    }

    }
    protected override void OnBarUpdate()
    {

    double currentBid = GetCurrentBid();

    //currentBid is using historical data,

    if(CurrentBar <= 14) return;

    atrValue = ATR(14)[0];
    riskperlot = atrValue*Instrument.MasterInstrument.PointValue;
    stop = currentBid - atrValue;

    Draw.TextFixed(this, "chartlegend", "Point Value = " + Instrument.MasterInstrument.PointValue + Environment.NewLine +
    "Risk/lot = " + riskperlot.ToString("F") + "ATR = " + atrValue.ToString("F") + Environment.NewLine +
    "STOP = " + stop.ToString("F") + "CurrentBid " + currentBid.ToString("F"),
    TextPosition.TopLeft, Brushes.White, new Gui.Tools.SimpleFont("Arial", 12), Brushes.Transparent, Brushes.Transparent, 100);
    ChartControl.InvalidateVisual();

    //Add your custom indicator logic here.
    }


    public override string DisplayName
    {
    get {return "";}
    }
    }
    }

    #2
    Hello ashlantz, and thank you for your question. To aid others I am including a formatted version of your code sample.

    Code:
    [FONT=Courier New]#region Using declarations
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Xml.Serialization;
    using NinjaTrader.Cbi;
    using NinjaTrader.Gui;
    using NinjaTrader.Gui.Chart;
    using NinjaTrader.Gui.SuperDom;
    using NinjaTrader.Gui.Tools;
    using NinjaTrader.Data;
    using NinjaTrader.NinjaScript;
    using NinjaTrader.Core.FloatingPoint;
    using NinjaTrader.NinjaScript.DrawingTools;
    #endregion
    
    //This namespace holds Indicators in this folder and is required. Do not change it.
    namespace NinjaTrader.NinjaScript.Indicators
    {
      public class IndicatorLegend : Indicator
      {
        private double atrValue = 0;
        private double riskperlot = 0;
        private double stop = 0;
    
        protected override void OnStateChange()
        {
          if (State == State.SetDefaults)
          {
            Description = @"Displays PV, Risk/Lot, Stop";
            Name = "IndicatorLegend";
            IsOverlay = true;
            DisplayInDataBox = true;
            DrawOnPricePanel = true;
            Calculate = Calculate.OnBarClose;
            //Disable this property if your indicator requires custom values that cumulate with each new market data event.
            //See Help Guide for additional information.
            IsSuspendedWhileInactive = true;
          }
    
        }
        protected override void OnBarUpdate()
        {
    
          double currentBid = GetCurrentBid();
    
          //currentBid is using historical data,
    
          if(CurrentBar <= 14) return;
    
          atrValue = ATR(14)[0];
          riskperlot = atrValue*Instrument.MasterInstrument.PointValue;
          stop = currentBid - atrValue;
    
          Draw.TextFixed(this, "chartlegend", "Point Value = " + Instrument.MasterInstrument.PointValue + Environment.NewLine +
          "Risk/lot = " + riskperlot.ToString("F") + "ATR = " + atrValue.ToString("F") + Environment.NewLine +
          "STOP = " + stop.ToString("F") + "CurrentBid " + currentBid.ToString("F"),
          TextPosition.TopLeft, Brushes.White, new Gui.Tools.SimpleFont("Arial", 12), Brushes.Transparent, Brushes.Transparent, 100);
          ChartControl.InvalidateVisual();
    
          //Add your custom indicator logic here.
        }
    
    
        public override string DisplayName
        {
          get {return "";}
        }
      }
    } [/FONT]
    While fully debugging user code is beyond the scope of the support we can provide directly, I did notice a potentially thread-unsafe call to ChartControl.InvalidateVisual . I would like to recommend reviewing this publicly available Microsoft forums help page on the topic.



    I would also like to recommend that you review the attached code sample for an example which uses a dispatcher to resolve a similar threading behavior. We are happy to answer any specific questions that come up.
    Attached Files
    Jessica P.NinjaTrader Customer Service

    Comment


      #3
      Hi Jessica - Thank you very much for the reply and the help. I have successfully made the changes you suggested, and on future posts I will insert the code in a more readable format. I am a beginner and appreciate your time and effort in replying.

      Regards,
      Ashley

      Comment


        #4
        I am glad we were able to help Please don't hesitate to reach out if any other questions come up we could answer
        Jessica P.NinjaTrader Customer Service

        Comment

        Latest Posts

        Collapse

        Topics Statistics Last Post
        Started by Geovanny Suaza, 02-11-2026, 06:32 PM
        0 responses
        581 views
        0 likes
        Last Post Geovanny Suaza  
        Started by Geovanny Suaza, 02-11-2026, 05:51 PM
        0 responses
        338 views
        1 like
        Last Post Geovanny Suaza  
        Started by Mindset, 02-09-2026, 11:44 AM
        0 responses
        103 views
        0 likes
        Last Post Mindset
        by Mindset
         
        Started by Geovanny Suaza, 02-02-2026, 12:30 PM
        0 responses
        554 views
        1 like
        Last Post Geovanny Suaza  
        Started by RFrosty, 01-28-2026, 06:49 PM
        0 responses
        552 views
        1 like
        Last Post RFrosty
        by RFrosty
         
        Working...
        X