Code covered by the BSD License  

Highlights from
Technical Indicators

4.91667

4.9 | 14 ratings Rate this file 96 Downloads (last 30 days) File Size: 10.8 KB File ID: #33430
image thumbnail

Technical Indicators

by

 

25 Oct 2011 (Updated )

A single function that calculates 27 different technical indicators

| Watch this File

File Information
Description

INDICATORS is a technical analysis tool that calculates various technical indicators. Technical analysis is the forecasting of future financial price movements based on an examination of past price movements. Most technical indicators require at least 1 variable argument. If these arguments are not supplied, default values are used.

The included indicators are:

Momentum:
    Commodity Channel Index
    Rate of Change
    Relative Strength Index
    Fast Stochastic Oscillator
    Slow Stochastic Oscillator
    KDJ Indicator
    William's %R
    Aroon
    True Strength Index
Trend:
    Simple Moving Average
    Exponential Moving Average
    Moving Average Convergence Divergence
    Wildmer's DMI (ADX)
    T3
Volume:
    On-Balance Volume
    Chaikin Money Flow
    Force Index
    Money Flow Index
Volatility:
    Bollinger Bands
    Keltner Channels
    Average True Range
    Volatility Ratio
    Highest High, Lowest Low
Other:
    ZigZag
    Price Comparison
    Pivot Points
    Stop and Reverse

Version : 1.1.3 (05/24/2013)
Author : Nate Jensen
Created : 10/10/2011
History :
 - v1.0 10/25/2011 : initial release of 21 indicators
 - v1.1 03/04/2012 : 23 indicators, fixed date conversion issue
 - v1.1.1 03/25/2012 : 24 indicators
 - v1.1.2 03/21/2013 : 25 indicators
 - v1.1.3 05/24/2013 : 27 indicators, bug fixes

MATLAB release MATLAB 7.14 (R2012a)
Tags for This File   Please login to tag files.
Please login to add a comment or rating.
Comments and Ratings (48)
10 Dec 2014 Fernando Esteves  
11 Nov 2014 Xie Ya  
18 Feb 2014 Nate Jensen

Fuad,

No problem. I'm glad my code has worked out for you.

I do. Please see my other submission to the exchange located here:
http://www.mathworks.com/matlabcentral/fileexchange/32992-figure-pixel-resize-function

Nate

18 Feb 2014 Fuad

Hi Nate, thanks for sharing.

Do you have any code for the charts you display in the preview image? Would be great to plot indicators at the bottom of my chart like you do...

Many thanks,

Fuad

27 Jan 2014 Nate Jensen

Let me look into this Ha and see what I can do for you.

Thanks for the rating!

27 Jan 2014 Ray Lee

hi, Nate, could you please add adaptive moving average (e.g. Kaufman, fractral, Jurik) and Andrew's Pitchfork to this function?

28 Dec 2013 Nate Jensen

Jean,

Could you please rephrase; I'm not sure exactly what you mean.

27 Dec 2013 jean

Hi,

Any idea how to calculate the return of these rule please?

thanks

24 Nov 2013 Nate Jensen

George,

You should format your code like this,

vout = indicators([hi,lo,cl],'kdj',k,d)

where,

vout = output vector
hi = high prices
lo = low prices
cl = closing prices
k = number of periods for %K
d = number of periods for %D

In order to extract fpctk, fpctd, and jline, please use the following code:

fpctk = vout(:,1);
fpctd = vout(:,2);
jline = vout(:,3);

Please note:
1. All inputs must be vertically oriented
2. All outputs are returned vertically oriented
3. This code is intended to be used for hundreds or thousands of points of data. Normally you cannot use any of these functions for 1 single point. This function will require at least 1 more point of data for each of the hi, lo, and cl inputs than the maximum of the k or d inputs.

HTH,
Nate

24 Nov 2013 Nate Jensen

Thanks for the feedback Alejandro! I'm glad everything is working out for you.

