Announcement

Collapse

Looking for a User App or Add-On built by the NinjaTrader community?

Visit NinjaTrader EcoSystem and our free User App Share!

Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
See more
See less

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 Barry Milan, Today, 10:35 PM
        1 response
        7 views
        0 likes
        Last Post NinjaTrader_Manfred  
        Started by WeyldFalcon, 12-10-2020, 06:48 PM
        14 responses
        1,428 views
        0 likes
        Last Post Handclap0241  
        Started by DJ888, Yesterday, 06:09 PM
        2 responses
        9 views
        0 likes
        Last Post DJ888
        by DJ888
         
        Started by jeronymite, 04-12-2024, 04:26 PM
        3 responses
        40 views
        0 likes
        Last Post jeronymite  
        Started by bill2023, Today, 08:51 AM
        2 responses
        16 views
        0 likes
        Last Post bill2023  
        Working...
        X