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

How do I get the value of a scaled overlay instrument?

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

    How do I get the value of a scaled overlay instrument?

    How do I get the value of a scaled overlay instrument?

    Attached Chart:
    EURUSD: Purple Line
    GBPUSD: Grey

    EURUSD is trading at 1.1361
    GBPUSD is trading at 1.2952

    When I overlay GBPUSD onto EURUSD
    GBPUSD appears to be in the range of 1.1360

    Without plotting any chart in my strategy, how do I get that GBPUSD "Overlay Value"
    of 1.1360?
    Attached Files

    #2
    Hello johnnybegoode,

    Thanks for your post.

    With the 2nd data series added to the chart with Scale Justification set to Overlay, you can translate the value to different scales by using the ChartScale.GetYByValue, and ChartScale.GetValueByY to convert from the Overlay scale to coordinates, and then to the ChartScale of the strategy.

    Here is some sample code to demonstrate finding your data series from the ChartObjects collection and translating its value:

    Code:
    protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
    {
        base.OnRender(chartControl, chartScale);
    
        ChartBars chartBars2 = null;
    
        IList<Gui.NinjaScript.IChartObject> myObjects = ChartPanel.ChartObjects;
    
        foreach (Gui.NinjaScript.IChartObject thisObject in myObjects)
        {
            if (thisObject.GetType() == typeof(ChartBars))
            {
                if((thisObject as ChartBars).Bars.Instrument.FullName == "GBPUSD")
                    chartBars2 = thisObject as ChartBars;
            }
        }
    
        foreach (ChartScale scale in ChartPanel.Scales)
        {
            if (scale.ScaleJustification == ScaleJustification.Overlay)
            {
                if (chartBars2 != null)
                {
                    float Y = scale.GetYByValue(chartBars2.Bars.GetClose(chartBars2.Bars.Count-1));
                    Print(string.Format("Value: {0} Translated value: {1}",
                      chartBars2.Bars.GetClose(chartBars2.Bars.Count-1), chartScale.GetValueByY(Y)));
                }
            }
        }  
    }
    Associated documentation is linked below.Please let us know if we can be of further assistance.
    JimNinjaTrader Customer Service

    Comment


      #3
      How do I call that Value for comparison in

      Code:
      protected override void OnBarUpdate()

      Comment


        #4
        Hello johnnybegoode,

        You can move the code to its own method and call it from OnBarUpdate, but you will have to create your own ChartScale object and update it in OnBarUpdate. We're using the ChartScales to translate the values from coordinates on the chart, so this would only be available during realtime processing when there are active rendering passes.

        Here is an idea of how it can be done in its own method. You could take it a step further and loop back to use barsAgo references, but this would not be synchronized to the data series of your script as the data points are external and found by looping through ChartObjects. I would then suggest trying to match bar time stamps and use GetBar() to find the closest associated bar with a given timestamp.

        Code:
        private ChartScale ChartScale;
        
        private double GetLastScaledClose(string instrumentName)
        {
            if(State != State.Realtime)
                return 0;
        
            ChartBars chartBars2 = null;
        
            IList<Gui.NinjaScript.IChartObject> myObjects = ChartPanel.ChartObjects;
        
            foreach (Gui.NinjaScript.IChartObject thisObject in myObjects)
            {
                if (thisObject.GetType() == typeof(ChartBars))
                {
                    if((thisObject as ChartBars).Bars.Instrument.FullName == instrumentName)
                        chartBars2 = thisObject as ChartBars;
                }
            }
        
            if (chartBars2 != null)
                foreach (ChartScale scale in ChartPanel.Scales)
                {
                    if (scale.ScaleJustification == ScaleJustification.Overlay)
                    {
                        float Y = scale.GetYByValue(chartBars2.Bars.GetClose(chartBars2.Bars.Count-1));
                        double translated = ChartScale.GetValueByY(Y);
        
                        return translated;
                    }
                }
        
            return 0;
        }
        
        
        
        protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
        {
            base.OnRender(chartControl, chartScale);
        
            ChartScale = chartScale;
        }
        
        protected override void OnBarUpdate()
        {
            if(State != State.Realtime)
                return;
        
            Print(String.Format("Primary: {0} Found and Scaled (GBPUSD): {1}", Close[0], GetLastScaledClose("GBPUSD")));
        }
        Please let me know if you have any additional questions.
        JimNinjaTrader Customer Service

        Comment


          #5
          I get

          Error on calling 'OnBarUpdate' method on bar 127002: Object reference not set to an instance of an object.
          Disabling NinjaScript strategy:


          for this line.

          Code:
          Print(String.Format("Primary: {0} Found and Scaled (GBPUSD): {1}", Close[0], GetLastScaledClose("GBPUSD")));
          I'm using 'Market Replay' playback.
          Last edited by johnnybegoode; 01-26-2019, 09:54 PM.

          Comment


            #6
            Hello johnnybegoode,

            The code provided is intended to provide an educational demonstration for how the task could be accomplished. It is not intended to be copy and pasted into your script as I do not know the exact context that it would be used. There will be some level of involvement to create your own implementation and to debug it to avoid any errors that may be encountered.

            I have created a demonstration video showing the sample code provided in action. You can take the same steps to test on your end to observe the function. After testing the same way I would then suggest to modify to suit your needs.

            Demo - https://drive.google.com/file/d/1EoW...w?usp=drivesdk

            To better see where you are getting an Object reference not set to an instance of an object error, I would suggest adding prints to see which last lines the code are reached before the strategy aborts. After identifying the line that is creating the error, you can then take steps to avoid the null reference by checking if the object is null before any reference is made.

            Debugging tips - https://ninjatrader.com/support/help...script_cod.htm

            Checking for null references - https://ninjatrader.com/support/help...references.htm

            Please let me know if you have any additional questions.
            JimNinjaTrader Customer Service

            Comment


              #7
              Hello! Just wondering if there is any sample code for what you are referring to here:

              "Here is an idea of how it can be done in its own method. You could take it a step further and loop back to use barsAgo references, but this would not be synchronized to the data series of your script as the data points are external and found by looping through ChartObjects. I would then suggest trying to match bar time stamps and use GetBar() to find the closest associated bar with a given timestamp."
              We are working on a project with a client that is similar in terms of what is discussed here (getting X/Y coordinates of an additional data series) but would like to have this working in a strategy for backtesting and not just with realtime data. From what I understand from my research we cannot get these values simply be adding an AddDataSeries object because actually at that point the data series is not actually being added to the chart... then we get to the next fun part which is, if the data series was added as an overlay, no access to that from OnBarUpdate correct? Just won't want to jump in the rabbit hole if there are examples of this out there already.

              In terms of what was mentioned above with looping through the ChartObjects... the good news is for the setup I am working on the dataseries is the exact same for both... so matching the time series shouldn't be a problem as it should be pretty much an exact same time.

              Thanks,


              -Chad
              chadnash
              NinjaTrader Ecosystem Vendor - Nash Technologies

              Comment


                #8
                Hello Chad,

                The additional data series added to the script would not be added to the chart, and a data series added to the chart would be a separate data series than the data series added to the script. We also cannot add additional data to charts in the Strategy Analyzer.

                The example code I gave would work for realtime only, because we would not yet be rendering anything on the chart until the State has reached State.Realtime, and the ChartScale used to translate the Y coordinate to a value relative to the indicator's data series would not be available before then. Therefore, it would not be possible to translate values from one price scale to another during State.Historical.

                It is really best to think of the overlaid data series on the chart as completely separate from the script. We can get some information about the overlaid data series ChartScale when we are done processing historical data, but not during or before.



                JimNinjaTrader Customer Service

                Comment

                Latest Posts

                Collapse

                Topics Statistics Last Post
                Started by warreng86, 11-10-2020, 02:04 PM
                7 responses
                1,360 views
                0 likes
                Last Post NinjaTrader_Manfred  
                Started by Perr0Grande, Today, 08:16 PM
                0 responses
                5 views
                0 likes
                Last Post Perr0Grande  
                Started by elderan, Today, 08:03 PM
                0 responses
                9 views
                0 likes
                Last Post elderan
                by elderan
                 
                Started by algospoke, Today, 06:40 PM
                0 responses
                10 views
                0 likes
                Last Post algospoke  
                Started by maybeimnotrader, Today, 05:46 PM
                0 responses
                14 views
                0 likes
                Last Post maybeimnotrader  
                Working...
                X