At the moment I do not have access to Matlab in order to make this change but as soon as I do, I will add in your suggestion.

23 Nov 2013 George Xu

Nate:

How to use the code on KDJ? Please,

Say, I have tick data(tick[30000]) and like to has KDJ(9,2,3). Thanks,

I did try, but get error.

______________________________
>> [fpctk,fpctd,jline] = indicators([2500,2490,2495],'kdj',9,2);
??? Error using ==> indicators
Too many output arguments.

18 Sep 2013 Alejandro Leija

Nate, I want to thank you a lot for sharing your code because it works great and saved me a lot of time.

I've been working with some of these indicators and found differences between your RSI calculation and another very popular version (used in platforms like MT4), where the second and subsequent totalGain/totalLoss values depend on their previous values providing a smoother result -similar to what is done in exponential moving averages. Here you find a detailed explanation: http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:relative_strength_index_rsi

The following modification over your code provides the smoothed RSI:

% Calculate the RSI of the non-nan closing prices. Ignore first non-nan
% vin b/c it is a reference point. Take into account any leading nans
% that may exist in vin vector.
trsi = nan(size(diffdata, 1)-numLeadNans, 1);
% Pre-allocating totalGain and totalLoss using 'trsi' size as reference.
totalGain = zeros(size(trsi,1),1);
totalLoss = zeros(size(trsi,1),1);
% First values are different than others
totalGain(period) = sum(advances(1:period))/period;
totalLoss(period) = sum(declines(1:period))/period;
% Subsequent totalGain/Loss values
for i1 = period+1:size(trsi, 1)
totalGain(i1) = (totalGain(i1-1)*(period-1)+advances(i1))/period;
totalLoss(i1) = (totalLoss(i1-1)*(period-1)+declines(i1))/period;
end
%Calculate RS and RSI
rs = totalGain ./ totalLoss;
for i2 = period:size(trsi,1)
trsi(i2) = 100 - (100 / (1+rs(i2)));
end

An improvement could be a "method option" in the formula to choose one of both versions of RSI; one method with your original RSI version and a second one with the smoothed RSI version.

02 Sep 2013 Ruilong

Nate - I wanted to thank you for your sharing of your collection of trading based technical indicators.
But the results of indicators(price,'t3',period,volfact) are different from what you can get by using the same function in TA-Lib.

26 Aug 2013 Leonardo Hermoso

Here goes another one i use

function [ velocidade ] = velocidade( price,pipSize,period )
%This indicator calculates price velocity. I developed this based on
%pyshics formula velocity v = v0 +at
%pipsize is for forex or data that the variation is small like 0.001
%points, in this case you should use 0.001 as pipsize.
velocidade= (((2 .* (price - [zeros(period,1);price(1:size(price,1)-period,:)])) / period.^2)./pipSize).*period;

end

22 Aug 2013 Nate Jensen

No problem Leonardo. I'm glad you have been able to put my code to good use and thank you for sharing for your hard work.

22 Aug 2013 Leonardo Hermoso  
22 Aug 2013 Leonardo Hermoso

Nate, tks a lot for this.

I use another indicator here that is fibonacci bands, i user your work to develop this indicador in matlab, and here is the code.

Tks again

function [upperband1,upperband2,upperband3,upperband4,lowerband1,lowerband2,lowerband3,lowerband4 ] = fibo(high,low,close,periodsEma,periodsAtr)
%This will calculate the fibonacciBands using the Atr (True Average
%Range).
%indicator
ema = indicators(close,'ema',periodsEma);
atr = indicators([high,low,close],'atr',periodsAtr);

upperband1 = ema + atr.*1.62;
upperband2 = ema + atr.*2.62;
upperband3 = ema + atr.*4.62;
upperband4 = ema + atr;
lowerband1 = ema - atr.*1.62;
lowerband2 = ema - atr.*2.62;
lowerband3 = ema - atr.*4.62;
lowerband4 = ema - atr;
end

