NinjaTrader Support Forum  
X

Attention!

This website will be down for maintenance from Friday May 24th at 6PM MDT until Sunday May 26th at 12PM 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-24-2012, 09:23 AM   #16
NinjaTrader_Bertrand
NinjaTrader Customer Service
 
NinjaTrader_Bertrand's Avatar
 
Join Date: Sep 2008
Location: Germany
Posts: 22,421
Thanks: 252
Thanked 982 times in 964 posts
Default

Alex, after looking further into I think the main issue is that the fill / execution time would simply be different for each series you submit to, if you fill on 0 > it would report it as 9:08 execution > which is correct for this series's resolution. If you submit to the finer 1 minute series > it would report it as fill at 9:07 already - in each bars series that's another bar number of course.

For the time of the fill event absent of any OnBarUpdate() event call, you can directly work in OnExecution() -

protected override void OnExecution(IExecution execution)
{
if (entry != null && entry == execution.Order)
Print("Executed @ " + execution.Time);
}

Pushing this DateTime returned to GetBar() would offer you requesting the bar number on which that execution fell.

I think that would be the best approach.
NinjaTrader_Bertrand is offline  
Reply With Quote
Old 05-24-2012, 05:49 PM   #17
anachronist
Senior Member
 
Join Date: Jul 2008
Posts: 271
Thanks: 4
Thanked 7 times in 7 posts
Default

I forgot to mention that in the code I posted above, the variable barSeries can be 0 or 1, it makes no difference in the result. It still reports bar 631 as the fill bar when it should be 632.

When I modify my test program to get the execution time in OnExecution(), the execution time is correctly recorded at 6:07 (Pacific time).

The trouble is, when I pass this DateTime to GetBar() in OnBarUpdate(), I get series 0 filling on bar 376 (should be 377), and series 1 filling on bar 629 (should be 632). I don't understand this. Bar 629 corresponds to a time of 6:04, not the fill time of 6:07.

Here's the current test:
PHP Code:
        #region Variables
        // Parameters for Zen-Fire TF 06-12 2 minute, Default 24/7 template, 1 day ending 5/14/2012 
        
private int barNum 375// Default setting for BarNum
        
private double limitPrice 780.3// Default setting for LimitPrice
        
private IOrder entry null;
        private 
int barSeries 1;
        private 
int [] fillbar;
        private 
DateTime filltime DateTime.MinValue;
        
#endregion

        
protected override void Initialize() {
            
Add(PeriodType.Minute1);
            
Unmanaged true;
            
CalculateOnBarClose false// doesn't matter
            
ExitOnClose false;
            
TraceOrders true;
        }
        protected 
override void OnStartUp() {
            
ClearOutputWindow();
            
fillbar = new int[CurrentBars.GetLength(0)];
        }

        protected 
override void OnExecution(IExecution e) {
            if (
entry != null && entry == e.Order) {
                
filltime e.Time;
                Print(
"Executed at "+e.Time.ToString());
            }
        }

        protected 
