NexusFi: Find Your Edge


Home Menu

 





Need little help/ Unable to access a global variable in custom method


Discussion in NinjaTrader

Updated
    1. trending_up 3,341 views
    2. thumb_up 8 thanks given
    3. group 2 followers
    1. forum 9 posts
    2. attach_file 0 attachments




 
Search this Thread

Need little help/ Unable to access a global variable in custom method

  #1 (permalink)
nemeis45
delhi, delhi, india
 
Posts: 59 since Dec 2013
Thanks Given: 10
Thanks Received: 14

Hi,
I have the following code
 
Code
#region Using declarations
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml.Serialization;
using System.Collections;
using System.Collections.Generic;
using System.Timers;
using NinjaTrader.Cbi;
using NinjaTrader.Data;
using NinjaTrader.Indicator;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Strategy;
#endregion

// This namespace holds all strategies and is required. Do not change it.
namespace NinjaTrader.Strategy
{
    /// <summary>
    /// TestLinkedList
    /// </summary>
    [Description("TestLinkedList")]
    public class TestLinkedList : Strategy
    {
        #region Variables
        // Wizard generated variables
        private static int myInput = 1; // Default setting for MyInput0
		private static LinkedList<double> printlist = new LinkedList<double>();
		private static double lastprint =0;
		private static double someprint =0;		
		private static DateTime startuptime = DateTime.MinValue;		
		private static LinkedListNode<double> currentnode = new LinkedListNode<double>(0.00);
		private System.Timers.Timer secondtimer = new System.Timers.Timer(1000);		
				
        // User defined variables (add any user defined variables below)
        #endregion

        /// <summary>
        /// This method is used to configure the strategy and is called once before any strategy method is called.
        /// </summary>
        protected override void Initialize()
        {
            CalculateOnBarClose = false;
			Add(PeriodType.Second, 1);
			startuptime = DateTime.Now;
        }
		protected override void OnStartUp()
		{
			secondtimer.AutoReset = true;
			secondtimer.Elapsed+=  new ElapsedEventHandler((sender, e) => ProcessPerSecond(sender,e,currentnode));
			secondtimer.Enabled = true;				
			//GC.SuppressFinalize(secondtimer);
		}		

        /// <summary>
        /// Called on each bar update event (incoming tick)
        /// </summary>
        protected override void OnBarUpdate()
        {			
		
        }
		protected override void OnTermination()
		{
			// Cleans up our Timer object
			//secondtimer.Dispose();
		}
		protected void ProcessPerSecond(object sender, EventArgs e,LinkedListNode<double> somenode)
		{
			var instance = new TestLinkedList();
			if(Math.Round(somenode.Value,1)!= 0&&somenode!=null)
			{
				if(somenode.Value != printlist.Last.Value)
				{
					while(somenode!=null)
					{
						instance.Print("From LList");
						instance.Print("Last="+somenode.Value);
						somenode = somenode.Next;
					}
				}
			}
			instance.Print("here");										
			currentnode= printlist.Last;			
		}
		protected override void OnMarketData(MarketDataEventArgs e)
		{
			if(e.MarketDataType==MarketDataType.Last)
			{
				lock(printlist)
				{
				double nowprint = e.Price;
				if(Math.Round(nowprint,2)!=Math.Round(lastprint,2))
				{
					Print("Last Print is"+ nowprint );
					printlist.AddLast(nowprint);
					lastprint = nowprint;
				}
				}				
			}
			
		}
		
    #region Properties
        [Description("")]
        [GridCategory("Parameters")]        
		public int MyInput
        {
            get { return myInput; }           
        }
		public void SetMyInput(int somevalue)
		{
			 myInput = somevalue; 
		}
		[XmlIgnore()]
		public LinkedList<double> Printlist
		{
			get; set;
		}
		public double Lastprint
		{
			get;set;
		}
		public double Someprint
		{
			get;set;
		}		
		[XmlIgnore()]
		public LinkedListNode<double> Currentnode
		{
			get{return currentnode;}set{value = currentnode;}
		}
        #endregion
    }
}
What i am trying to do is take input from OnMarketData(), and then process the fresh data i have received every second.
I have used a timer for the purpose.

