NexusFi: Find Your Edge


Home Menu

 





Global variables in NT


Discussion in NinjaTrader

Updated
      Top Posters
    1. looks_one Geir with 6 posts (30 thanks)
    2. looks_two Cheech with 5 posts (1 thanks)
    3. looks_3 shodson with 4 posts (10 thanks)
    4. looks_4 Zondor with 3 posts (4 thanks)
      Best Posters
    1. looks_one Geir with 5 thanks per post
    2. looks_two shodson with 2.5 thanks per post
    3. looks_3 drmartell with 1.5 thanks per post
    4. looks_4 Zondor with 1.3 thanks per post
    1. trending_up 17,964 views
    2. thumb_up 51 thanks given
    3. group 20 followers
    1. forum 24 posts
    2. attach_file 5 attachments




 
Search this Thread

Global variables in NT

  #1 (permalink)
 Geir 
Oslo, Norway
 
Experience: Intermediate
Platform: Ninja Trader
Trading: ES
Posts: 10 since Jan 2011
Thanks Given: 46
Thanks Received: 40

Hi

I have been looking for a way to share data between indicators and charts, i.e. replicating the Global Variable dll on TradeStation. The reason for this is that I would like to avoid having to recalculate stuff and spend CPU when I already have the values somewhere else.

I have come up with a very simple solution involving user methods, and it seems to work fine real time.

My lack of C# skills have prevented me from implementing historical data, but the way I see it is that it would be required to store a link to some sort of array per global variable. And then it would be necessary with some logic to retrieve the correct data when historical data is processed.

Would someone like to contribute to make this work on historical data, or does someone have a better idea?


The core are two methods
- SetGlobalVariable -> called by the calculating indicator with a uniqueue identifier (I use the following naming convention <Symbol><chart length><sending indicator>)
- GetGlobalVariable -> called by the receiving indicator, obviously using the same uniqueue identifier

Here is the code for the methods:

 
Code
#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.Collections.Generic;
	
#endregion

namespace NinjaTrader.Indicator
{

    partial class Indicator
    {
		public static Dictionary<string, double> gvHist = new Dictionary<string, double>();
				
		public bool SetGlobalVariable(string identifier, DateTime timeStamp, double value)
		{
			gvHist[identifier] = value;
			return true;
		}
		
		public double GetGlobalVariable(string identifier, DateTime timeStamp)
		{
			if(Historical)
				return 0;
			double value;
			gvHist.TryGetValue(identifier, out value);
			return value;
		}
    }
}
Here a modified SMA which sets a global variable:
 
Code
// 
// Copyright (C) 2006, NinjaTrader LLC <www.ninjatrader.com>.
// NinjaTrader reserves the right to modify or overwrite this NinjaScript component with each release.
//

#region Using declarations
using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;
using System.Xml.Serialization;
using NinjaTrader.Data;
using NinjaTrader.Gui.Chart;
#endregion

// This namespace holds all indicators and is required. Do not change it.
namespace NinjaTrader.Indicator
{
	/// <summary>
	/// The SMAGVExample (Simple Moving Average) is an indicator that shows the average value of a security's price over a period of time.
	/// </summary>
	[Description("The SMAGVExample (Simple Moving Average) is an indicator that shows the average value of a security's price over a period of time.")]
	public class SMAGVExample : Indicator
	{
		#region Variables
		private int		period	= 14;
		private string identifier = @"test";
		#endregion

		/// <summary>
		/// This method is used to configure the indicator and is called once before any bar data is loaded.
		/// </summary>
		protected override void Initialize()
		{
			Add(new Plot(Color.Orange, "SMAGVExample"));

			Overlay = true;
		}

		/// <summary>
		/// Called on each bar update event (incoming tick).
		/// </summary>
		protected override void OnBarUpdate()
		{
			if (CurrentBar == 0)
				Value.Set(Input[0]);
			else
			{
				double last = Value[1] * Math.Min(CurrentBar, Period);

				if (CurrentBar >= Period)
					Value.Set((last + Input[0] - Input[Period]) / Math.Min(CurrentBar, Period));
				else
					Value.Set((last + Input[0]) / (Math.Min(CurrentBar, Period) + 1));
			}
			SetGlobalVariable(identifier, Time[0], Value[0]);
		}

