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

runtime reference to the instance of the active ATM

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

    runtime reference to the instance of the active ATM

    Hi,

    I am very proficient in c# and spent quite a bit of time to familiarize myself with the NinjaScript model and already coded several hellow-world addons.

    I need a reference at runtime (either OnExecutionUpdate or OnOrderUpdate event) to the instance of the active ATM associated with this execution/order when entered discretionary by the user in the GUI, say the SuperDOM. I cannot tell what that unique instance identifier is. None of these classes help me — Execution, Order, ExecutionEventArgs, OrderEventArgs.

    In the GUI, the ATM selector combobox shows all the active ATM instances and even auto-names them with a 1-based index. Even if there are multiple active ATMs the GUI is aware which orders belong to which active ATM. So this logic clearly exists.

    In the @SampleAtmStrtegy the “AtmStrategyTemplate” is hardwired in the code and not even passed as a parameter. The code calls StrategyBase.GetAtmStrategyUniqueId() which is assigned to both an Order and a Strategy. So the code initiates the trade entry and and then generates and coordinates the ids for the the entire bundle of orders and their status. Whereas, I want the reference to the active ATM when the entry was initiated not by my code but by the user in the GUI. So technically this is more like an indicator. For now I just print out the output but later I will plot on the chart and/or populate a display control.

    Thanks a lot
    Last edited by xcondor; 04-02-2018, 09:42 AM.

    #2
    Hello xcondor,

    Thank you for your note.

    I have attached a sample strategy which will manage a ATM strategy submitted via a superdom.

    Within the script you'll find instructions for how to set up the ATM and enable the strategy.

    Please let us know if you need further assistance.
    Attached Files
    Alan P.NinjaTrader Customer Service

    Comment


      #3
      Do I need another BarsRequest to for an addon to the superdom

      Alan,

      Thanks for the sample. I cannot use a strategy because when enabled it will make position entries. But the code did help me figure out how the AtmStrategy orders are bundled and referenced.

      I figured out how to add controls to the left grid of the SuperDOM tree. I am developing a widget similar to the PositionDisplay control (which only shows the unrealized PnL) but my control calculates the entire trade PnL including the realized PnL from all but the last target. Until the first target is hit they are the same, but from that point on and with each consecutive target fill the realized PnL is added. Unfortunately neither the PositionDisplay control nor the SuperDOM were really designed to be extended. Do I need a whole new BarsRequest?

      I added a second PositionDisplay just for kicks, and I did not have to do anything to supply data to it. It worked but only one out of three times when I relaunch the window.

      The AddonFramework sample is not exactly the same as it inherits from NTWindow with all new controls rather than hacking an existing window.

      Also one of the added buttons is to center the ladder. When the static SuperDOM is in left-controls mode, the button "C" to center the ladder is way up on the top right and very small and right next to an X button. It was so easy to inadvertently close me out of several trades. I cannot find this as an exposed public method. I would like to call it in a button and also with the spacebar as a hotkey. I cannot help it but I still prefer the static DOM and manually center it.

      Please help.
      Thanks
      Last edited by xcondor; 04-03-2018, 02:14 PM.

      Comment


        #4
        Hello xcondor,

        In regards to your question about needing a whole new bars request, I’m not sure I understand what your question is. Could you please provide more information on what you are asking exactly?

        Modifying the Superdom is going to be unsupported however I can provide you a sample which adds two buttons to the Superdom.



        With any code changes to an Addon or Window, you will have to compile and relaunch the window for them to be reflected.

        I look forward to your reply.
        Alan P.NinjaTrader Customer Service

        Comment


          #5
          Originally posted by NinjaTrader_AlanP View Post
          In regards to your question about needing a whole new bars request, I’m not sure I understand what your question is. Could you please provide more information on what you are asking exactly?
          Alan,
          I have figured out all but one of my issues.

          Attached is a working sample showing successfully added controls and a new BarsRequest for real-time data. The code is solid. The OnBarUpdate prints to the Output window just fine. At the same time, OnBarUpdate fails to update the output textblock even though the control is fully accessible from the code. I don't think it's a threading issue. If a picture is worth a 1000 words, a working sample is worth even more.

          The platform kept crashing every time I tried to export. So I just zipped the files myself. Included is the visual tree helper on which it is dependent. No issues there. Full instructions and reference to my specific problem inside LeftDOMTest.cs at the top as comments.

          Remove line 26, not needed.
          //using VisualTreeUtility;

          Thanks
          Attached Files
          Last edited by xcondor; 04-05-2018, 12:00 PM.

          Comment


            #6
            Hello xcondor,

            If you replace,

            Dispatcher.CurrentDispatcher.InvokeAsync(() =>

            with

            Dispatcher.InvokeAsync(() =>

            Which is how the last example at the following link has it, are you able to get the text box to update?


            I look forward to your reply.
            Alan P.NinjaTrader Customer Service

            Comment


              #7
              Originally posted by NinjaTrader_AlanP View Post
              Hello xcondor,

              If you replace,

              Dispatcher.CurrentDispatcher.InvokeAsync(() =>

              with

              Dispatcher.InvokeAsync(() =>

              Which is how the last example at the following link has it, are you able to get the text box to update?


              I look forward to your reply.
              I could not use Dispatcher.InvokeAsync(() =>
              because the SuperDOM window does not expose it. The example you refer to derives from NTTabPage. Maybe I am missing something. I even tried Application.CurrentDispatcher but it did not help either.

              Thanks

              Comment


                #8
                Hello

                Thank you for the reply.

                I tried the attached sample but I can't seem to get it to add the controls for me. I am currently seeing your print "Cannot find the 'SuperDOMControlInstrumentSelector' control" when opening a superdom so it seems to be failing on the findGrid method. Do you happen to have an updated sample that excludes the extra items you noted to comment out and works to append the controls? If there are any other specific directions to use the addon successfully could you detail the steps so I can see the same result you are?

                I also noted you are using 8.0.12.0 from the comments, before continuing further I would suggest updating to the newest release as that is what we will be testing your code with.

                I look forward to being of further assistance.
                JesseNinjaTrader Customer Service

                Comment


                  #9
                  Originally posted by NinjaTrader_Jesse View Post
                  Do you happen to have an updated sample...
                  Here is LeftDOMTest1.cs Works straight out of the box. It is just one file now. No dependencies.
                  Originally posted by NinjaTrader_Jesse View Post
                  I tried the attached sample but I can't seem to get it to add the controls for me. I am currently seeing your print "Cannot find the 'SuperDOMControlInstrumentSelector' control" when opening a superdom so it seems to be failing on the findGrid method.
                  This error means the code successfully stepped out of the findGrid method and the container grid is not null.

                  As I commented, I have not fully implemented the Cleanup(). I could not find a canned base.Cleanup(). So this down-n-dirty sample leaves stuff behind even when the window is relaunched. OnWindowDestroyed(Window) handler is a hassle and a bit of a mystery to me in this compiling model. Is it partial compiling only of the Custom bin? The open windows with addons in them sometimes keep stuff from before, and sometimes not. It is haphazard.

                  Anyway, for the production code I will implement my own dictionary<string, FrameworkElement> and unsubscribe all event handlers and remove all objects explicitly.

                  For now, best to delete/remove the prior sample, do a full recompile and restart the platform. I guarantee it works and sends real-time data to the OutputTab2.

                  The issue is the different thread. I don't know enough about threading in WPF. I hope you can suggest a workaround. This functionality is key for us to pimp out the SuperDOM to be much more suited to active trading than it currently is. I have a pretty good prototype in the works. If I could just work out the threading issue.

                  Originally posted by NinjaTrader_Jesse View Post
                  I also noted you are using 8.0.12.0 from the comments, before continuing further I would suggest updating to the newest release..
                  8.0.13 is much snappier. It did not crash when exporting. So the attached zip was generated by the platform.
                  Attached Files
                  Last edited by xcondor; 04-06-2018, 11:43 AM.

                  Comment


                    #10
                    Jesse,

                    I figured it out.

                    The SuperDOMControl does derive from NTTabPage and does have a Dispatcher public property which is in the same thread and works. IntelliSense did not show it on a var variable. So my bad.

                    There is no point in posting the sample. I will post the full prototype when finished.

                    Even if not supported, the SuperDOMControl class is exposed and available for developing. So are many other classes. So the "Language Reference" should show all the available classes and all their members. Exploring the class members solely through the IntelliSense can be misleading if either not enough namespaces are referenced or too many. It is a poor and time consuming way to learn about the API.
                    Last edited by xcondor; 04-07-2018, 08:18 AM.

                    Comment


                      #11
                      Originally posted by NinjaTrader_AlanP View Post
                      Hello xcondor,

                      Thank you for your note.

                      I have attached a sample strategy which will manage a ATM strategy submitted via a superdom.

                      Within the script you'll find instructions for how to set up the ATM and enable the strategy.

                      Please let us know if you need further assistance.
                      NinjaTrader_AlanP

                      Does this still work?

                      When I iterate over my open orders, order.GetOwnerStrategy().Name does not seem to return the ATM name, but an id: 4667fda383dc401abc2bfed82a36e36d

                      The orders were created by an ATM and the ATM is visible from the Orders tab:

                      Click image for larger version  Name:	Capture.PNG Views:	0 Size:	75.9 KB ID:	1141606

                      Code:
                      Code:
                      else if (State == State.DataLoaded)
                      {
                           foreach (Order order in Account.Orders)
                           {
                                if( order.GetOwnerStrategy() != null)
                                {
                                      Print(String.Format("Order Name: {0}, Strategy ID: {1}", order.Name, order.GetOwnerStrategy().Name));
                                }
                      }
                      Output:
                      Order Name: Entry, Strategy ID: 4667fda383dc401abc2bfed82a36e36d
                      Order Name: Stop1, Strategy ID: 4667fda383dc401abc2bfed82a36e36d
                      Order Name: Target1, Strategy ID: 4667fda383dc401abc2bfed82a36e36d
                      Order Name: Stop1, Strategy ID: 4667fda383dc401abc2bfed82a36e36d
                      Order Name: Target1, Strategy ID: 4667fda383dc401abc2bfed82a36e36d
                      Order Name: Stop2, Strategy ID: 4667fda383dc401abc2bfed82a36e36d
                      Order Name: Target2, Strategy ID: 4667fda383dc401abc2bfed82a36e36d
                      Order Name: Stop2, Strategy ID: 4667fda383dc401abc2bfed82a36e36d
                      Order Name: Target2, Strategy ID: 4667fda383dc401abc2bfed82a36e36d

                      The Strategy itself created the ATM.

                      I'm trying to figure out a way for the strategy itself to pick up any active ATM that the strategy itself created using AtmStrategyCreate().

                      The use case for this is:
                      1. Strategy has complex logic that the end-user does not have the skills to code.
                      2. User does have the ability to create ATMs, and would like to use their ATM to manage the trade once the strategy detects an entry signal.
                      3. Strategy creates user-supplied ATM "trade" via AtmStrategyCreate().
                      4. Strategy saves atmStrategyId and monitors trade via the Atm Monitoring API using the saved atmStrategyId.
                      5. If the strategy stops for whatever reason, I'm trying to re-establish the monitoring from step 4. However, I have no way to get the original atmStrategyId. Internally, ninjatrader does associate an order with the ATM that created it(see screen shot)

                      This is not a one-off situation, there are a ton of questions and requests on the forum asking the same type of questions around this hybrid type of strategy, and it seems like big pieces are already in place to do this, just need a way to tie it all together.

                      Ideally, need a way to get the current running ATMs(Atm Name), the strategy that created the ATM, and the original atmStrategyId(to use with the ATM monitoring API)




                      Last edited by michelm; 02-12-2021, 01:44 PM.

                      Comment


                        #12
                        Hello michelm,

                        Thank you for your reply.

                        GetOwnerStrategy() isn't documented, so it's behavior may change in the future, but you'd want to cast the order to an ATM to see if it's actually an ATM then get the name from it:

                        Code:
                        else if (State == State.DataLoaded)
                        {
                        foreach (Order order in Account.Orders)
                        {
                        if (order.GetOwnerStrategy() != null)
                        {
                        AtmStrategy atm = (order.GetOwnerStrategy() as AtmStrategy);
                        
                        if (atm != null)
                        Print(atm.Id + " " + atm.Name + " " + atm.Template);
                        }
                        }
                        }
                        Please let us know if we may be of further assistance to you.
                        Kate W.NinjaTrader Customer Service

                        Comment


                          #13
                          Originally posted by NinjaTrader_Kate View Post
                          Hello michelm,

                          Please let us know if we may be of further assistance to you.
                          First of all, thank you for that, it's pretty interesting.

                          Now I am able to get the orderID I used in the initial call to AtmStrategyCreate(..), it's not pretty, but yea, it's down in the ATM's entry order object.
                          However, only 1 ATM Monitoring call takes the original orderID, GetAtmStrategyEntryOrderStatus().

                          The rest of the ATM Monitoring calls expects the strategyID I used in the initial call to AtmStrategyCreate(..)
                          I can't figure out a way to get that original strategyID back to resume ATM monitoring from the strategy after a strategy restarts with an open ATM running.
                          Any ideas ?

                          I have a feeling that the strategyID is just an in-memory runtime variable that is used as a lookup index and it's not persisted and when the strategy is destroyed the strategyID is gone forever, like tears in the rain....

                          Click image for larger version

Name:	tenor (1).gif
Views:	255
Size:	18.9 KB
ID:	1142200

                          I think I might be able to roll my own ATM monitoring in the strategy using the info you provided, but if I could get hold of that strategyID, yea that would easier.


                          I do understand this is undocumented​​

                          Thanks Again

                          Comment


                            #14
                            Hello michelm,

                            Thank you for your reply.

                            Getting atm.ID in the above example would get you the actual strategy ID. However, the atmStrategyID created from GetAtmStrategyUniqueID is just a unique value that is used in the NinjaScript ATM strategy methods, so you'd have to track that on your own unfortunately.

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

                            Comment


                              #15
                              Originally posted by NinjaTrader_Kate View Post
                              Hello michelm,

                              Thank you for your reply.

                              Getting atm.ID in the above example would get you the actual strategy ID. However, the atmStrategyID created from GetAtmStrategyUniqueID is just a unique value that is used in the NinjaScript ATM strategy methods, so you'd have to track that on your own unfortunately.

                              Please let us know if we may be of further assistance to you.
                              Yea, that's what I figured


                              It would be cool to expose the collection that the Strategy uses to hold ATMs so that there is a way to re-associate an ATM with the strategy that created it.
                              So perhaps something like:
                              AddExistingATM(AtmStrategy atm, string strategyID)
                              The idea would be to grab an existing ATM, generate a new strategyID, and punch it back into the strategy to resume monitoring.
                              Another option would be to overload the ATM Monitoring Methods to take an AtmStrategy object.

                              I know this seems like a corner case, but I do get this reoccurring request to have hybrid strategies that use ATMs to manage the actual trades.

                              The ATM API is pretty cool, but this type of strategy really seems incomplete without a way to resume the strategy after a re-start. It seems like all the pieces are in place, the strategy ATM API just needs to be flushed out a little more with consideration for "sad path" handling.

                              Thanks again


                              Last edited by michelm; 02-17-2021, 11:22 AM.

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by RookieTrader, Today, 07:41 AM
                              2 responses
                              7 views
                              0 likes
                              Last Post RookieTrader  
                              Started by kujista, Today, 05:44 AM
                              2 responses
                              12 views
                              0 likes
                              Last Post kujista
                              by kujista
                               
                              Started by trilliantrader, Today, 08:16 AM
                              0 responses
                              3 views
                              0 likes
                              Last Post trilliantrader  
                              Started by AttiM, 02-14-2024, 05:20 PM
                              9 responses
                              175 views
                              0 likes
                              Last Post NinjaTrader_BrandonH  
                              Started by funk10101, Today, 08:14 AM
                              0 responses
                              2 views
                              0 likes
                              Last Post funk10101  
                              Working...
                              X