Impressum


mcsniedrigzinsapp






In [1]:
import numpy as np # Import des Basis-Pakets
import pandas as pd # Import zur Basis-Datenverarbeitung, CSV-Datei lesen und schreiben etc.(z. B. per pd.read_csv)

# Input-Daten sind in dem Ordner "meininput/" verfügbar.
# Der nachfolgende Quellcode listet alle in dem Ordner enthaltenen Dateien.

import os
print(os.listdir("meininput"))
[]
In [3]:
mcsdaten =pd.read_csv("meininput/beispiel_stocks_5j.csv")
In [4]:
mcsdaten.head()
Out[4]:
date open high low close volume Name
0 2013-02-08 15.07 15.12 14.63 14.75 8407500 AAL
1 2013-02-11 14.89 15.01 14.26 14.46 8882000 AAL
2 2013-02-12 14.45 14.51 14.10 14.27 8126000 AAL
3 2013-02-13 14.30 14.94 14.25 14.66 10259500 AAL
4 2013-02-14 14.94 14.96 13.16 13.99 31879900 AAL
In [5]:
mcsdaten.tail()
Out[5]:
date open high low close volume Name
619035 2018-02-01 76.84 78.27 76.69 77.82 2982259 ZTS
619036 2018-02-02 77.53 78.12 76.73 76.78 2595187 ZTS
619037 2018-02-05 76.64 76.92 73.18 73.83 2962031 ZTS
619038 2018-02-06 72.74 74.56 72.13 73.27 4924323 ZTS
619039 2018-02-07 72.70 75.00 72.69 73.86 4534912 ZTS
In [6]:
#Es wird nur der Stock AAL ausgewählt
mcsdaten = mcsdaten[mcsdaten.Name == 'AAL']
In [7]:
mcsdaten.tail()
Out[7]:
date open high low close volume Name
1254 2018-02-01 54.00 54.64 53.59 53.88 3623078 AAL
1255 2018-02-02 53.49 53.99 52.03 52.10 5109361 AAL
1256 2018-02-05 51.99 52.39 49.75 49.76 6878284 AAL
1257 2018-02-06 49.32 51.50 48.79 51.18 6782480 AAL
1258 2018-02-07 50.91 51.98 50.89 51.40 4845831 AAL
In [8]:
from scipy.stats import norm
log_returns = np.log(1 + mcsdaten.close.pct_change())
u = log_returns.mean() #Mean des log-Returns
var = log_returns.var() #Varianz des log-Returns
drift = u - (0.5 * var) #drift bzw. Trend des log-Returns
stdev = log_returns.std() #Standardabweichung des log-Returns


t_intervals = 250 #Forecast von 250 Zeitpunkten
iterations = 10 #10 unterschiedliche Forecasts (als loop)

daily_returns = np.exp(drift + stdev * norm.ppf(np.random.rand(t_intervals, iterations)))
#daily_returns als "noise", bei Multiplikation mit t time price, erhält man t+1 time price
In [9]:
S0 = mcsdaten.close.iloc[-1]
S0
Out[9]:
51.4
In [10]:
#Erst wird eine leere Matrix für die daily_returns erzeugt
price_list = np.zeros_like(daily_returns)
price_list[0] = S0
price_list
Out[10]:
array([[51.4, 51.4, 51.4, ..., 51.4, 51.4, 51.4],
       [ 0. ,  0. ,  0. , ...,  0. ,  0. ,  0. ],
       [ 0. ,  0. ,  0. , ...,  0. ,  0. ,  0. ],
       ...,
       [ 0. ,  0. ,  0. , ...,  0. ,  0. ,  0. ],
       [ 0. ,  0. ,  0. , ...,  0. ,  0. ,  0. ],
       [ 0. ,  0. ,  0. , ...,  0. ,  0. ,  0. ]])
In [11]:
# Mit einem einfachen Loop wird ein Forecast für die nächsten 250 Tage performt.
for t in range(1, t_intervals):
    price_list[t] = price_list[t - 1] * daily_returns[t]
price_list = pd.DataFrame(price_list)
price_list['close'] = price_list[0]
price_list.head()
Out[11]:
0 1 2 3 4 5 6 7 8 9 close
0 51.400000 51.400000 51.400000 51.400000 51.400000 51.400000 51.400000 51.400000 51.400000 51.400000 51.400000
1 53.204133 50.815643 52.839073 52.340832 51.397597 50.819671 51.255417 50.770590 50.728515 51.329999 53.204133
2 53.588386 49.700971 52.307373 52.479590 50.680655 49.961748 50.649150 51.385898 51.647812 52.281951 53.588386
3 55.125797 48.321043 54.622920 53.744299 50.504168 51.183897 49.411163 53.942560 53.570796 50.736924 55.125797
4 56.933411 47.400700 54.210152 54.334949 51.051874 50.728833 49.964868 53.577100 53.079608 50.813041 56.933411
In [12]:
close = mcsdaten.close
close = pd.DataFrame(close)
frames = [close, price_list]
monte_carlo_forecast = pd.concat(frames)
C:\Users\XXX\Anaconda3\lib\site-packages\ipykernel_launcher.py:4: FutureWarning: Sorting because non-concatenation axis is not aligned. A future version
of pandas will change to not sort by default.

