Python Pandas for Financial Stuff

In [2]:
import datetime

import pandas as pd
import pandas.io.data
from pandas import Series, DataFrame
pd.__version__

import matplotlib.pyplot as plt
import numpy as np

%pylab inline
Populating the interactive namespace from numpy and matplotlib

TESLA Motors

In [3]:
sc='TSLA'
stoxx = pd.io.data.get_data_yahoo(sc, 
                                 start=datetime.datetime(2014, 1, 1))
stoxx.head(10)
Out[3]:
Open High Low Close Volume Adj Close
Date
2014-01-02 149.80 152.48 146.55 150.10 6188400 150.10
2014-01-03 150.00 152.19 148.60 149.56 4695000 149.56
2014-01-06 150.00 150.40 145.24 147.00 5361100 147.00
2014-01-07 147.62 150.40 145.25 149.36 5034100 149.36
2014-01-08 148.85 153.70 148.76 151.28 6163200 151.28
2014-01-09 152.50 153.43 146.85 147.53 5382000 147.53
2014-01-10 148.46 148.90 142.25 145.72 7446100 145.72
2014-01-13 145.78 147.00 137.82 139.34 6316100 139.34
2014-01-14 140.50 162.00 136.67 161.27 27607000 161.27
2014-01-15 168.45 172.23 162.10 164.13 20465600 164.13
In [4]:
print('Date: %s' % stoxx.index[-1])
Date: 2014-10-02 00:00:00

Schlusspreis

In [5]:
plt.figure(figsize=(16,4))
stoxx['Close'].plot();
plt.ylabel('\$')
plt.title('Closing Price %s' % sc);
plt.savefig('Closing-Price-TSLA.png',bbox_inches='tight', dpi=150)

Financial Stuff

Exponentially Weighted Moving Average

In [6]:
close_px = stoxx['Adj Close']
mavg10 = pd.ewma(close_px, 10)
mavg30 = pd.ewma(close_px, 30)
plt.figure(figsize=(16,4))
mavg10.plot(label='10days mavg');
mavg30.plot(label='30days mavg');
stoxx['Close'].plot(alpha=0.3);
plt.ylabel('\$')
plt.title('Exponentially Weighted Moving Averages %s' % (sc));
plt.legend(loc=2)
plt.savefig('Closing-Price-TSLA-EWMA.png',bbox_inches='tight', dpi=150)

Relative Strength Index

The relative strength index (RSI) is a technical indicator used in the analysis of financial markets. It is intended to chart the current and historical strength or weakness of a stock or market based on the closing prices of a recent trading period. The indicator should not be confused with relative strength. - Wikipedia

Source: http://stackoverflow.com/a/20527056

Commonly, the RSI is not calcualted with the rolling_mean but with the exponentially weighted moving average ewma!

In [7]:
# Get daily up or down
delta = stoxx['Close'].diff()

dUp, dDown = delta.copy( ), delta.copy( )
dUp[ dUp < 0 ] = 0
dDown[ dDown > 0 ] = 0

n=14
RolUp = pd.rolling_mean( dUp, n)
RolDown = pd.rolling_mean( dDown, n).abs()

RS = RolUp / RolDown
RSI = 100. - 100./(1.+RS)

plt.figure(figsize=(9,3))
RSI.plot();
plt.axhline(20, color='k', alpha=0.2)
plt.annotate('oversold',xy=(0.5, 0.28), xycoords='figure fraction', fontsize=20, alpha=0.4, ha='center')
plt.axhline(80, color='k', alpha=0.2)
plt.annotate('overbought',xy=(0.5, 0.82), xycoords='figure fraction', fontsize=20, alpha=0.4,ha='center')
plt.title('RSI %s (%i days)' % (sc, n));
plt.ylim([0,100]);
plt.ylabel('%');
plt.savefig('RSI-TSLA.png',bbox_inches='tight', dpi=150)
In [8]:
print('TSLA RSI (%s): %d%%' % (stoxx.index[-1], RSI.values[-1]))
TSLA RSI (2014-10-02 00:00:00): 31%

Load other Stock Values

In [9]:
df = pd.io.data.get_data_yahoo(['AAPL', 'FXXP.EX', 'GOOG', 'FDAX.EX', 'TSLA'], 
                               start=datetime.datetime(2013, 1, 1))['Adj Close']
