NexusFi: Find Your Edge


Home Menu

 





Need help in the coding of a simple Indicator (newbie inside ;) )


Discussion in NinjaTrader

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




 
Search this Thread

Need help in the coding of a simple Indicator (newbie inside ;) )

  #1 (permalink)
choubix
Bangkok + Thailand
 
Posts: 10 since Aug 2012
Thanks Given: 2
Thanks Received: 0

Hi everyone,

I am getting started coding my first indicator and I am running on a couple of difficulties.

I am coding a smoothed version of the RsRank where:
RsRank : ( ( Close-Close[140] + Close-Close[20] ) / 2 ) / 10 Day ATR )
and Smoothed: ( rsRankValue + rsRankValue[1]*2 + rsRankValue[2]*2 + rsRankValue[3] )/6;

I managed to code (and plot) the following:

RsRank.Set( (( Closes[1][0] - Closes[1][140] + Closes[1][0] - Closes[1][20] ) / 2 ) / ATR(10)[1] );


Now the problems are:

- My Closes[1][140] and Closes[1][20] are cast in stone (I created variables "LT_Close" and "ST_Close" but I cant add them to the formula without trigerring an error when compiling)
- how do I code a RsRank_Smoothed.Set as I need to call RsRank[n bars ago] in the calculation?

Thanks!

Reply With Quote

Can you help answer these questions
from other members on NexusFi?
Trade idea based off three indicators.
Traders Hideout
Exit Strategy
NinjaTrader
NexusFi Journal Challenge - May 2024
Feedback and Announcements
Pivot Indicator like the old SwingTemp by Big Mike
NinjaTrader
MC PL editor upgrade
MultiCharts
 
Best Threads (Most Thanked)
in the last 7 days on NexusFi
Spoo-nalysis ES e-mini futures S&P 500
34 thanks
Just another trading journal: PA, Wyckoff & Trends
30 thanks
Tao te Trade: way of the WLD
24 thanks
Bigger Wins or Fewer Losses?
23 thanks
GFIs1 1 DAX trade per day journal
21 thanks
  #3 (permalink)
choubix
Bangkok + Thailand
 
Posts: 10 since Aug 2012
Thanks Given: 2
Thanks Received: 0


Latest edition of my code:

 
Code
            double LT = Closes[1][0] - Closes[1][LT_Close];
			double ST = Closes[1][0] - Closes[1][ST_Close];
				
			RsRank_Smoothed.Set( (( LT + ST ) / 2 ) / ATR(10)[1] );
			RsRank_Smoothed.Set ( (RsRank_Smoothed[0] + RsRank_Smoothed[1]*2 + RsRank_Smoothed[2]*2 +RsRank_Smoothed[3]) / 6);
							
			}
			catch (Exception ex)
			{
				Print(ex.ToString());
			}
Well: it plots something AND I can use my variables (LT_Close and ST_Close)

Now I am not clear as per whether My 2 lines RsRank_Smoothed.Set actually tally with the formula I am trying to achieve:

( rsRankValue + rsRankValue[1]*2 + rsRankValue[2]*2 + rsRankValue[3] )/6;

I find it bizarre that I can call RsRankSmoothed[nBarsAgo] like that in my formula

Any opinion?

Thanks!

Reply With Quote
  #4 (permalink)
 
Fat Tails's Avatar
 Fat Tails 
Berlin, Europe
Market Wizard
 
Experience: Advanced
Platform: NinjaTrader, MultiCharts
Broker: Interactive Brokers
Trading: Keyboard
Posts: 9,888 since Mar 2010
Thanks Given: 4,242
Thanks Received: 27,102


choubix View Post
Hi everyone,

I am getting started coding my first indicator and I am running on a couple of difficulties.

I am coding a smoothed version of the RsRank where:
RsRank : ( ( Close-Close[140] + Close-Close[20] ) / 2 ) / 10 Day ATR )
and Smoothed: ( rsRankValue + rsRankValue[1]*2 + rsRankValue[2]*2 + rsRankValue[3] )/6;

I managed to code (and plot) the following:

RsRank.Set( (( Closes[1][0] - Closes[1][140] + Closes[1][0] - Closes[1][20] ) / 2 ) / ATR(10)[1] );


Now the problems are:

- My Closes[1][140] and Closes[1][20] are cast in stone (I created variables "LT_Close" and "ST_Close" but I cant add them to the formula without trigerring an error when compiling)
- how do I code a RsRank_Smoothed.Set as I need to call RsRank[n bars ago] in the calculation?

Thanks!

I understand that RsRank is a normalized average calculated from a momentum(140) and a momentum(20). In a second step you wish to apply further smoothing. I further assume that you wish to display both RsRank and RsRank_Smoothed on your chart.

In that case you would add two plots in the Initialize() section of your indicator. You also need to defined the properties for those two plots in the Properties section of the indicator.

The code in OnBarUpdate would be pretty simple:

 
Code
protected override void OnBarUpdate()
{
    if(CurrentBar < 1)
         return;
    if(ATR(10)[1] > 0) 
         RsRank.Set((Momentum(20)[0] + Momentum(140)[0]) / (2*ATR(10)[1])) 
    else
         RsRank.Set(0.0);
    RsRank_Smoothed.Set(TMA(RsRank, 2)[0]);
}


