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 to make two charts share variable values?

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

    How to make two charts share variable values?

    Hi there.

    I have successfully been able to make two or more charts share live values between each other within the Tradestation, Multicharts and InvestorRT platforms. This is without a third party go-between such as Excel. With Tradestation and Multicharts I have used "GlobalVariables" (some use AllDataEverywhere or ADE) and this function is already prebuilt into InvestorRT using V# variables.

    However, since NinjaTrader is my preferred platform I wished to do the same thing.

    Why would I wish to do this? Lets say I have a Weekly chart with a 50EMA on it and I wish to know the current value to plot on my 100 tick chart. I do not wish of course to take the usual course of adding at least 50 weeks of data onto my 100 tick chart. Of course this example is basic but I'm sure you get my drift.

    The image attached is my old InvestorRT 'Analyzer' or QuotePage that shows it's values using 'live' instant values from charts I have running in the background. There is no need to run multiple datas on the one chart. The same can be done in MC or TS via Global Variables.

    The idea is to set a "Global Variable" in one indicator in a chart and Get the same variable within another.

    bool SetDataInt(String name, int _value)
    int GetDataInt(String name)
    bool SetDataLong(String name, long _value)
    long GetDataLong(String name)
    bool SetDataFloat(String name, float _value)
    float GetDataFloat(String name)
    bool SetDataDouble(String name, double _value)
    double GetDataDouble(String name)
    bool SetDataString(String name, String _value)

    Some NT ideas:
    * Could a variable be set as "public' instead of private within an indicator and accessed by another in realtime?
    * Windows Message Queuing?
    * Singletons?
    * Using dictionaries like this http://www.multicharts.com/discussio...p?f=19&t=45280

    Please find included the necessary source code files for MC.net plus some documentation. Unfortunately I do not know enough how to do this for NT myself so please if anyone is so inclined to have a look that would be brilliant

    Simon.
    Attached Files
    Last edited by Sim22; 12-25-2015, 10:59 PM.

    #2
    I noticed @reachforthelasers mentioned "pipelines".



    BarsRequest() seems another option but is still used within the same chart?
    Last edited by Sim22; 12-26-2015, 10:45 PM.

    Comment


      #3
      Hello,

      Thank you for the question.

      While other platforms need to specifically define a global type of variable, NinjaTrader uses C# which would allow you to use standard C# structure. sharing data is not a NinjaTrader specific concept, you could look into static variables regarding general C# structure.

      I have attached a simple example that uses an addon which defines a static class, using the namespace you can call that class from a indicator or strategy or other, but keep in mind this is outside of NinjaTraders sync so anything you do from script A may not be updated when you need it in script B. Using the supported/documented approaches if possible would always be best as there is an expectation on how that syntax should work and we could assist in problems.

      Please let me know if I may be of further assistance .
      Last edited by NinjaTrader_Jesse; 09-09-2019, 10:08 AM. Reason: removed sample, sample is being used out of context for non-valid uses. static is not often the correct solution in NS but was for this specific thread.
      JesseNinjaTrader Customer Service

      Comment


        #4
        Static Variable...... got it.

        Thanks so much for the example

        Comment


          #5
          Okay, so I created a 'set' and 'get' version of your sample to test.

          Please see attached image.

          When the 'set' chart updates the value of "TestDouble" on the current tick or price change, the 'get' chart updates to the previous value of "TestDouble". Well, that's obvious since they are both in sync as the instruments ticks.

          However is there a way I can tell the "get" chart to 'refresh' again after a set milliseconds after it ticks or price changes so as to refresh to the current value of the 'set' chart?

          A pseudo-code might read like this:

          If bar has made a price change then ForceRefresh or get value after 300ms of time has passed;

          Thank for your help.
          Attached Files
          Last edited by Sim22; 01-10-2016, 03:59 PM.

          Comment


            #6
            Originally posted by Sim22 View Post
            Okay, so I created a 'set' and 'get' version of your sample to test.

            Please see attached image.

            When the 'set' chart updates the value of "TestDouble" on the current tick or price change, the 'get' chart updates to the previous value of "TestDouble". Well, that's obvious since they are both in sync as the instruments ticks.

            However is there a way I can tell the "get" chart to 'refresh' again after a set milliseconds after it ticks or price changes so as to refresh to the current value of the 'set' chart?

            A pseudo-code might read like this:

            If bar has made a price change then ForceRefresh or get value after 300ms of time has past;

            Thank for your help.
            Calculate.OnPriceChange?

            Comment


              #7
              Originally posted by koganam View Post
              Calculate.OnPriceChange?
              Thanks Koganam, but the issue was both indicators accessing the same addon at the 'same' time so it is irrelevant what "Calculate" is set to. All I am saying is that when both charts update on a tick or price change or bar close, that the "Get" chart accesses the 'old' value milliseconds before the "Set" chart has a chance to update the value.

              The only way it seems to "work" is to set the "Set" chart to "Calculate.OnPriceChange" and the "Get" chart to "Calculate.OnEachTick", that way it is forced to get the new value on the next tick. However, that is unnecessarily resource unfriendly and in a slow market that tick might take forever.

              Here is an example of what I might do with this......(see attachment).
              Attached Files

              Comment


                #8
                I put some psuedocode in here earlier which i have now deleted.

                Basically, all you need to do is add an extra (PeriodType.Tick, 100) to both your Set coding and Get coding.

                For your Set coding, CalculateOnBarClose = true, and calculate your static indicator as normal for BarsInProgress == 1.

                For your Get coding, CalculateOnBarClose = false and at the begining of OnBarUpdate, you need to be counting ticks in BarsInProgress == 1:

                OnBarUpdate{
                tickCounter++
                If tickCounter = 100, reset the counter.
                If tickCounter != 2, Return
                GetSharedStaticValue()
                ...
                Executing rest of OnBarUpdate only on tick 2
                ....
                }

                Don't forget, the instruments and session templates must be the same or you will get out of sync...
                Last edited by Zzoom; 01-11-2016, 05:13 AM. Reason: correceted code logic

                Comment


                  #9
                  Originally posted by Zzoom View Post
                  I put some psuedocode in here earlier which i have now deleted.

                  Basically, all you need to do is add an extra (PeriodType.Tick, 100) to both your Set coding and Get coding.

                  For your Set coding, CalculateOnBarClose = true, and calculate your static indicator as normal for BarsInProgress == 1.

                  For your Get coding, CalculateOnBarClose = false and at the begining of OnBarUpdate, you need to be counting ticks in BarsInProgress == 1:

                  OnBarUpdate{
                  tickCounter++
                  If tickCounter = 100, reset the counter.
                  If tickCounter != 2, Return
                  GetSharedStaticValue()
                  ...
                  Executing rest of OnBarUpdate only on tick 2
                  ....
                  }

                  Don't forget, the instruments and session templates must be the same or you will get out of sync...
                  Thank you Zzoom.

                  I appreciate the idea of the tick counter, basically to update 2 ticks after the previous value.

                  I have a couple of doubts with this method though (IMHO)....but please correct me if I'm wrong:

                  1. It still involves adding another data set to each chart, which is what I wanted to avoid in the first place. I may feed a value from a Daily chart, so this is impractical.
                  2. The "Set" chart would not be receiving the latest value of the "Get" chart since the "Get" chart indicator is not updating in real-time (OnBarClose). Take the daily chart again for example......the value would be yesterday's.

                  Surely there has to be an easier way or more efficient way to do this. I'm going to keep looking for a more .Net generic method, unless a Ninjascript technician has a stroke of genius!

                  Thanks again for your help!
                  Last edited by Sim22; 01-11-2016, 08:38 PM.

                  Comment


                    #10
                    Success......sort of!

                    Please see edit below

                    Okay....here it is......

                    You must make a chart with the "Set" indicator first.

                    You must make a chart with the "Get" indicator afterwards.

                    I printed the time-stamp in ticks from each indicator to see when the value was updating. Low and behold my 'Set' was updating after my 'Get'.

                    It is my guess that NT8 must register a chart or indicator instance by it's own ID. It therefore updates values based on that order.

                    So my question is: If I create a chart/add an indicator before another it will calculate first? Would someone from NT be so kind as to point out why this is AND how I can add some code to take care of this occurrence?

                    Thank you.

                    EDIT:

                    Upon further testing it seems this is not entirely true because upon changing my "Set" data series to Daily my 100t chart was not updating in the right order again. However if I then subsequently changed my "Get" chart to say, for example, 50t data series then the sync worked again

                    So my 2 cents of opinion would suggest the order in which the "Data series" is initialized is the key.

                    ie. load the "Set" chart first then load the "Get" chart next.

                    Comments?

                    Attached Files
                    Last edited by Sim22; 01-12-2016, 07:06 PM.

                    Comment


                      #11
                      A working example

                      Find uploaded an example of this concept.

                      You must extract the Zip file first before importing to NT8.

                      A work-space is included.

                      Please read the instructions for setup and comments on 'issues'.

                      This uses "ConcurrentDictionary" to hold values and I consider this more flexible than the generic 'static' value.

                      You can send strings, ints, bools, doubles and floats to other charts all through the same addon.

                      The example posted uses "NamedDouble" which allows you to use a string key with your value so you can use any name you like.
                      eg. Send and receive a value via the key "ES60Minute".

                      You can explore the other Globals properties in the "Sim22_Globals AddOn".

                      Still to be fixed:

                      Syncing of data. Please read the instructions. it works but I would like to explore automatic reloading of data series etc.

                      Further collaboration on this would be great, so I'd appreciate any improvements or comments!

                      Thank you.
                      Attached Files
                      Last edited by Sim22; 01-13-2016, 01:58 AM.

                      Comment


                        #12
                        Originally posted by Sim22 View Post
                        Thank you Zzoom.

                        I appreciate the idea of the tick counter, basically to update 2 ticks after the previous value.

                        I have a couple of doubts with this method though (IMHO)....but please correct me if I'm wrong:

                        1. It still involves adding another data set to each chart, which is what I wanted to avoid in the first place. I may feed a value from a Daily chart, so this is impractical.
                        2. The "Set" chart would not be receiving the latest value of the "Get" chart since the "Get" chart indicator is not updating in real-time (OnBarClose). Take the daily chart again for example......the value would be yesterday's.

                        Surely there has to be an easier way or more efficient way to do this. I'm going to keep looking for a more .Net generic method, unless a Ninjascript technician has a stroke of genius!

                        Thanks again for your help!
                        re: onbarclose

                        It has been a while since i did any programming on NT so please excuse my error - I would look at the first tick of each bar not the second - this is why:

                        if the "set" indicator is OnBarClose then it would always execute OnBarUpdate at the end of the 100tick bar only, saving you resources.

                        The "get" is executing OnBarUpdate every tick, but only updating your indicator and the rest of the your code at the begining each 100tick bar.

                        This way, with the other provisos, you will always get the latest value of the indicator, in sync by one tick

                        -----

                        A better way to make sure you stay in sync maybe to add another shared indicator, a sync/counter in "get". Add 1 (one) to it every time your original indicator is updated.

                        In the "set" you just check on every tick if the shared counter has changed yet. If it has changed, do the update of your original indicator value, then make sure you skip the majority of the ticks until the next bar.

                        The beauty of this is, your "get" indicator will auto-magically sync with the "set" indicator.

                        ----

                        I have done something similar a few years ago in Ninja to pull in and compare accurate time stamps from a different data source. it worked fine and made me realise how unreliable the then current data feed supplied by my broker was (missed bars, delayed data, etc).

                        I abandoned the data source (and hence the necessity of the coding).

                        -----

                        Hope some of this helps
                        ZZ
                        Last edited by Zzoom; 01-13-2016, 07:00 AM.

                        Comment


                          #13
                          Just looked at your screenshot on you last post using 15m and 5m bars.

                          I think you shoud just onbarclose = true as normal for your 15m bars and set your indicator and the "sync" indicator i mntioned above.

                          For your "get" 5 min bars, onbarclose = false, and use if(FirstTickOfBar)... then

                          I dont know of any way using the Ninja architecture of always making sure the indicator is set first that would not tae up more resources (tho as you have already stated if you create the charts in the right order, the issue is probably negated, not sure if i would be happy with that tho.)

                          Also just looked at your code...

                          IMHO I think you would be better off coding separate indicators to do the job, s22_RSI_set.cs, s22_RSI_get.cs or something. Saves the messing around with settings and extra coding and is easier to maintain - but that is just a personal preference!

                          Its been fun thinking about this stuff again!

                          Good Luck
                          ZZ
                          Last edited by Zzoom; 01-13-2016, 07:30 AM.

                          Comment


                            #14
                            Thank you ZZ.

                            I have to have a careful think about your suggestions. ie. I have to get my head around it first! LOL

                            Sync:

                            Yes, I thought of a 'send-back' DateTime.Now global var (GV) that would be able to tell whether one updated before the other and alert the user as such. In other words a reverse Set-Get. Unfortunately the Dictionary Method does not allow for a third entry so it would have been nice to send a time-stamp via the one GV. But alas it is not to be.......
                            Just an idea......... but I'd rather an automatic solution. Again, I will have a look at your suggestions.

                            Separate indicators:

                            Yes and No.

                            1. No. I made this as a sample for anyone willing to try it out, so it was hard-coded as such.
                            2. No. I was going to use perhaps 'Input[0]' so you can load up any data series into the indicator including any indicator value.
                            3. The Globals names can be automated using something like 'ToChartString()' or "Instrument name + period etc etc" so that the var names will have little risk of clashing.
                            4. Yes. When this concept is 'perfected' I would add a 'UseGV' bool to my favorite indicators.

                            Thanks for your sinking your teeth into this one. It certainly is an intellectual challenge.

                            Cheers!
                            Last edited by Sim22; 01-13-2016, 11:09 PM.

                            Comment


                              #15
                              Update: Using Memory Mapped Files (Inter Process Communication)

                              I solved the sync issue by using Memory Mapped Files. It simply uses a slice of system memory to set-get the real-time value. However, if using OnBarUpdate() in both indicators it still remained out-of-sync so the answer was to receive (get) the value within OnRender().

                              Find attached the .cs files to do this.

                              Find some samples here:

                              Memory Mapping:





                              Alternatives here:

                              Mailslot:



                              Named Pipes:

                              Attached Files
                              Last edited by Sim22; 01-29-2016, 06:16 PM.

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by ghoul, Today, 06:02 PM
                              1 response
                              10 views
                              0 likes
                              Last Post NinjaTrader_Manfred  
                              Started by jeronymite, 04-12-2024, 04:26 PM
                              3 responses
                              44 views
                              0 likes
                              Last Post jeronymite  
                              Started by Barry Milan, Yesterday, 10:35 PM
                              7 responses
                              20 views
                              0 likes
                              Last Post NinjaTrader_Manfred  
                              Started by AttiM, 02-14-2024, 05:20 PM
                              10 responses
                              179 views
                              0 likes
                              Last Post jeronymite  
                              Started by DanielSanMartin, Yesterday, 02:37 PM
                              2 responses
                              13 views
                              0 likes
                              Last Post DanielSanMartin  
                              Working...
                              X