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!
See more
See less

Partner 728x90

Collapse

Transferring code from TradeStation to NT

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

    Transferring code from TradeStation to NT

    Hi there.

    I am in the process of migrating the code that I currently use with TradeStation to NT8 and I have couple questions:
    1. Is there any ninjascript manual that I can read to see all the classes that nt8 uses? I am quite alright with c#, but need the details about ninjascript classes and methods.
    2. I use 1 sec interval data in TS, for index futures trading and besides the usual OHLC I also use bid and ask volumes that in TS I can get pretty easy as:
    a)UpTicks - Volume (shares) traded on Up Ticks
    b)DownTicks - Volume (shares) traded on Down Ticks
    My question is how can I get these data in NT8. To be specific, I am trading YM and DJI

    Thank you.

    #2
    Hello,

    Thank you for the post.

    We do have an API along with many samples which I will provide links for below. To access secondary data series, I would suggest reviewing the following document:



    The API reference can be found here:





    I look forward to being of further assistance.
    JesseNinjaTrader Customer Service

    Comment


      #3
      Hello Jesse. Thank you for your reply. As I was browsing through the code I found this:
      protected override void OnMarketData(MarketDataEventArgs e)
      {
      if(e.MarketDataType == MarketDataType.Last)
      {
      if(e.Price >= e.Ask)
      {
      buys += e.Volume;
      }
      else if (e.Price <= e.Bid)
      {
      sells += e.Volume;
      }
      }
      }

      Do you think this is what will give me BID and ASK volumes for each 1-second interval? Thank you.

      Comment


        #4
        Hello,

        Thank you for the reply.

        The OnMarketData override is a real-time data override so you would get the tick by tick events pushed through here. This is not broken up into bar segments like OnBarUpdate which is referencing the Series you add, this instead is just the live data as it comes in. This would not produce second increment values but should be tick by tick updates or price events for ask last and bid.

        As you noted that you are already familiar with using C#, I would likely also suggest reviewing the following resources for debugging techniques in the platform. For the OnMarketData override, a good way to physically see how this works would be to Print the data that comes in using the NinjaScript Output window and Prints.



        I look forward to being of further assistance.
        JesseNinjaTrader Customer Service

        Comment


          #5
          Thank you Jesse. Do I understand it correctly that OnBarUpdate fires every time when the new tick info arrives within the bar, even if the bar itself is 1 sec long/wide?

          Couple more questions, if I may:
          1. Does the NinjaTraderContinuum (demo) data feed provide a reliable data? I do not care if those data are delayed, just wanted to verify how OnBarUpdate works with data and compare the results with my tried and tested TS data.
          2. If yes, how can I get the username and password to connect to this data feed?
          3. If no, how would you recommend to test the results, as I want to be sure that when I move my account to NT I have no problem with the data?

          Thank you.

          Comment


            #6
            Hello,

            Thank you for the reply.

            No this would not be completely correct, OnBarUpdate would only be triggered when a bar closes. If you are specifically using Calculate.OnEachTick it would be called for each tick as that would be considered a bar close in that use. If you are using Calculate.OnBarClose on a 1 second chart, your OBU events should represent the series it is applied to or once every 1 second in your example.

            Regarding your other questions, the NinjaTrader continuum demo would be real live data.
            To register for a demo, please see ninjatrader.com. On the home page, enter an email and click Download now. When it asks if you need Market data you can press yes to subscribe to a demo account. Selecting "futures" would be the NinjaTrader continuum demo.


            I look forward to being of further assistance.
            JesseNinjaTrader Customer Service

            Comment


              #7
              Thank you Jesse. Your comments and explanations are extremely helpful. I guess I will have couple more questions before I will sail on my own Following your comments I already got the YM data flowing and displayed as a chart. I also slapped the VolumeUpDown indicator that I plan to use as a test bed. Now the question is, how could I get the numbers that this indicator generates? I tried the Data Box, but it just shows a stale numbers (please see the image attached).

              Is there any way to get the numbers as they get processed by indicator?
              Thank you.
              Attached Files

              Comment


                #8
                Hello,

                Thank you for the reply.

                Yes you can access most indicators using NinjaScript using a common signature in the following format:

                Code:
                IndicatorName(parameters)[BarsAgo]
                or
                IndicatorName(parameters).PlotName[BarsAgo]
                In this case, you can see the following document for the specific syntax for VolumeUpDown: https://ninjatrader.com/support/help...htsub=volumeup

                To access the two plots, it would look like:
                Code:
                double upVol = VolumeUpDown().UpVolume[0];
                double downVol = VolumeUpDown().DownVolume[0];
                I look forward to being of further assistance.
                JesseNinjaTrader Customer Service

                Comment


                  #9
                  Hello Jesse. As I finally get rolling with indicators and data feed, I see some issues that concern me. The most important one is the accuracy of data supplied. I checked NT data vs my TS data and found that when the 1-sec volume is small (~3 - 6 contracts), data from both feeds are pretty much the same. But when the 1-sec volume jumps the data feeds are becoming different both in terms of OHLC as well as vol up and vol Down (please see screen attached). As you can see (last 6 columns are YM18 (March), the first 6 columns are $DJI) in this particular case the difference between NT and TS data for YM is quite significant, and this is not the only instance when I see noticeable differences. Can you explain this, please? Thank you.
                  Attached Files

                  Comment


                    #10
                    Hi Jesse, I have found the reason why there is a discrepancy. The ind that I used has this line:
                    Calculate = Calculate.OnEachTick;

                    so it calculates by ticks, not by seconds.

                    But even when I changed this line to:
                    Calculate = Calculate.OnBarClose;

                    it still does not show any results until I change the indicator settings to "On each tick" through the configuration panel. Can you please help me to rewrite this code so the calculations be made on second-by-second basis:


                    Code:
                    protected override void OnStateChange()
                    		{
                    			if (State == State.SetDefaults)
                    			{
                    				Description				= @"rewriting the existent code - testing";
                    				Name					= "testCalcs";
                    				BarsRequiredToPlot		= 0;
                    				Calculate				= Calculate.OnBarClose;
                    				IsOverlay				= false;
                    				DisplayInDataBox		= true;	
                    				DrawOnPricePanel 		= false;
                    				PaintPriceMarkers		= false;
                    				AddPlot(new Stroke(Brushes.Blue, 2), PlotStyle.Bar, "Total");
                    				AddPlot(new Stroke(Brushes.Chartreuse, 2), PlotStyle.Bar, "Buys");
                    				AddPlot(new Stroke(Brushes.Red, 2), PlotStyle.Bar, "Sells");	
                    			}
                    		}
                    
                    		protected override void OnMarketData(MarketDataEventArgs e)
                    		{			
                    			if(e.MarketDataType == MarketDataType.Last)
                    			{				
                    				if(e.Price >= e.Ask)
                    				{
                    					buys += e.Volume;
                    				}
                    				else if (e.Price <= e.Bid)
                    				{
                    					sells += e.Volume;
                    				}
                    				
                    			}	
                    		}
                    Thank you. Cheers!

                    Comment


                      #11
                      Hello,

                      Thank you for the reply.

                      In regard to your post #9, we are currently reviewing this situation further so I will need to reply back on this likely in the coming week as I have further information on this question. I am not certain this would be related to the items in your next post and will need to review this further. Once I have more information I will be replying back here.


                      In regard to your post #10, the OnMarketData override is not controlled by the Calculate setting so changing from OnBarClose to OnEachTick should not affect the OnMarketData logic. This should always be tick by tick events being pushed in.

                      If changing the Calculate setting does affect your results, this is likely due to a change in how the OnBarUpdatel logic is being executed. As I cannot see the logic you have used in its entirety it would be hard to say what is changing in those two different cases. You could likely use Prints to isolate what is different to better understand why it is not working when used OnBarClose.

                      I look forward to being of further assistance.
                      JesseNinjaTrader Customer Service

                      Comment


                        #12
                        Revisiying the data feed issue

                        Hi Jesse,

                        It has been a while since my last post, but you see what is going on the market, so I obviously was being busy with that. Nonetheless, I have written (actually borrowed a large part of it) a script to calculate volume data and output it in the file. Here is the script:

                        Code:
                        using System.IO;
                        namespace NinjaTrader.NinjaScript.Indicators
                        {
                        	public class SYTestInd : Indicator
                        	{
                        		private double	buys 		= 0;
                        		private double	sells 		= 0;
                        		private double	ratio		= 2.0;
                        		private bool 	showTotal 	= true;
                        		private bool 	showMarker	= true;
                        		private int		activeBar;				// added 6/30/16 for renko & linebreak bars that remove bars
                        		
                        		private string path;
                        		private StreamWriter sw; // a variable for the StreamWriter that will be used 		
                        
                        		
                        		protected override void OnStateChange()
                        		{
                        			if (State == State.SetDefaults)
                        			{
                        				Description				= @"just a test to calc volume data and output them in a file";
                        				Name					= "SYTestInd";
                        				path 					= NinjaTrader.Core.Globals.UserDataDir + "MyTestFile.txt"; // Define
                        				BarsRequiredToPlot		= 0;
                        				Calculate				= Calculate.OnEachTick;
                        				IsOverlay				= false;
                        				DisplayInDataBox		= true;	
                        				DrawOnPricePanel 		= false;
                        				PaintPriceMarkers		= false;
                        				AddPlot(new Stroke(Brushes.Blue, 2), PlotStyle.Bar, "Total");
                        				AddPlot(new Stroke(Brushes.Chartreuse, 2), PlotStyle.Bar, "Buys");
                        				AddPlot(new Stroke(Brushes.Red, 2), PlotStyle.Bar, "Sells");	
                        			}
                        			// Cleaning up resources 
                        			else if(State == State.Terminated)
                        			{
                        				if (sw != null)
                        				{
                        					sw.Close();
                        					sw.Dispose();
                        					sw = null;
                        				}
                        			}			
                        		}
                        
                        		protected override void OnMarketData(MarketDataEventArgs e)
                        		{			
                        			if(e.MarketDataType == MarketDataType.Last)
                        			{				
                        				if(e.Price >= e.Ask)
                        				{
                        					buys += e.Volume;
                        				}
                        				else if (e.Price <= e.Bid)
                        				{
                        					sells += e.Volume;
                        				}
                        				
                        			}	
                        		}
                        		
                        		protected override void OnBarUpdate()
                        		{	
                        			
                        			if (CurrentBar < activeBar)  
                        				return;			
                        			
                        			// Update (plot) the bar
                        			Sells[0] 	= sells;
                        			Buys[0] 	= buys;
                        						
                        			sw = File.AppendText(path);  
                        			sw.WriteLine(Time[0] + "," + Open[0] + "," + High[0] + "," + Low[0] + "," + Close[0] + "," + buys + "," + sells); 
                        			sw.Close(); 
                        		
                        			
                        			if (showTotal)
                        			{
                        				Total[0] 	= buys + sells;
                        			}
                        			
                        			if (showMarker)
                        			{
                        			
                        				if ((buys / sells) >= ratio)
                        				{
                        					Draw.TriangleUp (this, "test1", true, 0, (buys+sells) * 1.1, Brushes.Lime);
                        				}
                        				else if ((sells / buys) >= ratio)
                        				{
                        					Draw.TriangleDown (this, "test2", true, 0, (buys+sells)* 1.1, Brushes.Red);
                        				}
                        				else 
                        				{
                        					RemoveDrawObject("test1");
                        					RemoveDrawObject("test2");
                        				}
                        					
                        			}
                        			
                        			
                        			// Reset accumulators/plots on new bar
                        			if (CurrentBar != activeBar)
                        			{
                        				RemoveDrawObject("test1");
                        				RemoveDrawObject("test2");
                        				buys 		= 0;
                        				sells		= 0;
                        				Sells[0]	= 0;
                        				Buys[0] 	= 0;
                        				activeBar 	= CurrentBar;	
                        				if (showTotal)
                        				{
                        					Total[0] = 0;
                        					
                        				}
                        				
                        			}
                        	
                        		}
                        I then ran this code for about 45 mins and collected data in a file. At the same time I was running my TS feed for the same instrument (YM 03.18). Attached please find the *.csv that has data from both streams and as you can see very often they differ a lot. Can you please let me know if this is a problem with the code, or the data somehow are not processed properly elsewhere?

                        Thank you. Cheers! Sergey
                        Attached Files

                        Comment


                          #13
                          Hello syatskevitch,

                          Thank you for the reply.

                          At this point, I dont have anything else I can relay but I can tell you that development is currently reviewing this item in further detail. For the time being, until I have more updates, I would likely suggest to hold off on providing more samples and output data. If development needs any further information surrounding this I can certainly post that here to work with you on this.

                          Once I have any further details I will post back here.


                          I look forward to being of further assistance.
                          JesseNinjaTrader Customer Service

                          Comment


                            #14
                            Hello syatskevitch,

                            I just wanted to reply back on this item as I have received some information from development.

                            Here is a copy of the information I had received in regard to your question.
                            We took a look into this and checked into our servers which record live data for the instrument and time you referenced below. What we found was that all ticks and volume are in fact the same when compared to an external source, what could differ however is the millisecond time stamping of the data. With different providers it’s just a matter of fact that the fractional part of the second can be different, where this comes into play on your test is that if you’re building counts of volume or ticks off, for example, a 10-second bar. Then that bar will include all the volume based on ticks received from 00:00:00 to 00:00:09. What can happen is that when comparing the two sources if the time synchronization is off by some base set of milliseconds, then ticks which occur at the end of the bar could be pushed into the next bar on one vendor and on another vendor those ticks could be still added to the current bar. This is an expected difference when working with time stamping at that low of a scale between multiple servers, locations, and time sync servers.

                            One other thing I did want to mention is that for this test we compared MDP 2.0 style data against MDP 2.0 style data from two vendors. A year or so back CME changed from MDP 2.0 to 3.0, which is a technical term to mean they changed the data format on how data was sent. When they changed to MDP 3.0 a lot less ticks would be sent out since they would be bundled. Market data vendors heard that customers preferred the unbundled data and hence implemented methods to unbundle the data shortly thereafter and is still the popular way to process data today. I do not know where Tradestation sits on that front but would be a known item for a difference that you could research further.
                            Please Let me know if you have any further questions.
                            JesseNinjaTrader Customer Service

                            Comment


                              #15
                              Thank you Jesse. Could you please do me a favor and take a look at the code that I am using? Just to make sure that my code calculates BID & ASK volumes correctly. If my code is fine, then I will try to get info from TS on how they do get 1-sec data.
                              One more question, if I may. If the code produces several lines for multiple ticks during one 1-sec bar (please see attached screen), do I have to take only the columns in the last row as the total BID and ASK volumes for this second, or I have to sum over all tick rows for this particular 1-sec interval?

                              Thank you. Cheers! Sergey
                              Attached Files

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by usazencort, Today, 01:16 AM
                              0 responses
                              1 view
                              0 likes
                              Last Post usazencort  
                              Started by kaywai, 09-01-2023, 08:44 PM
                              5 responses
                              603 views
                              0 likes
                              Last Post NinjaTrader_Jason  
                              Started by xiinteractive, 04-09-2024, 08:08 AM
                              6 responses
                              22 views
                              0 likes
                              Last Post xiinteractive  
                              Started by Pattontje, Yesterday, 02:10 PM
                              2 responses
                              21 views
                              0 likes
                              Last Post Pattontje  
                              Started by flybuzz, 04-21-2024, 04:07 PM
                              17 responses
                              230 views
                              0 likes
                              Last Post TradingLoss  
                              Working...
                              X