NexusFi: Find Your Edge


Home Menu

 





Anyone have any hints for optimizing C# code?


Discussion in NinjaTrader

Updated
      Top Posters
    1. looks_one Zondor with 20 posts (21 thanks)
    2. looks_two ZTR with 13 posts (0 thanks)
    3. looks_3 Richard with 11 posts (20 thanks)
    4. looks_4 Fat Tails with 7 posts (18 thanks)
      Best Posters
    1. looks_one Fat Tails with 2.6 thanks per post
    2. looks_two gomi with 2.1 thanks per post
    3. looks_3 Richard with 1.8 thanks per post
    4. looks_4 Zondor with 1.1 thanks per post
    1. trending_up 48,519 views
    2. thumb_up 108 thanks given
    3. group 39 followers
    1. forum 111 posts
    2. attach_file 13 attachments




 
Search this Thread

Anyone have any hints for optimizing C# code?

  #31 (permalink)
Richard
Dallas TX/USA
 
Posts: 153 since Jun 2009
Thanks Given: 33
Thanks Received: 284


Zondor View Post
Anyone writing Ninjascript code should look at that post at MoveTheMarkets, and implement that idea in their code.

Yeah, it's faster, and it keeps you from repeating the arguments every time. Just all-around better. It's too bad ninja encourages the style that they do.

Another big source of inefficiency are indicators using MAX and MIN either directly or indirectly. I also have an article with an online algorithm for maintaining a sorted sliding window, which is much faster than doing an Array.Sort() every time OnBarUpdate is called (think about it... last bar you had a sorted window for everything but the newest value... make use of it rather than throw the almost correct answer away!). Much better for median filters and interquartile ranges, etc. There are other easy things to do, but I haven't had time to write them up. I'm kinda lazy about writing.

Reply With Quote
Thanked by:

Can you help answer these questions
from other members on NexusFi?
Exit Strategy
NinjaTrader
NT7 Indicator Script Troubleshooting - Camarilla Pivots
NinjaTrader
MC PL editor upgrade
MultiCharts
How to apply profiles
Traders Hideout
Trade idea based off three indicators.
Traders Hideout
 
Best Threads (Most Thanked)
in the last 7 days on NexusFi
Spoo-nalysis ES e-mini futures S&P 500
29 thanks
Just another trading journal: PA, Wyckoff & Trends
25 thanks
Tao te Trade: way of the WLD
24 thanks
Bigger Wins or Fewer Losses?
21 thanks
GFIs1 1 DAX trade per day journal
16 thanks
  #32 (permalink)
 
Zondor's Avatar
 Zondor 
Portland Oregon, United States
 
Experience: Beginner
Platform: Ninjatrader®
Broker: CQG, Kinetick
Trading: Gameplay Klownbine® Trading of Globex
Posts: 1,333 since Jul 2009
Thanks Given: 1,246
Thanks Received: 2,731

Richard, this is great! I optimized several custom indicators using this approach and the performance improvement is tremendous. Posted in the Elite Section is the optimized version of the Big Mike CMA Envelope Bands.. it loads in a split second. Thanks so much!




Sometimes the definitions of the external indicators include parameters that are updated dynamically. Whenever that happens, the definition of the external indicator must also be updated. Here is an example:


For this reason, and also to avoid problems with NT6.5, I prefer to define the external indicators in a procedure module such as OnBarUpdate() rather than in OnStartUp().

Is there anything we can do about MAX and MIN? One particular custom indicator that uses them a lot is painfully slow to load. (BetterBuySellVolume, part of double Z trading package)

Do Math.Max and Math.Min also have problems?

Follow me on Twitter Visit my NexusFi Trade Journal Reply With Quote
Thanked by:
  #33 (permalink)
 
eDanny's Avatar
 eDanny 
East Rochester, NY
 
Experience: Intermediate
Platform: NT
Posts: 329 since Jul 2009
Thanks Given: 18
Thanks Received: 425


But what if the called indicator does not have just one output? Which is more efficient?

This?

in Variables:
private DataSeries myMacdAvg;

in Initialize():
myMacdAvg = new DataSeries(this);

in OnBarUpdate();
myMacdAvg.Set(MACD(12,26,9).Avg[0]);

if(myMacdAvg[0] > 0)
DoSomething

Or this?

in Variables:
private MACD myMacd:

in OnBarUpdate();
if(!init)
{
myMacd = MACD(12,26,9); //myMacd = MACD(12,26,9).Avg will not work here
init = true
}
if(myMacd.Avg[0] > 0)
DoSomething

Reply With Quote
  #34 (permalink)
 
Zondor's Avatar
 Zondor 
Portland Oregon, United States
 
Experience: Beginner
Platform: Ninjatrader®
Broker: CQG, Kinetick
Trading: Gameplay Klownbine® Trading of Globex
Posts: 1,333 since Jul 2009
Thanks Given: 1,246
Thanks Received: 2,731

If you want a dataseries to capture the SMA of the MACD: (Note... MACD12 should have been MyNewMACD)

