PDA

View Full Version : OnOrderUpdate not entered for Live Market Order


OnePutt
12-09-2007, 10:15 AM
I'm using Replay and I notice that an advanced "market" order entered in OnBarUpdate doesn't drive OnOrderUpdate. I thought OnOrderUpdate would be "called everytime an order managed by a strategy changes state". Limit and Stop orders work as expected. Historical orders also work correctly. Only "live" market orders fail to drive OnOrderUpdate.

I used SampleOnOrderUpdate to display this behavior. I changed the entry to a Market order and added a Print statement to the section of code that handles entry orders in On OrderUpdate. Then add the strategy to a chart and run Replay to simulate a live market.

NinjaTrader_Josh
12-09-2007, 02:35 PM
Thanks for reporting.

NinjaTrader_Ray
12-10-2007, 08:12 AM
OnOrderUpdate() is called for market orders when connected to Market Replay. The issue you are running into is that an IOrder object returned from an EnterLong() method will have fired the OnOrderUpdate() method prior to returning an IOrder object. This exception is only in Replay since we process everything in a manner that ensures the behaviour is consistent and all events are in sync across high speed replays.

KBJ
12-10-2007, 12:02 PM
OnOrderUpdate() is called for market orders when connected to Market Replay. The issue you are running into is that an IOrder object returned from an EnterLong() method will have fired the OnOrderUpdate() method prior to returning an IOrder object. This exception is only in Replay since we process everything in a manner that ensures the behaviour is consistent and all events are in sync across high speed replays.

Let me see if I correctly understand this.

I'm interpreting this to mean that Market Replay works differently ... that when a strategy running under Market Replay issues an order (EnterLong, EnterShort, etc.) then NinjaTrader at that time simulates a fill from the market by calling OnOrderUpdate before returning control back to the user's strategy code, instead of waiting and letting this call to OnOrderUpdate occur asynchronously at a shortly later time when a packet with market fill data comes back from the broker, which would be after OnBarUpdate had completed for the current bar.

Thus, the big difference for Market Replay would be that OnOrderUpdate is being called before OnBarUpdate has been completed for the current bar.

Is my understanding correct?

If so, perhaps adding a timer to call OnOrderUpdate a nanosecond later (or just calling it after OnBarUpdate has completed) would more accurately simulate market performance.

NinjaTrader_Dierk
12-10-2007, 12:05 PM
>> Is my understanding correct?
Yes

KBJ
12-10-2007, 01:30 PM
Thank you.

Will it be possible to make the Market Replay implementation compatible (timing wise) with the other implementations by making the suggested change or something like that?

NinjaTrader_Dierk
12-10-2007, 01:33 PM
No, since will make it unusable, since it would no longer have reproducible results on different replay speeds.

KBJ
12-10-2007, 02:24 PM
Sorry to hear that, since this type of incompatibility will make Market Replay unusable for some of us.

Obviously I don't understand the internals of NinjaTrader, so my suggestions may not be workable.

However, I strongly feel that this issue should be confronted and handled.

I know that conceptually it's possible to solve this so we can have a timing-compatible interface for all strategy implementations.

I hope that you can find one that works well within the current design constraints of version 6.5 of NinjaTrader.

NinjaTrader_Dierk
12-10-2007, 02:26 PM
MarketReplay would be useless if we changed it.

