Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Accessing price data in DrawingTools...

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

    #16
    Thanks for following up. I was able to get clarification on the fromLocal/toLocal parameters.

    When using that constructor, the lowest granularity for intraday requests you can obtain is 1 trading day of data. Meaning, for tick data, it will return at least one full trading day of tick data, even though your fromLocal/toLocal are using a shorter segement. You see multiple calendar days in your output since it starts from the session start based on the .TradingHours you configure (e..g, Default 24/7 would start at 12:00AM Eastern, which may be 10:00PM Mountain the previous day). It is not possible to request just a segment of tick data with that constructor.

    If you use the "barsBack" parameter, you can request less data, but it will be barsBack from the current bar, which I don't think meets your purposes.

    So as per your edit, you'd just need to loop through the request and filter for the data you need:

    Code:
    private DateTime BeginTime;
    private DateTime EndTime;
    private void DoRequest()
    {			
    	BarsRequest barsRequest = new BarsRequest(Instrument, BeginTime, EndTime);
    	barsRequest.BarsPeriod = new BarsPeriod {BarsPeriodType = BarsPeriodType.Tick, Value = 1};
    	barsRequest.TradingHours = TradingHours.Get("Default 24 x 7");
    
    	barsRequest.Request(new Action<BarsRequest, ErrorCode, string>((theBars, errorCode, errorMessage) => 
    	{ 
    		Print("BEGIN: " + BeginTime + "   END: " + EndTime); 				
    		Bars myBars = theBars.Bars;
    
    		for (int i = 0; i < myBars.Count; i++)
    		{ 
    		[B]	if(myBars.GetTime(i) < BeginTime || myBars.GetTime(i) > EndTime)
    				continue;[/B]
    			Print("  " + theBars.Bars.GetTime(i) + "  " + theBars.Bars.GetClose(i) + "  " + theBars.Bars.GetVolume(i)); 
    		} 
    	}));  
    }
    I'll make sure this is reflected in the help guide. Thanks for bringing it up.
    Last edited by NinjaTrader_Matthew; 11-06-2015, 11:52 AM.
    MatthewNinjaTrader Product Management

    Comment


      #17
      Originally posted by NinjaTrader_Matthew View Post
      If you use the "barsBack" parameter, you can request less data, but it will be barsBack from the current bar, which I don't think meets your purposes.
      Thanks for clarifying the behavior. You bring up a good point about the barsBack option. Perhaps I can just limit the data by calculating the numbers of "barsBack" from my BeginTime to CurrentBar (and still filter what I need up until EndTime in the loop) to limit the amount of data returned.

      So far, however, it does seem surprisingly snappy returning and looping through all the data (without further limiting it).

      Thanks again!

      Comment


        #18
        I'm getting some odd scope related behavior. If I define a variable outside the scope of the Request, try and set it within the Request, it will not be set afterward.

        In the code below, "B" will always be "0". Whereas "A" will always output correctly.

        I need to be able to grab data from the request and then do something with it afterward, outside the Request itself. How do I do that? Can I pass an object (a struct, for example) into the Request by ref to allow it to be modified?

        Code:
        private void DoRequest()
        {			
        	BarsRequest barsRequest = new BarsRequest(Instrument, BeginTime, EndTime);
        	barsRequest.BarsPeriod = new BarsPeriod {BarsPeriodType = BarsPeriodType.Tick, Value = 1};
        	barsRequest.TradingHours = TradingHours.Get("Default 24 x 7");
        
        	[B]double myTest = 0;[/B]
        
        	barsRequest.Request(new Action<BarsRequest, ErrorCode, string>((theBars, errorCode, errorMessage) => 
        	{ 
        		[B]myTest = theBars.Bars.GetClose(0);
        		Print("A: " + myTest);[/B]
        	}));  
        
        	[B]Print("B: " + myTest);[/B]
        }

        Comment


          #19
          The custom DoRequest() method does not wait for the BarsRequest.Request() to finish. In other words, in your example, Print B will run as soon as the method is called and would not wait for the Request() to finish, hence "myTest" is still 0 at that point

          If you wait until after the request returns, you'll see myTest contains a value.

          Since there is not a way to know outside of the Request() that it has finished, you might want to introduce some sort of flag to check before trying to access values from another scope. For example, you can check the ErrorCode within the Request() method and when it is NoErrors, mark some flag indicating it has loaded and then you can access that double variable you assigned.

          Code:
          bool isLoaded = false;
          void DoRequest()
          {
          	BarsRequest barsRequest = new BarsRequest(Instrument, 50);
          	barsRequest.BarsPeriod = new BarsPeriod {BarsPeriodType = BarsPeriodType.Tick, Value = 1};
          	barsRequest.TradingHours = TradingHours.Get("Default 24 x 7");			
          	barsRequest.Request(new Action<BarsRequest, ErrorCode, string>((theBars, errorCode, errorMessage) => 
          	{					
          		if(errorCode == ErrorCode.NoError)
          		{		
          			isLoaded = true;
          			myTest = theBars.Bars.GetClose(0);
          		}
          	})); 		
          }
          
          void SomeOtherMethod()
          {
          	if(isLoaded);
          		Print("B: " + myTest);
          }
          I would not suggest adding any thread .Sleep() concepts as the Request() runs on the actual Instrument thread and you could potentially halt processing outside of the indicator unbeknownst to processes also running on that thread.
          MatthewNinjaTrader Product Management

          Comment


            #20
            Originally posted by NinjaTrader_Matthew View Post
            The custom DoRequest() method does not wait for the BarsRequest.Request() to finish. In other words, in your example, Print B will run as soon as the method is called and would not wait for the Request() to finish, hence "myTest" is still 0 at that point
            Facepalm

            I've been coding way too long to not realize it was an async call. Yeah, I put some flags in my code to use the "detailed tick data" or my "less detailed method" based on the state of this BarsRequest call. Thanks for pointing this out!

            On a related note. Sometimes I perform the request, but the tick data for my range simply isn't there (on a tick-based bar type). Some data is returned, but not necessarily what is in my requested time range.

            If I manually perform "reload all historical data" on the chart, then the data seems to be there for the drawing tool. Is there something I can do to accomplish this via ninjascript? I was hoping this "BarsRequest" would do it for me. I haven't tried on a minute-based chart (on a never-loaded symbol that doesn't have any tick data loaded), but I imagine this would be even more problematic.

            Comment


              #21
              I would expect the BarsRequest to Request the data if not there for you too... sounds like there may be a bug. Do you have something specific I can test where you do not get the data returned that is requested?
              MatthewNinjaTrader Product Management

              Comment


                #22
                I believe the problem has to do with making a request within a single day, then making a second request that's from a different day. (Done via a second instance of the same drawing tool on the chart) After that first request, it seems all future requests are limited to that one day.

                Perhaps there is some caching within the scope of the chart? Do I have to nullify the request somehow?

                I'm still testing to determine what is going on and to make sure it's just not some mishandling on my end, but I don't think so. Unless there is something that I need to invalidate or destroy that I don't know about (to force it to perform a fresh Request).

                I am also finding that if I "reload all historical data", then perform a Request, that first Request takes slightly longer than any future requests (implying there is some caching going on). Which is great, but perhaps there needs to be a way to invalidate it to force a fresh fetch?

                A test would be to perform a request on a range from yesterday (before 11pm, but within the same day), once finished, perform a request on a range from today and see what the result is (or vice versa). I'm finding that the returned data is from the first request only.

                EDIT: Another sign of caching is when I perform a Request (making note of the time the request was made (which should also be the most recent data item)). Then, perform a new Request a few minutes later (that has an end time after the time the first request was made), thus requiring new data to be present. The result is it's still limited to the first request's start/end times. Let me know if that doesn't make sense.
                Last edited by neoikon; 11-10-2015, 02:29 PM.

                Comment


                  #23
                  If you're making multiple requests, you should be checking if that old request is null and if so, create a new request as per the example in our help guide:


                  Code:
                    // Unsubscribe to any old bars requests
                            if (barsRequest != null)
                                 barsRequest = new BarsRequest(....)
                  There is caching involved per our data loading rules. By default it will look in the repository first. However there is a property on the bars request where you can tell it to look up by provider

                  Code:
                  myBarsRequest.LookupPolicy = LookupPolicies.Provider; // get data from the provider
                  myBarsRequest.LookupPolicy = LookupPolicies.Repository; // get data from the cache
                  MatthewNinjaTrader Product Management

                  Comment


                    #24
                    Originally posted by NinjaTrader_Matthew View Post
                    If you're making multiple requests, you should be checking if that old request is null and if so, create a new request
                    I'm only making a new request if my local copy of the requested bars does not contain all the bars within my time ranges. If my selected bar range is outside the requested data range, it gets triggered to create a new request. Unfortunately, the new request keeps sending me the same data as the original request (even though the begin and end times changed).

                    However...

                    Originally posted by NinjaTrader_Matthew View Post
                    There is caching involved per our data loading rules. By default it will look in the repository first. However there is a property on the bars request where you can tell it to look up by provider

                    Code:
                    myBarsRequest.LookupPolicy = LookupPolicies.Provider; // get data from the provider
                    myBarsRequest.LookupPolicy = LookupPolicies.Repository; // get data from the cache
                    I think that helped it! I set the LookupPolicy to always be the Provider and it seems to be working better now. (Still not perfect, as it doesn't always return all the requested data.)

                    I feel like it would be better if it stayed set to Repository, so I'm going to keep looking to see if there is something I can do. Progress!

                    Comment

                    Latest Posts

                    Collapse

                    Topics Statistics Last Post
                    Started by yertle, Yesterday, 08:38 AM
                    7 responses
                    28 views
                    0 likes
                    Last Post yertle
                    by yertle
                     
                    Started by bmartz, 03-12-2024, 06:12 AM
                    2 responses
                    21 views
                    0 likes
                    Last Post bmartz
                    by bmartz
                     
                    Started by funk10101, Today, 12:02 AM
                    0 responses
                    4 views
                    0 likes
                    Last Post funk10101  
                    Started by gravdigaz6, Yesterday, 11:40 PM
                    1 response
                    8 views
                    0 likes
                    Last Post NinjaTrader_Manfred  
                    Started by MarianApalaghiei, Yesterday, 10:49 PM
                    3 responses
                    11 views
                    0 likes
                    Last Post NinjaTrader_Manfred  
                    Working...
                    X