Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Inconsistency in Unrealized PnL Updates Relative to Market Price Changes

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

  • Aviram Y
    replied
    This is what i used exactly haha, thanks!

    Leave a comment:


  • NinjaTrader_ChelseaB
    replied
    Hello Aviram Y,

    Below is a link to an example of a BarsRequest you may find helpful.

    Leave a comment:


  • Aviram Y
    replied
    Originally posted by Aviram Y View Post
    Hi NinjaTrader_ChelseaB

    I’m following up on my earlier discussions regarding challenges with unrealized PnL updates and their synchronization with market movements. I've encountered a persistent issue with subscribing to real-time market data using BarsRequest, which is critical for implementing local PnL calculations as previously discussed.

    I have used the following documentation for the logic: https://ninjatrader.com/support/help...arsrequest.htm

    The Issue: Despite various attempts to fetch and subscribe to market data using BarsRequest for instruments, I consistently receive an error indicating that "The given key was not present in the dictionary," accompanied by an "ErrorCode: Panic". This occurs even after validating the instrument’s availability and trying multiple retrieval methods:
    1. Direct use of the passed Instrument object.
    2. Fetching the instrument using Instrument.GetInstrument(instrument.FullName).
    3. Fetching the instrument using Instrument.GetInstrument(instrument.MasterInstrume nt.Name).

    Each method fails to prevent the error during the subscription request. Here's a condensed version of the code used to manage subscriptions:

    First the OnPositionUpdate event handler used to call the method:
    Code:
    public void OnPositionUpdate(object sender, PositionEventArgs e, Account account)
    {
    Print($"MarketPosition: {e.MarketPosition}, Operation: {e.Operation}, Quantity: {e.Quantity}, Instrument: {e.Position.Instrument.FullName}");
    
    if (e.MarketPosition != MarketPosition.Flat && e.Operation == Operation.Add)
    {
    // Subscribe to market data when a new position is added or an existing position is modified but not closed
    EnsureMarketDataSubscription(e.Position.Instrument);
    
    }
    else if (e.MarketPosition == MarketPosition.Flat)
    {
    // consider unsubscribing from market data if applicable
    
    ConsiderMarketDataUnsubscription(e.Position.Instrument);
    
    }
    }​
    Then the code handling the subscription:
    Code:
    private void EnsureMarketDataSubscription(Instrument passedInstrument)
    {
    var activeBarsRequests = new Dictionary<string, BarsRequest>(); // Simulated active requests dictionary for context
    
    Instrument validInstrument = Instrument.GetInstrument(passedInstrument.FullName);
    if (validInstrument == null)
    {
    Print("Instrument retrieval failed. Unable to subscribe to market data.");
    return;
    }
    
    if (!activeBarsRequests.ContainsKey(validInstrument.FullName))
    {
    var barsRequest = new BarsRequest(validInstrument, DateTime.Now.AddMinutes(-30), DateTime.Now)
    {
    BarsPeriod = new BarsPeriod { BarsPeriodType = BarsPeriodType.Tick, Value = 1 },
    TradingHours = TradingHours.UseInstrumentSettingsInstance
    };
    
    barsRequest.Update += OnBarUpdate;
    barsRequest.Request((bars, errorCode, errorMessage) =>
    {
    if (errorCode != ErrorCode.NoError)
    {
    Print($"Error requesting bars for {validInstrument.FullName}: {errorMessage}, ErrorCode: {errorCode}");
    }
    else
    {
    Print($"Successfully subscribed to market data for {validInstrument.FullName}");
    activeBarsRequests[validInstrument.FullName] = barsRequest;
    }
    });
    }
    else
    {
    Print($"Already subscribed to {validInstrument.FullName}");
    }
    }
    
    private void OnBarUpdate(object sender, BarsUpdateEventArgs e)
    {
    // Handling bar updates
    }
    ​
    Questions:
    • Are there known issues with BarsRequest that could lead to such errors, particularly with certain instruments or configurations?
    • Could the "ErrorCode: Panic" provide specific insights into what might be going wrong?
    • Are there alternative approaches within NinjaTrader to ensure more reliable real-time data subscriptions that I might consider?
    What am i missing?

    Thank you in advance for any help or insights you can offer!

    Best regards, Aviram Y.
    The issue was the trading hours, i now use the passed instrument like so and it works great:
    barsRequest.TradingHours = instrument.MasterInstrument.TradingHours;

    Leave a comment:


  • Aviram Y
    replied
    Hi NinjaTrader_ChelseaB

    I’m following up on my earlier discussions regarding challenges with unrealized PnL updates and their synchronization with market movements. I've encountered a persistent issue with subscribing to real-time market data using BarsRequest, which is critical for implementing local PnL calculations as previously discussed.

    I have used the following documentation for the logic: https://ninjatrader.com/support/help...arsrequest.htm

    The Issue: Despite various attempts to fetch and subscribe to market data using BarsRequest for instruments, I consistently receive an error indicating that "The given key was not present in the dictionary," accompanied by an "ErrorCode: Panic". This occurs even after validating the instrument’s availability and trying multiple retrieval methods:
    1. Direct use of the passed Instrument object.
    2. Fetching the instrument using Instrument.GetInstrument(instrument.FullName).
    3. Fetching the instrument using Instrument.GetInstrument(instrument.MasterInstrume nt.Name).

    Each method fails to prevent the error during the subscription request. Here's a condensed version of the code used to manage subscriptions:

    First the OnPositionUpdate event handler used to call the method:
    Code:
            public void OnPositionUpdate(object sender, PositionEventArgs e, Account account)
            {
                Print($"MarketPosition: {e.MarketPosition}, Operation: {e.Operation}, Quantity: {e.Quantity}, Instrument: {e.Position.Instrument.FullName}");
            
                if (e.MarketPosition != MarketPosition.Flat && e.Operation == Operation.Add)
                {
                    // Subscribe to market data when a new position is added or an existing position is modified but not closed
                    EnsureMarketDataSubscription(e.Position.Instrument);
                    
                }
                else if (e.MarketPosition == MarketPosition.Flat)
                {
                    // consider unsubscribing from market data if applicable
                    
                    ConsiderMarketDataUnsubscription(e.Position.Instrument);
                    
                }
            }​
    Then the code handling the subscription:
    Code:
    private void EnsureMarketDataSubscription(Instrument passedInstrument)
    {
        var activeBarsRequests = new Dictionary<string, BarsRequest>(); // Simulated active requests dictionary for context
    
        Instrument validInstrument = Instrument.GetInstrument(passedInstrument.FullName);
        if (validInstrument == null)
        {
            Print("Instrument retrieval failed. Unable to subscribe to market data.");
            return;
        }
    
        if (!activeBarsRequests.ContainsKey(validInstrument.FullName))
        {
            var barsRequest = new BarsRequest(validInstrument, DateTime.Now.AddMinutes(-30), DateTime.Now)
            {
                BarsPeriod = new BarsPeriod { BarsPeriodType = BarsPeriodType.Tick, Value = 1 },
                TradingHours = TradingHours.UseInstrumentSettingsInstance
            };
    
            barsRequest.Update += OnBarUpdate;
            barsRequest.Request((bars, errorCode, errorMessage) =>
            {
                if (errorCode != ErrorCode.NoError)
                {
                    Print($"Error requesting bars for {validInstrument.FullName}: {errorMessage}, ErrorCode: {errorCode}");
                }
                else
                {
                    Print($"Successfully subscribed to market data for {validInstrument.FullName}");
                    activeBarsRequests[validInstrument.FullName] = barsRequest;
                }
            });
        }
        else
        {
            Print($"Already subscribed to {validInstrument.FullName}");
        }
    }
    
    private void OnBarUpdate(object sender, BarsUpdateEventArgs e)
    {
        // Handling bar updates
    }
    ​
    Questions:
    • Are there known issues with BarsRequest that could lead to such errors, particularly with certain instruments or configurations?
    • Could the "ErrorCode: Panic" provide specific insights into what might be going wrong?
    • Are there alternative approaches within NinjaTrader to ensure more reliable real-time data subscriptions that I might consider?
    What am i missing?

    Thank you in advance for any help or insights you can offer!

    Best regards, Aviram Y.

    Leave a comment:


  • Aviram Y
    replied
    Thanks for the quick reply, your services are much appreciated! i will update if i need anything else.

    Best, Aviram Y.

    Leave a comment:


  • NinjaTrader_ChelseaB
    replied
    Hello Aviram Y,

    Yes, that would be correct. You would need data feeds streaming data for each instrument to make these calculations as the price changes for each instrument.
    Yes, you would be comparing the number of ticks from the entry price multiplied by the point value.
    Yes, you would need to adjust the average position price as new entries are made.
    Yes, you would need to add up the calculated pnl of each instrument (number of ticks by point value).

    Leave a comment:


  • Aviram Y
    replied
    Understood. To calculate the unrealized PnL locally and more promptly, would this approach necessitate subscribing to price data feeds for each individual instrument involved in open positions? Would I then compute the unrealized PnL by comparing the entry price with the current market price?

    For position updates, such as increasing the size of an open position, would I need to continuously adjust the calculation based on the new average fill price for these updated positions against the current market price?

    Does implementing this local calculation also require converting price movements into currency values for each specific instrument, particularly considering different tick sizes and value per tick across various instruments?

    Leave a comment:


  • NinjaTrader_ChelseaB
    replied
    Hello Aviram Y,

    The information coming from the account can have a small delay as it takes a small amount of time for the account value to change on the brokerage servers and then for this information to be sent to the subscribing client, that message is then processed and the account values are updated in NinjaTrader.

    You could choose to calculate the unrealized pnl based on the entry price and the current price all locally which would be a bit faster than waiting on update messages from the brokerage.

    Leave a comment:


  • Inconsistency in Unrealized PnL Updates Relative to Market Price Changes

    Hi everyone,

    I'm currently developing an add-on that uses the AccountItemUpdate event to manage trading restrictions based on unrealized PnL changes. I've subscribed to the AccountItemUpdate event as follows:

    Code:
    account.AccountItemUpdate += (sender, e) => eventHandlers.OnAccountItemUpdate(sender, e);
    In the event handler, I am monitoring unrealized PnL to apply trading restrictions based on certain conditions (e.g., exceeding a loss threshold). However, I've noticed an issue where the unrealized PnL updates provided through this event do not always seem to align closely with the actual market price movements observed on the chart. There appears to be a delay or inconsistency in how quickly these PnL updates reflect the current market conditions.

    Here’s what I am observing:
    • When a significant price movement occurs, the corresponding update to unrealized PnL seems delayed or does not occur as frequently as I would expect based on the price volatility at the time.
    • This delay affects the responsiveness of my trading restrictions, potentially impacting the effectiveness of the strategy, especially in fast-moving markets.

    I'm curious if anyone else has encountered similar issues or if there are known limitations or settings within NinjaTrader that might affect the frequency and timing of these updates. Any insights into how unrealized PnL calculations are triggered and whether there are ways to optimize or better synchronize this with real-time market data would be greatly appreciated.

    Thank you in advance for your help and suggestions!

Latest Posts

Collapse

Topics Statistics Last Post
Started by kujista, 04-25-2023, 02:22 AM
5 responses
66 views
0 likes
Last Post bltdavid  
Started by KaizenNU, Today, 06:28 PM
0 responses
9 views
0 likes
Last Post KaizenNU  
Started by bertochi, Today, 05:25 PM
0 responses
14 views
0 likes
Last Post bertochi  
Started by ntbone, 02-12-2025, 01:51 AM
4 responses
27 views
0 likes
Last Post ntbone
by ntbone
 
Started by XanderT, Today, 03:38 PM
4 responses
13 views
0 likes
Last Post XanderT
by XanderT
 
Working...
X