The problem i am getting is that the OnMarketData() is handling the global variables like lastprint just fine,
but i cannot seem to get global variables to work in my custom methods. in this case an event method ProcessPerSecond. When i try to access them in custom methods, they seem to be either returning null or a junk value.

Right now the only other thing i can think of is to print the data onto a file and then handle it in both methods separately, but that would significantly increase overhead, plus i want to know why the code isnt working.
How does NT differentiate between OnMarketData() and my custom method that i cannot seem to process global variables.

I tried changing the variable to static variable, using this.Variable to set the values etc, but nothing seems to be working.

Please help

Reply With Quote
Thanked by:

Can you help answer these questions
from other members on NexusFi?
Cheap historycal L1 data for stocks
Stocks and ETFs
Pivot Indicator like the old SwingTemp by Big Mike
NinjaTrader
How to apply profiles
Traders Hideout
NexusFi Journal Challenge - May 2024
Feedback and Announcements
Trade idea based off three indicators.
Traders Hideout
 
Best Threads (Most Thanked)
in the last 7 days on NexusFi
What is Markets Chat (markets.chat) real-time trading ro …
75 thanks
Spoo-nalysis ES e-mini futures S&P 500
55 thanks
Just another trading journal: PA, Wyckoff & Trends
36 thanks
Bigger Wins or Fewer Losses?
24 thanks
The Program
16 thanks
  #2 (permalink)
 
ratfink's Avatar
 ratfink 
Birmingham UK
Market Wizard
 
Experience: Intermediate
Platform: NinjaTrader
Broker: TST/Rithmic
Trading: YM/Gold
Posts: 3,633 since Dec 2012
Thanks Given: 17,423
Thanks Received: 8,426


nemeis45 View Post
I tried changing the variable to static variable, using this.Variable to set the values etc, but nothing seems to be working.

Please help

For reliable global variable use it is best to have the class loaded in an earlier opened workspace chart indicator. Then reference them anywhere using the class name prefix. You can just 'F5' to reload them before any edit/compilation cycles which will otherwise also delink. i.e. always load variables first, then reload distributed code. Also be aware of clearing them in any Initialise methods.

Travel Well
Visit my NexusFi Trade Journal Reply With Quote
  #3 (permalink)
nemeis45
delhi, delhi, india
 
Posts: 59 since Dec 2013
Thanks Given: 10
Thanks Received: 14


you mean like create a dummy class

class dummy: Indicator
{
private int variable1 =0;
private double varibale2 =0;

//Do nothing
// get; set for variables
}
save as an indiactor,
then

var instance = new Dummy();
and then access instance.variable1 and instance.variable2?

Is there any other way to do it, though it is marginally better than using a file to print, but in this case my variables will be in a different file, my code in another, again would be hard to debug if a bug comes up...

Just want to know though why the code isnt working. Is it because i made a mistake somewhere or is it due to Ninjatrader limitation?

The ideal scenario for me would be to use the dll which ninjatrader provides and work on a project using visual studio, but the dll which they provide have very limited functionality . i suspect its becuase they want people to use ninjascript only

Reply With Quote
  #4 (permalink)
 
ratfink's Avatar
 ratfink 
Birmingham UK
Market Wizard
 
Experience: Intermediate
Platform: NinjaTrader
Broker: TST/Rithmic
Trading: YM/Gold
Posts: 3,633 since Dec 2012
Thanks Given: 17,423
Thanks Received: 8,426

It's not that hard, you can just declare the other class in the same file, always using 'public static', and only one declaration needed, it is made available to *all* code in your system then anyway, it's just the memory management and compilation re-linking that gets in the way when making changes.

 
Code
public static class nemVars
{
    public static double theAnswer = 0;
}

You can then reference 'nemVars.theAnswer' anywhere in all the Ninja codespace.

Travel Well
Visit my NexusFi Trade Journal Reply With Quote
Thanked by:
  #5 (permalink)
nemeis45
delhi, delhi, india
 
Posts: 59 since Dec 2013
Thanks Given: 10
Thanks Received: 14

