NexusFi: Find Your Edge


Home Menu

 





NinjaScript Little Helpers Code Share - Snippets/UserDefinedMethods


Discussion in NinjaTrader

Updated
      Top Posters
    1. looks_one gregid with 13 posts (28 thanks)
    2. looks_two bltdavid with 12 posts (17 thanks)
    3. looks_3 Fat Tails with 3 posts (8 thanks)
    4. looks_4 ratfink with 2 posts (1 thanks)
      Best Posters
    1. looks_one Fat Tails with 2.7 thanks per post
    2. looks_two gregid with 2.2 thanks per post
    3. looks_3 timefreedom with 2 thanks per post
    4. looks_4 bltdavid with 1.4 thanks per post
    1. trending_up 10,281 views
    2. thumb_up 61 thanks given
    3. group 11 followers
    1. forum 34 posts
    2. attach_file 3 attachments




 
Search this Thread

NinjaScript Little Helpers Code Share - Snippets/UserDefinedMethods

  #1 (permalink)
 
gregid's Avatar
 gregid 
Wrocław, Poland
 
Experience: Intermediate
Platform: NinjaTrader, Racket
Trading: Ockham's razor
Posts: 650 since Aug 2009
Thanks Given: 320
Thanks Received: 623

I've seen many times how a small helper methods can greatly increase productivity. So the idea for this thread is to share such little code snippets that will extend the existing NinjaScript methods.

In NinjaTrader the simplest way to extend its functionality accross the board (ie: for all Indicators or Strategies) is to include the methods and properties in UserDefinedMethods.cs file, where already an empty partial class is defined.

There are 2 separate UserDefinedMethods.cs files - one for Strategies and one for Indicators so if you have a method you would like to see both in Strategies and Indicators you need to paste the code into both of them.

For Indicator you place the code inside of:
 
Code
partial class Indicator
{
    // Your code here
}
For Strategies you place the code inside of:
 
Code
partial class Strategy
{
    // Your code here
}
Also remember to make all methods and properties you would like to access public, eg.
 
Code
public void DoSomething()
{
}

If you have some cool methods, feel free to post them in this thread!

Started this thread Reply With Quote
The following 5 users say Thank You to gregid 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
ZombieSqueeze
Platforms and Indicators
Request for MACD with option to use different MAs for fa …
NinjaTrader
 
Best Threads (Most Thanked)
in the last 7 days on NexusFi
Retail Trading As An Industry
67 thanks
NexusFi site changelog and issues/problem reporting
47 thanks
Battlestations: Show us your trading desks!
43 thanks
GFIs1 1 DAX trade per day journal
32 thanks
What percentage per day is possible? [Poll]
31 thanks

  #3 (permalink)
 
gregid's Avatar
 gregid 
Wrocław, Poland
 
Experience: Intermediate
Platform: NinjaTrader, Racket
Trading: Ockham's razor
Posts: 650 since Aug 2009
Thanks Given: 320
Thanks Received: 623


One example where I've realized I spent too much time is with native Print method.

Firstly I wasted time on formatting and adding prefixes like Time[0], or some identifiers to know where the info came from.

Secondly I wasted time on writing Print, testing, commenting out or removing then writing it again and again.
So I wrote the extension to Print called PrintMe with the following functionality:
  1. You can turn printing On and Off
  2. You can add identifiers such as Time, Name, your own Identifier
  3. You can change the separator for the above parts
  4. You can change the time formatting
  5. You can group messages into different categories/level of depth and decide which ones to display

These properties will be included in any Indicator or Strategy once in UserDefinedMethods and from the code instead of old Print("Some Message") you use:
 
Code
PrintMe("Some Message");
// or with grouping:
PrintMe(1,"Some Message");

Here is the code (follow the instructions from first post):
 