To accept the future behavior, pass 'sort=False'.

To retain the current behavior and silence the warning, pass 'sort=True'.

  after removing the cwd from sys.path.
In [13]:
monte_carlo_forecast.head()
Out[13]:
close 0 1 2 3 4 5 6 7 8 9
0 14.75 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1 14.46 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2 14.27 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
3 14.66 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
4 13.99 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
In [14]:
monte_carlo_forecast.tail()
Out[14]:
close 0 1 2 3 4 5 6 7 8 9
245 86.730582 86.730582 33.702698 78.069997 41.582686 68.000821 49.687845 61.215850 103.876008 55.594627 54.605421
246 85.552658 85.552658 33.802081 77.617334 42.467013 66.149360 48.758026 61.809711 102.644513 54.441041 55.219265
247 85.312422 85.312422 33.592286 77.259121 42.398846 67.003178 51.156854 62.519812 102.967436 53.246924 57.158346
248 85.917793 85.917793 34.337167 78.115106 42.798142 67.416512 50.531375 61.192381 107.650519 51.474543 56.300239
249 86.906389 86.906389 33.665049 76.614539 42.624562 65.507907 51.050383 60.598224 106.404068 50.067770 56.965318
In [15]:
monte_carlo = monte_carlo_forecast.iloc[:,:].values
import matplotlib.pyplot as plt
plt.figure(figsize=(17,8))
plt.plot(monte_carlo)
plt.show()
<Figure size 1700x800 with 1 Axes>
In [16]:
monte_carlo = monte_carlo_forecast.iloc[:,:].values
import matplotlib.pyplot as plt
plt.figure(figsize=(17,8))
plt.plot(monte_carlo)
plt.show()
In [19]:
#Nachfolgend die Verteilung der log-Returns
import plotly.plotly as py
from plotly.offline import init_notebook_mode, iplot
init_notebook_mode(connected=True)
import plotly.graph_objs as go
trace = go.Histogram(x=log_returns,opacity=0.85,name = "Logarithmic Return", marker=dict(color='rgba(0, 0, 255, 0.8)'))
info = [trace]
layout = go.Layout(barmode='overlay',
                   title='Verteilung der Logarithmic Returns',
                   xaxis=dict(title='Logarithmic Return'),
                   yaxis=dict( title='Verteilung'),
)
fig = go.Figure(data=info, layout=layout)
iplot(fig)

In [26]:
mcsdaten = mcsdaten.dropna()
In [28]:
#Nun wird die Seasonalität untersucht
from statsmodels.tsa.seasonal import seasonal_decompose
decomposition = seasonal_decompose(mcsdaten.log_return, freq = 260) #mit 260 Arbeitstagen pro Jahr
trend = decomposition.trend
seasonal = decomposition.seasonal
residual = decomposition.resid

plt.figure(figsize=(12,6))
plt.subplot(411)
plt.plot(log_returns, label='Original')
plt.legend(loc='best')
plt.subplot(412)
plt.plot(trend, label='Trend')
plt.legend(loc='best')
plt.subplot(413)
plt.plot(seasonal,label='Seasonalität')
plt.legend(loc='best')
plt.subplot(414)
plt.plot(residual, label='Residuale')
plt.legend(loc='best')
plt.tight_layout()
plt.show()
In [29]:
#Nun wird die serielle Korrelation untersucht
import statsmodels.api as sm  
from statsmodels.tsa.stattools import acf  
from statsmodels.tsa.stattools import pacf
fig = plt.figure(figsize=(12,8))
ax1 = fig.add_subplot(211)
fig = sm.graphics.tsa.plot_acf(mcsdaten.log_return, lags=40, ax=ax1)
ax2 = fig.add_subplot(212)
fig = sm.graphics.tsa.plot_pacf(mcsdaten.log_return, lags=40, ax=ax2)
plt.show()
In [30]:
#Nun wird das Auto Regressive Moving Average Modell zugrunde gelegt
#...mit den Parametern Ar(p) and Ma(q)
from statsmodels.tsa.stattools import ARMA
def best_AR_MA_checker(df,lower,upper):
    from statsmodels.tsa.stattools import ARMA
    from statsmodels.tsa.stattools import adfuller
    arg=np.arange(lower,upper)
    arg1=np.arange(lower,upper)
    best_param_i=0
    best_param_j=0
    temp=12000000
    rs=99
    for i in arg:
        for j in arg1:
            model=ARMA(df, order=(i,0,j))
            result=model.fit(disp=0)
            resid=adfuller(result.resid)
            if (result.aic<temp and  adfuller(result.resid)[1]<0.05):
                temp=result.aic
                best_param_i=i
                best_param_j=j
                rs=resid[1]
                
                
            print ("AR: %d, MA: %d, AIC: %d; resid stationarity check: %d"%(i,j,result.aic,resid[1]))
            
    print("the following function prints AIC criteria and finds the paramters for minimum AIC criteria")        
    print("best AR: %d, best MA: %d, best AIC: %d;  resid stationarity check:%d"%(best_param_i, best_param_j, temp, rs))     
