What is the best way to structuring custom classes?
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, SMA(20)) 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 from a class outside of NT.Custom?
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 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.
The following 3 users say Thank You to ratfink for this post:
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 :
Small, easily navigable files - Custom classes housed in separate .cs files, and
Custom classes that can safely access properties (e.g. High, SMA(20)) 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 :
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) 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".
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.
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.
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.
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
// This namespace holds all strategies and is required. Do not change it.
public class CMyCustomClass : Strategy
public void runMyCustomMethod(int barsAgo)
double steepness20 = steepness(barsAgo, 2, SMA(20));
double steepness10 = steepness(barsAgo, 2, SMA(10));