Code
        private bool _isPrint = true;
        private bool _printWithName = false;
        private string _uniqueIdentifier = "";
        private bool _printWithTime = true;
        private string _timeFormat = "MM-dd hh:mm:ss";
        private string _groupsIncluded = "0";
        private string _separator = " | ";

        private string[] _groupsArray;
        private int _gInt = 0;
        private string _msg = "";

        /// <summary>
        /// Print if group is to be included
        /// </summary>
        public void PrintMe(int group, string message)
        {
            if (_groupsIncluded == "" || _groupsIncluded == "0" || _groupsIncluded == "*")
                PrintMe(message);
            else
            {
                _groupsArray = _groupsIncluded.Split(',');
                foreach (string g in _groupsArray)
                {
                    int.TryParse(g, out _gInt);
                    if (group == _gInt)
                        PrintMe(message);
                }
            }
        }

        /// <summary>
        /// Print with predefined prefixes (date, time, name)
        /// </summary>
        public void PrintMe(string message)
        {
            if (_isPrint)
            {
                if (_printWithName) _msg += this.Name + _separator;
                if (_uniqueIdentifier != "") _msg += _uniqueIdentifier + _separator;
                if (_printWithTime) _msg += Time[0].ToString(_timeFormat) + _separator;

                _msg += message;
                Print(_msg);
                _msg = "";
            }
        }


        /// <summary>
        /// </summary>
        [Description("Print To Output Window?\n/False disables printing")]
        [Category("Debug")]
        [Gui.Design.DisplayName("Debug Print to Output Window?")]
        public bool PrintToOutputWindow
        {
            get { return _isPrint; }
            set { _isPrint = value; }
        }
        /// <summary>
        /// </summary>
        [Description("Comma separated, '0' to print all groups")]
        [Category("Debug")]
        [Gui.Design.DisplayName("Limit Print to Groups:")]
        public string GroupsIncluded
        {
            get { return _groupsIncluded; }
            set { _groupsIncluded = value; }
        }
        /// <summary>
        /// </summary>
        [Description("Include Name in Print To Output Window?")]
        [Category("Debug")]
        [Gui.Design.DisplayName("Print with Name?")]
        public bool PrintWithName
        {
            get { return _printWithName; }
            set { _printWithName = value; }
        }
        /// <summary>
        /// </summary>
        [Description("Include this Indentifier in Print To Output Window.\nLeave blank to ignore.")]
        [Category("Debug")]
        [Gui.Design.DisplayName("Print with this Identifier:")]
        public string UniqueIdentifier
        {
            get { return _uniqueIdentifier; }
            set { _uniqueIdentifier = value; }
        }

        /// <summary>
        /// </summary>
        [Description("Include Time in Print To Output Window?")]
        [Category("Debug")]
        [Gui.Design.DisplayName("Print with Time?")]
        public bool PrintWithTime
        {
            get { return _printWithTime; }
            set { _printWithTime = value; }
        }
        /// <summary>
        /// </summary>
        [Description("Separate Message Parts With Following Charackters.")]
        [Category("Debug")]
        [Gui.Design.DisplayName("Parts Separator:")]
        public string SeparatorForStrings
        {
            get { return _separator; }
            set { _separator = value; }
        }

        /// <summary>
        /// </summary>
        [Description("Time Format to be used in Print to Output Window")]
        [Category("Debug")]
        [Gui.Design.DisplayName("Time Format")]
        public string DebugTimeFormat
        {
            get { return _timeFormat; }
            set { _timeFormat = value; }
        }
New properties are added to PropertyGrid under category "Debug".

With PrintMe in place I no longer need to comment out any PrintMe, I leave them where they are and if I feel I don't need them for now I simply change the default for PrintToOutputWindow to false in Initialize in the specific indicator. The same with other properties - you can change the default values in Initialize().

Started this thread Reply With Quote
The following 9 users say Thank You to gregid for this post:
  #4 (permalink)
 
gregid's Avatar
 gregid 
Wrocław, Poland
 
Experience: Intermediate
Platform: NinjaTrader, Racket
Trading: Ockham's razor
Posts: 650 since Aug 2009
Thanks Given: 320
Thanks Received: 623

If you would rather use names for grouping PrintMe here is another overload to do just that:
 
