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

Clarifications on OnPositionUpdate

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

    Clarifications on OnPositionUpdate


    Here's how I think OnPositionUpdate is supposed to work:

    A. The Quantity parameter of PositionEventArgs is supposed to be the quantity of shares in the position after the latest OnExecutionUpdate.
    B. When a share quantity of an instrument goes from 0 to X, Operation is set to Add.
    C. When a share quantity of an instrument goes from X to Y, where neither X nor Y are 0, Operation is set to Update.
    D. When a share quantity of an instrument goes from X to 0, Operation is set to Remove.
    E. Since OnPositionUpdate is not guaranteed to happen after OnExecutionUpdate, you might get a non-zero position even if the position has been closed out by a forthcoming OnExecutionUpdate.

    Question 1: Is everything I've said above correct? Am I missing anything?

    I ask b/c when using Simulated Data against AMD, my Removes all have a Quantity of 0, which is as I would expect; you get a Remove when the position is closed out. Every time, so far.

    On live on TDA against NVAX, Remove looks like it contains the number of shares that were removed to close out the trade. I.e. instead of Remove always being accompanied by a Quantity of 0, it is accompanied by the Quantity of shares sold (say 10) to close out the position. Every time, so far.

    My main theory explaining the difference is that different vendors implement the Quantity value of OnPositionUpdate differently. Like, maybe TDA is treating the Quantity parameter as a delta, while NT8 treats it as a level. That would be annoying, but not terrible if it is the same for all tickers when I'm connected to TDA.

    Question 2: Can you clarify here? Do vendors vary in how they implement the meaning or values of the OnPositionUpdate parameters (Quantity in particular)? Or am I seeing a timing artifact, as suggested in item E, above? (Timing seems unlikely though, given that behavior has been uniformly consistent so far.)

    Question 3: Can you open an enhancement request to add these clarifications to the NT8 OnPositionUpdate doc, so everyone can benefit from this discussion without a lot of searching through the forums? The current doc for OnPositionUpdate in both the Add On and Strategy sections does not explicitly state any of this and uses language to describe Quantity that could be interpreted in different ways, thus requiring people to infer and confirm through experimentation how this stuff works.

    (For instance, Strategy/OnPositionUpdate says Quantity is "An int value representing the updating quantity of a position" implying a delta, whereas Add On/Account/PositionUpdate implies in a comment "Output the new position" that the Quantity is the final updated value.)

    Thanks in advance for your help! Cheers.

    #2
    Hello carnitron,

    Thanks for your notes.

    e.Position is the currently updating position, such as e.Position.MarketPosition / e.Position.Quantity. This is not the actual position of the account.

    e.MarketPosition / e.Quantity is the actual pointed position of the account. The e.Position updates the e.MarketPosition and causes the <account>.PositionUpdate to trigger.

    Please see this forum thread where my colleague Chelsea explains a bit more about this topic: https://forum.ninjatrader.com/forum/...on#post1061172

    From the OnPositionUpdate() help guide: "Rithmic and Interactive Brokers Users: When using a NinjaScript strategy it is best practice to only work with passed by value data from OnExecution. Instances of multiple fills at the same time for the same instrument might result in an incorrect OnPositionUpdate, as sequence of events are not guaranteed due to provider API design. For an example on protecting positions with this approach, see OnExecutionUpdate()"

    Yes, I have submitted your request to the Development team to take into consideration.​​ This request is being tracked under the number SFT-1821.

    As with all feature requests, interest is tracked before implementation is considered, so we cannot offer an ETA or promise of fulfillment. If implemented, it will be noted on the Release Notes page of the Help Guide.

    Release Notes — https://ninjatrader.com/support/help...ease_notes.htm
    Brandon H.NinjaTrader Customer Service

    Comment


      #3

      Thank you for your reply Brandon. On a Sunday no less!

      Ok, I want to be crystal clear on what you are saying here.

      1. When you say e.Position is the updating position, not the actual position of the account, what do you mean exactly? Are you drawing a distinction between two Position objects? Like a Position object in the Account.Positions collection vs a Position object that represents the operation when I respond to the OnUpdatePosition() event?

      My main concern is interpreting Quantity correctly in all cases. What Quantities should I expect to see in each of these Positions?

      2. By "pointed position" do you just mean Long X shares or Short X shares? Bard and Copilot are giving me weird answers on what "pointed position" means, heh.

      FWIW, I do understand that the ground truth comes from OnExecutionUpdate and that OnPositionUpdate can be somewhat unreliable. Nevertheless, I'm trying to track and understand it as double confirmation that my account is truly flat.

      Also:

      1. If it's not too much trouble, can you directly answer Questions 1 and 2 from the first post? I phrased them specifically to get answers to those specific questions. I.e. Did I get the Add, Update and Remove behavior correct? Can vendors vary in the way they implement OnPositionUpdates? What explains the discrepancy I'm seeing between Sim and Live? I didn't get answers to any of those questions.

      (I'm not trying to be pedantic here, but I am definitely trying to get answers to those specific questions.)

      2. Thank you for logging the doc request. Just an FYI, I'm not doing it for me. I'll have my answers soon enough. I just think that for APIs this fundamental, NT owes it to the user base to explain the parameters and behavior clearly and precisely. Particularly since there appears to be nuance.
      Last edited by carnitron; 11-12-2023, 10:24 PM.

      Comment


        #4
        Also, I'm not touching e.Position ever at this point (though I did very briefly right when I got the event up until recently). I can understand why one would include it for reference in the event response, but given the multi-threading going on, I only want to look at data passed by value, which I think NT8 comments on in the doc as well. So none of my above comments have me looking at e.Position now.
        Last edited by carnitron; 11-12-2023, 09:12 PM.

        Comment


          #5
          Hello carnitron,

          Thanks for your notes.

          e.Position is the currently updating position. For example, e.Position.Quantity.

          The particular position update would be e.Quantity.

          The order of position events is not guaranteed, however, OnPositionUpdate() is typically called after OnExecutionUpdate() as noted in the help guide. The order of position events can change depending on the broker being used.

          From the OnPositionUpdate() help guide page:
          • This method is typically called after OnExecutionUpdate()
          • OnPositionUpdate() will update with PositionUpdates that are filtered for the strategy. The strategy Position object is driven by Executions, and is updated as early as OnExecutionUpdate()
          The operations are not documented in the help guide but what you described may be what they represent. The operations are not something that is passed into OnPositionUpdate() as a parameter.

          If you want the actual position of the account, use e.Quantity.

          OnPositionUpdate(): https://ninjatrader.com/support/help...tionupdate.htm

          That said, Using OnPositionUpdate() is for the purpose of using passed in variables for that position update. If you are using Position or any other script level variables, those likely will not be in the correct state when OnPositionUpdate() is called.

          Depending on your goal, you likely would not need to use OnPositionUpdate() if you are trying to drive logic based on the position. This would be better to do in OnBarUpdate(), OnExecutionUpdate() or OnOrderUpdate() depending on the broker being used.

          We would not be able to answer your question about what vendors do because we do not have their code. We are only able to explain how the override is described to work in the help guide.

          This forum thread will be open for other community members to share their insights on what they specifically do in their code.​
          Brandon H.NinjaTrader Customer Service

          Comment

          Latest Posts

          Collapse

          Topics Statistics Last Post
          Started by fx.practic, 10-15-2013, 12:53 AM
          5 responses
          5,406 views
          0 likes
          Last Post Bidder
          by Bidder
           
          Started by Shai Samuel, 07-02-2022, 02:46 PM
          4 responses
          98 views
          0 likes
          Last Post Bidder
          by Bidder
           
          Started by DJ888, Yesterday, 10:57 PM
          0 responses
          8 views
          0 likes
          Last Post DJ888
          by DJ888
           
          Started by MacDad, 02-25-2024, 11:48 PM
          7 responses
          160 views
          0 likes
          Last Post loganjarosz123  
          Started by Belfortbucks, Yesterday, 09:29 PM
          0 responses
          9 views
          0 likes
          Last Post Belfortbucks  
          Working...
          X