Global variables in NT - NinjaTrader Programming | futures io social day trading
futures io futures trading


Global variables in NT
Updated: Views / Replies:7,936 / 24
Created: by Geir Attachments:5

Welcome to futures io.

(If you already have an account, login at the top of the page)

futures io is the largest futures trading community on the planet, with over 90,000 members. At futures io, our goal has always been and always will be to create a friendly, positive, forward-thinking community where members can openly share and discuss everything the world of trading has to offer. The community is one of the friendliest you will find on any subject, with members going out of their way to help others. Some of the primary differences between futures io and other trading sites revolve around the standards of our community. Those standards include a code of conduct for our members, as well as extremely high standards that govern which partners we do business with, and which products or services we recommend to our members.

At futures io, our focus is on quality education. No hype, gimmicks, or secret sauce. The truth is: trading is hard. To succeed, you need to surround yourself with the right support system, educational content, and trading mentors – all of which you can find on futures io, utilizing our social trading environment.

With futures io, you can find honest trading reviews on brokers, trading rooms, indicator packages, trading strategies, and much more. Our trading review process is highly moderated to ensure that only genuine users are allowed, so you don’t need to worry about fake reviews.

We are fundamentally different than most other trading sites:
  • We are here to help. Just let us know what you need.
  • We work extremely hard to keep things positive in our community.
  • We do not tolerate rude behavior, trolling, or vendors advertising in posts.
  • We firmly believe in and encourage sharing. The holy grail is within you, we can help you find it.
  • We expect our members to participate and become a part of the community. Help yourself by helping others.

You'll need to register in order to view the content of the threads and start contributing to our community.  It's free and simple.

-- Big Mike, Site Administrator

Reply
 5  
 
Thread Tools Search this Thread
 

Global variables in NT

  #11 (permalink)
Elite Member
Portland Oregon, United States
 
Futures Experience: Beginner
Platform: Ninjatrader®
Broker/Data: CQG, Kinetick
Favorite Futures: Gameplay Klownbine® Trading of Globex
 
Zondor's Avatar
 
Posts: 1,327 since Jul 2009
Thanks: 1,246 given, 2,635 received

Practical Application of Global Variables - Request for Comments

Let's postulate a workspace with ~10, ~20 charts, or N charts of one instrument that I want to pretend I am trading, in the simulator, of course! Let's call the charts that I use for my "trading" decisions the "client" charts.

Suppose that for some reason I want to be able to put the daily pivots and previous N days VWAPS, Highs, Lows, PoC's etc on all of those charts.

It would NOT be necessary to add pivot, VWAP and profile level indicators to all of these "client" charts. There would be one chart with an indicator that calculates these values and pushes them to another indicator that stores the values in a static DataTable. So the calculations to determine the values only need to be done on ONE chart.

Now that these values are stored in a static DataTable, my understanding is that they would then be accessible to very simple read only indicators on the "client" charts. These indicators would not need to do any calculations and, since the DataTable is static, would not be reliant upon instances of external indicators - they would just grab the values from the static DataTable.

In this particular case all of the static data remain unchanged during the course of the session, so the size of the DataTable would be very small. But even if we extend the concept to include in the table something like the CURRENT DAY VWAP, and the width of its various types of deviation bands, at [for example] one minute intervals, the size of the DataTable would remain manageable.

And, for non-historical operation, the pushing indicators could update the values of static variables, so that the very latest real time values could always be available. So the DataTable would be used only to backfill the "client" charts.

"If we don't loosen up some money, this sucker is going down." -GW Bush, 2008
“Lack of proof that something is true does not prove that it is not true - when you want to believe.” -Humpty Dumpty, 2014
“The greatest shortcoming of the human race is our inability to understand the exponential function.”
Prof. Albert Bartlett
Reply With Quote
The following 3 users say Thank You to Zondor for this post:
 
  #12 (permalink)
Elite Member
Oslo, Norway
 
Futures Experience: Intermediate
Platform: Ninja Trader
Favorite Futures: ES
 
Posts: 6 since Jan 2011
Thanks: 29 given, 29 received


Zondor View Post
Let's postulate a workspace with ~10, ~20 charts, or N charts of one instrument that I want to pretend I am trading, in the simulator, of course! Let's call the charts that I use for my "trading" decisions the "client" charts.

Suppose that for some reason I want to be able to put the daily pivots and previous N days VWAPS, Highs, Lows, PoC's etc on all of those charts.

It would NOT be necessary to add pivot, VWAP and profile level indicators to all of these "client" charts. There would be one chart with an indicator that calculates these values and pushes them to another indicator that stores the values in a static DataTable. So the calculations to determine the values only need to be done on ONE chart.