Code
        /// <summary>
        /// Print if group is to be included using string or characters to identify groups
        /// </summary>
        public void PrintMe(string group, string message)
        {
            if (_groupsIncluded == "" || _groupsIncluded == "0" || _groupsIncluded == "*")
                PrintMe(message);
            else
            {
                _groupsArray = _groupsIncluded.Split(',');
                foreach (string g in _groupsArray)
                {
                    if (group == g)
                        PrintMe(message);
                }
            }
        }
To use:
 
Code
PrintMe("Orders", "Some Message");
You can mix use of all overloads together when requesting them in the list, eg:

 
Code
Limit Print to Groups: Order,1,test,2

Started this thread Reply With Quote
  #5 (permalink)
 
gregid's Avatar
 gregid 
Wrocław, Poland
 
Experience: Intermediate
Platform: NinjaTrader, Racket
Trading: Ockham's razor
Posts: 650 since Aug 2009
Thanks Given: 320
Thanks Received: 623

I recently learned from @cory, a nice trick to draw symbols with graphic fonts (eg. wingdings).

So I added a custom method where I predefine some symbols I want to use and then call it from Indicator like this:
 
Code
DrawFontSymbol("Sun"+Time[0].ToString(), SymbolFontType.Sun, 15, 0,High[0],Color.IndianRed);
Here is a code with 2 predefined symbols (one from Webdings and one from Wingdings), just add it to your partial class (eg. UserDefinedMethod.cs) to have it available for all:
 
Code
        #region DrawFontSymbol
        public enum SymbolFontType
        {
            LightningBolt,
            Sun
        }

        public void DrawFontSymbol(string tag, SymbolFontType symbol, int size, int barsAgo, double y, Color color)
        {
            bool ascale = false;

            switch (symbol)
            {
                case SymbolFontType.LightningBolt:
                    DrawText(tag, ascale, "~", barsAgo, y, 0, color, new Font("Webdings", size), StringAlignment.Center, Color.Empty, Color.Empty, 1);
                    break;
                case SymbolFontType.Sun:
                    DrawText(tag, ascale, "R", barsAgo, y, 0, color, new Font("Wingdings", size), StringAlignment.Center, Color.Empty, Color.Empty, 1);
                    break;
                default:
                    break;
            }
        }
        #endregion

For a list of available symbols in both Webdings and Wingdings go to:
Wingdings and Webdings!

Started this thread Reply With Quote
The following 2 users say Thank You to gregid for this post:
  #6 (permalink)
 
gregid's Avatar
 gregid 
Wrocław, Poland
 
Experience: Intermediate
Platform: NinjaTrader, Racket
Trading: Ockham's razor
Posts: 650 since Aug 2009
Thanks Given: 320
Thanks Received: 623

If you've ever worked with Plot override and custom drawing then you know how painfull the process is with finding the right coordinates. Attached file (ChartHelper) has some nice helper methods to assist you in the process.

PS. I don't know who the original author of the file is.

Attached Files
Elite Membership required to download: ChartHelper.zip
Started this thread Reply With Quote
The following user says Thank You to gregid for this post:
  #7 (permalink)
 
gregid's Avatar
 gregid 
Wrocław, Poland
 
Experience: Intermediate
Platform: NinjaTrader, Racket
Trading: Ockham's razor
Posts: 650 since Aug 2009
Thanks Given: 320
Thanks Received: 623

Another simple helper I use from time to time to display or print the numbers in their ordinal form (1st, 2nd, 3rd, etc.).

To use with integers, eg.:

 
Code
int exampleNumber = 5;
Print(GetOrdinal(exampleNumber) + " Trade")
// Result: 5th Trade
Code:
 
Code
        public static string GetOrdinal(int num)
        {
            if (num.ToString().EndsWith("11")) return num+"th";
            if (num.ToString().EndsWith("12")) return num + "th";
            if (num.ToString().EndsWith("13")) return num + "th";
            if (num.ToString().EndsWith("1")) return num + "st";
            if (num.ToString().EndsWith("2")) return num + "nd";
            if (num.ToString().EndsWith("3")) return num + "rd";
            return num + "th";
        }