in Variables:

private DataSeries myMacdAvg;
private bool init = false;
private MACD MyNewMACD
private SMA SMAofMACD


in Initialize():

myMacdAvg = new DataSeries(this);


in OnBarUpdate();

if(!init)
{
MyNewMACD= MACD(12,26,9);
SMAofMACD=SMA(MyNewMACD, 7); // 7 period SMA of MACD(12,26,9)
init = true;
}

MyMacdAvg.Set(SMAofMACD[0]);
if(MyMacdAvg[0] > 0) // if current value of 7 period SMA of MACD(12,26,9)>0
(
Print("Hello Vorld");
FabianCancellera.WinWorldTimeTrialChampionship;
)

Follow me on Twitter Visit my NexusFi Trade Journal Reply With Quote
  #35 (permalink)
 
eDanny's Avatar
 eDanny 
East Rochester, NY
 
Experience: Intermediate
Platform: NT
Posts: 329 since Jul 2009
Thanks Given: 18
Thanks Received: 425

Very nice (except I don't see where MACD12 comes in or is actually used). In my previous example, which would be better in accomplishing the same result, using a DataSeries or not using a DataSeries? That is my question which might be better left to Richard.

Dan

Reply With Quote
  #36 (permalink)
Richard
Dallas TX/USA
 
Posts: 153 since Jun 2009
Thanks Given: 33
Thanks Received: 284


eDanny View Post
But what if the called indicator does not have just one output? Which is more efficient?

The main thing is to remember a reference to the indicator, so that you don't have to ask ninja to look it up again. The number of DataSeries you need to look at isn't a factor.

So, your second example--just referencing myMacd.Avg[0]--is the one I'd use. Putting the information in an additional DataSeries isn't a necessary step, and wastes time and memory.

If you really just want a reference to the Avg part of the MACD indicator, you should be able to do that like this, though:

 
Code
in Variables:
private DataSeries macdAvg;

in OnBarUpdate():
if(!init)
{
macdAvg= MACD(12,26,9).Avg; 
init = true;
}

if(macdAvg[0] > 0)
DoSomething
.. but you lose easy access to the rest of the MACD that way, and the performance increase would be negligible.

Reply With Quote
Thanked by:
  #37 (permalink)
 
eDanny's Avatar
 eDanny 
East Rochester, NY
 
Experience: Intermediate
Platform: NT
Posts: 329 since Jul 2009
Thanks Given: 18
Thanks Received: 425

Thanks Richard. I was trying to avoid the memory consumption of an additional DataSeries and that is why I asked. Also I could not get this to work (I was using something other than the MACD but same idea).

Dan


macdAvg= MACD(12,26,9).Avg;

Reply With Quote
Thanked by:
  #38 (permalink)
Richard
Dallas TX/USA
 
Posts: 153 since Jun 2009
Thanks Given: 33
Thanks Received: 284


Zondor View Post
Sometimes the definitions of the external indicators include parameters that are updated dynamically.

Yeah, I can't see the code you are posting, but just be aware that when you change the inputs you are actually creating an additional indicator that runs in parallel with the original one. So, that can easily get out of hand if you don't do some quantizing... like: instead of changing the SMA length each bar, only change it in length multiples of 5, or whatever.



Quoting 
Is there anything we can do about MAX and MIN?

There are fast algorithms for maintaining the max/min of the last n samples. As with the sliding sorted window I posted about, the key is to realize that on the previous bar you had almost the right answer. If you can just incorporate the current bar's information without just searching all over again for the maximum, you are much better off. I just haven't had time to write those up yet. Maybe soon, but I'm sure someone motivated to speed them up can work out the details. Hint: if the maximum was 3 bars ago on the last bar, then it was 4 bars ago on this bar. So if the current bar's not larger than the previous maximum, and your length is >= 4, then there's no need to do anything. The maximum hasn't changed.

Reply With Quote
Thanked by:
  #39 (permalink)
Richard
Dallas TX/USA
 
Posts: 153 since Jun 2009
Thanks Given: 33
Thanks Received: 284


eDanny View Post
Thanks Richard. I was trying to avoid the memory consumption of an additional DataSeries and that is why I asked. Also I could not get this to work (I was using something other than the MACD but same idea).

Dan


macdAvg= MACD(12,26,9).Avg;

Avg will be a Dataseries or IDataSeries... so macdAvg must be defined as one, as well (not a MACD). Does that help? So...

 
Code
DataSeries macdAvg;
macdAvg = MACD(12,26,9).Avg;
... compiles for me.

Reply With Quote
Thanked by:
  #40 (permalink)
 
eDanny's Avatar
 eDanny 
East Rochester, NY
 
Experience: Intermediate
Platform: NT
Posts: 329 since Jul 2009
Thanks Given: 18
Thanks Received: 425


Thanks Richard. I would be right back to using a DataSeries in that example so that is NOT the way to go.

Dan

Reply With Quote
Thanked by:




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