df.head()
Out[9]:
AAPL FDAX.EX FXXP.EX GOOG TSLA
Date
2013-01-02 75.63 7778.78 285.33 NaN 35.36
2013-01-03 74.68 7756.44 286.83 NaN 34.77
2013-01-04 72.60 7776.37 287.83 NaN 34.40
2013-01-07 72.17 7732.66 286.63 NaN 34.34
2013-01-08 72.37 7695.83 286.25 NaN 33.68

Returns

In [10]:
rets = df.pct_change()
In [11]:
stoxx['rets'] = close_px.pct_change()
plt.figure(figsize=(16,4))
stoxx.rets.plot();
plt.title('Returns %s' % sc);
plt.ylabel('\$');

Monte Carlo Simulation

Monte Carlo methods are used in finance and mathematical finance to value and analyze (complex) instruments, portfolios and investments by simulating the various sources of uncertainty affecting their value, and then determining their average value over the range of resultant outcomes. - Wikipedia

In [12]:
SO=stoxx['Close'][-1] # letzter Preis
vol=np.std(stoxx['rets'])*np.sqrt(252) # Historical Volatility
r=0.025 # Constant Short Rate

K = SO*1.1 # 10% OTM Call Option
T = 1.0 # Maturity 1 Year

M=364
dt=T/M # Time Steps
I = 100 # Simulation Paths
In [13]:
S=np.zeros((M+1,I))
S[0,:]=SO
for t in range(1, M+1):
    ran = np.random.standard_normal(I)
    S[t,:]=S[t-1,:] * np.exp((r-vol**2/2)*dt + vol*np.sqrt(dt)*ran)


MC=pd.DataFrame(data=S, index=pd.date_range(start=stoxx.index[-1], periods=M+1))
MCmean = pd.DataFrame(data=S, index=pd.date_range(start=stoxx.index[-1], periods=M+1)).mean()

ax=MC.plot(alpha=0.2, color='k');

stoxx['Close'].plot(ax=ax);
plt.legend(['Monte Carlo Simulation'], loc='upper left');
plt.ylabel('Closing Price \$');
plt.title('Possible Future of TSLA (Tesla Motors Stock)')
plt.savefig('Monte-Carlo-Simulation-TSLA.png',bbox_inches='tight', dpi=150)

Option Valuation

In [14]:
VO=np.exp(-r*T)*np.sum(np.max(S[-1]-K,0))/I
print('Call Value %8.3f' % VO)
Call Value    4.475

Vergleich

In [15]:
fig=plt.figure(figsize=(12,12));
pd.scatter_matrix(rets, diagonal='kde', figsize=(10, 10));
<matplotlib.figure.Figure at 0x109034990>

Korrelation der Returns

In [16]:
corr = rets.corr()
corr
Out[16]:
AAPL FDAX.EX FXXP.EX GOOG TSLA
AAPL 1.000000 0.145819 0.143540 0.257940 0.066756
FDAX.EX 0.145819 1.000000 0.917556 0.308664 0.127384
FXXP.EX 0.143540 0.917556 1.000000 0.338610 0.151210
GOOG 0.257940 0.308664 0.338610 1.000000 0.402618
TSLA 0.066756 0.127384 0.151210 0.402618 1.000000
In [17]:
plt.imshow(corr, cmap='YlGn', interpolation='none')
plt.colorbar()
plt.xticks(range(len(corr)), corr.columns)
plt.yticks(range(len(corr)), corr.columns);
In [18]:
fig=plt.figure(figsize=(12,12))
plt.scatter(rets.mean(), rets.std(), s=50)
plt.xlabel('Expected returns')
plt.ylabel('Risk')
for label, x, y in zip(rets.columns, rets.mean(), rets.std()):
    plt.annotate(
        label, 
        xy = (x, y), xytext = (20, -20),
        textcoords = 'offset points', ha = 'right', va = 'bottom',
        bbox = dict(boxstyle = 'round,pad=0.5', fc = 'w', alpha = 0.5),
        arrowprops = dict(arrowstyle = '->', connectionstyle = 'arc3,rad=0'))

Elon Musk