ivanidris.
net
Jarque Bera, the CAPM and undervalued stocks
The Capital Asset Pricing Model ( CAPM ) links the expected return of assets to their risk. A linear fit of this relationship gives us the so called Security Market Line ( SML ). One of the problems with this model is that it assumes a normal distribution of returns. The python [Link] module provides a Jarque Bera normality test, which allows me to select only the stocks which have nearly normal return distribution.
Jarque Bera test
I check with the Jarque-Bera test for normality. Normality implies predictability. Predictability leads to safety. Safety leads to joy. The code below screens for a certain Jarque Bera test p value of open, high, low and close prices returns.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 ... def get_returns( arr ): beforeLast = len( arr ) - 2 return diff( arr[ : beforeLast] ) / arr[ : beforeLast - 1] def get_pvals( returns ): pvals = [] for i in range(0, len( returns ) ): (jb, pval, skew, kurtosis) = jarque_bera( returns[ i ] ) [Link]( pval ) return pvals def check_pvals( pvals ): for i in range(0, len( pvals )): if pvals[ i ] < float( argv[ 1 ] ): return False return True ... returns = [] [Link]( [Link]( [Link]( [Link]( get_returns( get_returns( get_returns( get_returns( c o h l ) ) ) ) ) ) ) )
output = [] pvals = get_pvals( returns ) if check_pvals( pvals ): ev = geomean( returns[ 0 ] )
...
The expected return is estimated by the geometric mean function below. Actually it calls a [Link] function with positive values. This requires a bit of cheating in the form of taking the absolute value etcetera.
1 def geomean( arr ): 2 filtered = abs( arr ) 3 indices = flatnonzero( filtered ) 4 filtered = take( filtered, indices ) 5 6 return [Link]( filtered)
CAPM
So we need to have the slope and intercept of the security market line.
1 2 3 4 5 6 7 8 9 10 11 12 13 ... returns = [] [Link]( get_returns( c ) ) ev = geomean( returns[ 0 ] ) [Link]( ev ) stdC = std( returns[ 0 ] ) [Link]( stdC ) A = vstack([stds, ones(len(stds))]).T (p,residuals,rank,s) = [Link](A, evs) a,b=p ...
After that its just a question of selecting the points above the SML, which should be undervalued
If you liked this post and are interested in NumPy check out NumPy Beginners Guide by yours truly.