override void OnBarUpdate() {
            if (
entry != null && filltime DateTime.MinValue && fillbar[BarsInProgress] == 0)
                
fillbar[BarsInProgress] = GetBar(BarsInProgressfilltime);
            if (
BarsInProgress != 0) return;
            if (
CurrentBar == barNum)
                
entry SubmitOrder(barSeriesOrderAction.BuyOrderType.Limit1limitPrice0"""test");
            if (
CurrentBar == barNum+10 && entry != null) {
                Print(
"Filled "+filltime.ToString()+" at "+entry.AvgFillPrice.ToString());
                for (
int i 0fillbar.GetLength(0); ++i)
                    Print(
"on series "+i.ToString()+" bar "+fillbar[i].ToString());
            }
        } 
...and here's the output:

5/14/2012 6:04:00 Entered internal SubmitOrder() method at 5/14/2012 6:04:00: Action=Buy OrderType=Limit Quantity=1 LimitPrice=780.3 StopPrice=0 OcoId='' Name='test'
Executed at 5/14/2012 6:07:00
Filled 5/14/2012 6:07:00 at 780.3
on series 0 bar 376
on series 1 bar 629

The actual fill bars should be 377 and 632.

-Alex
Last edited by anachronist; 05-25-2012 at 07:06 PM.
anachronist is offline  
Reply With Quote
Old 05-25-2012, 10:59 AM   #18
NinjaTrader_Bertrand
NinjaTrader Customer Service
 
NinjaTrader_Bertrand's Avatar
 
Join Date: Sep 2008
Location: Germany
Posts: 22,421
Thanks: 252
Thanked 982 times in 964 posts
Default

Alex, here's for example an approach with OnExecution and GetBar that works fine in my testing returning 377 and 632 for your test and the filled bar, which is correct according to the reported execution timestamp :

Code:
protected override void OnBarUpdate() 
{ 
if (entry != null && entry.OrderState == OrderState.Filled && Time[0] >= exeTime)
	{
	      refBack = GetBar(exeTime);
		
              	if (BarsInProgress == 0)
		   Print(CurrentBar - refBack);
				
		if (BarsInProgress == 1)
		   Print(CurrentBars[1] - refBack);
	}
			
if (BarsInProgress != 0) return; 
            
	if (CurrentBar == barNum)
	{
		DrawDot("dot", true, 0, Low[0], Color.Blue);
		DrawText("text", CurrentBar.ToString(), 0, High[0] + TickSize, Color.Blue);  
                            entry = SubmitOrder(barSeries, OrderAction.Buy, OrderType.Limit, 1, limitPrice, 0, "", "test"); 
	}
}
		
protected override void OnExecution(IExecution execution)
{
   if (entry != null && entry == execution.Order)
	exeTime = execution.Time;
}
NinjaTrader_Bertrand is offline  
Reply With Quote
The following user says thank you to NinjaTrader_Bertrand for this post:
Old 05-25-2012, 07:16 PM   #19
anachronist
Senior Member
 
Join Date: Jul 2008
Posts: 271
Thanks: 4
Thanked 7 times in 7 posts
Default

Thanks Bertrand. The trick I was failing to grasp is to check whether Time[0] >= filltime in my OnBarUpdate(). I also was using GetBar() wrong.

I must say, the documentation for GetBar() isn't clear at all. The example code, which calculates BarsAgo, implies that GetBar() returns the bar number. The documentation text says the index returned is from the first bar "oldest to newest" but seems to be just the opposite.

-Alex
anachronist is offline  
Reply With Quote
Old 05-25-2012, 07:19 PM   #20
anachronist
Senior Member
 
Join Date: Jul 2008
Posts: 271
Thanks: 4
Thanked 7 times in 7 posts
Default

One other thing I don't understand. I have been using OnOrderUpdate() in my ATM backtest code to process all the order events because I need cancellations and rejections too. Does OnExecution() get called only for fills?
anachronist is offline  
Reply With Quote
Old 05-27-2012, 12:26 AM   #21
NinjaTrader_Bertrand
NinjaTrader Customer Service
 
NinjaTrader_Bertrand's Avatar
 
Join Date: Sep 2008
Location: Germany
Posts: 22,421
Thanks: 252
Thanked 982 times in 964 posts
Default

Thanks for the input, we'll oversee the GetBar() docs for your next update. Correct, OnExecution() would only deal with incoming fills (this could be a partial as well). Keep in mind it will be called after OnOrderUpdate.

A good weekend,
NinjaTrader_Bertrand is offline  
Reply With Quote
Old 05-31-2012, 05:33 PM   #22
anachronist
Senior Member
 
Join Date: Jul 2008
Posts: 271
Thanks: 4
Thanked 7 times in 7 posts
Default

Okay, it was working fine for limit orders but now I'm getting a severe misalignment with market orders. The misalignment also shows up on the chart.

How can a market order get filled 26 bars and 18 minutes later on the primary series??

To reproduce:
  • Zen-fire ES 06-12, 3 minute bars, 1 day of history ending 5/24/2012, default 24/7 session template.
  • Add a secondary series of 1-tick bars.
  • Submit an unmanaged market order to buy at bar when the primary series CurrentBar==160.
  • The fill is on bar 186, and this fill is also shown on the chart on bar 186.
Here is the code to reproduce:
Code:
		#region Variables
		// Parameters for Zen-Fire TF 06-12 3 minute, Default 24/7 template, 1 day ending 5/24/2012 
		private int barNum = 160;
 		private IOrder entry = null;
		private int [] fillbar;
		private DateTime filltime = DateTime.MinValue;
		#endregion

		protected override void Initialize() {
			Add(PeriodType.Tick, 1);
			Unmanaged = true;
			CalculateOnBarClose = false;
			ExitOnClose = false;
			TraceOrders = true;
		}
		protected override void OnStartUp() {
			ClearOutputWindow();
			fillbar = new int[CurrentBars.GetLength(0)];
		}

		protected override void OnExecution(IExecution e) {
			if (entry != null && entry == e.Order) {
				filltime = e.Time;
				Print("Executed at "+e.Time.ToString());
			}
		}

		protected override void OnBarUpdate() {
			if (entry != null && entry.OrderState == OrderState.Filled && Time[0] >= filltime
				&& filltime > DateTime.MinValue && fillbar[BarsInProgress] == 0) {
				fillbar[BarsInProgress] = CurrentBars[BarsInProgress] - GetBar(BarsInProgress, filltime);
				Print("Filled on series "+BarsInProgress.ToString()+" bar "+fillbar[BarsInProgress].ToString()+", time "+Time[0].ToString());
			}
			if (BarsInProgress != 0) return;
			if (CurrentBar == barNum)
				entry = SubmitOrder(1, OrderAction.Buy, OrderType.Market, 1, 0, 0, "", "test");
		}
Here is the output (times are Pacific time zone):

Quote:
5/22/2012 23:15:26 Entered internal SubmitOrder() method at 5/22/2012 23:15:26: Action=Buy OrderType=Market Quantity=1 LimitPrice=0 StopPrice=0 OcoId='' Name='test'
Executed at 5/23/2012 6:18:46
Filled on series 1 bar 5879, time 5/23/2012 6:18:46
Filled on series 0 bar 186, time 5/23/2012 6:21:00
The order trace shows a really weird time for the order submission: the prior day. It should be 5/23/2012 at 5:03:00. The fill should occur immediately after that.

I know I must be missing something fundamental here, but the above result seems totally nonsensical.

If I change the secondary series type to 1 minute bars, it works fine. It just messes up when the secondary series uses PeriodType,Tick or PeriodType.Second.

-Alex
Last edited by anachronist; 05-31-2012 at 05:37 PM.
anachronist is offline  
Reply With Quote
Old 06-01-2012, 09:16 AM   #23
NinjaTrader_Bertrand
NinjaTrader Customer Service
 
NinjaTrader_Bertrand's Avatar
 
Join Date: Sep 2008
Location: Germany
Posts: 22,421
Thanks: 252
Thanked 982 times in 964 posts
Default

Alex, is the tick data completely loaded as needed? If you added tick data in the strategy and data was missing, NT would not reload that according to the data loading rules internally - this is a limitation we currently experience for added series. I tip on this being a data issue, as for a MultiSeries strategy all series would have to be loaded up and passing their BarsRequired before any action is taken. Can you please check into your tick data loaded up and reload manually if needed?
NinjaTrader_Bertrand is offline  
Reply With Quote
Old 06-01-2012, 01:33 PM   #24
anachronist
Senior Member
 
Join Date: Jul 2008
Posts: 271
Thanks: 4
Thanked 7 times in 7 posts
Default

Ah. While I have tick data history, apparently it's only for day-session data, even though the data series on my chart is for 24/7. The bar in question occurs before the session start. This leads me to ask some additional questions:
  • Does historical data get fetched to fill holes only when I request the data on a chart, but not when I request it in a strategy?
  • I have noticed in a process monitor that NinjaTrader makes requests from 7ticks.com, which appears to be a provider of historical data. Is the history being requested from there, or through my zen-fire data feed?
  • Does my data feed or 7ticks provide tick data outside the regular trading hours?
Thanks.
Alex
anachronist is offline  
Reply With Quote
Old 06-01-2012, 02:01 PM   #25
NinjaTrader_Brett
NinjaTrader Customer Service
 
NinjaTrader_Brett's Avatar
 
Join Date: Dec 2009
Location: Denver, CO, USA
Posts: 6,498
Thanks: 109
Thanked 291 times in 280 posts
Default

Hello,

Data requests occur based on these data load rules:

http://www.ninjatrader.com/support/h...rical_data.htm

This is the historical data servers for your Zenfire connection.

All data is recorded, ETH and RTH on the servers.

-Brett
NinjaTrader_Brett is offline  
Reply With Quote
Old 06-01-2012, 03:37 PM   #26
anachronist
Senior Member
 
Join Date: Jul 2008
Posts: 271
Thanks: 4
Thanked 7 times in 7 posts
Default

Hmm, I wonder why I can't seem to get ETH tick data then.
-Alex
anachronist is offline  
Reply With Quote
Old 06-04-2012, 03:35 AM   #27
NinjaTrader_Bertrand
NinjaTrader Customer Service
 
NinjaTrader_Bertrand's Avatar
 
Join Date: Sep 2008
Location: Germany
Posts: 22,421
Thanks: 252
Thanked 982 times in 964 posts
Default

Alex, same on a standalone chart for the TF for example running on your Default 24/7? Then please try with a fresh cache for NT7. Shutdown the plaftfrom and go to

Documents\NinjaTrader 7\db\cache

and delete the sub(!!) folders seen here completely.

Once done, restart NT7 and reconnect to your provider. When you open your charts now it will rebuild the cache used. Would you still see issues receiving ETH tick data properly?

Thanks,
NinjaTrader_Bertrand is offline  
Reply With Quote
Old 06-04-2012, 05:17 PM   #28
anachronist
Senior Member
 
Join Date: Jul 2008
Posts: 271
Thanks: 4
Thanked 7 times in 7 posts
Default

That worked, after I figured out that I have to close all my workspaces before shutting down, and don't try to re-load the data by re-opening one of those workspaces, but rather create a whole new chart. Thanks!
-Alex
anachronist is offline  
Reply With Quote
Old 06-05-2012, 10:10 AM   #29
NinjaTrader_Bertrand
NinjaTrader Customer Service
 
NinjaTrader_Bertrand's Avatar
 
Join Date: Sep 2008
Location: Germany
Posts: 22,421
Thanks: 252
Thanked 982 times in 964 posts
Default

Thanks for reporting back Alex, glad to hear.
NinjaTrader_Bertrand is offline  
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 11:04 PM.