Started this thread Reply With Quote
The following user says Thank You to gregid for this post:
  #8 (permalink)
 
gregid's Avatar
 gregid 
Wrocław, Poland
 
Experience: Intermediate
Platform: NinjaTrader, Racket
Trading: Ockham's razor
Posts: 650 since Aug 2009
Thanks Given: 320
Thanks Received: 623

It seems to me I vastly overestimated usefullness of such thread - as the only people that have shown any interest (thanks) are the ones that could easily deal without my help, plus my hope was to learn something from others as well.

I think I will stop sharing more for now as I feel that I am sharing it with myself

Next time I will decide to share something I will call the thread something more catchy, how about: "Traders are thieves!!!"

Started this thread Reply With Quote
The following user says Thank You to gregid for this post:
  #9 (permalink)
 timefreedom 
Indianapolis, IN USA
 
Experience: Advanced
Platform: Ninjatrader TOS Custom
Broker: Several
Trading: ES CL ZB
Posts: 374 since Dec 2009
Thanks Given: 226
Thanks Received: 381


gregid View Post
It seems to me I vastly overestimated usefullness of such thread - as the only people that have shown any interest (thanks) are the ones that could easily deal without my help, plus my hope was to learn something from others as well.

I think I will stop sharing more for now as I feel that I am sharing it with myself

Next time I will decide to share something I will call the thread something more catchy, how about: "Traders are thieves!!!"

I think your thread is a great idea. A couple of quick snippets that come to mind... the beautiful code posted by @Fat Tails to convert to treasury format numbers. Also @Silvester17 has posted a treasure trove of little gems as well. Hang in there - right now, indicators and t/a have been dismissed here in favor of using vix, usd/jpy, bonds, and the fed to "form a market opinion" and then based on that you guess what the market will do and trade accordingly. That will pass. What the market is actually doing is far more important than what someone thinks it should do, or might do, etc. Thanks for your contributions.

Reply With Quote
The following 2 users say Thank You to timefreedom for this post:
  #10 (permalink)
 timefreedom 
Indianapolis, IN USA
 
Experience: Advanced
Platform: Ninjatrader TOS Custom
Broker: Several
Trading: ES CL ZB
Posts: 374 since Dec 2009
Thanks Given: 226
Thanks Received: 381



timefreedom View Post
I think your thread is a great idea. A couple of quick snippets that come to mind... the beautiful code posted by @Fat Tails to convert to treasury format numbers. Also @Silvester17 has posted a treasure trove of little gems as well. Hang in there - right now, indicators and t/a have been dismissed here in favor of using vix, usd/jpy, bonds, and the fed to "form a market opinion" and then based on that you guess what the market will do and trade accordingly. That will pass. What the market is actually doing is far more important than what someone thinks it should do, or might do, etc. Thanks for your contributions.

Here is the code from @Fat Tails that displays treasury formats. Insert #region Miscellaneous after #region Properties.

 
Code
		#region Miscellaneous

		public override string FormatPriceMarker(double price)
		{
			double trunc = Math.Truncate(price);
			int fraction = Convert.ToInt32(320 * Math.Abs(price - trunc) - 0.0001); // rounding down for ZF and ZT
			string priceMarker = "";
			if (TickSize == 0.03125) 
			{
				fraction = fraction/10;
				if (fraction < 10)
					priceMarker = trunc.ToString() + "'0" + fraction.ToString();
				else 
					priceMarker = trunc.ToString() + "'" + fraction.ToString();
			}
			else if (TickSize == 0.015625 || TickSize == 0.0078125)
			{
				if (fraction < 10)
					priceMarker = trunc.ToString() + "'00" + fraction.ToString();
				else if (fraction < 100)
					priceMarker = trunc.ToString() + "'0" + fraction.ToString();
				else	
					priceMarker = trunc.ToString() + "'" + fraction.ToString();
			}
			else
				priceMarker = price.ToString(Gui.Globals.GetTickFormatString(TickSize));
			return priceMarker;
		}		
		#endregion

Reply With Quote
The following 2 users say Thank You to timefreedom for this post:





Last Updated on May 15, 2015


© 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