26 Jul 2013 Nate Jensen

Hi Mark,

Thank you for sharing your work. Your efforts are greatly appreciated and I hope that others may find your work helpful.

Nate

16 Jul 2013 Mark

Nate - I wanted to thank you for your sharing of your collection of trading based technical indicators.

I wanted to share similar work with you and your followers in the hopes that some may find it complimentary and useful. As it isn't a file submission direct to Mathworks I really can't create my own thread.

I have created a C++ mex-able wrapper for the open source TA-LIB library of functions.

It is available in the repository of http://www.openAlgo.org

27 May 2013 Jose

Nate,
Thank you very much.

24 May 2013 Nate Jensen

The issues have been fixed and the update should appear shortly. I have also added 2 more indicators.

The example should have read:
load disney.mat
vout = indicators([dis_HIGH,dis_LOW,dis_CLOSE],'fsto',14,3);
fpctk = vout(:,1);
fpctd = vout(:,2);
plot(1:length(fpctk),fpctk,'b',1:length(fpctd),fpctd,'g')
title('Fast Stochastics for Disney')

There was also an error in the FSTO and SSTO functions.

24 May 2013 Nate Jensen

Jose,

Thank you for pointing this issue out! I will upload a fix tonight.

I'm sorry about the error.

Nate

24 May 2013 Jose

I do not understand what is happening. I'm using your example!!!

load disney.mat
[fpctk,fpctd] = indicators([dis_HIGH,dis_LOW,dis_CLOSE],'fsto',14,3)

Error using indicators
Too many output arguments.

21 Mar 2013 Nate Jensen

Ha,

I have just added the KDJ Indicator as requested. It should appear shortly depending on how long Matlab takes to approve my submission.

This indicator was a little confusing. I'm not sure exactly which method is correct so I input 3 different methods. Simply uncomment whichever method you wish to use.

Method # 1:
J = 3*FastK - 2*FastD;

Method # 2:
J = ema(K,period);

Method # 3:
J = 3*SlowK - 2*SlowD;

Hope that helps!

Nate

11 Mar 2013 Ray Lee

could u add KDJ to the next version?

19 Dec 2012 Nate Jensen

Thanks Lu Li!

I'll try my hand at the mex function, but unfortunately I don't have a whole lot of experience with them so no guarantees.

I do agree with you, this function is slow as an optimizer. I suggest pulling out the individual indicators that you are interested in and turn them into their own functions. Then try to optimize those, that way you aren't bogged down by the 'Switch' statement.

19 Dec 2012 lu li

Excellent work!
I want to use it in an optimization, but it is kind of slow.
It would be wonderful if it can be into mex funtcion so the it will be much faster.

13 Jun 2012 Nate Jensen

Any time! Thanks again.

13 Jun 2012 Arty

Works like a charm. Thanks.

13 Jun 2012 Nate Jensen

Arty - If you look at line 680,
ema6 = [nan(5*period-1,1); ema(ema5(~isnan(ema5)),period,observ-5*period+1)];
notice that ema6 must have a minimum of '5*period-1' for the size of the input vector. In your case you input a period of 20, therefore, you would need at least 5*20-1 (or 99) for size of your input vector. Either increase the size of your input vector, or decrease the period.
Thanks for the compliment!

Peter - Yeah there are many calculations like that in my code where you could use one method or another to calculate ema or use sma over ema. It is really a matter of opinion. Thank you for the rating!

13 Jun 2012 Peter

Noticed the stochastics delay is calculated using EMA, my TA program calculates it using SMA so there was a slight discrepancy.

12 Jun 2012 Arty

Hi Nate, I tried the t3 indicator and got an error message:

>> t3 = indicators(A, 't3', 20, 0.7);
??? Error using ==> plus
Matrix dimensions must agree.

Error in ==> indicators at 689
t3 = c1*ema6+c2*ema5+c3*ema4+c4*ema3;