OnePutt
12-10-2007, 11:29 PM
A little more research confirms what Ray said (he's always right...) about OnOrderUpdate and Replay. That is, the method is driven for all order types including Market orders. The distinction is that for a market order the object may not be created prior to calling the method. In fact, it isn't clear that an object is ever created for a Maket order. It would seem if you're interested in doing something in OnOrderUpdate for this type of order you will need to base it on the orderName and not the order object's token (as described in SampleOnOrderUpdate).

Another interesting tidbit is by changing the entry to a EnterLongLimit at the Close of the current bar the behavior of REPLAY is slightly different than an EnterLong at Market. No object is present when OnOrderUpdate is called for "Pending Submit", "Accepted", and "Working" but it is present for "Filled".

As a programmer my intent is to mirror as much as possible the behavior of a live market when I run REPLAY. The above tells me to not depend on the object (and it's token) being present for Entry Orders. I assume it will always be present for Stop and Limit orders -- at least the fills.

KBJ -- I don't really see this as a problem. I much prefer this implementation to how REPLAY worked in NT 6.0. I believe you can do whatever you need in OnOrderUpdate with or without the object being passed. If not, please explain what you need to do. Personally, I plan to use OnPositionUpdate for managing orders that can't wait until the bar is complete.

Josh -- I suggest adding some additional comments to SampleOnOrderUpdate to warn of this behavior if the entry order is Market and not Limit. It wouldn't hurt to add the "Discrepancy" to the Help Guide.

The only thing left is to run this same strategy live and see how the results may differ. Stay tuned..........

NinjaTrader_Josh
12-11-2007, 12:43 AM
Thanks for the suggestion OnePutt.

NinjaTrader_Ray
12-11-2007, 08:38 AM
I did add some text to the OnOrderUpdate() section of our Help Guide to point out the different behaviour for Market orders during replay.

As a last clarifying point...In order to make high speed replay (at any speed) possible for testing strategies, things must run synchronous otherwise you end up with race conditions where you can get different results each time and you can get orders filled 20 bars after the condition is satisfied etc... This OnOrderUpdate() issue is the cost of that.

KBJ
12-12-2007, 12:07 AM
OnePutt: I agree that this implementation is improved from 6.0. I've been busy on other projects recently and have not tried coding strategies which might have problems with the new methods, so my concerns on this are based on prior experiences with other unrelated software products which had incompatible modes of operation, and thus caused extra support problems.

My understanding of the difference is as follows:

During market replay...

OnBarUpdate runs...
it calls EnterLong
and EnterLong calls OnOrderUpdate
and EnterLong then returns to OnBarUpdate
OnBarUpdate may perform other actions
OnBarUpdate finishes running.


When the strategy is run NOT during market replay...

OnBarUpdate runs...
it calls EnterLong
and EnterLong then returns to OnBarUpdate
OnBarUpdate may perform other actions
OnBarUpdate finishes running.

then a bit later (maybe 20 bars as Ray points out) OnOrderUpdate is called

So, I guess we're OK if we always make sure if EnterLong is called from OnBarUpdate that nothing gets done after that (it immediately exits.)

But, if there is no immediate exit, this leaves the potential for trouble.

Ray: I understand the reason for not adding a timer to do this. But, there are a couple of different designs I've encountered in the past that would synchronously ensure that OnBarUpdate completes before OnOrderUpdate gets called. Depending on NinjaTrader's current implementation details, one of these techniques should eliminate the possibility of any incompatibility.

NinjaTrader_Dierk
12-12-2007, 12:48 AM
Please understand that the nature of "live" events is that they are asynchronous. Meaning they can pop in at any (!) time and your code needs to be prepared for that. Buffering live events (and replay basically is live) in the NT core to process them at a later point (after OnBarUpdate) for sure makes the problem worse.

KBJ
12-12-2007, 09:30 AM
Please understand that the nature of "live" events is that they are asynchronous. Meaning they can pop in at any (!) time and your code needs to be prepared for that. Buffering live events (and replay basically is live) in the NT core to process them at a later point (after OnBarUpdate) for sure makes the problem worse.

Thanks for explaining that.

I was under the mistaken impression that each of these methods (OnBarUpdate, OnOrderUpdate, etc.) would be run with other events blocked until each of these methods completed.

There are advantages and disadvantages of either approach, and it sounds like these are new issues which were not relevant to 6.0 and earlier.

This lack of synchronization may become a problem for strategy implementors who (perhaps) will not be experienced in thinking through the potential synchronization issues if any part of their code can be interrupted.

If "live" events can pop in at any time, how are we to synchronize if we want to update the contents of a variable in memory?

NinjaTrader_Ray
12-12-2007, 09:58 AM
That is why we make it very clear in the documentation that these new event driven methods are for advanced/experienced programmers only :).