yes its not hard, will try it, not sure if will work 100%, cause the global variable is an object LinkedListNode<double> , there was earlier some problem with getter setter.
thanks!

is there any reason why the first code isnt working? also any other way to use global variables? why is this hard in ninjatrader? any difference in the way compiler sees code from visual studio.

Reply With Quote
  #6 (permalink)
 
ratfink's Avatar
 ratfink 
Birmingham UK
Market Wizard
 
Experience: Intermediate
Platform: NinjaTrader
Broker: TST/Rithmic
Trading: YM/Gold
Posts: 3,633 since Dec 2012
Thanks Given: 17,423
Thanks Received: 8,426


nemeis45 View Post
is there any reason why the first code isnt working? also any other way to use global variables? why is this hard in ninjatrader? any difference in the way compiler sees code from visual studio.

I only glanced at it, applied my simple rule - if it looks too complicated for me then it probably is.

Stuff's not hard in NinjaTrader, I just don't think most people realise what an open environment these guys are providing and how enormous a risk that is, for them and for anybody who thinks programming is easy. Most people do not use simple debugging methods - e.g. Print output from the diagnostics, etc.

There's no difference in code, pretty much anything you can do in C#/.Net you can do under Ninja.

There is an almost infinite way to do things in any programming language, the key is to always look for examples, then learn to select and simplify and build your own bag of techniques and forget the rest.

E.g. if I were doing something like this I might use decalarations like:

 
Code
using System.Collections.Generic;

public class NemItem
{
    public int  value;
    public double ratio;
}


public static class Nem
{
    public static Dictionary<double, NemItem> MyItems = new Dictionary<double, NemItem>();
    public static int  count = 0;
}

(No relation to your application, just for illustration.)

But others might teach you to go the full get/set/object route, it's just choice and what works for you at the end of the day, but above all I say keep it simple and assume code is wrong unless you've seen a Print that says it's right. Cheers.

Travel Well
Visit my NexusFi Trade Journal Reply With Quote
Thanked by:
  #7 (permalink)
nemeis45
delhi, delhi, india
 
Posts: 59 since Dec 2013
Thanks Given: 10
Thanks Received: 14

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

// This namespace holds all strategies and is required. Do not change it.
namespace NinjaTrader.Strategy
{
	public static class GlobalVariables
	{
		public static int myInput = 1; // Default setting for MyInput0
		public static LinkedList<double> printlist = new LinkedList<double>();
		public static double lastprint =0;
		public static double someprint =0;		
		public static LinkedListNode<double> currentnode = new LinkedListNode<double>(0.00);
	}
    /// <summary>
    /// TestLinkedList
    /// </summary>
    [Description("TestLinkedList")]
    public class TestLinkedList : Strategy
    {
        #region Variables
        // Wizard generated variables
		private static DateTime startuptime = DateTime.MinValue;        
		private System.Timers.Timer secondtimer = new System.Timers.Timer(1000);		
				
        // User defined variables (add any user defined variables below)
        #endregion

        /// <summary>
        /// This method is used to configure the strategy and is called once before any strategy method is called.
        /// </summary>
        protected override void Initialize()
        {
            CalculateOnBarClose = false;
			Add(PeriodType.Second, 1);
			startuptime = DateTime.Now;
        }
		protected override void OnStartUp()
		{
			secondtimer.AutoReset = true;
			secondtimer.Elapsed+=  new ElapsedEventHandler((sender, e) => ProcessPerSecond(sender,e,GlobalVariables.currentnode));
			secondtimer.Enabled = true;	
			
		}		

