A Step-by-Step Guide for Calculating RSI Indicator Values Programmatically
Overview
At first, this might seem easy, just find a basic formula online, convert it into a code and run a function on a set of values, right? But in real life, a number of fine and important details come into play that we should always take into consideration, without this, you’ll realize (if you haven’t already) that your values do not always match those in trading terminals or online charts. This article, although thorough and longer than most others on the subject, goes through all the necessary steps and verifications, and if you keep following it, you’ll not only be able to have a consistent, reliable function for RSI calculation but will be able to successfully replicate the process for other indicators and save a lot of time and headache in the end…
History
RSI — Relative Strength Index is a widely used momentum indicator. It measures the strength of price changes to evaluate overbought or oversold states in the market.
RSI can have a reading from 0 to 100, originally developed by J. Welles Wilder Jr., an American mechanical engineer, real estate developer, and technical analyst. Wilder invented several technical indicators that now come standard in most of the technical analysis software and trading terminals. These indicators include the Average True Range (ATR), Relative Strength Index (RSI), Average Directional Index (ADX), and the Parabolic SAR (Parabolic Stop And Reverse).
The calculations behind the RSI value aren’t as easy as the Simple Moving Average (SMA) indicator, which just calculates an average value of a series of Open, High, Low, or Close prices, and although they’re not very difficult either, there are a number of small, often overlooked details besides the main formula, that play an important role in the end.
So, without further ado, let’s begin:
Main Bits of Logic
Step 1.1 — the differences: Let’s say, we have a standard RSI 14 based on Close prices. First, it calculates a difference between 2 consecutive Close prices (Close — previous Close), then goes back in history further and calculates the difference between the previous Close price and the Close price before that, all the way up to (at least) 14 values, requiring 15 Close prices in total in order to have at least 14 differences for basic equations, but in reality, you absolutely need all the bars you can get (I’ll show you the reason why below), simplified notation (difference = close-previous close):DIFF = C - PC
Step 1.2 — splitting into positive & negative differences: Now we need to get 2 sets of values from the differences we’ve got from Step 1, a list of positive values, and a list of negative values, however, we should store the negative difference values as absolute values, without the minus sign:
PD = DIFF > 0 ? DIFF : 0
And for the negative one: ND = DIFF < 0 ? DIFF * -1 : 0
Step 1.3 — calculating average positive and average negative differences: to do that we just need the sum of the last 14 positive differences to divide by the RSI period (14), in the end, getting an average value, and we do the same for all negative differences as well (sum of absolute values divided by 14): APD = (PD1 + PD2 + PD3 + PD4 + PD5 + PD6 + PD7 + PD8 + PD9 + PD10 + PD11 + PD12 + PD13 + PD14) / 14
And the Average Negative Difference (AND): AND = (ND1 + ND2 + ND3 + ND4 + ND5 + ND6 + ND7 + ND8 + ND9 + ND10 + ND11 + ND12 + ND13 + ND14) / 14
As we already have our first APD and AND values, every subsequent (15th, 16th, and so on..) calculation of APD and AND will take into consideration previous APD values with the following formula: APD = (PREVIOUS_APD * 13 + PD1) / 14
, The same goes for AND: AND = (PREVIOUS_AND * 13 + ND1) / 14
Step 1.4 — calculating the Relative Strength (RS): RS = APD / AND
Step 1.5 — calculating the Relative Strength Index (RSI): Relative Strength Index is just a Relative Strength bound by upper and lower limits of 100 and 0 respectively, to do that, we use the following formula: 100-(100/(1+RS))
The Whole Picture
Step 2.1 — A MUST READ: Now the deal is, you’re not going to have exact RSI values unless you have exactly the same amount of historical data available, for example, if a trading terminal has an RSI 14 indicator attached to a EURUSD H1 chart with 100s of thousands of bars on it, you’ll need exactly the same quantity of bars to get exactly the same value. There’s no way around it.
As the number of bars or Close prices in your disposition increases, your values will become closer and closer to the Terminal’s value, to the point where the difference between 2 values is negligible, but if you have just 14 or even 50 bars, let’s say, your RSI might return a value of 53, for example, on the last bar and the Terminal might show 50. The difference could easily be 2, 4, or as high as 6.
RSI is NOT an indicator that only uses the same number of bars as its period, in this case — 14. RSI with a period of 14 uses ALL THE BARS ON THE CHART to get a final value. On the other hand, the further back in history the bars are, the less their influence on the current RSI value but the chances are if you’re creating a software to do calculations/optimizations with it, your test results should be as close as possible to real trading results and this matters whole a lot.
Any function that calculates values of indicators like RSI should always get all the available bars for processing, not just a bare minimum, and once it calculates all the values, it should also store them globally for further access.
Here’s a screenshot of an excel version that generates almost exactly the same final RSI value after 102 bars as does the Metatrader 5 trading terminal (the difference is as low as 0.01, EURUSD H1 chart):
Step 2.2 — now that we’ve got that out of the way and verified the actual math, let’s convert these formulas into the code… As all trading terminals I know of work in Windows, I’ll provide source codes in the C# programming language, but the logic can be replicated in PHP, SQL ( Yes, databases themselves can perform the calculations required for RSI based on your query and return RSI value in a separate column ), Java, Visual Basic, MQL5 ( MT5 ), MQL4 ( MT4 ), Pine Script (Tradingview), NinjaScript (NinjaTrader)…
First, let’s create a function for calculating the difference between two values, this is a very simple subtraction, but this way we’re avoiding additional comments (function name will be the comment) and can easily modify the function in the future for additional value checks for increased stability, let’s begin:
let’s also calculate positive and negative values:
It’s probably time to create global arrays for positive changes and negative changes to save resources, as well as average gain, average loss, and RSI…
We don’t really need an RS (Relative Strength) array, because it’s just a middle step in the RSI (Relative Strength Index) calculation.
After we declare the global variables (inside the class) we need to initialize them once, preferably in a function that gets called once as well:
DataManager.data is a DataTable object that stores price data exported from MT5 terminal, in short, the number of its entries is used here to define array sizes, we can now create a next function that will calculate average gain and average loss. See all the functions and arrays combined below:
Well.. let’s add one last line in the CalculateAverageGainsAndLosses function and rename it while we’re at it:
As DataEngine.data object contains exactly the same number of bars exported from the MT5 terminal itself, we get exactly the same value in this program as we do in MT5!
Here’s A complete PriceEngine.cs class (all in one file version):
Thanks for reading and good luck!
Would you like to know what I do for a living? I’m a Senior Software Developer at the Proxify Network.
Right now Proxify is looking for new developers, so I wanted to share a few words about my experience here — compared to other things I’ve tried in my career:
1️⃣ The friendly and professional Proxify team and the amount of care they put into each candidate
2️⃣ The hiring process is quite simple and allows to show your skills in full
3️⃣ And, what’s most important, Proxify is the ideal way to find remote work with endless projects and companies to choose from.
Apply here to join me at Proxify: https://bit.ly/3hd64mN
If you enjoyed this article, please, hit the clap button, this way more people will be able to find it!
There’s more! Get $100 in cloud credits from DigitalOcean when you register from this link: https://m.do.co/c/88f25eea9442
And even more:
Free $140 from FBS: regulated by IFSC, this broker is one of the oldest and most established institutions, operating since 2009.
Requirements:
- Register a new account with $140 on it
- Use the leverage of 1:500 to maximize your profits
- You can withdraw all profits
Available Markets: Cryptocurrencies, Stocks, CFDs, Metals, Commodities, Foreign Exchange
Free $30 from Tickmill: regulated by FSA, this broker operates since 2015.
Requirements:
- Register a new account with $30 on it
- Use the leverage of up to 1:500 to maximize your profits
- Withdraw the profits after 5 lots are traded
- The maximum withdrawal amount is $300
Available Markets: Stock Indices, Oil, Precious Metals, Bonds, Foreign Exchange.
Free $30 from Roboforex: regulated by CySEC and IFSC, Roboforex is operating since 2009 and is one of the most popular and trusted brokers among traders today.
Requirements:
- Open an account and deposit $10 to verify your payment method (can be withdrawn at any time) and get $30 as a gift
- Profits are withdrawable without limitations
- If you trade the necessary number of lots, you can withdraw the $30 too
Available Markets: Stocks (all NYSE, NASDAQ, and AMEX shares + German and Chinese listed companies), Stock CFDs (on all stocks, $1.5 per trade fee on US-listed shares), Indices, ETFs, Commodities, Metals, Energy Commodities, Cryptocurrencies, Cryptoindices, Foreign Exchange.