Now that these values are stored in a static DataTable, my understanding is that they would then be accessible to very simple read only indicators on the "client" charts. These indicators would not need to do any calculations and, since the DataTable is static, would not be reliant upon instances of external indicators - they would just grab the values from the static DataTable.

In this particular case all of the static data remain unchanged during the course of the session, so the size of the DataTable would be very small. But even if we extend the concept to include in the table something like the CURRENT DAY VWAP, and the width of its various types of deviation bands, at [for example] one minute intervals, the size of the DataTable would remain manageable.

And, for non-historical operation, the pushing indicators could update the values of static variables, so that the very latest real time values could always be available. So the DataTable would be used only to backfill the "client" charts.

Hi Zondor

sorry about the late reply, I only just saw your post.

I use my global variables exactly the way you outline it. As you probably saw I have written the receiving indicator in such a way that it caches the latest value. So in my humble opinion there is little overhead for pushing out real time values to the lower time frame charts. You just need to let the sending indicator update real time.

I have written a new indicator that picks up the global variable values. If I recall correctly it can handle up to 8 different global variables. That makes it a bit easier to handle. It also has a parameter for showing the name of the GV on the chart. It then really helps to have a good naming standard for the global variable names, like for instance <instrument><bar size><indicator><key indicator setting (for instance length)>. And of course it makes sense to let the GV plot identically to the original indicator so that you visually recognize the plot.

Regards
Geir

Reply With Quote
The following 4 users say Thank You to Geir for this post:
 
  #13 (permalink)
Market Wizard
 
Futures Experience: Advanced
Platform: Spoon!
 
Rory's Avatar
 
Posts: 2,743 since May 2014
Thanks: 5,444 given, 8,097 received


Hi @drmartell,


drmartell View Post
When I add this user defined method, it compiles fine, but it causes all my custom indicators to stop appearing on the Indicator chart dialog. Can anyone see what might be causing that?

Update: It appears to be this line:

 
Code
public static DataTable	gvTable = new DataTable(); // stores all historical data

but I still don't know why. . .

I tried to compile your code on NT7 and find that the DataTable type is unrecognised. Should this be a part of the available library functions or should I add a reference to some database dll?

Thanks in advance.

Reply With Quote
 
  #14 (permalink)
Elite Member
Oslo, Norway
 
Futures Experience: Intermediate
Platform: Ninja Trader
Favorite Futures: ES
 
Posts: 6 since Jan 2011
Thanks: 29 given, 29 received

Hi Rory

in case your question relates to my initial post there is actually a small omission in my explanation. You need to reference System.Data.dll by right clicking in the NT window for coding and choose References. Then you need to figure out where to find System.Data.dll. Mine is under C:\Windows\Microsoft.NET\Framework64\v2.0.50727\System.Data.dll

Good luck
Geir

Reply With Quote
The following user says Thank You to Geir for this post:
 
  #15 (permalink)
Market Wizard
 
Futures Experience: Advanced
Platform: Spoon!
 
Rory's Avatar
 
Posts: 2,743 since May 2014
Thanks: 5,444 given, 8,097 received


Geir View Post
Hi Rory

in case your question relates to my initial post there is actually a small omission in my explanation. You need to reference System.Data.dll by right clicking in the NT window for coding and choose References. Then you need to figure out where to find System.Data.dll. Mine is under C:\Windows\Microsoft.NET\Framework64\v2.0.50727\System.Data.dll

Good luck
Geir

Much appreciated Geir, thanks for the response! Tried a few DLLs but not that one of course. Looking forward to testing, cheers for your efforts on this idea. Rory.

Reply With Quote
 
  #16 (permalink)
Elite Member
Mesa, AZ/USA
 
Futures Experience: Intermediate
Platform: NinjaTrader, ThinkorSwim
Broker/Data: AMP Futures/CQG, TDA
Favorite Futures: Currency Futures, my Harley Davidson
 
Posts: 94 since Jun 2012
Thanks: 41 given, 126 received


shodson View Post
I would avoid accessing public static data sets directly in order to be more thread-safe. First, I would make the data private, etc.

@shodson @Geir

First I would like to thank all that contributed to the code and ideas in this section, this is exactly what I was looking for in order to solve a problem that I was having with a few indicators I am in the process of developing. I agree that the sharing of global variables in a multiprocessor environment requires a locking mechanism.

So, if I understood your instructions all of your code (with the necessary modifications) needed to be placed into the partial indicator containing the methods as provided by @Geir. Note I tested the unmodified version first and everything worked fine. There are a number of errors that are displayed by the receiver when the chart first comes up (see SS). However, they do not appear when refreshing the chart (F5). They also do not appear if both indicators are deleted, applied and then re-added.

