NexusFi: Find Your Edge


Home Menu

 





What is the best way to structuring custom classes?


Discussion in NinjaTrader

Updated
    1. trending_up 4,379 views
    2. thumb_up 4 thanks given
    3. group 5 followers
    1. forum 4 posts
    2. attach_file 4 attachments




 
Search this Thread

What is the best way to structuring custom classes?

  #1 (permalink)
 shansen 
Melbourne, Australia
 
Experience: Intermediate
Platform: NinjaTrader
Trading: ES
Posts: 18 since Aug 2013
Thanks Given: 2
Thanks Received: 5

futures.io (formerly BMT) Forum,

My question would likely have been faced by most developers at some point. What is the best way to structure custom classes for quick writing, eased debugging, improved reliability & increased reusability?

I was of the understanding creating a new project for Business Logic (BL) (as per the attached screenshot) was the approach to take... now I'm not so sure. It is effective for creating custom classes which can be instantiated by classes within NT.Custom.Indicators. However, custom classes can not access properties (e.g. High[0], SMA(20)[0]) and methods from the class Indicator. What is the best way to structure custom code to access these properties from a project outside of the project NT.Custom? Alternatively, is there an entirely different approach I should be taking?

By way of example, the code (below and attached) compiles and runs. It demonstrates dependency inversion within the namespace NT.Indicator within the project NT.Custom. However, my problem presents where:
- a new project "NT.Custom.BL" is added to the solution NT.Custom
- a reference is added to the project "NT.Custom.BL" pointing to NT.Core
- a reference is added to the project "NT.Custom pointing" to "NT.Custom.BL" (within VS2013 and via the NinjaScript window within NT)
- the class SubClass (in the below code) is moved from the project NT.Custom to the project NT.Custom.BL.

As the reference added to NT.Custom points to NT.Custom.BL, a reference can not be added to NT.Custom.BL pointing back to NT.Custom. Without such a reference, NT.Custom.BL can not resolve the symbol 'StandardIndicator' in the constructor of the class SubClass. How can I appropriately access High[0] from a class outside of NT.Custom?

 
Code
namespace NinjaTrader.Indicator
{
  [Description("Enter the description of your new custom indicator here")]
  public class StandardIndicator : Indicator
  {
    private SubClass _subClass;

    protected override void Initialize()
    {
      Overlay = false;
    }

    protected override void OnStartUp()
    {
      _subClass = new SubClass(this);
    }

    protected override void OnBarUpdate()
    {
      var stdClassHigh = High[0];
      var subClassHigh = _subClass.GetHighUsingDependancyInversion();
      if (Math.Abs(stdClassHigh - subClassHigh) < 0.01)
        Print(stdClassHigh.ToString("n") + " = " + subClassHigh.ToString("n"));
    }
  }

  /* Unlike the class StandardIndicator, the class SubClass does not inherit from the class Indicator.  
   * As such, it can not access any methods or properties from the class Indicator or in turn IndicatorBase */ 
  public class SubClass
  {
    /* The GetHigh method does not compile.  
     * Can not resolve the symbol 'High' */
    public double GetHigh()
    {
      //return High[0];
      return 0.00;
    }
	
    /* Using Dependency Inversion, methods and properties from the class Indicator can be accessed.
     * This includes any methods in the class UserDefinedMethods. */
    private StandardIndicator _ind;

    public SubClass(StandardIndicator indicator)
    {
      _ind = indicator;
    }

    public double GetHighUsingDependancyInversion()
    {
      return _ind.High[0];
    }
  }
}
This has also been posted in the NT forum Undocumented/Unsupported Ninja Tips and Tricks #169 .

Thanks & regards
Shannon

Attached Thumbnails
Click image for larger version

Name:	NT.Custom.BL.PNG
Views:	197
Size:	8.8 KB
ID:	153906  
Attached Files
Elite Membership required to download: StandardIndicator.cs
Started this thread Reply With Quote
Thanked by:

Can you help answer these questions
from other members on NexusFi?
Exit Strategy
NinjaTrader
Deepmoney LLM
Elite Quantitative GenAI/LLM
Ninja Mobile Trader VPS (ninjamobiletrader.com)
Trading Reviews and Vendors
Futures True Range Report
The Elite Circle
My NT8 Volume Profile Split by Asian/Euro/Open
NinjaTrader
 
Best Threads (Most Thanked)
in the last 7 days on NexusFi
Get funded firms 2023/2024 - Any recommendations or word …
59 thanks
Funded Trader platforms
37 thanks
NexusFi site changelog and issues/problem reporting
24 thanks
GFIs1 1 DAX trade per day journal
22 thanks
The Program
19 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,425

You can create your own classes outside of the Ninja Indicator namespace but inside the same file, this works fine and you can do anything you want in them. If they are public static they will be seen throughout all Ninja files.