		#region Properties
		/// <summary>
		/// </summary>
		[Description("Numbers of bars used for calculations")]
		[GridCategory("Parameters")]
		public int Period
		{
			get { return period; }
			set { period = Math.Max(1, value); }
		}
		
        [Description("Global variable identifier")]
        [GridCategory("Parameters")]
        public string Identifier
        {
            get { return identifier; }
            set { identifier = value; }
        }		
        #endregion
	}
}
And here the indicator for plotting
 
Code
#region Using declarations
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Data;
using NinjaTrader.Gui.Chart;
#endregion

// This namespace holds all indicators and is required. Do not change it.
namespace NinjaTrader.Indicator
{
    /// <summary>
    /// Plots global variables RT
    /// </summary>
    [Description("Plots global variables")]
    public class GlobalVariablePlot : Indicator
    {
        #region Variables
        // Wizard generated variables
            private string identifier = @""; // Default setting for Identifier
        // User defined variables (add any user defined variables below)
        #endregion

        protected override void Initialize()
        {
            Add(new Plot(Color.FromKnownColor(KnownColor.OrangeRed), PlotStyle.Line, "GlobalVariable"));
            Overlay				= false;
        }

        protected override void OnBarUpdate()
        {
			// Do not plot if historical values
			if (Historical)
				return;
			
            GlobalVariable.Set(GetGlobalVariable(identifier, Time[0]));
        }

        #region Properties
        [Browsable(false)]	// this line prevents the data series from being displayed in the indicator properties dialog, do not remove
        [XmlIgnore()]		// this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove
        public DataSeries GlobalVariable
        {
            get { return Values[0]; }
        }

        [Description("Global variable identifier")]
        [GridCategory("Parameters")]
        public string Identifier
        {
            get { return identifier; }
            set { identifier = value; }
        }
        #endregion
    }
}
The simplest way of testing it is probably to set up a 10 second chart pushing the data, and a 5 seconds chart plotting the global variable.

Added 22.01.2013: See my later post for historical global variables

Attached Thumbnails
Click image for larger version

Name:	GlobalVariables-Example.png
Views:	560
Size:	40.9 KB
ID:	68357  
Started this thread Reply With Quote
The following 19 users say Thank You to Geir for this post:

Can you help answer these questions
from other members on NexusFi?
My NT8 Volume Profile Split by Asian/Euro/Open
NinjaTrader
NexusFi Journal Challenge - April 2024
Feedback and Announcements
Request for MACD with option to use different MAs for fa …
NinjaTrader
ZombieSqueeze
Platforms and Indicators
 
Best Threads (Most Thanked)
in the last 7 days on NexusFi
Retail Trading As An Industry
58 thanks
Battlestations: Show us your trading desks!
50 thanks
NexusFi site changelog and issues/problem reporting
47 thanks
GFIs1 1 DAX trade per day journal
32 thanks
What percentage per day is possible? [Poll]
31 thanks

  #3 (permalink)
 
Big Mike's Avatar
 Big Mike 
Manta, Ecuador
Site Administrator
Developer
Swing Trader
 
Experience: Advanced
Platform: Custom solution
Broker: IBKR
Trading: Stocks & Futures
Frequency: Every few days
Duration: Weeks
Posts: 50,322 since Jun 2009
Thanks Given: 33,143
Thanks Received: 101,476


Very nice, thank you for sharing.

Mike

We're here to help: just ask the community or contact our Help Desk

Quick Links: Change your Username or Register as a Vendor
Searching for trading reviews? Review this list
Lifetime Elite Membership: Sign-up for only $149 USD
Exclusive money saving offers from our Site Sponsors: Browse Offers
Report problems with the site: Using the NexusFi changelog thread
Follow me on Twitter Visit my NexusFi Trade Journal Reply With Quote
  #4 (permalink)
 Taddypole 