Also, the second problem is that the output of the indicators do not match, sometimes. Although I did not do extensive testing of the unmodified version, after an F5 refresh they plots always matched. The only difference between the unmodified and the modified version is the addition of the locking code. What I also noticed is that they go back into sync after refreshing the historical data even through they did from an F5 refresh, however they begin to go out of sync after the refresh.

I may need to retest the original code again but before I remove the locking to do so I wanted to make sure I understood your instructions correctly and maybe clear up the error messages when it first starts up.

Thank you for your assistance.


 
Code
// GlobalVariableMethods
// by Geir Nilsen
// 
// use SetGlobalVariable to push the global variable value. Note that this method has to be called at CurrentBar 0
// in order to do some house keeping.
#region Using declarations
using System;
using System.ComponentModel;
using System.Drawing;
using NinjaTrader.Cbi;
using NinjaTrader.Data;
using NinjaTrader.Gui.Chart;
using System;
using System.Data;
using System.Collections.Generic;
	
#endregion

namespace NinjaTrader.Indicator
{
    partial class Indicator
    {		
		#region Variables
		// the following dictionaries hold real time values. When new time stamp comes in then data is sent to 
		// table for historic data
		/*
		public static Dictionary<string, DateTime> gvTime 	= new Dictionary<string, DateTime>();
		public static Dictionary<string, double> gvPrice 	= new Dictionary<string, double>();
		
		public static DataTable	gvTable = new DataTable(); // stores all historical data
		*/
		private static Dictionary<string, DateTime>	 	gvTime 	= new Dictionary<string, DateTime>();
		private static Dictionary<string, double> 		gvPrice = new Dictionary<string, double>();
		
		private static DataTable						gvTable = new DataTable(); 		// stores all historical data
		
		private static object 							lockObject = new object();		// Locking Object
		
		#endregion Variables
		
		public void SetGlobalVariable(string identifier, DateTime timeStamp, double value)
		{
		lock(lockObject);
		{	
			
			// prepare table first time the method is used
			if(gvTable.Columns.Count == 0)
			{
				gvTable.Columns.Add("ID", typeof(string));
				gvTable.Columns.Add("Time", typeof(DateTime));
				gvTable.Columns.Add("Price", typeof(double));
			}
			
			// clean up table in case data is already available (when refreshing chart)
			if(CurrentBar == 0)
			{
				string criteria = "ID = '" + identifier + "'";		// sql string
				DataRow[] toBeDeleted = gvTable.Select(criteria);	// perform sql
				if(toBeDeleted.Length > 0)
					foreach (DataRow row in toBeDeleted)
						gvTable.Rows.Remove(row);
			}	
			
			// add new values. For historical data table a row can just be added
			if(Historical)
				gvTable.Rows.Add(identifier, timeStamp, value);
			else
			{
				// check if new timestamp is <> from what is held in dictionary -> new bar
				// ==> add row to gvTable. store current value in dictionary.
				DateTime oldTimeStamp;
				gvTime.TryGetValue(identifier, out oldTimeStamp);
				
				// if we get a new timeStamp, then real time time stamp has changed. Send to table
				if(timeStamp != oldTimeStamp)
				{
					gvTable.Rows.Add(identifier, timeStamp, value);
				}
				
				// cache updated global variable
				gvTime[identifier] = timeStamp;
				gvPrice[identifier] = value;
			}	
		}
		//return true;
		
		}
		public double GetGlobalVariable(string identifier, DateTime timeStamp)
		{
		lock(lockObject);
		{
			
			double toBeReturned = -1;
			
			if(!Historical)
				// check if timeStamp is cached in dictionary. If yes, then return value
				gvPrice.TryGetValue(identifier, out toBeReturned);
			else
			{
				// select specified global variable data from table
				string criteria = "ID = '" + identifier + "'"; 		// sql string
				DataRow[] valuesForID = gvTable.Select(criteria);	// perform sql
				
				// walk through from oldest until time stamp in table is younger than what we are looking for
				foreach(DataRow row in valuesForID)
				{
					if((DateTime)row[1] <= timeStamp)
						toBeReturned = (double)row[2];
					else
						break;
				}
			}
			return toBeReturned;
		}
		}
	}	
}

Attached Thumbnails
Global variables in NT-gv_errors.png   Global variables in NT-gv_error_2.png  
Attached Files
Register to download File Type: cs Global Variables Methods.cs (3.6 KB, 10 views)

Last edited by Cheech; January 29th, 2015 at 09:37 PM.
Reply With Quote
 
  #17 (permalink)
 Vendor: www.probabletrades.com 
OC, California, USA
 
Futures Experience: Advanced
Platform: IB/TWS, NinjaTrader, thinkorswim
Favorite Futures: stocks, options, futures, VIX
 