best_AR_MA_checker(mcsdaten.log_return,0,3) #For each parameter I want to try from 0 to 2
C:\Users\XXX\Anaconda3\lib\site-packages\statsmodels\tsa\base\tsa_model.py:221: ValueWarning:

An unsupported index was provided and will be ignored when e.g. forecasting.

C:\Users\XXX\Anaconda3\lib\site-packages\scipy\signal\signaltools.py:1341: FutureWarning:

Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.

C:\Users\XXX\Anaconda3\lib\site-packages\scipy\signal\signaltools.py:1344: FutureWarning:

Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.

C:\Users\XXX\Anaconda3\lib\site-packages\scipy\signal\signaltools.py:1350: FutureWarning:

Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.

C:\Users\XXX\Anaconda3\lib\site-packages\statsmodels\tsa\base\tsa_model.py:221: ValueWarning:

An unsupported index was provided and will be ignored when e.g. forecasting.

C:\Users\XXX\Anaconda3\lib\site-packages\statsmodels\tsa\base\tsa_model.py:221: ValueWarning:

An unsupported index was provided and will be ignored when e.g. forecasting.

AR: 0, MA: 0, AIC: -5974; resid stationarity check: 0
AR: 0, MA: 1, AIC: -5974; resid stationarity check: 0
AR: 0, MA: 2, AIC: -5974; resid stationarity check: 0
C:\Users\XXX\Anaconda3\lib\site-packages\statsmodels\tsa\base\tsa_model.py:221: ValueWarning:

An unsupported index was provided and will be ignored when e.g. forecasting.

C:\Users\XXX\Anaconda3\lib\site-packages\statsmodels\tsa\base\tsa_model.py:221: ValueWarning:

An unsupported index was provided and will be ignored when e.g. forecasting.

AR: 1, MA: 0, AIC: -5976; resid stationarity check: 0
AR: 1, MA: 1, AIC: -5976; resid stationarity check: 0
AR: 1, MA: 2, AIC: -5976; resid stationarity check: 0
C:\Users\XXX\Anaconda3\lib\site-packages\statsmodels\tsa\base\tsa_model.py:221: ValueWarning:

An unsupported index was provided and will be ignored when e.g. forecasting.

C:\Users\XXX\Anaconda3\lib\site-packages\statsmodels\tsa\base\tsa_model.py:221: ValueWarning:

An unsupported index was provided and will be ignored when e.g. forecasting.

AR: 2, MA: 0, AIC: -5974; resid stationarity check: 0
AR: 2, MA: 1, AIC: -5974; resid stationarity check: 0
C:\Users\XXX\Anaconda3\lib\site-packages\statsmodels\tsa\base\tsa_model.py:221: ValueWarning:

An unsupported index was provided and will be ignored when e.g. forecasting.

C:\Users\XXX\Anaconda3\lib\site-packages\statsmodels\tsa\base\tsa_model.py:221: ValueWarning:

An unsupported index was provided and will be ignored when e.g. forecasting.

AR: 2, MA: 2, AIC: -5974; resid stationarity check: 0
the following function prints AIC criteria and finds the paramters for minimum AIC criteria
best AR: 1, best MA: 0, best AIC: -5976;  resid stationarity check:0
In [31]:
#Nun wird arma(1,0) untersucht
from statsmodels.tsa.stattools import ARMA
model=ARMA(mcsdaten.log_return, order=(1,0))
res=model.fit(disp=0)
print (res.summary())
                              ARMA Model Results                              
==============================================================================
Dep. Variable:             log_return   No. Observations:                 1258
Model:                     ARMA(1, 0)   Log Likelihood                2991.154
Method:                       css-mle   S.D. of innovations              0.022
Date:                Sun, 17 Mar 2019   AIC                          -5976.308
Time:                        13:12:27   BIC                          -5960.896
Sample:                             0   HQIC                         -5970.516
                                                                              
====================================================================================
                       coef    std err          z      P>|z|      [0.025      0.975]
------------------------------------------------------------------------------------
const                0.0010      0.001      1.476      0.140      -0.000       0.002
ar.L1.log_return     0.0582      0.028      2.066      0.039       0.003       0.113
                                    Roots                                    
=============================================================================
                  Real          Imaginary           Modulus         Frequency
-----------------------------------------------------------------------------
AR.1           17.1950           +0.0000j           17.1950            0.0000
-----------------------------------------------------------------------------
C:\Users\XXX\Anaconda3\lib\site-packages\statsmodels\tsa\base\tsa_model.py:221: ValueWarning:

An unsupported index was provided and will be ignored when e.g. forecasting.

In [ ]: