Welcome to NexusFi: the best trading community on the planet, with over 150,000 members Sign Up Now for Free
Genuine reviews from real traders, not fake reviews from stealth vendors
Quality education from leading professional traders
We are a friendly, helpful, and positive community
We do not tolerate rude behavior, trolling, or vendors advertising in posts
We are here to help, just let us know what you need
You'll need to register in order to view the content of the threads and start contributing to our community. It's free for basic access, or support us by becoming an Elite Member -- see if you qualify for a discount below.
-- Big Mike, Site Administrator
(If you already have an account, login at the top of the page)
Need help in the coding of a simple Indicator (newbie inside ;) )
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;
- 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!
Can you help answer these questions from other members on NexusFi?
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:
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.
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
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:
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());
}
}
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:
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
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].
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.
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 ....