Phoenix, Arizona
 
Experience: Advanced
Platform: Ninja Trader
Trading: Oil
Posts: 54 since Jul 2009
Thanks Given: 1
Thanks Received: 7

Do a search over on the Ninja Trader forum for: Gloabal Variables?

There is a thread with 55 responses about using the Globalvariable.dll written for TradeStation. There is also a full example of the SMA.

I'm following that thread right now and have questions about the inner workings because I can't get it to fully work.

I too have needs and believe Global Variable is the best solution. I also used it in TradeStatoin and it worked well.

regards,

taddypole...

Reply With Quote
The following user says Thank You to Taddypole for this post:
  #5 (permalink)
 Geir 
Oslo, Norway
 
Experience: Intermediate
Platform: Ninja Trader
Trading: ES
Posts: 10 since Jan 2011
Thanks Given: 46
Thanks Received: 40


Taddypole View Post
Do a search over on the Ninja Trader forum for: Gloabal Variables?

There is a thread with 55 responses about using the Globalvariable.dll written for TradeStation. There is also a full example of the SMA.

I will follow it as well and see if a solution with historic data is provided. Thanks for pointing mentioning the thread..

Regards
Geir

Started this thread Reply With Quote
  #6 (permalink)
 Geir 
Oslo, Norway
 
Experience: Intermediate
Platform: Ninja Trader
Trading: ES
Posts: 10 since Jan 2011
Thanks Given: 46
Thanks Received: 40

In the mean time I have updated the code slightly to support historical global variables.

Methods required:
 
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
    {		
		// 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
				
		public void SetGlobalVariable(string identifier, DateTime timeStamp, double value)
		{
			// 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;
			}	
		}
		
		public double GetGlobalVariable(string identifier, DateTime timeStamp)
		{
			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;
		}
	}	
}

Here a sample indicator to push a value - it is the same indicator as above, but it pushes with Time[1] in order to get the data right on the receiving chart(s):

 
Code
// 
// Copyright (C) 2006, NinjaTrader LLC <www.ninjatrader.com>.
// NinjaTrader reserves the right to modify or overwrite this NinjaScript component with each release.
//

#region Using declarations
using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;
using System.Xml.Serialization;
using NinjaTrader.Data;
using NinjaTrader.Gui.Chart;
#endregion

// This namespace holds all indicators and is required. Do not change it.
namespace NinjaTrader.Indicator
{
	/// <summary>
	/// The SMAGVExample (Simple Moving Average) is an indicator that shows the average value of a security's price over a period of time.
	/// </summary>
	[Description("The SMAGVExample (Simple Moving Average) is an indicator that shows the average value of a security's price over a period of time.")]
	public class SMAGVExample : Indicator
	{
		#region Variables
		private int		period	= 14;
		private string identifier = @"test";
		#endregion

		/// <summary>
		/// This method is used to configure the indicator and is called once before any bar data is loaded.
		/// </summary>
		protected override void Initialize()
		{
			Add(new Plot(Color.Orange, "SMAGVExample"));

			Overlay = true;
		}

		/// <summary>
		/// Called on each bar update event (incoming tick).
		/// </summary>
		protected override void OnBarUpdate()
		{
			if (CurrentBar == 0)
			{
				Value.Set(Input[0]);
				SetGlobalVariable(identifier, Time[0], Value[0]);
			}
			else
			{
				double last = Value[1] * Math.Min(CurrentBar, Period);

				if (CurrentBar >= Period)
					Value.Set((last + Input[0] - Input[Period]) / Math.Min(CurrentBar, Period));
				else
					Value.Set((last + Input[0]) / (Math.Min(CurrentBar, Period) + 1));
			}
			SetGlobalVariable(identifier, Time[1], Value[0]);
		}