You can cross reference any variables that are 'public' by prefixing them with the class name. e.g. myStuff.bugCount.

However, you should not expect to safely access internal Ninja event series without care. The 'TriggerCustomEvent' routine can be used to ease this, but the approach I prefer is to have OnBarUpdate write any values that I am interested in (e.g. High[0] or whatever) out to my class, rather than the other way around.

This way, and by making appropriate use of the 'lock' constructor, I can also safely run multithreaded systems inside Ninja, without risk to Ninja structures.

i haven't found much that can't be done inside the beast, which is of course it's phenomenal strength and it's weakness. Just like Windows.


Cheers

Travel Well
Visit my NexusFi Trade Journal Reply With Quote
Thanked by:
  #3 (permalink)
 shansen 
Melbourne, Australia
 
Experience: Intermediate
Platform: NinjaTrader
Trading: ES
Posts: 18 since Aug 2013
Thanks Given: 2
Thanks Received: 5


Ratfink & the futures.io (formerly BMT) Forum,

Thank you for your quick and knowledgeable reply.

I take your point on the dangers of attempting to access internal NT event series from outside the NT.Indicator namespace. By no means do I wish to complicate code and introduce the chance of it all going awry when money is on the line. Hence, my line of questioning.

I understand custom classes can be written outside of the NT.Indicator namespace but inside the same .cs file. However, this approach leads to the problem I am trying to overcome... excessively long files that become increasingly difficult to navigate. As the file become larger, it becomes less readable.

I am trying to divine a structure that improves readability by allowing for :
  1. Small, easily navigable files - Custom classes housed in separate .cs files, and
  2. Custom classes that can safely access properties (e.g. High[0], SMA(20)[0]) and methods from the Indicator class.
Where there is another approach that improves readability... I am all ears.

With this goal in mind, I would appreciate any input on the merits of two different approaches :
  1. Continuing from my earlier post, the Custom.BL project could include a"DataSeries" class which inherits from NT.Data.IDataSeries. From within an indicator OnBarUpdate event, appropriate values (e.g. High[0]) could be written to an instantiated "DataSeries" object. From there other classes in the Custom.BL project should be able to access the "DataSeries" values (I think). The structure would look like the attached screenshot "Custom.BL".
  2. I am clutching at straws here... If "BusinessLogic" was housed in the NinjaTrader.Custom project, would it be possible to have an indicator appropriately reference the custom classes and have the custom classes safely access indicator properties etc? How could this be achieved? This structure would look like the attached screenshot "BusinessLogic".

I am confident this problem has been encountered and solved by many people. Any ideas and insights are greatly appreciated.

Thanks again
Shannon

Attached Thumbnails
Click image for larger version

Name:	Custom.BL.PNG
Views:	183
Size:	6.4 KB
ID:	154007   Click image for larger version

Name:	BusinessLogic.PNG
Views:	197
Size:	7.8 KB
ID:	154008  
Started this thread 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,425


shansen View Post
I understand custom classes can be written outside of the NT.Indicator namespace but inside the same .cs file. However, this approach leads to the problem I am trying to overcome... excessively long files that become increasingly difficult to navigate. As the file become larger, it becomes less readable.

Where there is another approach that improves readability... I am all ears.

Just use the preprocessor #region/#endregion directives, I use loads, problem goes away. Since NT always recompiles all files anyway no extra overhead for building, on an i7 huge files are done by the time the key press comes back up anyway.

e.g.:

 
Code
#region LOADSOFCODE

blah, blah, blah

#endregion
Once compiled, saved and reloaded whole region drops into a single line that you can just click on the left hand [+] to open or [-] to close. That's the route I use, but then I don't use any tools outside of Ninja for building or debugging.

I should also have said 'custom classes can be inside or outside Ninja namespaces, other problem solved if you go that route.

If you want to go the more sophisticated VS and external project route then @rleplae has just written an excellent piece on using external DLL's, see here :

Cheers.

Travel Well
Visit my NexusFi Trade Journal Reply With Quote
  #5 (permalink)
breathedml
Orlando
 
Posts: 1 since Oct 2013
Thanks Given: 0
Thanks Received: 0

I'm having the same issue. I was able to avoid the compile error by having my class (CMyCustomClass) inherit from "Strategy" as shown below. Note, "steepness" is a function I defined in "UserDefinedMethods.cs". It seems like NT indicators like SMA will now work within my class methods.



#region Using declarations
#endregion

// This namespace holds all strategies and is required. Do not change it.
namespace NinjaTrader.Strategy
{
public class CMyCustomClass : Strategy
{
public void runMyCustomMethod(int barsAgo)
{
double steepness20 = steepness(barsAgo, 2, SMA(20));
double steepness10 = steepness(barsAgo, 2, SMA(10));
}
}
}

Reply With Quote




Last Updated on October 7, 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