pStar = pStarFct(mat, states, a_r, b_r) pStarT = pStarTFct(mat, states, a_r, a_s, b_r, p) # Compute the log-likelihood to maximise logLik = logLikFct(var, p, pStar, pStarT) # Save parameters for later plotting (redundant wrt optimisation) vs[:, m] = var ps[:, m] = p llh[m] = logLik # ============================================= # # ===== Plotting ============================== # # ============================================= # if states == 2: pltm.plotDuo(range(sims), vs[0,:], vs[1,:], 'Var_1', 'Var_2', 'Trials', 'Variance') pltm.plotDuo(range(sims), ps[0,:], ps[3,:], 'p11', 'p22', 'Trials', 'Probability') elif states == 3: pltm.plotTri(range(sims), vs[0,:], vs[1,:], vs[2,:], 'Trials', 'Var_1', 'Var_2', 'Var_3', 'Variance') pltm.plotTri(range(sims), ps[0,:], ps[4,:], ps[8,:], 'Trials', 'p11', 'p22', 'p33', 'Probability') pltm.plotUno(d, pStar[0,:], xLab = 'Time', yLab = 'p1', title = 'Smoothed State Probabilities') pltm.plotUno(d, pStar[1,:], xLab = 'Time', yLab = 'p2', title = 'Smoothed State Probabilities') pltm.plotUno(d, pStar[2,:], xLab = 'Time', yLab = 'p3', title = 'Smoothed State Probabilities') elif states == 4: pltm.plotQuad(range(sims), vs[0,:], vs[1,:], vs[2,:], vs[3,:], 'Trials', 'Var_1', 'Var_2', 'Var_3', 'Var_4', 'Variance') pltm.plotQuad(range(sims), ps[0,:], ps[5,:], ps[10,:], ps[15,:], 'Trials', 'p11', 'p22', 'p33', 'p44', 'Probability') pltm.plotUno(range(sims), llh, yLab = 'log-likelihood value')
np.random.seed(12345) z = np.random.normal(0, 1, size=mat) u = np.random.uniform(0, 1, size=mat) state = (u > p) * 1 + (u < p) * 0 vol = [1] * mat ret = [0] * mat for t in range(1, mat): vol[t] = (s_h**2 + a_h * ret[t - 1]**2) if state[t] else (s_l**2 + a_l * ret[t - 1]**2) ret[t] = vol[t]**.5 * z[t] x = np.arange(0, mat) pltm.plotDuo(x = x, y1 = ret, y2 = state, \ yLab1 = 'Returns', yLab2 = 'State', \ yLab = 'Returns', xLab = 'Time') # Compare with old model returns = ((u > p) * s_h + (u < p) * s_l) * z pltm.plotDuo(x = x, y1 = returns, y2 = state, \ yLab1 = 'Returns', yLab2 = 'State', \ yLab = 'Returns', xLab = 'Time') # s ~ Markov chain " Two-state hidden Markov volatility model " p11 = 0.95 p22 = 0.90 state_ms = np.repeat(0, mat)
import scipy.stats as ss # Distribution functions import plotsModule as pltm # Custom plotting import likelihoodModule as llm # Likelihood functions np.set_printoptions(suppress=True) # Disable scientific notation # First exercise 1.5 x = np.arange(-5, 5, 0.01) y = ss.norm.pdf(x) z = ss.t.pdf(x, 3) pltm.plotDuo(x, y, z, 'Standard Normal PDF', "Student's t (v=3)", '', 'Density', "Comparison between PDF's", loc='upper right') tArch = tsm.tArchFct(1., 0.8, 3, 10000) sig2 = 1.0 alpha = 0.8 periods = 100 n = 10000 scores = np.zeros(n) for i in np.arange(n): tArch = tsm.tArchFct(sig2, alpha, 3, periods)
s1, s2, p = 1.0, 0.5, 0.3 # Compute initial pStar given initial parameters f1 = 1 / np.sqrt(2 * np.pi * s1) * np.exp(-0.5 * y**2 / s1) f2 = 1 / np.sqrt(2 * np.pi * s2) * np.exp(-0.5 * y**2 / s2) pStar = p * f1 / (p * f1 + (1 - p) * f2) for m in range(rep): # Reevaluate parameters given pStar s1 = sum(pStar * y**2) / sum(pStar) s2 = sum((1 - pStar) * y**2) / sum(1 - pStar) p = sum(pStar) / mat # Update pStar given new parameters f1 = 1 / np.sqrt(2 * np.pi * s1) * np.exp(-0.5 * y**2 / s1) f2 = 1 / np.sqrt(2 * np.pi * s2) * np.exp(-0.5 * y**2 / s2) pStar = p * f1 / (p * f1 + (1 - p) * f2) # Compute new pStar # Compute the log-likelihood to maximise logLik = pStar * np.log(f1 * p) + (1 - pStar) * np.log(f2 * (1 - p)) sVol = pStar * s1 + (1 - pStar) * s2 # Save parameters for later plotting (redundant wrt optimisation) par[0, m], par[1, m], par[2, m] = s1, s2, p llh[m] = sum(logLik) pltm.plotDuo(range(rep), par[0, :], par[1, :], 'Sigma_h', 'Sigma_l', 'Time', 'Volatility') pltm.plotUno(range(rep), par[2, :]) pltm.plotUno(range(rep), llh)
a[0, 0], a[1, 0] = f1[0] / mat, f2[0] / mat for t in range(1, mat): a[0, t] = f1[t] * (p11 * a[0, t - 1] + p21 * a[1, t - 1] ) # Has to end in state 1 a[1, t] = f2[t] * (p12 * a[0, t - 1] + p22 * a[1, t - 1] ) # Has to end in state 2 # a[0, t] = f1[t] * sum([p11, p21] * a[:, t-1]) <-- Slightly more dynamic for t in range(mat - 2, -1, -1): b[0, t] = f1[t + 1] * b[0, t + 1] * p11 + f2[t + 1] * b[1, t + 1] * p12 b[1, t] = f1[t + 1] * b[0, t + 1] * p21 + f2[t + 1] * b[1, t + 1] * p22 # We note, that there is a problem because of extremely small values of a, b. pltm.plotDuo(range(mat), a[0, :], a[1, :], 'State 1', 'State 2', 'Time', 'Forward') pltm.plotDuo(range(mat), b[0, :], b[1, :], 'State 1', 'State 2', 'Time', 'Backward') # Because of these extremely small values, stable solutions are not found, and # for this reason we skip the computation of probabilities. # To fix the problem of scale, we rescale a, b to find stable solutions. # ============================================= # # ===== Rescaled EM algorithm ================= # # ============================================= # # A. Forward algorithm a_s = np.ones(mat) # a_scale a_r = np.ones(states * mat).reshape(states, mat) # a_rescale