• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar
  • Skip to footer

The Indicator Club

  • Indicators
    • All Indicators
    • Free Indicators
    • Join the Club!
    • Indicator TImeline
  • Blog
    • All
    • NinjaScript Tutorials
    • Trade Ideas
    • Free Strategies
    • Favorite Posts
  • FAQ
  • My Account
    • Activate License
    • API Keys
    • API Downloads
  • Contact
  • Cart

June 28, 2017 by The Indicator Club 3 Comments

First Indicator with NinjaScript

Brief Introduction

We’ve put together a series of posts to help you in your journey to learn how to program from scratch, or edit existing NinjaTrader indicators and strategies. All of our posts are geared toward the non-programmer, so even though we will present a lot of information, for all of you more technical people out there, we will not go into all the technicalities of C#, NinjaTrader, or NinjaScript. It’s also important to note that even though we show you how to do something in NinjaTrader, that is by no way the only way to do it. We will present what has worked best for us and what will be most easily understood by someone learning how to program. Finally, for the more advance users, we are going to leave things out and over simplify certain parts because we are focused on learning what we need to so we can get started on our NinjaScript journey.

There are two extremely important concepts that need to be understood when you are programming in NinjaTrader: CurrentBar and PriceSeries. Briefly, each bar on your chart is assigned a number, which is stored as a value in the variable CurrentBar. Also, each bar can reference certain data, such as the Close of the bar, based on the number of BarsAgo (bars to the left of the bar currently processing OnBarUpdate()).

CurrentBar Basics

The variable CurrentBar allows us to determine how many bars are currently on the chart, or if bars have been drawn on the chart at all. For example, let’s assume you open a new chart and no bars are present, CurrentBar will have a value of -1. Now, let’s assume one bar is drawn on that same chart (on the extreme left of your chart). CurrentBar will have a value of 0, which tells us that 1 bar is on the chart. Using the same chart with 1 bar (CurrentBar == 0), NinjaTrader will continue building the chart by adding 1 bar to the right, until all of your data is loaded. Each time NinjaTrader adds a bar to the chart, CurrentBar increases by 1, which can be expressed as CurrentBar = CurrentBar + 1, or CurrentBar++, or CurrentBar += 1. In the below image, I have drawn the value of CurrentBar above even and below odd numbered candles:

PriceSeries Basics

Think of PriceSeries as another name for all the price data that is available for us to reference on any given bar, which are as follows (we will not go into the multi-time frame consideration at this point, but we will later!):

  • Close: Represents the Close of the referenced bar.
  • High: Represents the High of the referenced bar.
  • Input: Represents the Input of the referenced bar, which can be changed when you are editing the settings of an indicator–there is an option Input Series, which you can choose the Price Type and / or another indicator value as the input for that indicator. Instead of using Close while we are coding, we can choose to use Input, which will allow the user to select the desired value, such as Weighted, for the indicator calculation.
  • Low: Represents the Low of the referenced bar.
  • Median: Represents the Median of the referenced bar, which is defined as: (High + Low) / 2.
  • Open: Represents the Open of the referenced bar.
  • Typical: Represents the Typical price of the referenced bar, which is defined as: (High + Low + Close) / 3.
  • Value: We will explore this option in a later Part when we add Plots to our chart.
  • Weighted: Represents the Typical price of the referenced bar, which is defined as (Close + Close is not a typo): (High + Low + Close + Close) / 4 .

I know, I kept repeating referenced bar, so let’s define what I really mean with a little more explanation and some examples. First remember that CurrentBar starts counting at 0 (-1 represents no bars being on the chart) and then increments by 1 for each bar that is added to your chart, so think of CurrentBar as starting at 0 and counting in increments of 1 from left to right. It is important to remember this because the way we reference a PriceSeries, which is based on BarsAgo. Let’s assume we open a new chart and have 100 bars. If we want to reference the Close of the bar to the very right of your chart, we would write Close[BarsAgo], which would be Close[0]. If we wanted to reference the bar to the immediate left of the right most bar, we would write Close[1], which says I want the Close 1 bar prior to the right most bar. So, think of PriceSeries as starting at 0 and counting in increments of 1 from right to left. Here is an example, similar to the CurrentBar example, where I print how we would reference the bar by plotting the BarsAgo number above / below the candle:

The one thing you most likely noticed is that the right most bar did not have a number over it. Well, that gets into what our setting is for  Calculate. The image above was taken with Calculate.OnBarClose, which means NinjaTrader only processes the right most bar after it has closed and a new bar has opened. If we used a different setting, such as  Calculate.OnEachTick, NinjaTrader will process the right most bar as each tick is processed by your data feed, which makes the image look like this:

As you will notice, the numbers all moved one bar to the right because of the Calculate setting. For now, we will assume our indicators are processed on Calculate.OnBarClose, since we are still learning and this is the least resource intensive option.