Do you know what the problem is? I'm knew to Matlab so having a hard time trying to decipher the code. SMA's and other stuff work fine. Cheers for the hard work.

25 Mar 2012 Nate Jensen

Sorry for the delay, but I have finally added the True Strength Index. Work has been crazy busy and this unfortunately was moved down on the priority list.

I would like to point out that I have included 2 methods for calculating the ema in the tsi. The first method is very similar to Mike's, and is based off of Wikipedia's interpretation of the ema. The second method is based off of Matlab's interpretation of the ema. To choose one or the other, simply comment whichever method you do not wish to use. The default method is based off of Wikipedia.

08 Mar 2012 Nate Jensen

Thanks again Mike!

I will take at look at your code this weekend and hopefully have something put together by Sunday.

07 Mar 2012 Mike

Nate,
I had some time so I coded the True Strength Index (TSI). Probably not the most efficient code, and I don't know if it handles the NaN's properly, but basically it works with your program. I quickly checked the output and it looks right. Here it is:

% tsi - True Strength Index
% tsi = indicators(cl ,'tsi' ,fast,slow)

case 'tsi' % True Strength Index
% Input Data
close = vin(:,1);

% Variable Argument Input
if isempty(varargin)
fast = 3;
slow = 14;
else
fast = varargin{1};
slow = varargin{2};
end

momentum = [0; (close(2:end,1)) - close(1:end-1,1)];

slowEma = 0;
fastAbsEma = 0;
fastEma = 0;
slowAbsEma = 0;
vout = 0;

for i = uint16([2:size(momentum,1)])
slowEma(i,1) = (momentum(i,1) .* (2.0 ./ (1 + slow)) + (1 - (2.0 ./ (1 + slow))) .* slowEma(i-1,1));
fastEma(i,1) = (slowEma(i,1) .* (2.0 ./ (1 + fast)) + (1 - (2.0 ./ (1 + fast))) .* fastEma(i-1,1));
slowAbsEma(i,1) = (abs(momentum(i,1)) .* (2.0 ./ (1 + slow)) + (1 - (2.0 ./ (1 + slow))) .* slowAbsEma(i-1,1));
fastAbsEma(i,1) = (slowAbsEma(i,1) .* (2.0 ./ (1 + fast)) + (1 - (2.0 ./ (1 + fast))) .* fastAbsEma(i-1,1));

if(fastAbsEma(i,1) == 0)
vout(i,1) = 0;
else
vout(i,1) = 100 .* fastEma(i,1) ./ fastAbsEma(i,1);
end
end

05 Mar 2012 Nate Jensen

Thanks Mike!

Yeah I could probably put that in.

05 Mar 2012 Mike

Oh, I see you added these:
mfi - Money Flow Index
atr - Average True Range

excellent! Thank you.

Any plans to code the True Strength Index (TSI)?

05 Mar 2012 Mike  
04 Mar 2012 Nate Jensen

The problem is fixed, and the new file should appear shortly.

I decided to use Matlab's datvecmx function to calculate the year, month, and day rather than try to figure it out on my own. I originally thought that I could write a script to calculate dates faster than Matlab's built-in functions could, but at the moment I can't even calculate those values correctly, much less faster than Matlab.

03 Mar 2012 Nate Jensen

I forgot about this problem. The problem arises because I don't evaluate leap years correctly. I'll try to fix it in the next day or two.

02 Mar 2012 Bruno Pajusco

I've first got the error by running the function using S&P exchange prices on the last 4000 observations. I have also tried with smaller subsets of other market data and even used my fake market data constructed from random variables but the error was still there. You could try to run it with your own data as I suspect you will get that same error but if you want me to send you the actual values for dates, open, high, low, close prices I would need your email address.

Bruno

29 Feb 2012 Nate Jensen

Bruno,

Could you give me an example of how you are getting this error? You could email me your input that triggers the error, and I will see if I can reproduce it.

