Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Strange behavior with Multi-Instrument and Limit Orders

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

    Strange behavior with Multi-Instrument and Limit Orders

    Hello.

    During backtesting with NT7 i discovered 2 different problems with multi-instrument strategies and LimitOrders.

    But first, here is the strategy fragment i used for reproducing the behavior. It's quite simple, for both instruments (primary and XLF) a Limit Order 3% below the close valid for one bar will be submitted.

    Code:
    public class Test_LimitOrders: Strategy
        {
    		private bool[] m_OrdersSubmitted;
    
    		protected override void Initialize()
            {
    			TraceOrders = true;
    			
    			m_OrdersSubmitted = new bool[2];
    			m_OrdersSubmitted[0] = false;
    			m_OrdersSubmitted[1] = false;
    			
    			Add("XLF", PeriodType.Day, 1);
            }
    		
    	    protected override void OnBarUpdate()
            {
    			if (m_OrdersSubmitted[BarsInProgress]) 
    			{	// Limit Order already submitted
    				return;
    			}
    			
    			EnterLongLimit(BarsInProgress, false, 100, Closes[BarsInProgress][0] * 0.97, BarsInProgress.ToString());
    			
    			m_OrdersSubmitted[BarsInProgress] = true;
    		}
    	}
    Ok, let's run this strategy for XLK as primary instrument, XLF will be the secondary. Start date is 15.02.2011, daily bars.

    Here the output:

    16.02.2011 06:00:00 Entered internal PlaceOrder() method at 16.02.2011 06:00:00: BarsInProgress=0 Action=Buy OrderType=Limit Quantity=100 LimitPrice=26,03 StopPrice=0 SignalName='0' FromEntrySignal=''

    17.02.2011 06:00:00 Cancelled expired order: BarsInProgress=0: Order='NT-00000/Backtest' Name='0' State=Working Instrument='XLK' Action=Buy Limit price=26,0348 Stop price=0 Quantity=100 Strategy='Test_LimitOrders' Type=Limit Tif=Gtc Oco='' Filled=0 Fill price=0 Token='b6a4d143d3f74f0b82b5e6a6e9fa9d80' Gtd='01.12.2099 00:00:00'

    17.02.2011 06:00:00 Entered internal PlaceOrder() method at 17.02.2011 06:00:00: BarsInProgress=1 Action=Buy OrderType=Limit Quantity=100 LimitPrice=16,65 StopPrice=0 SignalName='1' FromEntrySignal=''

    18.02.2011 06:00:00 Cancelled expired order: BarsInProgress=1: Order='NT-00001/Backtest' Name='1' State=Working Instrument='XLF' Action=Buy Limit price=16,6452 Stop price=0 Quantity=100 Strategy='Test_LimitOrders' Type=Limit Tif=Gtc Oco='' Filled=0 Fill price=0 Token='db6ae6471a454e8ca2bde1d6f4c74ea5' Gtd='01.12.2099 00:00:00'
    This is the first part of my question. Why does the secondary instrument starts with one day delay? I would expect both Limit Orders to be submitted the same day!

    Apart from that, EnterLongLimit performs as expected, the Orders are cancelled one bar later. So, let's restart again with 16.02.2011 as starting day (one day later)...

    17.02.2011 06:00:00 Entered internal PlaceOrder() method at 17.02.2011 06:00:00: BarsInProgress=0 Action=Buy OrderType=Limit Quantity=100 LimitPrice=26,18 StopPrice=0 SignalName='0' FromEntrySignal=''

    18.02.2011 06:00:00 Cancelled expired order: BarsInProgress=0: Order='NT-00000/Backtest' Name='0' State=Working Instrument='XLK' Action=Buy Limit price=26,1803 Stop price=0 Quantity=100 Strategy='Test_LimitOrders' Type=Limit Tif=Gtc Oco='' Filled=0 Fill price=0 Token='2e8928e303fa4b95af3a19d6c08e1632' Gtd='01.12.2099 00:00:00'

    18.02.2011 06:00:00 Entered internal PlaceOrder() method at 18.02.2011 06:00:00: BarsInProgress=1 Action=Buy OrderType=Limit Quantity=100 LimitPrice=16,63 StopPrice=0 SignalName='1' FromEntrySignal=''
    Same problem with the day delay but an additional one. As you can see, the LimitOrder for XLF is not cancelled one day later (19.02.), instead it's filled two days later (23.02.). Can you explain that? And it gets even more strange. When i run the same strategy with XLF as primary instrument (primary and secondary are the same then) the one day delay issue remains but an order placed on 18.02. is canceled one day later on 19.02.

    Thank you, Robin

    #2
    Hi Robin,

    This will depend on a few things:
    The time stamp of each series. The rules can be complex for what session template is used in multiseries scripts and is detailed here. See note #2 in section True Event Driven OnBarUpdate() Method

    Verify by printing and seeing how they line up when accessing within context of primary series updates:

    if (BarsInProgress == 0)
    Print("Primary Series " + Time[0] + " Secondary Series " + Times[1][0]);

    EntriesPerDirection and EntryHandlingProperties - These will limit the number of entries, as well as orders submitted in a direction, so check that these aren't restricting submission of both orders at once.

    Bars Required setting must be satisfied for all series before orders are submitted, so may want to start printing CurrentBar so you can track bar # when you're submitting orders. CurrentBar for multiple series is CurrentBars[][]

    As you can see, the LimitOrder for XLF is not cancelled one day later (19.02.), instead it's filled two days later (23.02.).
    This may be from submitting on a weekend?

    Please let us know if we can offer additional clarification here, or if it's still not working as you expect.
    Ryan M.NinjaTrader Customer Service

    Comment


      #3
      Hi Ryan,

      i added following code fragment at the beginning of OnBarUpdate():

      Code:
      Print("BarsInProgress " + BarsInProgress + "  Time[0] " + Time[0] + "  Times[1][0] " + Times[1][0] + "  CurrentBars[0] " + CurrentBars[0] + "  CurrentBars[1] " + CurrentBars[1]);
      			
      if (CurrentBars[0] <= BarsRequired || CurrentBars[1] <= BarsRequired)
      {
           Print("Return!");
           return;
      }
      Starting again on 16.02.2011, everything was kept constant as in my first post. Here the output:

      BarsInProgress 0 Time[0] 17.02.2011 06:00:00 Times[1][0] 17.02.2011 06:00:00 CurrentBars[0] 0 CurrentBars[1] 0
      Return!
      BarsInProgress 0 Time[0] 18.02.2011 06:00:00 Times[1][0] 18.02.2011 06:00:00 CurrentBars[0] 1 CurrentBars[1] 1
      18.02.2011 06:00:00 Entered internal PlaceOrder() method at 18.02.2011 06:00:00: BarsInProgress=0 Action=Buy OrderType=Limit Quantity=100 LimitPrice=26,23 StopPrice=0 SignalName='0' FromEntrySignal=''
      BarsInProgress 1 Time[0] 18.02.2011 06:00:00 Times[1][0] 18.02.2011 06:00:00 CurrentBars[0] 1 CurrentBars[1] 1
      18.02.2011 06:00:00 Entered internal PlaceOrder() method at 18.02.2011 06:00:00: BarsInProgress=1 Action=Buy OrderType=Limit Quantity=100 LimitPrice=16,63 StopPrice=0 SignalName='1' FromEntrySignal=''
      BarsInProgress 0 Time[0] 19.02.2011 06:00:00 Times[1][0] 19.02.2011 06:00:00 CurrentBars[0] 2 CurrentBars[1] 2
      19.02.2011 06:00:00 Cancelled expired order: BarsInProgress=0: Order='NT-00000/Backtest' Name='0' State=Working Instrument='XLK' Action=Buy Limit price=26,2288 Stop price=0 Quantity=100 Strategy='Test_LimitOrders' Type=Limit Tif=Gtc Oco='' Filled=0 Fill price=0 Token='5158994c9c604bd695e5d0dc2ced8a9d' Gtd='01.12.2099 00:00:00'
      BarsInProgress 1 Time[0] 19.02.2011 06:00:00 Times[1][0] 19.02.2011 06:00:00 CurrentBars[0] 2 CurrentBars[1] 2
      BarsInProgress 0 Time[0] 23.02.2011 06:00:00 Times[1][0] 23.02.2011 06:00:00 CurrentBars[0] 3 CurrentBars[1] 3
      BarsInProgress 1 Time[0] 23.02.2011 06:00:00 Times[1][0] 23.02.2011 06:00:00 CurrentBars[0] 3 CurrentBars[1] 3
      BarsInProgress 0 Time[0] 24.02.2011 06:00:00 Times[1][0] 24.02.2011 06:00:00 CurrentBars[0] 4 CurrentBars[1] 4
      BarsInProgress 1 Time[0] 24.02.2011 06:00:00 Times[1][0] 24.02.2011 06:00:00 CurrentBars[0] 4 CurrentBars[1] 4
      Actually it worked, the first call for series 0 is skipped and both instruments are synchronous. But i still do not understand why series 1 is not called on 17.02.2011.

      Regarding the correct configuration, please have a look at the attached screenshot of the strategy configuration. I think i have done nothing wrong here?!

      Relating to my second question (the LimitOrder which is not cancelled), as you can see in the Trace output above, both orders (0: XLK , 1: XLF) are submitted on 18.02., but only XLK's order is cancelled one day later. XLF is filled on 23.02. (no trading from 20-22 due to weekend + holiday).

      Before you have a look at the calendar i must admit that there is an additional problem (new with NT7, did not exist with N6.5) that there is a one day delay between NT days and "Real World" days. E.g.20-22.2. means 19-21.2. in real world (saturday, sunday, president's day). But i guess this is another problem, maybe it's because auf my time zone (CET). It's very low on my priority list of NT problems and hopefully not related with the one above...
      Attached Files

      Comment


        #4
        First item to look into here is how your session templates are defined. NinjaTrader uses your PC clock to time stamp bars, and session templates are built according to a user defined time zone. So, if the session template is defined in US time zone, and your PC clock is set to CET, NT takes this into account. It looks like there is a 1 day delay but is really the difference between the time zone defined in the session template, and the time zone of your computer clock.

        For the order not expiring, will need to look at the underlying bar data as well, and see if we are able to reproduce the same here. Can you please let us know the following: What version of NT are you using? Check with Help > About. Who are you using as a data provider? What is the session template used for these instruments? Since used in a backtest, may need to check this under Tools > Instrument Manager for these instruments.
        Ryan M.NinjaTrader Customer Service

        Comment


          #5
          Ok, the current session template is 'Default 24/7' with timezone EST. The time '06:00:00' of the trace output matches with the time delay between EST and CET. Looks like a sound explanation. I did not care about session templates until today but i will have a look into this...

          For the order not expiring:
          NT version: 7.0.1000.4
          Data provider: i used yahoo for the test
          Session template: Default 24/7 for both intruments

          Comment


            #6
            Thanks, Robin. You are a few releases behind. Can you please try this scenario using our latest release 7 and let us know if you still see.

            Ryan M.NinjaTrader Customer Service

            Comment


              #7
              I upgraded to 7.0.1000.7. Unfortunately, the limit order for xlf is still filled two days later instead of being cancelled one day later.

              Comment


                #8
                Thanks for the update. I will work on reproducing this. One issue right away is with the name of your strategy. How did you input an underscore _? This character is not allowed during the strategy creation or when saving a modified copy.

                Manually renaming the class is not advised/supported. To save any copies or change the name, always right click > Save As in the editor. I don't suspect it's contributing here but always good to eliminate unknowns.
                Ryan M.NinjaTrader Customer Service

                Comment


                  #9
                  Thank you for investigating this issue!

                  I do not use the wizard for strategy creation. Instead i start with an existing one by renaming file and class name to create new strategies efficiently.

                  Regarding the underscore, since NT does not allow sub-directories for strategy management i try to handle the chaos by using underscores for strategy namespaces for the files (and the classes also).

                  Nevertheless i just tested the strategy with a class name without underscore. As expected, the problem persists.

                  Comment


                    #10
                    Thanks for confirming. I also tested this with the details provided and can see the same thing. Unfortunately it is due to a limitation of backtesting multi instrument strategies and evaluating order fills. Fairly detailed explanation below and the exact limitation that causes the unexpected fill is highlighted:

                    In a multi-series strategy the following steps are taken on every single BIP update event:
                    1. Process pending orders
                    2. Amend stop targets
                    3. Cancel expired orders
                    4. Process backtest orders

                    This is the sequence detailed for the two instruments.
                    1st BIP0 event = send order for BIP0’s instrument
                    1st BIP1 event = process ALL orders first, then process BIP1 event’s OnBarUpdate logic which tells it to send order for BIP1’s instrument
                    - since BIP0’s instrument did not get processed to fill here based on BIP1’s prices, it continues as a Working order
                    2nd BIP0 event = process ALL orders again, then OnBarUpdate logic
                    - BIP0’s order is processed, no fill. No fill goes to next step which cancels this order because it has expired (not kept alive via code)
                    - BIP1’s order is processed,based on 2nd BIP0 event’s prices, gets filled
                    2nd BIP1 event = process ALL orders except there are no orders to process so will run the OnBarUpdate logic.
                    Ryan M.NinjaTrader Customer Service

                    Comment


                      #11
                      Hi Ryan,

                      i guess you will understand that i'm not fully satisfied with that output. It's good to see that you can reproduce this behavior. However, the question that remains is: what should i do now? Will this bug be adressed in one of the coming releases? Is there any workaround i can use till then? It's crucial for me to be able to test strategies with limit orders with one day of validity. And i cannot image that i'm the only one with such quite simple requirements?

                      Comment


                        #12
                        I understand this is not the ideal scenario. Thank you for bringing this to our attention and working through it. Development is aware of this current limitation but unfortunately it is not slated to be changed in an upcoming release. It's something we are aware of and on our list for future consideration. The only work around available is to adapt this into multiple strategies since the limitation is specific to backtesting multi-Instrument strategies.
                        Ryan M.NinjaTrader Customer Service

                        Comment

                        Latest Posts

                        Collapse

                        Topics Statistics Last Post
                        Started by Jon17, Today, 04:33 PM
                        0 responses
                        1 view
                        0 likes
                        Last Post Jon17
                        by Jon17
                         
                        Started by Javierw.ok, Today, 04:12 PM
                        0 responses
                        6 views
                        0 likes
                        Last Post Javierw.ok  
                        Started by timmbbo, Today, 08:59 AM
                        2 responses
                        10 views
                        0 likes
                        Last Post bltdavid  
                        Started by alifarahani, Today, 09:40 AM
                        6 responses
                        41 views
                        0 likes
                        Last Post alifarahani  
                        Started by Waxavi, Today, 02:10 AM
                        1 response
                        21 views
                        0 likes
                        Last Post NinjaTrader_LuisH  
                        Working...
                        X