First Indicator Example

One of the first things we want to do when developing any indicator is to add a “check,” in OnBarUpdate, to determine if we have enough data loaded on our chart to begin processing our indicators logic. For example, if we are working on a Moving Average that has a Period of 5, we need at least 5 bars for the calculation, so we need to have our code check that we have at least 5 bars on the chart before we process any calculations. Since CurrentBar keeps track of the number of bars on the chart, we can use that variable to check if we can start processing (if we have a little more data loaded on the chart than we absolutely need, that is ok):

Once our If Statement from above is False, we have enough bars loaded on our chart and can begin processing information in OnBarUpdate (everything below return). The next thing we want to do is create an If Statement for IsFirstTickOfBar, which will be true if the incoming tick is the first tick of a new bar (otherwise it will be false). An important note is that this property is only of value when the Calculate property is set to Calculate.OnEachTick or Calculate.OnPriceChange, so we are adding this in if you decide to run this indicator on something other than OnBarClose. Why do we need this? Well, we are going to draw something, so we want to make sure we only draw it once per bar. If we did not have this check in place and you were using OnEachTick, as each tick was processed, NinjaTrader would redraw the draw object, which can end up being resource intensive. So, we can write something like:

Great, now we are going to create a temporary variable that will only be valid / able to be referenced within our If Statement, which we want to hold the value of CurrentBar as a string:

The next step is to draw the CurrentBar number above / below the bar. So, what we need to do is determine if a bar is even or odd. To do that we could divide the CurrentBar by 2 and see if there is a remainder, which we can accomplish with the % (Modulus) Operator:


Finally! We are at the part where we can draw something on our chart. We will be using Draw.Text. The important thing to know is how to reference methods such as these in the NinjaTarder help guide because under Syntax, NinjaTrader details all the valid ways to call this method. Under Parameters, NinjaTrader gives a detailed explanation for each input. Let’s take the first as an example:  Draw.Text(NinjaScriptBase owner, string tag, string text, int barsAgo, double y)

  • NinjaScriptBase owner: For our purposes this is extremely simple and the input will be “this”. Think to yourself, “this” indicator is the owner of the draw object.
  • string tag: The “string” lets us know that the input must be a string variable and will be the draw objects tag. The tag will be view-able if you double click on the draw object on your chart.
  • string text: Again “string” lets us know that the input must be a string variable and will be the text that is actually drawn.
  • int barsAgo: The “int” lets us know that the input must be an integer and will draw the object based on the same BarsAgo logic in our PriceSeries discussion.
  • double y: The “double” lets us know that the input must be a double data type and the y is where the draw object will be drawn, which is normally an offset from a PriceSeries object.

Let’s see what this looks like in action:

Great! Now save, compile, and load the indicator on your chart and it should look like the example in CurrentBar. We are almost finished, but we need to add one additional component–creating an option for the offset of our text. We can create a user input like this:

Now that we have an input, we need to incorporate the input into our logic, which if we wanted to recalculate our offset each time OnBarUpdate was called we would change Draw.Text to this:

  • Draw.Text(this, “Even ” + xCB, xCB, 0, High[0] + iOffsetTicks * TickSize);
  • Draw.Text(this, “Odd ” + xCB, xCB, 0, Low[0] – iOffsetTicks * TickSize);

There is another option that will demonstrate the importance State.DataLoaded. In State.DataLoaded, NinjaTrader has downloaded the Bar information, so starting at this point we can reference information such as Instrument Name, Instrument Description, and TickSize. Since we can reference TickSize at this point and our offset (in ticks) will not change, we can calculate what the offset is (iOffsetTicks * TickSize) by performing the following:

  • Declare a new double variable: private double iOffset = 0;
  • Inside of State.DataLoaded perform the following calculation: iOffset = iOffsetTicks * TickSize;
  • Updated Draw.Text: Draw.Text(this, “Even ” + xCB, xCB, 0, High[0] + iOffset);

Once those updates are made, our indicator should now look like this:

It’s As Simple As That

We reviewed a lot of important NinjaScript concepts in this Part and created our first indicator, even though it was simple, it demonstrated several concepts that you will be able to use in your own development. Now it’s time to checkout Part 7 – Series<T> Basics.

Filed Under: Tutorial Tagged With: Learn, NinjaScript

Reader Interactions

Comments

  1. Gabriel says

    May 10, 2018 at 2:59 pm

    Hi!

    I am following the post’s instructions and when I apply the indicator to the chart the rightmost bar of the chart is not number 0 but the last number (591)… I have double-checked my code and I think it is exactly like yours… do you know what can be happening?

    Reply
    • The Indicator Club says

      May 10, 2018 at 6:47 pm

      Perfect, that is exactly what the indicator was intended to show (the count of the CurrentBar)–the very first picture of the post. In the second and third picture of the post, I was demonstrating BarsAgo, which is typically what we use when coding in NinjaScript, but we can certainly use CurrentBar (the second and third image was also to show the difference in the settings for Calculate).

      Reply
      • Gabriel says

        May 12, 2018 at 4:48 pm

        OK, got it! thank you for the clarification…

        Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Primary Sidebar