shodson's Avatar
 
Posts: 1,859 since Jun 2009
Thanks: 480 given, 3,254 received

It looks like your GetGlobalVariable() is getting called before the gvTable and it's columns are initialized. In GetGlobalVariable() you need to make sure your gvTable.Columns.Count > 0 before doing the gvTable.Select().

The clues were in the error message

Please register on futures.io to view futures trading content such as post attachment(s), image(s), and screenshot(s).

Reply With Quote
 
  #18 (permalink)
Elite Member
Mesa, AZ/USA
 
Futures Experience: Intermediate
Platform: NinjaTrader, ThinkorSwim
Broker/Data: AMP Futures/CQG, TDA
Favorite Futures: Currency Futures, my Harley Davidson
 
Posts: 94 since Jun 2012
Thanks: 41 given, 126 received


shodson View Post
It looks like your GetGlobalVariable() is getting called before the gvTable and it's columns are initialized. In GetGlobalVariable() you need to make sure your gvTable.Columns.Count > 0 before doing the gvTable.Select().

The clues were in the error message

Please register on futures.io to view futures trading content such as post attachment(s), image(s), and screenshot(s).

OK, I think I understand what you are saying (I am not a C# programmer so please bear with me on this).

In the GetGlobalVariables method would the test below satisfy the requirement?

If(!Historical && gvTable.Columns.Count > 0)

Is the reason that it worked after the first time because the table was populated?

Reply With Quote
 
  #19 (permalink)
 Vendor: www.probabletrades.com 
OC, California, USA
 
Futures Experience: Advanced
Platform: IB/TWS, NinjaTrader, thinkorswim
Favorite Futures: stocks, options, futures, VIX
 
shodson's Avatar
 
Posts: 1,859 since Jun 2009
Thanks: 480 given, 3,254 received

No, you want to put the check at a higher level, the error is happening inside the "else" part of your if.

I'd do this

below the line

 
Code
double toBeReturned = -1;
put this line

 
Code
if (gvTable.Columns.Count == 0)
    return toBeReturned;
if the table columns aren't there, just get out and bail

Reply With Quote
The following user says Thank You to shodson for this post:
 
  #20 (permalink)
Elite Member
Mesa, AZ/USA
 
Futures Experience: Intermediate
Platform: NinjaTrader, ThinkorSwim
Broker/Data: AMP Futures/CQG, TDA
Favorite Futures: Currency Futures, my Harley Davidson
 
Posts: 94 since Jun 2012
Thanks: 41 given, 126 received



shodson View Post
No, you want to put the check at a higher level, the error is happening inside the "else" part of your if.

I'd do this

below the line

 
Code
double toBeReturned = -1;
put this line

 
Code
if (gvTable.Columns.Count == 0)
    return toBeReturned;
if the table columns aren't there, just get out and bail

OK thank you, I will do that, give it a shot, and report the results.

That said, the second problem is that after the historical data is plotted (correctly) they go out of sync. I didn't modify any of the original code when I added in the locks and at this point not sure if the original code worked. Should the locaks have prevented this from happening or is there something missing in the original code?

Reply With Quote

Reply



futures io > > > > > Global variables in NT

Thread Tools Search this Thread
Search this Thread:

Advanced Search



Upcoming Webinars and Events (4:30PM ET unless noted)

Linda Bradford Raschke: Reading The Tape

Elite only

Adam Grimes: TBA

Elite only

NinjaTrader: TBA

January

Ran Aroussi: TBA

Elite only
     

Similar Threads
Thread Thread Starter Forum Replies Last Post
Global Variables In TS c12345 EasyLanguage Programming 7 October 14th, 2017 10:52 AM
Global Variables - does this beast exist in Ninja trendisyourfriend NinjaTrader Programming 13 May 29th, 2013 07:15 PM
Global variables for sharing data between Charts ECI Ed NinjaTrader Programming 5 March 6th, 2012 10:02 AM
global variables: anyone got a complete NT7 example? elbone NinjaTrader Programming 2 July 19th, 2011 10:13 AM
Global Variables and Strategies in Ninja 6.5 TonyA NinjaTrader Programming 3 November 6th, 2010 08:50 AM


All times are GMT -4. The time now is 12:32 PM.

Copyright © 2017 by futures io, s.a., Av Ricardo J. Alfaro, Century Tower, Panama, +507 833-9432, info@futures.io
All information is for educational use only and is not investment advice.
There is a substantial risk of loss in trading commodity futures, stocks, options and foreign exchange products. Past performance is not indicative of future results.
no new posts
Page generated 2017-12-12 in 0.15 seconds with 20 queries on phoenix via your IP 54.145.16.43