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

Custom strategy adding a secondary Market Data source

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

    Custom strategy adding a secondary Market Data source

    Hi. I have an extremely complex Order Entry and Analytic Unmanaged Strategy DLL, which trades into a single
    futures instrument; either NQ or MNQ. This is a Rithmic incoming feed, and I analyze every single tick and DOM update.
    That's not a problem since I queue up the incoming OnMarketDepth data; and process it in
    a different thread to take care of "data bursting" rates.

    ******** I'd like to add a secondary Instrument. If my primary is MNQ, then I'd like to add a secondary
    which would be NQ futures (same contract months). If possible, this would yield incoming OnMarketData and OnMarketDepth
    callbacks, and these could easily be differentiated by Instrument.

    I will use only Market Data/Depth on this secondary feed; I'm not trying to trade against it; just analyze it...

    I was planning to use a external source, and interprocess communications to get the secondary feed
    in; but I think that I might be able to "add" an additional Instrument feed, and this may be supported by NinjaTrader 8. ??

    Could you just tell me either that it's not possible; or how I can add the secondary instrument Market Data
    subscription which will stream data into OnMarketData and OnMarketDepth; in just the same way
    that the primary tradable instrument does that?

    I see there is an Instruments[ ] array, which currently has length 2, and contains my primary instrument, twice.
    e.g. stringified to "NQ 06-21 Globex"

    I am not certain what MasterInstrument is.

    If there's a straightforward supported way of doing this; thanks for letting me know; otherwise, I'll
    have to pipe data in from an external source; and that would be STUPID if there's a simple and
    supported way to add a secondary full Market Depth data source (which will be Rithmic).

    THANKS for your help !!
    hyperscalper

    #2
    Study AddDataSeries.

    When inside OnMarketData and OnMarketDepth, you will
    use BarsInProgress. It will be properly setup beforehand
    by NinjaScript internal framework, just like it is when calling
    OnBarUpdate.

    BarsInProgress is used to distinguish between the primary
    data series and your secondary data series.

    Comment


      #3
      If you look carefully at the overloads for AddDataSeries, you will see,

      Code:
      AddDataSeries([COLOR=#0000ff]string [/COLOR]instrumentName)[COLOR=#008000] //only for R15 and higher[/COLOR]
      I presume this is what you want, since this overload will use the
      same BarsPeriod type & interval when setting up the secondary
      data series for "instrumentName".

      Comment


        #4
        Thank you for the tip !! I'm studying this now.

        In my analysis I don't use the concept of "bars"; but just raw event updates.

        I think this may indeed allow me to add a secondary instrument; so I will study it, and try an implementation.

        hyperscalper

        Comment


          #5
          Hello Hyper,

          Thank you for your post.

          In addition to what bltdavid has suggested, I'd recommend taking a look at our help guide article on working with multi-instrument scripts here:



          Please let us know if we may be of further assistance to you.
          Kate W.NinjaTrader Customer Service

          Comment


            #6
            OK, I implemented a secondary Data Series, and I implemented Instrument ID recognition
            and event processing in OnMarketData and OnMarketDepth.

            But the system won't start my strategy and pops up this message, once when Ninja starts,
            and once when I enable my Custom Strategy on its Chart.

            I do only Unmanaged Orders; and all I wanted from the additional Instrument were
            the raw callbacks to OnMarketData and OnMarketDepth. I don't use "bars" in any
            way related to Order Processing.

            Click image for larger version  Name:	Multi-data-series-message2.PNG Views:	0 Size:	7.7 KB ID:	1155871

            I haven't finished reading all the doc on multi series, but maybe you can point me
            in the right direction to understand, and resolve this issue?

            Thanks in advance,
            hyper
            Attached Files
            Last edited by Hyper; 05-12-2021, 10:51 PM.

            Comment


              #7
              When setting up your strategy,
              inside the "Historical fill processing" category,
              set "Order fill resolution" to "Standard (Fastest)".

              If you're using this, make sure it is set to Standard.

              Comment


                #8
                First, read Understanding Historical Fill Processing.

                Then realize this is all about backtesting.

                IMHO, what you ultimately do in this area really just depends
                upon how much you care about backtesting.

                If you add a 1-Tick secondary data series, and direct your
                order submissions to that BIP during backtesting, there is
                a trade-off: your backtesting takes longer.

                If backtesting results from Strategy Analyzer are not that
                important to you, then set everything to Standard and forget
                about it.

                Comment


                  #9
                  Hello Hyper,

                  Thank you for your reply.

                  Really bltdavid is on the money here. High order fill resolution cannot be used with multi-series scripts and attempting to do so, even if no orders are submitted to the secondary series, would result in this error. Adding a 1 tick secondary series and submitting your orders to that series would mimic the same function as using Order Fill Resolution: High.

                  Please let us know if we may be of further assistance to you.
                  Kate W.NinjaTrader Customer Service

                  Comment


                    #10
                    Thank you so much for trying to help.

                    First of all, I have ZERO interest in any backtesting; I do realtime only.

                    Secondly, I don't care what I have to declare the Order Fill Resolution to be...

                    Just so long as my Unmanaged Order submissions are unaffected by that declaration.

                    I just don't trigger order processing in the ordinary way; I have Thread Executors which
                    submit Unmanaged Orders based upon Triggers which I have code myself. I react to
                    detail market conditioins, and am able to do that in about 50 milliseconds, and then
                    submit an order with a round-trip time of another 50 msecs or so. So "bars" are not part
                    of this Custom client strategy at all.

                    As I said, I won't be submitting orders to this secondary series; I just want the OnMarketData
                    and OnMarketDepth event callbacks to occur for both my Primary (as normal) and Secondary
                    Instrument series.

                    I wish I could declare that the added Data Series was FEED ONLY; and not tradable, or
                    declarations to that effect.

                    I'll fiddle with the Order Fill Resolution settings; since I think they have NO EFFECT on my
                    Unmanaged Order Submission methods..... wish me luck? LOL

                    hyper

                    Comment


                      #11
                      Just a quick update, and thanks again for the help.

                      In the Strategy, declaring the OrderFillResolution:

                      OrderFillResolution = OrderFillResolution.Standard; //.High;

                      and then when the Strategy is attached and enabled on the Chart,
                      selecting the Standard (Fastest) for the order fill resolution...

                      DOES allow the Strategy to run, and I'll have to check whether
                      the Order Processing is affected; and also whether I'm getting
                      the OnMarketData and OnMarketDepths raw callbacks for the
                      two series ( NQ and MNQ) as expected.

                      THANKS AGAIN !!

                      Watch this space? lol

                      [update] I am definitely getting the Data from both series streaming
                      in; and I expect Order Processing will be unaffected. That would mean
                      that IT WORKS, and I want to thank you guys for the help !!! )
                      The data rates for the Rithmic DOM can burst up around a
                      hundred updates per second, since it's an unrestricted very wide
                      DOM feed; but that's what makes it fun !!... ha ha

                      [order processing update]
                      Here's a $45 gross short micro scalp in NQ with a single contract,
                      so that verifies that Unmanaged Order processing is unaffected
                      by the required Order fill resolution setting to "standard".

                      Click image for larger version

Name:	Micro-scalp.PNG
Views:	305
Size:	67.4 KB
ID:	1155999
                      NinjaTrader is an incredible piece of engineering; and your Support is just the best, even
                      with the weird and customized requirements of guys like myself.... YOU GUYS ROCK, as they say )

                      hyper
                      Last edited by Hyper; 05-13-2021, 11:04 AM.

                      Comment


                        #12
                        I HAD ONE ODD ANOMALY

                        It looks like I was obtaining fluctuating POINT VALUES.

                        My Chart Symbol is MNQ and I want to trade into MNQ; however, I am allowing
                        the secondary AddDataSeries for NQ (the bigger contract) to drive all of my
                        analytics.

                        My Order Processing is using the attached Chart's Symbol, in this case MNQ
                        with no problem at all; nothing to do in the code. I think of this as the Primary Data Series.

                        In this case NQ is my secondary data series; which I want for Analytics only.

                        In calculating P&L; I was obtaining sometimes the MNQ Point value; and
                        sometimes the NQ Point value; so temporarily I hard-coded the Point value
                        to MNQ's value of 2.0 just to verify that:

                        public double getPointValue() {
                        // TODO TEMPORARY hard code MNQ Point Value TESTING
                        return 2; // this works perfectly when MNQ is the instrument
                        //return this.Instrument.MasterInstrument.PointValue;
                        }

                        As you can see, when I was obtaining these "fluctuating" Point values,
                        I was using "Instrument.MasterInstrument.PointValue" and I confess to not fully
                        understanding what MasterInstrument means in this context; and maybe
                        that's not the way for me to obtain the Point value in this multi-series context ??

                        I wonder if anyone has insight into why this might be occuring; and how I might
                        obtain the Point value by specifically mentioning the Instrument for which I want
                        the Point value ???

                        [edit] I use such a small number of Instruments, that I'd be able to hard code the
                        list of Point values; but it's always nice to have a more general solution...

                        hyper
                        Last edited by Hyper; 05-13-2021, 12:32 PM.

                        Comment


                          #13
                          Hello Hyper,

                          Thank you for your reply.

                          I assume you're referring to this from OnBarUpdate. OnBarUpdate will process for both data series, so if you're referring to this there, what the "this" in this.Instrument.MasterInstrument.PointValue refers to will change depending on which bar series is iterating through OBU.

                          If you want it to always return the point value of the primary series, use BarsArray[0].Instrument.MasterInstrument.PointValue instead. That will return the point value of the primary data series regardless of which data series is currently running through OnBarUpdate.

                          Please let us know if we may be of further assistance to you.
                          Kate W.NinjaTrader Customer Service

                          Comment


                            #14
                            You might enjoy these common code snippets,

                            Code:
                            // return PointValue (currency value of 1 point of movement) of primary instrument
                            protected double PointValue {
                              get { return BarsArray[0].Instrument.MasterInstrument.PointValue; }
                            }
                            
                            // return TickValue (currency value of 1 tick of movement) of primary instrument
                            protected double TickValue {
                              get { return BarsArray[0].Instrument.MasterInstrument.PointValue * TickSize; }
                            }
                            
                            // return TickPerPoint (number of ticks per 1 point of movement) of primary instrument
                            protected double TicksPerPoint {
                              get { return BarsArray[0].Instrument.MasterInstrument.PointValue / TickValue; }
                            }
                            I have many others.


                            Comment


                              #15
                              OK, that all makes perfect sense. My calls to Instrument.MasterInstrument.PointValue were completely
                              unsynchronized with any notion of a "bar" or "OnBarUpdate"; they could happen any time; hence the issue...
                              Instrument.MasterInstrument.PointValue, probably for coding convenience, appears to return different
                              values, depending upon context; so now I have a much better idea what's going on !!

                              But now I realize I can use BarsArray[0] and BarsArray[1] to determine which one I need.

                              So I had very little real difficulty integrating the NQ (bigger contract) and MNQ (little one) together
                              within my Strategy Client, and only a very few mods were needed to do that.

                              Again, that's really good Engineering !!! THANKS to all who helped me!

                              hyper

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by aussugardefender, Today, 01:07 AM
                              0 responses
                              3 views
                              0 likes
                              Last Post aussugardefender  
                              Started by pvincent, 06-23-2022, 12:53 PM
                              14 responses
                              238 views
                              0 likes
                              Last Post Nyman
                              by Nyman
                               
                              Started by TraderG23, 12-08-2023, 07:56 AM
                              9 responses
                              384 views
                              1 like
                              Last Post Gavini
                              by Gavini
                               
                              Started by oviejo, Today, 12:28 AM
                              0 responses
                              4 views
                              0 likes
                              Last Post oviejo
                              by oviejo
                               
                              Started by pechtri, 06-22-2023, 02:31 AM
                              10 responses
                              125 views
                              0 likes
                              Last Post Leeroy_Jenkins  
                              Working...
                              X