Recent Posts

  • Top Shelf Trader October 6, 2017
  • Use Any Indicator with Our Frameworks: Universal Inputs September 21, 2017
  • NinjaTrader Training: Part 10: Coloring Plots and Backgrounds September 1, 2017
  • NinjaTrader Training: Part 9 – AddPlot and Plot Variables August 31, 2017
  • NinjaTrader Training: Part 8 – Referencing Indicators August 30, 2017

Post Tags

Advance Internals Automated Backtest Day Trading Detrend Forex Trading Free Futures Trading Learn Moving Average MTF NinjaScript NinjaTrader 7 NInjaTrader 8 Oscillator Pivot Points RSI Stock Trading Strategy Vix Trend Volume

Footer

WHO WE ARE

The Indicator Club is made up of normal traders and professional software developers who want to share their indicators for a fraction of the cost it would take to code just one!

The Indicator Club

Purchase & Support

To get access to all of our current and future indicators and strategies, check out our Complete Package.

If you need support please email [email protected], or head over to our contact page.

New Releases

  • NinjaTrader 8 Osc Universal Input Osc Universal Input $497.00
  • NinjaTrader 8 MA Universal Input MA Universal Input $497.00
  • NinjaTrader 8 Bar Orders Bar Orders $297.00
  • NinjaTrader 8 Tick Offset Tick Offset $0.00

Recent Posts

  • Top Shelf Trader
  • Use Any Indicator with Our Frameworks: Universal Inputs
  • NinjaTrader Training: Part 10: Coloring Plots and Backgrounds
  • NinjaTrader Training: Part 9 – AddPlot and Plot Variables

Copyright ©2020 | All Rights Reserved | By Using This Site you Agree to our Terms and Conditions, Risk Disclosures, and Software Agreement

NinjaTrader Disclosure: NinjaTrader® is a registered trademark of NinjaTrader Group, LLC. No NinjaTrader company has any affiliation with the owner, developer, or provider of the products or services described herein, or any interest, ownership or otherwise, in any such product or service, or endorses, recommends or approves any such product or service.

RISK DISCLOSURE: Futures and forex trading contains substantial risk and is not for every investor. An investor could potentially lose all or more than the initial investment. Risk capital is money that can be lost without jeopardizing ones financial security or life style. Only risk capital should be used for trading and only those with sufficient risk capital should consider trading. Past performance is not necessarily indicative of future results.

HYPOTHETICAL PERFORMANCE DISCLAIMER: HYPOTHETICAL PERFORMANCE RESULTS HAVE MANY INHERENT LIMITATIONS, SOME OF WHICH ARE DESCRIBED BELOW. NO REPRESENTATION IS BEING MADE THAT ANY ACCOUNT WILL OR IS LIKELY TO ACHIEVE PROFITS OR LOSSES SIMILAR TO THOSE SHOWN; IN FACT, THERE ARE FREQUENTLY SHARP DIFFERENCES BETWEEN HYPOTHETICAL PERFORMANCE RESULTS AND THE ACTUAL RESULTS SUBSEQUENTLY ACHIEVED BY ANY PARTICULAR TRADING PROGRAM. ONE OF THE LIMITATIONS OF HYPOTHETICAL PERFORMANCE RESULTS IS THAT THEY ARE GENERALLY PREPARED WITH THE BENEFIT OF HINDSIGHT. IN ADDITION, HYPOTHETICAL TRADING DOES NOT INVOLVE FINANCIAL RISK, AND NO HYPOTHETICAL TRADING RECORD CAN COMPLETELY ACCOUNT FOR THE IMPACT OF FINANCIAL RISK OF ACTUAL TRADING. FOR EXAMPLE, THE ABILITY TO WITHSTAND LOSSES OR TO ADHERE TO A PARTICULAR TRADING PROGRAM IN SPITE OF TRADING LOSSES ARE MATERIAL POINTS WHICH CAN ALSO ADVERSELY AFFECT ACTUAL TRADING RESULTS. THERE ARE NUMEROUS OTHER FACTORS RELATED TO THE MARKETS IN GENERAL OR TO THE IMPLEMENTATION OF ANY SPECIFIC TRADING PROGRAM WHICH CANNOT BE FULLY ACCOUNTED FOR IN THE PREPARATION OF HYPOTHETICAL PERFORMANCE RESULTS AND ALL WHICH CAN ADVERSELY AFFECT TRADING RESULTS.