Mike,

Thanks for the positive feedback!

29 Feb 2012 Mike

Great code, easy to use, and Very well documented! Thank you! Saved me a lot of time by not having to code this from scratch.

Note: When running this on Matlab version 2008 or older, the tilde (~) output argument is not supported. Simply change this to a dummy value (such as "val"), and the error will go away. Search for "~" and change lines: 407, 408, 802, 811, 858, 867. http://www.mathworks.com/help/techdoc/matlab_prog/bresuxt-1.html#br67dkp-1

29 Feb 2012 Bruno Pajusco

Nate, I have come across a problem with the file while trying to estimate pivot points. The problem seems to be related to the code where you work out years, months and days from Matlab serial dates. In particular I had issues with the following block of code:

% Convert Matlab time to years, months, and days
temp_var1 = floor(date); % number of full days
temp_var2 = temp_var1/365.242199; % number of years
year = floor(temp_var2); % number of full years
if (4*(year/4-floor(year/4)) == 0) & ... % if it is a leap year
(100*(year/100-floor(year/100)) ~= 0) ...
| (400*(year/400-floor(year/400)) == 0) %#ok<AND2,OR2>
temp_var3 = floor((temp_var2-year)*366);% number of full days in year
month = cum_days1(temp_var3); % determine month
day = temp_var3-cum_days3(month); % determine day
else % if it's a normal year
temp_var3 = floor((temp_var2-year)*365);% number of full days in year
month = cum_days2(temp_var3); % determine month
day = temp_var3-cum_days4(month); % determine day
end

The code throws the following exception when constructing the variable month:

"Subscript indices must either be real positive integers or logicals.

Error in indicators (line 967)
month = cum_days2(temp_var3); % determine month"

I'm not sure why this is the case but when I construct similar variable to temp_var3 cum_days2 and then run that block of code it seems a lot happier than when I run the function. Any ideas?

Bruno

17 Feb 2012 Nate Jensen

Krzysztof,

I suggest you simply write a new ema code that includes the previous ema value and you should be set. The following should do what you want,

function vout = ema(vin,prev_ema)

k = 2/(lag+1);
kvin = vin * k;
oneK = 1-k;

vout = kvin + (prev_ema * oneK);

end

17 Feb 2012 Krzysztof Fajst

Hi,

I made some more investigation and I think tsmovavg based solution has a major drawback i.e. will not work for real time application. Lets assume you have 10k bars and you calculate ema on it. Than a new bar comes and calculate again 10k would be very time costly - much easier to calculate just last bar.

But in this case this code will not work because instead of use x-1 data
for initial value (so last data point of 1st calculation of ema) it will use some average values.

in other words it means that ema calculated on 10k+1 bars in one pass will have different value than ema calculated on last bar and it should not be a case.

Filter solution seems to be ok

Krzysztof

08 Jan 2012 Nate Jensen

Krzysztof,

The method that I used is the method that Matlab uses to calculate the ema in their own moving average function 'tsmovavg'. This is not to say that that method is correct, but that is why I used it.

I briefly compared it to Google's ema on their finance page and the results were the same.

I would suggest to stick with what I have.

Nate

08 Jan 2012 Krzysztof Fajst

It looks that there are at least 2 versions of code for EMA around i.e.
EMA calculated with algorithm from this function and EMA calculated with this code

% convert the period to an exponential percentage
ep = 2/(period+1);

% calculate the EMA
out = filter(ep,[1-(1-ep)],data,data(1)*(1-ep));

Unfortunately they give different results. Which one is correct ??

Krzysztof

Updates
04 Mar 2012

added 2 more indicators, corrected date conversion issue

25 Mar 2012

Added the True Strength Index

21 Mar 2013

Added the KDJ Indicator

24 May 2013

Added Volatility Ratio, Highest High Lowest Low. Fixed example error. Fixed FSTO and SSTO error.

Contact us