		#region Properties
		/// <summary>
		/// </summary>
		[Description("Numbers of bars used for calculations")]
		[GridCategory("Parameters")]
		public int Period
		{
			get { return period; }
			set { period = Math.Max(1, value); }
		}
		
        [Description("Global variable identifier")]
        [GridCategory("Parameters")]
        public string Identifier
        {
            get { return identifier; }
            set { identifier = value; }
        }		
        #endregion
	}
}

And finally the code for plotting global variables. Be aware that you need to ensure that the sending chart is calculated before the receiver. In case that does not happen when loading ninja you need to go and recalculate manually using F5.

 
Code
#region Using declarations
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Data;
using NinjaTrader.Gui.Chart;
#endregion

// This namespace holds all indicators and is required. Do not change it.
namespace NinjaTrader.Indicator
{
    /// <summary>
    /// Plots global variables RT
    /// </summary>
    [Description("Plots global variables")]
    public class GlobalVariablePlot : Indicator
    {
        #region Variables
        // Wizard generated variables
            private string identifier = @""; // Default setting for Identifier
        // User defined variables (add any user defined variables below)
        #endregion

        protected override void Initialize()
        {
            Add(new Plot(Color.FromKnownColor(KnownColor.OrangeRed), PlotStyle.Line, "GlobalVariable"));
            Overlay				= false;
        }

        protected override void OnBarUpdate()
        {
	            GlobalVariable.Set(GetGlobalVariable(identifier, Time[0]));
        }

        #region Properties
        [Browsable(false)]	// this line prevents the data series from being displayed in the indicator properties dialog, do not remove
        [XmlIgnore()]		// this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove
        public DataSeries GlobalVariable
        {
            get { return Values[0]; }
        }

        [Description("Global variable identifier")]
        [GridCategory("Parameters")]
        public string Identifier
        {
            get { return identifier; }
            set { identifier = value; }
        }
        #endregion
    }
}

Started this thread Reply With Quote
The following 6 users say Thank You to Geir for this post:
  #7 (permalink)
 
drmartell's Avatar
 drmartell 
Portland, OR
 
Experience: Intermediate
Platform: NinjaTrader mostly
Broker: I've tried 'em all
Trading: ZN, ES, 6E, TF, CL
Posts: 94 since Mar 2010
Thanks Given: 176
Thanks Received: 79

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. . .

Visit my NexusFi Trade Journal Reply With Quote
  #8 (permalink)
 Geir 
Oslo, Norway
 
Experience: Intermediate
Platform: Ninja Trader
Trading: ES
Posts: 10 since Jan 2011
Thanks Given: 46
Thanks Received: 40


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. . .

Hi drmartell

I have not heard of similar problems and I have no idea what this could be.

I guess that Ninja Trader does not provide support when it comes to custom code, but they do provide a framework in which it is possible to program the platform. And when this framework starts behaving strangely in some instances, then I assume that they would be interested in investigating the issue.

I hope this helps.

Regards
Geir

Started this thread Reply With Quote
  #9 (permalink)
 
drmartell's Avatar
 drmartell 
Portland, OR
 
Experience: Intermediate
Platform: NinjaTrader mostly
Broker: I've tried 'em all
Trading: ZN, ES, 6E, TF, CL
Posts: 94 since Mar 2010
Thanks Given: 176
Thanks Received: 79


Geir View Post
I have not heard of similar problems and I have no idea what this could be.

Thanks for the reply, this turned out to be a Reference issue. Somehow a reference to .NET 4.0 snuck in and I had to point it back to 2.0.

I also made some changes that I have not thoroughly tested, but seem to be working for me.

I moved the GV list into its own class to further insulate it conceptually and I changed up the indicator codes. The intended function is now that you would set the sending indicator's "Input series" to whatever you like. So in other words you can choose any indicator available within your platform as an Input. In order to make this work I had to change from Time[0] to Bars.GetTime(CurrentBar).

Anyhow hope it is helpful:

