NinjaTrader Support Forum  
X

Attention!

This website will be down for maintenance from Friday May 24th at 6PM MDT until Saturday May 25th at 11AM MDT. We apologize for the inconvenience. If you need assistance during this time, please email sales@ninjatrader.com


Go Back   NinjaTrader Support Forum > NinjaScript Development Support > Strategy Development

Strategy Development Support for the development of custom automated trading strategies using NinjaScript.

Reply
 
Thread Tools Display Modes
Old 05-17-2012, 04:53 PM   #1
anachronist
Senior Member
 
Join Date: Jul 2008
Posts: 271
Thanks: 4
Thanked 7 times in 7 posts
Default Fill event misalignment in backtesting

I'm backtesting something using using the unmanaged approach, and I noticed a weird result.

If the next bar after the current bar would fill a limit order, the fill event fires off on the current bar rather than the next bar. In other words, a fill event for a limit order doesn't align with the bar that filled it.

This misalignment messes up the logic for adjusting stops and targets on the current bar if the entry order's status has already been set to Filled before it actually happens, resulting in occasional errors in the backtest results.

I got around this by delaying stoploss and target processing until the bar following the fill event (which is the bar that actually caused the fill).

If others are accounting for this misalignment in their code and NinjaTrader corrects this behavior, it might break some things.

-Alex
anachronist is offline  
Reply With Quote
Old 05-18-2012, 05:20 AM   #2
NinjaTrader_Bertrand
NinjaTrader Customer Service
 
NinjaTrader_Bertrand's Avatar
 
Join Date: Sep 2008
Location: Germany
Posts: 22,411
Thanks: 252
Thanked 976 times in 959 posts
Default

Thanks for the report Alex, I'm not aware of similiar issues seen sofar so would like to investigate with your help if possible.

Is there any way you could mask your proprietary logic and send me your script for testing to support at ninjatrader dot com Attn Bertrand?

Please include datafeed, instrument / expiry and timeframe / chart type as well.

Thanks much,
NinjaTrader_Bertrand is online now  
Reply With Quote
Old 05-18-2012, 12:04 PM   #3
anachronist
Senior Member
 
Join Date: Jul 2008
Posts: 271
Thanks: 4
Thanked 7 times in 7 posts
Default

It isn't a problem in my script. This should be easy to duplicate with a simple script. I was on a 2 minute chart of TF using a Zen-Fire data feed through Mirus Futures, with trades executed on a 20-second secondary data series.
  • Find any bar in the history that makes a significant pivot low, several ticks below the prior several bars, on both time frames.
  • Identify the bar number of this new low (I have a simple indicator that plots the value of CurrentBar on every bar, so I can view the bar number in the data window).
  • Run a simple script that places an unmanaged limit order a few bars beforehand, to buy 1 or 2 ticks above the pivot low price. e.g. if (CurrentBar==pivotbar-3) SubmitOrder(...).
  • In OnOrderUpdate(), print the primary and secondary bar numbers to the output window when the Fill event is captured. Also print the low of the current bar.
  • You will find that the low of the current bar would not fill the order, but the low of the next bar would. The bar number printed for the fill bar will be 1 bar prior to the bar that would fill the order.
I've read other messages from support staff on this forum saying that the backtesting logic looks ahead to the next bar to determine if a limit order is filled. That makes sense, but it seems that the fill event isn't delayed until the next bar but instead gets fired off as soon as a fill is detected on the next bar.

-Alex
anachronist is offline  
Reply With Quote
Old 05-21-2012, 07:18 AM   #4
NinjaTrader_Bertrand
NinjaTrader Customer Service
 
NinjaTrader_Bertrand's Avatar
 
Join Date: Sep 2008
Location: Germany
Posts: 22,411
Thanks: 252
Thanked 976 times in 959 posts
Default

Alex, thanks - so this would be different for you in a managed script, is this correct?

I would be surprised since accessing bar info in the event order / execution method would not be a valid check for your situation, since the executions in backtesting are proccessed before the bar update events.
NinjaTrader_Bertrand is online now  
Reply With Quote
Old 05-21-2012, 04:44 PM   #5
anachronist
Senior Member
 
Join Date: Jul 2008
Posts: 271
Thanks: 4
Thanked 7 times in 7 posts
Default