Explanations:

-> You do not need to use Closes[1][0], this would be the second bar series added to a multi-timeframe indicator. For your purposes the primary bar series should be ok, which is called as Close[0].
-> Although the ATR usually does not hold the value zero, this may happen at rare occasions.
-> Your smoothing idea uses a triangular moving average with the period 2, which is already available with NinjaTrader.
-> To calculate RsRank_Smoothed you need to use RsRank as input series for the TMA.

Reply With Quote
  #5 (permalink)
 
Fat Tails's Avatar
 Fat Tails 
Berlin, Europe
Market Wizard
 
Experience: Advanced
Platform: NinjaTrader, MultiCharts
Broker: Interactive Brokers
Trading: Keyboard
Posts: 9,888 since Mar 2010
Thanks Given: 4,242
Thanks Received: 27,102


choubix View Post
Latest edition of my code:

 
Code
            double LT = Closes[1][0] - Closes[1][LT_Close];
			double ST = Closes[1][0] - Closes[1][ST_Close];
				
			RsRank_Smoothed.Set( (( LT + ST ) / 2 ) / ATR(10)[1] );
			RsRank_Smoothed.Set ( (RsRank_Smoothed[0] + RsRank_Smoothed[1]*2 + RsRank_Smoothed[2]*2 +RsRank_Smoothed[3]) / 6);
							
			}
			catch (Exception ex)
			{
				Print(ex.ToString());
			}
Well: it plots something AND I can use my variables (LT_Close and ST_Close)

Now I am not clear as per whether My 2 lines RsRank_Smoothed.Set actually tally with the formula I am trying to achieve:

( rsRankValue + rsRankValue[1]*2 + rsRankValue[2]*2 + rsRankValue[3] )/6;

I find it bizarre that I can call RsRankSmoothed[nBarsAgo] like that in my formula

Any opinion?

Thanks!


This code will not perform correctly. But you could use

 
Code
RsRank_Smoothed.Set ( (RsRank[0] + RsRank[1]*2 + RsRank[2]*2 + RsRank[3]) / 6);

Reply With Quote
  #6 (permalink)
choubix
Bangkok + Thailand
 
Posts: 10 since Aug 2012
Thanks Given: 2
Thanks Received: 0

Hi Fat Tails

