|
| 1 | +############################################################################## |
| 2 | +# |
| 3 | +# Example of particle Metropolis-Hastings in a stochastic volatility model |
| 4 | +# |
| 5 | +# (c) 2015 Johan Dahlin |
| 6 | +# johan.dahlin (at) liu.se |
| 7 | +# |
| 8 | +############################################################################## |
| 9 | + |
| 10 | +# Import some libraries |
| 11 | +import matplotlib.pylab as plt |
| 12 | +import numpy as np |
| 13 | +import stateEstimationHelper as helpState |
| 14 | +import parameterEstimationHelper as helpParam |
| 15 | + |
| 16 | +# Set the random seed to replicate results in tutorial |
| 17 | +np.random.seed( 10 ); |
| 18 | + |
| 19 | +############################################################################## |
| 20 | +# Define the model |
| 21 | +############################################################################## |
| 22 | + |
| 23 | +# Here, we use the following model |
| 24 | +# |
| 25 | +# x[tt+1] = par[0] * x[tt] + par[1] * v[tt] |
| 26 | +# y[tt] = par[2] * exp( xt[tt]/2 ) * e[tt] |
| 27 | +# |
| 28 | +# where v[tt] ~ N(0,1) and e[tt] ~ N(0,1) |
| 29 | + |
| 30 | +# Set the number of time steps |
| 31 | +T = 500; |
| 32 | + |
| 33 | +############################################################################## |
| 34 | +# Load data |
| 35 | +############################################################################## |
| 36 | +y = np.loadtxt('omxs30data.csv') |
| 37 | + |
| 38 | +############################################################################## |
| 39 | +# Parameter estimation using PMH |
| 40 | +############################################################################## |
| 41 | + |
| 42 | +# The inital guess of the parameter |
| 43 | +initPar = np.array(( 0.99, 0.13, 0.90)); |
| 44 | + |
| 45 | +# No. particles in the particle filter ( choose nPart ~ T ) |
| 46 | +nPart = 500; |
| 47 | + |
| 48 | +# The length of the burn-in and the no. iterations of PMH ( nBurnIn < nRuns ) |
| 49 | +nBurnIn = 2500; |
| 50 | +nRuns = 7500; |
| 51 | + |
| 52 | +# The standard deviation in the random walk proposal |
| 53 | +stepSize = np.array(( 0.01, 0.05, 0.05)); |
| 54 | + |
| 55 | +# Run the PMH algorithm |
| 56 | +res = helpParam.pmh_sv(y,initPar,nPart,T,helpState.pf_sv,nRuns,stepSize) |
| 57 | + |
| 58 | +# State inference |
| 59 | +( xhat, ll ) = helpState.pf_sv(y, np.mean( res[nBurnIn:nRuns,:], axis=0 ) ,nPart,T); |
| 60 | + |
| 61 | +#============================================================================= |
| 62 | +# Plot the results |
| 63 | +#============================================================================= |
| 64 | + |
| 65 | +plt.figure(1); |
| 66 | + |
| 67 | +# Plot the log-returns with volatility estimate |
| 68 | +plt.subplot(4,2,(1,2)); |
| 69 | +plt.plot(y,color = '#1B9E77', linewidth=1.5); |
| 70 | +plt.plot(xhat,color = '#D95F02', linewidth=1.5); |
| 71 | +plt.xlabel("time"); plt.ylabel("log-return") |
| 72 | + |
| 73 | +# Plot the parameter posterior estimate |
| 74 | +# Plot the trace of the Markov chain after burn-in |
| 75 | +# Solid black line indicate posterior mean |
| 76 | +plt.subplot(4,2,3); |
| 77 | +plt.hist(res[nBurnIn:nRuns,0], np.floor(np.sqrt(nRuns-nBurnIn)), normed=1, facecolor='#7570B3') |
| 78 | +plt.xlabel("phi"); plt.ylabel("posterior density estimate") |
| 79 | +plt.axvline( np.mean(res[nBurnIn:nRuns,0]), linewidth=1.5, color = 'k' ) |
| 80 | + |
| 81 | +plt.subplot(4,2,4); |
| 82 | +plt.plot(np.arange(nBurnIn,nRuns,1),res[nBurnIn:nRuns,0],color='#7570B3') |
| 83 | +plt.xlabel("iteration"); plt.ylabel("trace of phi") |
| 84 | +plt.axhline( np.mean(res[nBurnIn:nRuns,0]), linewidth=1.5, color = 'k' ) |
| 85 | + |
| 86 | +plt.subplot(4,2,5); |
| 87 | +plt.hist(res[nBurnIn:nRuns,1], np.floor(np.sqrt(nRuns-nBurnIn)), normed=1, facecolor='#E7298A') |
| 88 | +plt.xlabel("sigmav"); plt.ylabel("posterior density estimate") |
| 89 | +plt.axvline( np.mean(res[nBurnIn:nRuns,1]), linewidth=1.5, color = 'k' ) |
| 90 | + |
| 91 | +plt.subplot(4,2,6); |
| 92 | +plt.plot(np.arange(nBurnIn,nRuns,1),res[nBurnIn:nRuns,1],color='#E7298A') |
| 93 | +plt.xlabel("iteration"); plt.ylabel("trace of sigmav") |
| 94 | +plt.axhline( np.mean(res[nBurnIn:nRuns,1]), linewidth=1.5, color = 'k' ) |
| 95 | + |
| 96 | +plt.subplot(4,2,7); |
| 97 | +plt.hist(res[nBurnIn:nRuns,2], np.floor(np.sqrt(nRuns-nBurnIn)), normed=1, facecolor='#66A61E') |
| 98 | +plt.xlabel("beta"); plt.ylabel("posterior density estimate") |
| 99 | +plt.axvline( np.mean(res[nBurnIn:nRuns,2]), linewidth=1.5, color = 'k' ) |
| 100 | + |
| 101 | +plt.subplot(4,2,8); |
| 102 | +plt.plot(np.arange(nBurnIn,nRuns,1),res[nBurnIn:nRuns,2],color='#66A61E') |
| 103 | +plt.xlabel("iteration"); plt.ylabel("trace of beta") |
| 104 | +plt.axhline( np.mean(res[nBurnIn:nRuns,2]), linewidth=1.5, color = 'k' ) |
| 105 | + |
| 106 | +############################################################################## |
| 107 | +# End of file |
| 108 | +############################################################################## |
0 commit comments