It is no different in a managed script.

Here's an example. TF 09-11 contract loaded from ZenFire, 2-minute bars, Default 24/7 session template, 2 days ending on 7/4/2011.
  • Place order on bar 296 (this is 08:28 Pacific time) to sell at 839.3 limit.
  • Trading halts on bar 298, the 08:30 bar (this is a holiday). Note that trading has halted without the limit order being filled (price never reached it).
  • Nevertheless, the fill event fires off on bar 298, even though price never touched it.
  • The actual fill is hours later when trading resumes, on bar 299 at 17:02.
  • Another problem observed: Even though ExitOnClose=false, the order is exited on the session close anyway. Why?
The script below prints the message:
7/4/2011 8:26:00 Entered internal PlaceOrder() method at 7/4/2011 8:26:00: BarsInProgress=0 Action=SellShort OrderType=Limit Quantity=1 LimitPrice=839.3 StopPrice=0 SignalName='test' FromEntrySignal=''
Filled on bar 298 at 839.3 where high=839 and low=838.8

Regardless of whether I use the managed or unmanaged approach, the fill event fires for 1 bar in the future, not on the bar where the order got filled.
PHP Code:

        
#region Variables
        // Parameters for TF 09-11 2 minute, Default 24/7 template, 2 days ending 7/4/2011
        
private int barNum 296// Default setting for BarNum
        
private double limitPrice 839.3// Default setting for LimitPrice
        
private IOrder entry;
        
#endregion

        
protected override void Initialize() {
            
CalculateOnBarClose true;
            
ExitOnClose false;
            
TraceOrders true;
        }

        protected 
override void OnOrderUpdate(IOrder o) {
            if (
== entry && o.OrderState == OrderState.Filled)
                Print(
"Filled on bar "+CurrentBar.ToString()+" at "+o.AvgFillPrice.ToString()+" where high="+High[0].ToString()+" and low="+Low[0].ToString());
        }

        protected 
override void OnBarUpdate() {
            if (
CurrentBar == barNum)
                
entry EnterShortLimit(0true1limitPrice"test");
        } 
Quote:
I would be surprised since accessing bar info in the event order / execution method would not be a valid check for your situation, since the executions in backtesting are proccessed before the bar update events.
That's good to know. However, it still messes things up. Notwithstanding the example above, I don't access the bar information in the OnOrderUpdate() method. I access the bar information in the OnBarUpdate() method.

The problem is that I need to check order states in OnBarUpdate(), so that I can adjust stops and targets for any positions running. The order state is being set to "Filled" and the position is created before the bar that actually fills the entry.

-Alex
Last edited by anachronist; 05-21-2012 at 04:54 PM.
anachronist is offline  
Reply With Quote
Old 05-22-2012, 04:18 AM   #6
NinjaTrader_Bertrand
NinjaTrader Customer Service
 
NinjaTrader_Bertrand's Avatar
 
Join Date: Sep 2008
Location: Germany
Posts: 22,411
Thanks: 252
Thanked 976 times in 959 posts
Default

Thanks for the clarifications Alex, this would be expected in backtesting and it would not be different for managed vs unmanaged approach how the fill simulation would work - your CurrentBar print comes from the OnOrderUpdate() and it would report the last seen state, at the point your print this CurrentBar would not have advanced as OnBarUpdate() for the next bar has not yet been called. In simulation with CalculateOnBarClose = false this should align as you expext.

For the ExitOnClose issue - so is the position exited or the order expired at session boundary? For order expiration, please try with a TIF of GTC.

http://www.ninjatrader.com/support/h...imeinforce.htm
NinjaTrader_Bertrand is online now  
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Fill trades on currect close in backtesting freewind General Programming 21 04-25-2012 08:27 AM
ProfitTarget filled on backtesting and did not fill on real scenario Fabiorp Strategy Analyzer 3 01-02-2012 11:44 AM
backtesting - historical fill processing adamus Strategy Development 5 06-21-2010 07:04 AM
Backtesting Timestamp/Order Fill Bug DanielB Version 7 Beta General Questions & Bug Reports 12 05-28-2010 09:13 PM
Fill event notification, choice of ATI interface sizeup Automated Trading 1 07-01-2007 04:08 AM


All times are GMT -6. The time now is 02:48 AM.