I will try your suggestions as soon as I can get access to my laptop.
I think I get the gist (and good idea to take into account a possible 0 value of the ATR).
I like the use of NT momentum method (at least I won't have to reinvent the wheel...)

I will look into the triangular MA as I wasn't aware of it. The big idea was to use a FIR filter (Ehler) from what I read in an article.

By the way: what would you recommend I read to get up to speed quickly on Ninjascript? (I have some coding background, self taught pop a long time ago and some basic understanding of java/c#)

Thanks again for your input on my code, it really makes huge impact on my understanding of NT as this early stage

Reply With Quote
  #7 (permalink)
choubix
Bangkok + Thailand
 
Posts: 10 since Aug 2012
Thanks Given: 2
Thanks Received: 0

Hi,

Here is the latest version of the code (works! Thanks Fat Tail for the help and point taken on Closes[n][n] vs Close[n])

Quick questions regarding some lines in the code:

- Isnt my "try/catch" redundant with the if statement at the beginning?

- Why is it that the second brackets for momentum() and ATR() are [0] and [1] respectively if they apply to the same series? should it be [0] for both Momentum and ATR?

I didnt use the TMA as it doesntt seem to give the same output as the FIR filter which gives weight the RSRank[1] and [2].

Code:

 
Code
protected override void OnBarUpdate()
        
        {
            // Use this method for calculating your indicator values. Assign a value to each
            // plot below by replacing 'Close[0]' with your own formula.
			
			try {
				
			if(CurrentBar < 1)
				return;
			if(ATR(ATR_Length)[1] > 0) 
				RSRank.Set(( ( (Momentum(ST_Close)[0] + Momentum(LT_Close)[0]) / 2 ) / ATR(ATR_Length)[1]) );
			else
				RSRank.Set(0.0);
			//RSRank_Smoothed.Set(TMA(RSRank, 2)[0]);
			
			RSRank_Smoothed.Set( (RSRank[0] + RSRank[1]*2 + RSRank[2]*2 + RSRank[3]) / 6 );
			
			}
			catch (Exception ex)
			{
				Print(ex.ToString());
			}
        
        }

Reply With Quote
  #8 (permalink)
 
Fat Tails's Avatar
 Fat Tails 
Berlin, Europe
Market Wizard
 
Experience: Advanced
Platform: NinjaTrader, MultiCharts
Broker: Interactive Brokers
Trading: Keyboard
Posts: 9,888 since Mar 2010
Thanks Given: 4,242
Thanks Received: 27,102


choubix View Post
Hi,

Here is the latest version of the code (works! Thanks Fat Tail for the help and point taken on Closes[n][n] vs Close[n])

Quick questions regarding some lines in the code:

- Isnt my "try/catch" redundant with the if statement at the beginning?

- Why is it that the second brackets for momentum() and ATR() are [0] and [1] respectively if they apply to the same series? should it be [0] for both Momentum and ATR?

I didnt use the TMA as it doesntt seem to give the same output as the FIR filter which gives weight the RSRank[1] and [2].

Code:

 
Code
protected override void OnBarUpdate()
        
        {
            // Use this method for calculating your indicator values. Assign a value to each
            // plot below by replacing 'Close[0]' with your own formula.
			
			try {
				
			if(CurrentBar < 1)
				return;
			if(ATR(ATR_Length)[1] > 0) 
				RSRank.Set(( ( (Momentum(ST_Close)[0] + Momentum(LT_Close)[0]) / 2 ) / ATR(ATR_Length)[1]) );
			else
				RSRank.Set(0.0);
			//RSRank_Smoothed.Set(TMA(RSRank, 2)[0]);
			
			RSRank_Smoothed.Set( (RSRank[0] + RSRank[1]*2 + RSRank[2]*2 + RSRank[3]) / 6 );
			
			}
			catch (Exception ex)
			{
				Print(ex.ToString());
			}
        
        }

-> The "try/catch" statement just shows that you do not fully understand what you are doing. Otherwise you would not use it here. However, it might help you to find bugs as long as the code is not working.

-> The average true range is used to normalize the indicator. To explain why I used ATR(....)[1], we need to differentiate between running an indicator in CalculateOnBarClose = true and CalculateOnBarClose = false. Let us go back to Welles Wilder jr. who created the ATR. First of all it is important to understand that he probably used exponential moving averages because they were easier to calculate. Back in the 70s there were no PCs or pocket calculators available. Also he applied those indicators to printed daily charts, which reflected the prices at the end of the trading session. The indicator is not fit to be applied to intraday screenshots of daily charts.

CalculateOnBarClose = true: The indicator uses the final current bar to calculate the average true range. This is fine and you can also use the current value ATR(...)[0].

CalculateOnBarClose = false: The problem here is that the new bar starts out with a single tick. This means that the true range for the current bar is typically 0, when the new bar opens. As a consequence the ATR(...)[0] is systematically skewed to the downside, while the bar is developing. While the bar develops, the range of the current bar gradually builds up and the systematic error of the ATR becomes smaller.

In fact the ATR belongs to a class of indicators that cannot be used with COBC = false. However, you can take the ATR of the prior bar which is correct, as the prior bar is already complete. Therefore, if you wish to run an indicator in mode CalculateOnBarClose = false, you need to use the ATR(...)[1] and not the ATR[0].

Another advantage of using the ATR(....)[1] is that you only need to calculate it once during the life of the current bar. This reduces CPU load. Here is the code

 
Code
protected override void OnBarUpdate()
{
      if(CurrentBar < 1)
           return;    // this is needed because you cannot calculate ATR(...)[1] for CurrentBar ==0
      if(FirstTickOfBar)
           double atr = ATR(...)[1] // you only need to calculate it once for every bar
      if(atr > 0)
           RSRank.Set( 0.5 * (Momentum(shortPeriod)[0] + Momentum(longPeriod[0]) / atr);     
      else
           RSRank.Set(0.0);
      RSRank_Smoothed.Set(TMA(RSRank, 4)[0]);
}

The formula for the triangular moving average TMA should be identical to your formula with the period p=4 (above I had written p = 2), another variation would be SMA(SMA(RSRank, 2), 3)[0].

Reply With Quote
Thanked by:
  #9 (permalink)
choubix
Bangkok + Thailand
 
Posts: 10 since Aug 2012
Thanks Given: 2
Thanks Received: 0

A lot of good info in your post Fat Tails... Thanks! (Indeed : the TMA looks good with p = 4, makes me wonder how much repainting this will generate).

This RS Rank indicator seems to be working just fine for now

Next in line: using an indicator on 2 different time series (for pair switching).
Basically a ROC((SMA(15),65)[0] which would go long the ETF with the highest momentum.

Objective: to learn how to use an indicator on 2 times series, code a basic strategy, use the backtester and a walk forward.

Reply With Quote
  #10 (permalink)
 
Fat Tails's Avatar
 Fat Tails 
Berlin, Europe
Market Wizard
 
Experience: Advanced
Platform: NinjaTrader, MultiCharts
Broker: Interactive Brokers
Trading: Keyboard
Posts: 9,888 since Mar 2010
Thanks Given: 4,242
Thanks Received: 27,102



choubix View Post
A lot of good info in your post Fat Tails... Thanks! (Indeed : the TMA looks good with p = 4, makes me wonder how much repainting this will generate).

This RS Rank indicator seems to be working just fine for now

Next in line: using an indicator on 2 different time series (for pair switching).
Basically a ROC((SMA(15),65)[0] which would go long the ETF with the highest momentum.

Objective: to learn how to use an indicator on 2 times series, code a basic strategy, use the backtester and a walk forward.


The TMA does not repaint at all.

However, there is a notorious indicator called TMABands. That one does indeed repaint. It can be used for embellishment of your charts ....

Reply With Quote




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