Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Multi-Instrument sync issue / bug

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

    Multi-Instrument sync issue / bug

    Hi,

    I am working on a multi-instrument trading strategy that will use the simple 1:1 crack spread as its price input as follows:

    Code:
    CrackClose[0] = 42 * Closes[1][0] - Closes[0][0];
    where BarsArray[1] = RB 10-16 in this case.

    I have made a simple Indicator (attached) that calculates the spread using above formula and happily runs with Calculate.OnPriceChange on a 15 min chart and updates the spread in real time. The values I see usually fall between the Bid-Ask as given by the TWS Intermarket Spread RB.CL OCT'16, which is as expected.

    If I then set this indicator to Calculate.OnBarClose and let it run in real-time for a few 15min bars, the values it produces no longer match those from TWS. To add to the confusion, when I refresh the chart, the plot values that were built in real-time magically change and appear to again match those from TWS!

    I am guessing this is a simple sync issue between the two instruments at bar close and not a bug, but I have no idea how to correct for this to ensure the correct spread value is available at the close of a 15MIN bar for a Strategy input...

    Any help highly appreciated!

    Thanks.

    Im running B12 with IB data feed using TWS (latest).
    Attached Files

    #2
    Hello ours_solaire,

    I've started looking into this by adding prints to your script to debug the code.

    Code:
    Print(string.Format("\r\n{0} | Closes[0][0]: {1} | Opens[0][0]: {2} | Highs[0][0]: {3} | Lows[0][0]: {4}", Times[0][0], Closes[0][0], Opens[0][0], Highs[0][0], Lows[0][0]));
    Print(string.Format("{0} | Closes[1][0]: {1} | Opens[1][0]: {2} | Highs[1][0]: {3} | Lows[1][0]: {4}", Times[1][0], Closes[1][0], Opens[1][0], Highs[1][0], Lows[1][0]));
    Print(string.Format("{0} | Close: {1} | Open: {2} | High: {3} | Low: {4}", Times[0][0], CrackClose[0], CrackOpen[0], CrackHigh[0], CrackLow[0]));
    What I am finding is, the last price update does not match the close price of that minute bar.

    I appreciate your patience while I look further into this.
    Chelsea B.NinjaTrader Customer Service

    Comment


      #3
      Hi Chelsea,

      Thank for looking into this issue. Have you made any progress?

      I have tried a workaround by running the strategy with Calculate.OnPriceChange and putting the entry logic inside an if(IsFirstTickOfBar) condition, my thinking being that in using a historical bar to check for the entry condition I would avoid the price discrepancy, but unfortunately the problem remains - all the 15MIN bars that are built in realtime are affected.

      Could it be that at the instant the Crack is calculated at Bar Close, the value of Closes[1][0] is sometimes outdated (i.e. it's using the previous value) on a more or less random basis, depending on which of the two price changes occurs last? Just a theory..

      Comment


        #4
        Hi ours_solaire,

        What is happening is that in real-time, the RB does not have a value (as this does not have as much activity as the CL) by the time the CL updates.

        This means that when the primary bar closes, the index of the secondary is 1 bar ago.

        When the script is reloaded, NinjaTrader is no longer loading the data in the order the ticks were received, but is now loading them by the timestamp of bar as only the Time, Open, High, Low, and Close are known of that bar. The index of the secondary series is 0 bars ago.

        Adding prints to the script allows us to see this:

        In real-time:
        Code:
        if (State == State.Realtime && IsFirstTickOfBar)
        {
        	Print(string.Format( "\r\n{0} | BIP0 | Close: {1} | Open: {2} | High: {3} | Low: {4}", Times[0][1], Closes[0][1], Opens[0][1], Highs[0][1], Lows[0][1] ));
        	Print(string.Format( "{0} | BIP1 | Close: {1} | Open: {2} | High: {3} | Low: {4}", Times[1][1], Closes[1][1], Opens[1][1], Highs[1][1], Lows[1][1] ));
        	Print(string.Format( "{0} | {1} | CrackClose: {2} | CrackOpen: {3} | CrackHigh: {4} | CrackLow: {5}", Times[0][1], Times[1][1], CrackClose[1], CrackOpen[1], CrackHigh[1], CrackLow[1]));
        }
        8/16/2016 10:30:00 PM | BIP0 | Close: 46.3 | Open: 46.35 | High: 46.36 | Low: 46.29
        8/16/2016 10:15:00 PM | BIP1 | Close: 1.4011 | Open: 1.4011 | High: 1.4011 | Low: 1.4011
        8/16/2016 10:30:00 PM | 8/16/2016 10:15:00 PM | CrackClose: 12.53 | CrackOpen: 12.48 | CrackHigh: 12.54 | CrackLow: 12.46
        Historically:
        Code:
        else if (State == State.Historical)
        {
        	Print(string.Format( "\r\n{0} | BIP0 | Close: {1} | Open: {2} | High: {3} | Low: {4}", Times[0][0], Closes[0][0], Opens[0][0], Highs[0][0], Lows[0][0]));
        	Print(string.Format( "{0} | BIP1 | Close: {1} | Open: {2} | High: {3} | Low: {4}", Times[1][0], Closes[1][0], Opens[1][0], Highs[1][0], Lows[1][0] ));
        	Print(string.Format( "{0} | {1} | CrackClose: {2} | CrackOpen: {3} | CrackHigh: {4} | CrackLow: {5}", Times[0][0], Times[1][0], CrackClose[0], CrackOpen[0], CrackHigh[0], CrackLow[0]));
        }
        8/16/2016 10:30:00 PM | BIP0 | Close: 46.3 | Open: 46.35 | High: 46.36 | Low: 46.29
        8/16/2016 10:30:00 PM | BIP1 | Close: 1.4007 | Open: 1.4006 | High: 1.4007 | Low: 1.4004
        8/16/2016 10:30:00 PM | 8/16/2016 10:30:00 PM | CrackClose: 12.53 | CrackOpen: 12.48 | CrackHigh: 12.54 | CrackLow: 12.46

        So, I would suggest that instead of processing during BarsInProgress 0 (the primary) I would suggest updating in BarsInProgress 1 (the secondary). Then add additional code so that if an entire bar of the primary goes by without any update to the secondary, then have the plot value of the previous bar copied to the current bar.
        Chelsea B.NinjaTrader Customer Service

        Comment


          #5
          Thanks for the clarification Chelsea. Makes sense. I think I have an alternative solution that uses GetCurrentBid() and GetCurrentAsk() in order to get a midprice for RB on the close of the Primary bar. As long as the spread isnt too wide, this gives a good up to date value for the spread in real time.

          Comment

          Latest Posts

          Collapse

          Topics Statistics Last Post
          Started by terkk, Today, 01:16 PM
          1 response
          10 views
          0 likes
          Last Post NinjaTrader_Heath  
          Started by TraderElegante, Today, 12:14 PM
          1 response
          12 views
          0 likes
          Last Post NinjaTrader_PaulH  
          Started by dgee949, Today, 11:44 AM
          1 response
          13 views
          0 likes
          Last Post NinjaTrader_JustinD  
          Started by NinjaTrader_Kate, Today, 12:01 PM
          0 responses
          16 views
          0 likes
          Last Post NinjaTrader_Kate  
          Started by efeuvejota01, Today, 11:42 AM
          2 responses
          25 views
          0 likes
          Last Post efeuvejota01  
          Working...
          X