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

Pair Trading: timing of bar close for 2 dataseries

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

    Pair Trading: timing of bar close for 2 dataseries

    Testing a pair trading strategy for long one short other one on same bar close. I only issue buy/sell orders to both instruments when BarsInProgress == 0.
    If i run it strategy and it takes positions, often when i refresh it, the positions change.

    I think this is because of micro timing differences in the bar close of primary series vs the secondary series which impacts the assessment of indicators, rules or, any entry criteria, which is supposed to be based on the closing price of both data series instantly. This is the result we see in the back tests.. but in live trading it goes out of wack.

    Example if strategy runs OnBarUpdate, on 60min timeframe and BarsInProgress == 0, there is no guarantee that Ratio = Closes[0][0] / Closes[1][0] is based on the latest hourly candle that closed at 2pm. in fact it seems to often take 2pm value for primary series and 1pm value for secondary, and trade. then if you refresh the strat at say 2:01PM the net strategy positions suddenly looks different.

    Am i correct to consider this is the reason for my issue? What is the solution for this?

    Thanks








    #2
    Hello madb123,

    Thanks for your post.

    What version of NinjaTrader are you using? Please provide the entire version number. This can be found under Help -> About (Example: 8.?.?.?)

    Is the added secondary series in your script also a 60-minute series? How exactly are you defining the AddDataSeries() call in your script?

    When you mention you 'refresh the strat' are you referring to right-clicking on the chart and selecting 'Reload NinjaScript'?

    Is the strategy set to run using Calculate mode Calculate.OnBarClose?

    Could you provide a screenshot demonstrating the behavior in question?
    • To send a screenshot with Windows 10 or newer I would recommend using the Windows Snipping Tool.
    • Alternatively to send a screenshot press Alt + PRINT SCREEN to take a screenshot of the selected window. Then go to Start--> Accessories--> Paint, and press CTRL + V to paste the image. Lastly, save it as a jpeg file and send the file as an attachment.
    We look forward to assisting further.
    Brandon H.NinjaTrader Customer Service

    Comment


      #3
      Hi brandon, thanks for the reply.

      - Ninja version: 8.1.2.1 64-bit
      - second data series is also 60 minute. i use: AddDataSeries(Symbol2, Data.BarsPeriodType.Minute, BarsPeriod.Value, Data.MarketDataType.Last); in State.Configure.
      - by refresh strat i mean disabling and reenabling the strategy from the strategy window. I've seen the same issue when i press F5 on the chart as well.
      - strategy running with Calculate.OnBarClose
      - additionally im using 5000 days of data loaded


      Regarding screenshot its hard to capture, i have to check try every hour. But basically after every hour candle closes, if a position is taken, or already open. and i then disable the strategy and re-enable it, the position may or may not be there anymore or may be different. Happens often.

      Is there a micro timing difference between candle closes of various BarsInProgress that ninjatrader might be missing?

      Thanks

      Comment


        #4
        Hello madb123,

        Thanks for your notes.

        I see you are dynamically calling AddDataSeries() in the script which is not supported. All values must be hardcoded into the AddDataSeries() method including the instrument parameter and BarsPeriod.

        From the AddDataSeries() help guide page:

        "Arguments supplied to AddDataSeries() should be hardcoded and NOT dependent on run-time variables which cannot be reliably obtained during State.Configure (e.g., Instrument, Bars, or user input). Attempting to add a data series dynamically is NOT guaranteed and therefore should be avoided.​"

        AddDataSeries(): https://ninjatrader.com/support/help...dataseries.htm

        Please modify the AddDataSeries() method so that all values are hardcoded into the method and test to see if the behavior persists.

        For example, the AddDataSeries() code might look something like:

        Code:
        if (State == State.Configure)
        {
            AddDataSeries("ES 03-24", BarsPeriodType.Minute, 60, MarketDataType.Last);
        }
        Further, being able to resume the position created by your strategy after disabling/re-enabling the strategy would require changing the Start Behavior to Immediately Submit when it is re-enabled.

        Immediately Submit will try to match any active orders that were made by the strategy. Immediately Submit automatically submits working orders from when the strategy processed historical data, and assumes the strategy position and account position are where you want it when you enable the strategy. This is typically used to have a strategy resume a position after disabling/enabling. If the strategy already had live orders running, the orders will resume with the new enablement of the strategy if they match the historically calculated orders. If the orders calculated from historical data do not match the live working orders, the live working orders will be cancelled and replaced by those calculated from historical data.

        See this help guide page for more information about Immediately Submit Start Behavior: https://ninjatrader.com/support/help..._positions.htm
        ​​

        Please let us know if we may assist further.​
        Brandon H.NinjaTrader Customer Service

        Comment


          #5
          well thanks, but thats not the reason and doesnt help. Like i said the difference comes in during LIVE trading.
          I changed anyway the AddDataSeries to fully static and just had the same issue recurring.

          The question is:
          Is there a micro timing difference between candle closes of various BarsInProgress in ninjatrader? even if both are 60min candles? is there a way to handle and wait for both bars to close?


          Comment


            #6
            Hello madb123,

            Thanks for your notes.

            What you have described would be correct. Since you are using two different instruments in Realtime data, the OnBarUpdate() events will not happen at the same exact time so submitting orders to both instruments from BarsInProgress 0 could end up showing they filled in the same bar right now but when you reload the script, historical processing will take over and that same trade will likely be different due to historical data.

            Historical Order Backfill Logic: https://ninjatrader.com/support/help...fill_logic.htm
            Understanding Historical Fill Processing: https://ninjatrader.com/support/help...ical_fill_.htm

            Something you could consider trying would be to add a secondary 1-Tick series for each instrument and submit orders to the 1-Tick series to make the historical order fill more granular, however, the trades may still be different due to the times that the markets hit certain prices and closed bars.
            Brandon H.NinjaTrader Customer Service

            Comment


              #7
              Hi Brandon,
              thanks a lot, but changing to ontick submission/calculation would change things fundamentally and need to continue submitting orders On Bar Close.

              I'm thinking to add the secondary as Tick and then run all the code only when BarsInProgress == 0.
              If i do this what will be the result of a code like:
              Ratio = Closes[0][0] / Closes[1][0]

              - is Ratio going to be last close price for primary data series divided by most recent tick price for data series 2?
              - is it going to be the same result for Ratio value live trading and in historical?

              Thanks,

              Edit: im assuming Ratio[0] value will then be different (live vs historical) on reload only if BarsInProgress == 1 closed with a different new tick.. and i can live with that. please let me know if this is the expected case and i will try it.
              Last edited by madb123; 02-21-2024, 02:27 AM.

              Comment


                #8
                Hello madb123,

                Thanks for your notes.

                If the secondary series is a 1-Tick series instead of a 60-minute series and you are using Calculate.OnBarClose, Closes[0][0] would refer to the close price of the most recently closed bar on the primary series and Closes[1][0] would refer to the close price of the most recently closed bar for the 1-Tick secondary series.

                So Ratio would be the Close price of the most recently closed bar for the primary series divided by the close price of the most recently close bar for the 1-Tick secondary series.

                You could add debugging prints to your script that print out the Time of the primary and secondary series, Closes[0][0], and Closes[1][0] to see exactly how those values are evaluating in your script.

                For example, if we print out the Time of both series, Closes[0][0], and Closes[1][0] in BarsInProgress 0 we can see that Closes[0][0] is returning the close price of the most recently closed bar for the primary series and Closes[1][0] is returning the close price of the most recently closed bar of the 1-tick series when BarsInProgress 0 processes.

                When testing this on a 1-Minute Chart with the ES 03-24 as the primary series and the NQ 03-24 as the 1-Tick secondary series the Output looks something like this:

                Historically calculated values:

                Time BIP0: 2/21/2024 10:05:00 AM Closes[0][0]: 4984
                Time BIP1: 2/21/2024 10:04:59 AM Closes[1][0]: 17522.75


                Enabling NinjaScript strategy 'AddedSeriesBIPTest/315756022' : On starting a real-time strategy - StartBehavior=WaitUntilFlat EntryHandling=All entries EntriesPerDirection=1 StopTargetHandling=Per entry execution ErrorHandling=Stop strategy, cancel orders, close positions ExitOnSessionClose=True / triggering 30 seconds before close SetOrderQuantityBy=Strategy ConnectionLossHandling=Recalculate DisconnectDelaySeconds=10 CancelEntriesOnStrategyDisable=False CancelExitsOnStrategyDisable=False Calculate=On bar close IsUnmanaged=False MaxRestarts=4 in 5 minutes

                Realtime values:

                Time BIP0: 2/21/2024 10:06:00 AM Closes[0][0]: 4982.5
                Time BIP1: 2/21/2024 10:05:59 AM Closes[1][0]: 17517.25
                Brandon H.NinjaTrader Customer Service

                Comment


                  #9
                  thanks, I will give this a try.
                  But hoping for a more elegant solution than having to bring in tick data, or maybe anybody on the forum might contribute other ideas.
                  Ideally would be able to evaluate at the close of both bars.

                  Comment

                  Latest Posts

                  Collapse

                  Topics Statistics Last Post
                  Started by Shai Samuel, 07-02-2022, 02:46 PM
                  4 responses
                  93 views
                  0 likes
                  Last Post Bidder
                  by Bidder
                   
                  Started by DJ888, Yesterday, 10:57 PM
                  0 responses
                  6 views
                  0 likes
                  Last Post DJ888
                  by DJ888
                   
                  Started by MacDad, 02-25-2024, 11:48 PM
                  7 responses
                  158 views
                  0 likes
                  Last Post loganjarosz123  
                  Started by Belfortbucks, Yesterday, 09:29 PM
                  0 responses
                  7 views
                  0 likes
                  Last Post Belfortbucks  
                  Started by zstheorist, Yesterday, 07:52 PM
                  0 responses
                  7 views
                  0 likes
                  Last Post zstheorist  
                  Working...
                  X