        /// <summary>
        /// Called on each bar update event (incoming tick)
        /// </summary>
        protected override void OnBarUpdate()
        {			
		
        }
		protected override void OnTermination()
		{
			// Cleans up our Timer object
			//secondtimer.Dispose();
		}
		protected void ProcessPerSecond(object sender, EventArgs e,LinkedListNode<double> somenode)
		{
			var instance = new TestLinkedList();
			if(Math.Round(somenode.Value,1)!= 0&&somenode!=null)
			{
				if(Math.Round(somenode.Value,1) != Math.Round(GlobalVariables.printlist.Last.Value,1))
				{
					while(somenode!=null)
					{
						instance.Print("From LList");
						instance.Print("Last="+somenode.Value);
						somenode = somenode.Next;
					}
				}
			}
			instance.Print("here");
			GlobalVariables.currentnode= GlobalVariables.printlist.Last;			
		}
		protected override void OnMarketData(MarketDataEventArgs e)
		{
			if(e.MarketDataType==MarketDataType.Last)
			{
				lock(GlobalVariables.printlist)
				{
				double nowprint = e.Price;
				if(Math.Round(nowprint,2)!=Math.Round(GlobalVariables.lastprint,2))
				{
					Print("Last Print is"+ nowprint );
					GlobalVariables.printlist.AddLast(nowprint);
					GlobalVariables.lastprint = nowprint;
				}
				}				
			}
			
		}
		
    #region Properties
        [Description("")]
        [GridCategory("Parameters")]     
		
		public double Someprint
		{
			get;set;
		}
		public DateTime Startuptime
		{
			get;set;
		}
        #endregion
    }
}
ok i did this. but the same problem is persisting. the timer() isnt working. ill try and debug .
it only times once.

Edit: Nope cant get the timer to work. there is no reason for timer object to be public.
there is nothing complicated about this code. Just takes data from OnMarketData, puts it in a linkedlist and then tries to process fresh data from LinkedList when event from timer is called.

I am getting the data from OnMarketData all right, its printing the o/p allright , problem is processing it from the timer, or any other custom method for that matter.
Also used GC.KeepAlive(), i am pretty sure now its not a timer problem.
I have tested all the individual code snippets in visual studio, the logic works fine, please do help have been struck at same point for almost a week

Reply With Quote
  #8 (permalink)
 
trendwaves's Avatar
 trendwaves 
Florida
Legendary Market Wizard
 
Experience: Advanced
Platform: NinjaTrader 8
Trading: ES, NQ, CL
Posts: 703 since Dec 2012
Thanks Given: 2,898
Thanks Received: 2,525

Try putting the declaration outside the namespace like this...


#region Using declarations
using System;
.......
#endregion

#region GlobalVariableDeclarations
public static class GlobalVariables
{
public static int myInput = 1; // Default setting for MyInput0
public static LinkedList<double> printlist = new LinkedList<double>();
public static double lastprint =0;
public static double someprint =0;
public static LinkedListNode<double> currentnode = new LinkedListNode<double>(0.00);
}
#endregion

// This namespace holds all strategies and is required. Do not change it.
namespace NinjaTrader.Strategy
{
/// Summary...
}

Be Patient and Trade Smart
Visit my NexusFi Trade Journal Reply With Quote
  #9 (permalink)
nemeis45
delhi, delhi, india
 
Posts: 59 since Dec 2013
Thanks Given: 10
Thanks Received: 14

Thanks!, did that now at least the timer is firing

Last Print is103.54
Last Print is103.55
here
here

Its getting fired twice though, i set the timer interval to 10 seconds just to be sure,
its supposed to print "here" only once.

still i think i am dealing with garbage values...

Also in OnTermination()
if i use
GlobalVariables.secondtimer.Dispose();

and i try to apply strategy now, it gives an error in output,
**NT** Error on calling 'OnStartUp' method for strategy 'TestLinkedList/6dce577bd2a643f5b55160c750207055': Cannot access a disposed object.
Object name: 'Timer'.

any idea as to this? getting junk output. how else to dispose off timer

public static class GlobalVariables
{
public static int myInput = 1; // Default setting for MyInput0
public static LinkedList<double> printlist = new LinkedList<double>();
public static double lastprint =0;
public static double someprint =0;
public static LinkedListNode<double> currentnode = new LinkedListNode<double>(0.00);
public static System.Timers.Timer secondtimer = new System.Timers.Timer(10000);
}

Reply With Quote
  #10 (permalink)
nemeis45
delhi, delhi, india
 
Posts: 59 since Dec 2013
Thanks Given: 10
Thanks Received: 14


Got it working nvm, please ignore

Reply With Quote




Last Updated on April 17, 2014


© 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