Global Variable User Defined Method

 
Code
// by Geir Nilsen
// https://nexusfi.com/ninjatrader-programming/18967-global-variables-ninjatrader.html
// 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.Data;
using System.Collections.Generic;
	
#endregion

namespace NinjaTrader.Indicator
{
    partial class Indicator
    {		
		// the following dictionaries hold real time values. When new time stamp comes in then data is sent to 
		// table for historic data
		public class GV
		{
			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
		}
		
		public void SetGlobalVariable(string identifier, DateTime timeStamp, double value)
		{
			// prepare table first time the method is used
			if(GV.gvTable.Columns.Count == 0)
			{
				GV.gvTable.Columns.Add("ID", typeof(string));
				GV.gvTable.Columns.Add("Time", typeof(DateTime));
				GV.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 = GV.gvTable.Select(criteria);	// perform sql
				if(toBeDeleted.Length > 0)
					foreach (DataRow row in toBeDeleted)
						GV.gvTable.Rows.Remove(row);
			}	
			
			// add new values. For historical data table a row can just be added
			if(Historical)
				GV.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;
				GV.gvTime.TryGetValue(identifier, out oldTimeStamp);
				
				// if we get a new timeStamp, then real time time stamp has changed. Send to table
				if(timeStamp != oldTimeStamp)
				{
					GV.gvTable.Rows.Add(identifier, timeStamp, value);
				}
				
				// cache updated global variable
				GV.gvTime[identifier] = timeStamp;
				GV.gvPrice[identifier] = value;
			}	
		}
		
		public double GetGlobalVariable(string identifier, DateTime timeStamp)
		{
			double toBeReturned = -1;
			
			if(!Historical)
				// check if timeStamp is cached in dictionary. If yes, then return value
				GV.gvPrice.TryGetValue(identifier, out toBeReturned);
			else
			{
				// select specified global variable data from table
				string criteria = "ID = '" + identifier + "'"; 		// sql string
				DataRow[] valuesForID = GV.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;
		}
	}	
}

GlobalVariableSend Indicator

 
Code
#region Using declarations
using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;
using System.Xml.Serialization;
using NinjaTrader.Data;
using NinjaTrader.Gui.Chart;
using System.Windows.Forms;
#endregion

namespace NinjaTrader.Indicator
{
	/// <summary>
	/// GlobalVariableSend
	/// https://nexusfi.com/ninjatrader-programming/18967-global-variables-ninjatrader.html
	/// </summary>
	[Description("GlobalVariableSend")]
	public class GlobalVariableSend : Indicator
	{
		//-> Variables
		//<- Variables

		//-> Properties
		private string identifier;
        [Description("Global variable identifier")]
        [GridCategory("Parameters")]
        public string Identifier
        {
            get { return identifier; }
            set { identifier = value; }
        }		
		
        [Browsable(false)]	// this line prevents the data series from being displayed in the indicator properties dialog, do not remove
        [XmlIgnore()]		// this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove
        public DataSeries GVsend
        {
            get { return Values[0]; }
        }
        //<- Properties
		
		protected override void Initialize()
		{
           	Add(new Plot(new Pen(Color.OrangeRed, 2), PlotStyle.Line,  "GVsend"));
			Overlay = false;
				
			identifier = Instrument.FullName + " " + BarsPeriod.Value + " " + BarsPeriod.BasePeriodType + " " + "[UniqueID?]";
			
			BarsRequired = 0;
		}

		protected override void OnStartUp()
		{
			if (identifier == Instrument.FullName + " " + BarsPeriod.Value + " " + BarsPeriod.BasePeriodType + "[UniqueID?]")
			{
				MessageBox.Show("It appears you are using the default identifier.\n\nThe intention is to replace 'UniqueID?' with something of your choosing. . .", "Global Variable Send Unique Identifier", MessageBoxButtons.OK, MessageBoxIcon.Exclamation,MessageBoxDefaultButton.Button1);
			}
		}

		protected override void OnBarUpdate()
		{
			GVsend.Set(Input[0]);
			SetGlobalVariable(identifier, Bars.GetTime(CurrentBar), GVsend[0]);
		}
	}
}

