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!
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
NinjaTrader
Tick Replay
Collapse
X
-
Tick Replay
In NT 8.0.0.9, I would like Tick Replay to be on during historical data, but off when real-time (so that I get Market Data Types Bid and Ask as well as Last). I am brand new here and I am a little fuzzy about what data I am receiving in these states, so please give as much detail as you like. I believe I am getting only Last data when Tick Replay is on (regardless of state). I have found some discrepancies when looking at NTs Volume Profile indicator in Tick Replay or No Tick Replay. It seems the Bid and Ask volume decision can be different in the two modes. I have seen orders coming in where the bid and ask price were the same, so the order could be classified incorrectly (should never happen). I have an NT Continuum feed. I only looked into this because it seemed odd that the Volume Profile indicator would use two different ways for deciding if the order was bid or ask based on the state of Tick Replay. Why? Thanks for your help.Last edited by nedlloyd; 03-07-2016, 01:02 PM.Tags: None
-
Hello nedlloyd,
Thank you for writing in.
Tick Replay is a property that can be optionally enabled on NinjaScript indicators and strategies which will ensure that the market data (bid/ask/last) that went into building a bar is loaded in the exact sequence of market data events.
Having Tick Replay enabled on your chart should not be affecting your live data.
I would suggest taking a look at the following two links below for further information about Tick Replay and utilizing it in your scripts:
Tick Replay events only occur on the "Last" market data type, so to check for ask and bid...
Code:protected override void OnMarketData(MarketDataEventArgs marketDataUpdate) { if(marketDataUpdate.MarketDataType == MarketDataType.Last) { Print(marketDataUpdate.Ask); Print(marketDataUpdate.Bid); } }
As the volume profile indicator works on real-time data, the historical bars on your Tick Replay chart are essentially "real-time" and builds the volume profile indicator output. With Tick Replay off, it is only running on that current real-time data.Zachary G.NinjaTrader Customer Service
-
Thank you for your response. If I run the following code:
Code:protected override void OnMarketData(MarketDataEventArgs marketDataUpdate) { if (marketDataUpdate.MarketDataType == MarketDataType.Last) { if (marketDataUpdate.Bid == marketDataUpdate.Ask) Print(marketDataUpdate.ToString()); } }
instrument='CL 04-16 Nymex' type=Last price=31.92 volume=1 time=2/24/2016 12:04:11 PM bid=31.92 ask=31.92 isReset=False
Now, since Volume Profile is making a decision like this: (logic here seems weird, but I could be missing something)
Code:[COLOR=Blue] if (Bars.IsTickReplay)[/COLOR] { if (e.MarketDataType == MarketDataType.Last) { if (e.Price >= e.Ask) askPrice = e.Price; else if (e.Price <= e.Bid) bidPrice = e.Price; price = e.Price; volume = e.Volume; if (!cacheDictionary.ContainsKey(price)) cacheDictionary.Add(price, new VolumeInfoItem()); volumeInfoItem = cacheDictionary[price]; if (price >= askPrice) volumeInfoItem.up += volume; else if (price <= bidPrice) volumeInfoItem.down += volume; else volumeInfoItem.neutral += volume; } } [COLOR=Blue]else[/COLOR] { [COLOR=Blue] if (e.MarketDataType == MarketDataType.Ask) { askPrice = e.Price; return; } if (e.MarketDataType == MarketDataType.Bid) { bidPrice = e.Price; return; }[/COLOR] if (e.MarketDataType != MarketDataType.Last || ChartControl == null || askPrice == 0 || bidPrice == 0) return; if (Bars != null && !SessionIterator.IsInSession(Core.Globals.Now, true, true)) return; price = e.Price; volume = e.Volume; if (!cacheDictionary.ContainsKey(price)) cacheDictionary.Add(price, new VolumeInfoItem()); volumeInfoItem = cacheDictionary[price]; if (price >= askPrice) volumeInfoItem.up += volume; else if (price <= bidPrice) volumeInfoItem.down += volume; else volumeInfoItem.neutral += volume; }
Buy Sell Pressure indicator also ONLY uses the 'Last' type market data updates, so how does it determine correctly what type of order came in (when ask == bid == price)?
When Historical data is loading and IsTickReplay is true, the data that comes in is all 'Last' data. So, if bid == ask we have no idea what the order actually was.Last edited by nedlloyd; 02-25-2016, 03:38 PM.
Comment
-
Hello nedlloyd,
I'll be looking into this further and will return with my findings.
Thank you for your patience.
As a reminder, if you haven't already updated to the latest version of NinjaTrader, please note that all NinjaTrader users MUST update to NinjaTrader 7.0.1000.31 by Saturday, February 27th if they wish to continue using NinjaTrader; older versions of NinjaTrader will no longer work after the 27th. We encourage everyone to update now to avoid interruption in service.
None of your settings, work spaces, indicators, etc. will be affected if you follow the directions below.
To install the update please follow these instructions:
- CRITICAL Shut Down NinjaTrader
- Download the update HERE
- Double click the file once it has completed downloading and follow the installation prompts on your screen
For more information about this critical update please click HERE.Last edited by NinjaTrader_ZacharyG; 02-26-2016, 09:11 AM.Zachary G.NinjaTrader Customer Service
Comment
-
Hello nedlloyd,
Please take a look at the example code in the Developing for Tick Replay section of the help guide for information on how to access historical bid and ask prices with Tick Replay enabled: http://ninjatrader.com/support/helpG...ick_replay.htm
Code:protected override void OnMarketData(MarketDataEventArgs marketDataUpdate) { if (marketDataUpdate.MarketDataType == MarketDataType.Last) { if (marketDataUpdate.Price >= marketDataUpdate.Ask) Print(marketDataUpdate.Volume + " contracts traded at asking price " + marketDataUpdate.Ask); else if (marketDataUpdate.Price <= marketDataUpdate.Bid) Print(marketDataUpdate.Volume + " contracts traded at bidding price " + marketDataUpdate.Bid); } }
Zachary G.NinjaTrader Customer Service
Comment
-
Zachary,
Your response:
"Please take a look at the example code in the Developing for Tick Replay section of the help guide for information on how to access historical bid and ask prices with Tick Replay enabled:"
I understand how to access the bid and ask prices. In fact, the code that I put in the reply included ACCESSING the bid and ask prices (marketDataUpdate.Bid == marketDataUpdate.Ask)). I believe the DATA is wrong. What I am trying to determine is how to resolve the ambiguities in the data when Bid price == Ask Price == Price. In my previous reply I posted this code:
Code:protected override void OnMarketData(MarketDataEventArgs marketDataUpdate) { if (marketDataUpdate.MarketDataType == MarketDataType.Last) { if (marketDataUpdate.Bid == marketDataUpdate.Ask) Print(marketDataUpdate.ToString()); } }
Code:protected override void OnMarketData(MarketDataEventArgs marketDataUpdate) { if (marketDataUpdate.MarketDataType == MarketDataType.Last) { if (marketDataUpdate.Price >= marketDataUpdate.Ask) Print(marketDataUpdate.Volume + " contracts traded at asking price " +marketDataUpdate.Ask); else if (marketDataUpdate.Price <= marketDataUpdate.Bid) Print(marketDataUpdate.Volume + " contracts traded at bidding price " + marketDataUpdate.Bid); } }
(example output from my code)
instrument='CL 04-16 Nymex' type=Last price=31.92 volume=1 time=2/24/2016 12:04:11 PM bid=31.92 ask=31.92 isReset=False
then the volume will always be classified as Ask volume. But, there is absolutely no way to tell if the volume was truly Ask or Bid because the Ask and Bid price are the same. The BEST we could do is count it as neither Ask nor Bid, which makes no sense (the contract was either bought or sold).
Run Volume Profile on the same symbol over the same day in two configurations. 1) Using Playback Connection on Market Replay data with Tick Replay off. 2) Then, do it with Tick Replay on and you will get different outputs. The total volume will be the same, but the Bid and Ask volume will be different.
This is crucial. It effectively renders Tick Replay useless because we cannot be sure that the volume is accurately classified as Bid or Ask.Last edited by nedlloyd; 03-07-2016, 12:59 PM.
Comment
-
Hello nedlloyd,
It would not be expected for the bid and ask to be at the same price.
I have enabled Tick Replay on a CL 04-16 chart in Market Replay and created a a simple script that will only print the historic calls of OnMarketData(). This was tested between February 23, 2016 22:00 to February 24, 2016 21:45 Mountain Time.
I was unable to find an instance of a matching ask and bid price with the script.
Code:protected override void OnMarketData(MarketDataEventArgs m) { if (State == State.Realtime) return; if (m.MarketDataType == MarketDataType.Last) { if (m.Bid == m.Ask) Print(m.Time + " match " + m.Bid + " " + m.Ask); else Print(m.Time + " no match"); } }
Zachary G.NinjaTrader Customer Service
Comment
-
Zachary,
We have been doing this for three weeks now. I would really just like to solve the problem. Do you think that I manually created the output in a previous post where the bid and ask are equal? Are you telling me that my data feed is bad? It is a Ninja feed. Are you telling me the historical data was downloaded incorrectly? Is there more than one way? Are you telling me the code is wrong? I ran your code, except I commented out the else if there is no match:
Code:protected override void OnMarketData(MarketDataEventArgs m) { if (State == State.Realtime) return; if (m.MarketDataType == MarketDataType.Last) { if (m.Bid == m.Ask) Print(m.Time + " match " + m.Bid + " " + m.Ask); // else // Print(m.Time + " no match"); } }
2/23/2016 9:09:08 AM match 32.9 32.9
2/23/2016 9:12:17 AM match 32.81 32.81
2/23/2016 9:15:42 AM match 32.75 32.75
2/23/2016 9:15:42 AM match 32.75 32.75
2/23/2016 9:47:20 AM match 32.57 32.57
2/23/2016 11:05:09 AM match 31.78 31.78
2/23/2016 11:27:22 AM match 31.75 31.75
2/23/2016 11:31:07 AM match 31.76 31.76
2/23/2016 11:34:54 AM match 31.79 31.79
2/23/2016 1:58:54 PM match 31.83 31.83
2/23/2016 2:00:42 PM match 31.9 31.9
2/23/2016 2:27:56 PM match 31.99 31.99
2/23/2016 3:11:22 PM match 31.83 31.83
2/23/2016 4:54:48 PM match 31.34 31.34
2/23/2016 6:00:00 PM match 31.28 31.28
2/24/2016 10:30:08 AM match 31.23 31.23
2/24/2016 10:41:31 AM match 31.53 31.53
2/24/2016 10:43:40 AM match 31.4 31.4
2/24/2016 10:47:49 AM match 31.2 31.2
2/24/2016 10:47:59 AM match 31.22 31.22
2/24/2016 11:36:50 AM match 31.04 31.04
2/24/2016 12:04:11 PM match 31.92 31.92
2/24/2016 12:34:51 PM match 31.88 31.88
2/24/2016 1:58:05 PM match 31.91 31.91
2/24/2016 2:40:47 PM match 32.23 32.23
2/24/2016 3:15:12 PM match 32.18 32.18
2/24/2016 4:48:30 PM match 32.2 32.2
2/24/2016 6:00:00 PM match 32.19 32.19
2/24/2016 6:59:29 PM match 32.2 32.2
2/24/2016 8:34:15 PM match 32.05 32.05
So, where am I going wrong, if you cannot produce this output? Can anybody produce this output, or am I the only one? If I am the only, how in the world is that happening?Last edited by nedlloyd; 03-15-2016, 06:55 AM.
Comment
-
Hello nedlloyd,
Thank you for your patience.
I have consulted with the product management team. This behavior can occur from time to time and is expected.
What you do with the matching bid and ask ticks would be up to you. As it cannot be proven if it is a bid or ask, then perhaps the best thing to do is ignore these ticks.
With the volume profile indicator, the ticks would be assumed as ask due to the logic.Zachary G.NinjaTrader Customer Service
Comment
-
Zachary,
Thank you for all of your help. It is really strange that the answer would be "this behavior is expected." It is expected to not know if the contracts were bought or sold? As I first stated, I have not seen this problem when the bid and ask market data types are being used to update the bid and ask price (ie, no Tick Replay). Can there not be an extra field in the market data update that tells us if the contracts were bought and sold? Surely at some point in time somebody (or some machine) knew! Or, and I understand that this would require huge memory, Ninja could save the bid and ask market data types as well as the last types. I mean, why have Tick Replay at all if we are uncertain of the accuracy? What if a 500 contract order goes through and we cannot determine if it is bid or ask?
Again, Thanks.
Comment
-
Hello nedlloyd,
Tick Replay only replays the Last market data event and only stores the best inside bid/ask price at the time of the last trade event.
Historical bid/ask market data events (such as bid/ask volume) do not replay during Tick Replay. To obtain those values, you need to use a historical bid/ask series.
The Developing for Tick Replay section has recently been updated and provides much more information about how to utilize Tick Replay in a script: http://ninjatrader.com/support/helpG...ick_replay.htmZachary G.NinjaTrader Customer Service
Comment
-
Hello NinjaTeam,
Could you please clarify real time market data?
If I download historical data using 'Tick' Intervals and 'Last' Data Type and then export them with the same parameters, I get the data in the following format:
yyyyMMdd HHmmss fffffff;last_price;bid_price;ask_price;volume
1. The question is:
If I use OnMarketData event handler in real time, how can I get exactly the same data sequence as above? I mean, do I need to filter out any real time data and what conditions I have to check?
In the Developing for Tick Replay section of NT8 manual I can see:
Accessing the current best bid and ask at the time of a trade
NinjaTrader stores the best bid price and best ask price as the last trade occurs during the MarketDataType.Last event and provides it per the table below:
Code:if (marketDataUpdate.MarketDataType == MarketDataType.Last) { }
2. The second question is:
Is it possible to get the real time data timestamps in UTC, not in my local time, without any additional conversion? I guess, the data provider stores all the historical data with UTC stamps, isn't it?
Comment
-
yyyyMMdd HHmmss fffffff;last_price;bid_price;ask_price;volume
Hello quicktrick,
Thank you for writing in.
As you're only wanting to obtain information from the Last MarketDataType, you'll just need to filter for that:
Code:protected override void OnMarketData(MarketDataEventArgs m) { if (m.MarketDataType == MarketDataType.Last) Print(m.Time.ToString("yyyyMMdd HHmmss") + ";" + m.Price + ";" + m.Bid + ";" + m.Ask + ";" + m.Volume); }
This will output the time according to your local timezone, though. You would need to convert to UTC in your code. This can be done with the ToUniversalTime() method: https://msdn.microsoft.com/en-us/lib...=vs.110).aspx6
Code:m.Time.ToUniversalTime().ToString("...")
Zachary G.NinjaTrader Customer Service
Comment
Latest Posts
Collapse
Topics | Statistics | Last Post | ||
---|---|---|---|---|
Started by AttiM, 02-14-2024, 05:20 PM
|
12 responses
212 views
0 likes
|
Last Post
by DrakeiJosh
Today, 11:17 AM
|
||
Started by cre8able, 02-11-2023, 05:43 PM
|
3 responses
236 views
0 likes
|
Last Post
by rhubear
Today, 10:46 AM
|
||
Started by frslvr, 04-11-2024, 07:26 AM
|
8 responses
115 views
1 like
|
Last Post Today, 10:30 AM | ||
Started by stafe, 04-15-2024, 08:34 PM
|
10 responses
47 views
0 likes
|
Last Post
by stafe
Today, 10:29 AM
|
||
Started by rocketman7, Today, 09:41 AM
|
3 responses
11 views
0 likes
|
Last Post Today, 10:07 AM |
Comment