GlobalVariableReceive Indicator

 
Code
#region Using declarations
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Data;
using NinjaTrader.Gui.Chart;
using System.Windows.Forms;
#endregion

// This namespace holds all indicators and is required. Do not change it.
namespace NinjaTrader.Indicator
{
    /// <summary>
    /// GlobalVariableReceive
	/// https://nexusfi.com/ninjatrader-programming/18967-global-variables-ninjatrader.html
    /// </summary>
    [Description("GlobalVariableReceive")]
    public class GlobalVariableReceive : Indicator
    {
		//-> Variables
		private bool isError = false;
		//<- Variables

        //-> Properties
		private string identifier;
        [Description("Global variable identifier")]
        [GridCategory("Parameters")]
        public string Identifier
        {
            get { return identifier; }
            set { identifier = value; }
        }
		
        [Browsable(false)]	// this line prevents the data series from being displayed in the indicator properties dialog, do not remove
        [XmlIgnore()]		// this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove
        public DataSeries GVreceive
        {
            get { return Values[0]; }
        }
        //<- Properties
		
        protected override void Initialize()
        {
            Add(new Plot(new Pen(Color.OrangeRed, 2), PlotStyle.Line,  "GVreceive"));
			Overlay	= false;
		
			identifier = "???";
        }
		
		protected override void OnStartUp()
		{
			if (identifier == "???")
			{
				MessageBox.Show("It appears you are using the default identifier.\n\nEnsure this identifier matches that of the sending chart.", "Global Variable Receive Unique Identifier", MessageBoxButtons.OK, MessageBoxIcon.Exclamation,MessageBoxDefaultButton.Button1);
			}
		}
		
        protected override void OnBarUpdate()
        {
			if (isError) return;
			
			try
			{
				GVreceive.Set(GetGlobalVariable(identifier, Time[0]));
			}
			catch (Exception e)
			{
				isError = true;
				MessageBox.Show(e.ToString(), "Global Variable Receive Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation,MessageBoxDefaultButton.Button1);
			}
        }
    }
}

Visit my NexusFi Trade Journal Reply With Quote
The following 3 users say Thank You to drmartell for this post:
  #10 (permalink)
 
shodson's Avatar
 shodson 
OC, California, USA
Quantoholic
 
Experience: Advanced
Platform: IB/TWS, NinjaTrader, ToS
Broker: IB, ToS, Kinetick
Trading: stocks, options, futures, VIX
Posts: 1,976 since Jun 2009
Thanks Given: 533
Thanks Received: 3,709


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

 
Code
private static Dictionary<string, double> gvHist = new Dictionary<string, double>();
Then, in any methods that read or write the global data I would place locking mechanisms to avoid multi-threading problems. To do this I would first create a lock

 
Code
private static object lockObject = new object();
Then create a critical section around reading/reading of the Dictionary

 
Code
public bool SetGlobalVariable(string identifier, DateTime timeStamp, double value)
{
	lock(lockObject)
	{
		gvHist[identifier] = value;
	}
	return true;
}

public double GetGlobalVariable(string identifier, DateTime timeStamp)
{
	if(Historical)
		return 0;
	double value;
	
	lock(lockObject)
	{
		gvHist.TryGetValue(identifier, out value);
	}
	return value;
}
You can learn more about locks here - lock Statement (C# Reference)

Follow me on Twitter Visit my NexusFi Trade Journal Reply With Quote
The following 8 users say Thank You to shodson for this post:





Last Updated on March 31, 2016


© 2024 NexusFi™, s.a., All Rights Reserved.
Av Ricardo J. Alfaro, Century Tower, Panama City, Panama, Ph: +507 833-9432 (Panama and Intl), +1 888-312-3001 (USA and Canada)
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.
About Us - Contact Us - Site Rules, Acceptable Use, and Terms and Conditions - Privacy Policy - Downloads - Top
no new posts