├── results ├── README.md ├── 1.png ├── 2.png ├── 3.png └── 4.png ├── README.md ├── accuracy_test.py ├── summaries.py ├── core.py └── MAVAR.ipynb /results/README.md: -------------------------------------------------------------------------------- 1 | this Directory display some results 2 | -------------------------------------------------------------------------------- /results/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yudai-il/Multivariate-Markov-Switching-Regressions/HEAD/results/1.png -------------------------------------------------------------------------------- /results/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yudai-il/Multivariate-Markov-Switching-Regressions/HEAD/results/2.png -------------------------------------------------------------------------------- /results/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yudai-il/Multivariate-Markov-Switching-Regressions/HEAD/results/3.png -------------------------------------------------------------------------------- /results/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yudai-il/Multivariate-Markov-Switching-Regressions/HEAD/results/4.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Multivariate Markov-Switching Models Regressions Framework 2 | This Directory contains Multivariate Markov-Switching Models Regressions Framework Written in Python 3 | 4 | Reference From " 5 | Bellone B. Classical Estimationof Multivariate Markov-Switching Models using MSVARlib[J]. Econometrics, 2005. 6 | " 7 | 8 | You can use This Package to build a Statistical arbitrage Strategy using MS-VECM (Markov-Switching Vector Error correction Models.) 9 |

10 | or Do some empirical Study of Asymmetric effects using MS-VAR( Markov-Switching Vector AutoRegression) 11 |


12 | 13 | Some Results Display Here: 14 | 15 | Time variant impact of M2 on Stocks Market: 16 |

17 | 18 | 19 |

20 | impluse response : 21 |

22 | 23 | 24 |


25 | 26 | Time variant impact of M2 on substantial economy: 27 |

28 | 29 |

30 | impluse response : 31 |

32 | 33 |


34 | 35 | For Detail Usage can Go To 36 | This Page 37 | 38 | An empirical Study based on China's macroeconomic and Financial Data. 39 | 40 | On the topic of 「Asymmetric effects of M2 on Stocks Market and substantial economy」.(Project during 2018) 41 | 42 | 43 | 44 | """ Notice: 45 | This Python Package are Based On the Gauss Language witten by Benoit BELLONE (2004) 46 | 47 | [The GAUSS programs available on the website http://bellone.ensae.net6 are written 48 | and copyrighted c 2004 by Benoit BELLONE, all rights reserved. They can be run on 49 | Gauss 3.2 or upper versions and should be OX-Gauss compliant, thanks to the routine 50 | M@ximize developped by Laurent and Urbain (2005)7. The code is licensed gratis to all 51 | third parties under the terms of this paragraph. Copying and distribution of the files 52 | in this archive is unrestricted if and only if the files are not modified. Modification of 53 | the files is encouraged, but the distribution of modifications of the code in this archive 54 | is unrestricted only if you meet the following conditions: modified files must carry a 55 | prominent notice stating 56 | (i) the original author and date, 57 | (ii) the new author and the date of release of the modification, 58 | (iii) that there is no warrantee for the code, and 59 | (iv) that the work is licensed at no charge to all parties. 60 | If you use the code extensively in your research, you are requested to provide appropriate 61 | attribution and thanks to the author of the code. No representation is made or implied 62 | as to the accuracy or completeness of the programs which may indeed contain bugs or 63 | errors unknown to the author. Benoit Bellone takes no responsibility for results produced 64 | by MSVARlib programs which are used entirely at the reader’s risk. This package is by 65 | no means finished yet, a enhancement “to do list” remains open. If you plan to extend 66 | the library, find any problems or have suggestions for improvement, contact the author.]""" 67 | -------------------------------------------------------------------------------- /accuracy_test.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import numpy as np 3 | # from.tools import * 4 | from Multivariate_Markov_Switching_Model.tools import * 5 | from Multivariate_Markov_Switching_Model.core import * 6 | from Multivariate_Markov_Switching_Model.tools import _2dim 7 | import numpy as np 8 | import os 9 | # os.chdir("Multivariate_Markov_Switching_Model") 10 | 11 | 12 | """ 13 | test A 14 | """ 15 | 16 | 17 | data = [] 18 | 19 | with open("Multivariate_Markov_Switching_Model/test_data/MSVARUN.txt") as f: 20 | for _ in f.readlines(): 21 | data.append(_.strip().split("\t")) 22 | data = pd.DataFrame(data) 23 | 24 | s = data.set_index([1,0]).replace(".",np.nan)[2].astype(float).rename_axis(['year','month']) 25 | 26 | apr = data.set_index([1,0]).replace(".",np.nan)[3].astype(float).rename_axis(['year','month']) 27 | 28 | apriori = apr[apr.index.get_loc(("1967","7")):apr.index.get_loc(("2004","3"))].values 29 | 30 | k_lag = 2 31 | 32 | _ = np.log(s).diff(k_lag)*100 33 | 34 | s = _[_.index.get_loc(("1967","2"))+k_lag:_.index.get_loc(("2004","2"))+1] 35 | 36 | s = ((s-s.mean())/s.std()).values[:,np.newaxis] 37 | y = s 38 | 39 | z = generate_lagged_regressors(s,3).values 40 | x = [1]*z.shape[0] 41 | x = _2dim(np.array(x)) 42 | 43 | model = Markov_Multivarite_Regression(y[-z.shape[0]:],x,z,2,2,"full",apriori=None) 44 | # model = Multivariate_Markov_Switching_Model(y[-z.shape[0]:],x,None,2,2,"full",apriori=None) 45 | 46 | res = model.fit() 47 | 48 | 49 | 50 | """ 51 | test B 52 | """ 53 | 54 | 55 | data = [] 56 | 57 | with open("Multivariate_Markov_Switching_Model/test_data/MSVARANAS.txt") as f: 58 | for _ in f.readlines(): 59 | data.append(_.strip().split("\t")) 60 | data = pd.DataFrame(data) 61 | 62 | 63 | data = data.replace(".",np.nan).set_index([1,0]).rename_axis(['year','month']).astype(float) 64 | 65 | k_lag = 1 66 | _ = np.log(data).diff(k_lag)*100 67 | 68 | s = _[_.index.get_loc(("1984","1"))+k_lag:_.index.get_loc(("2003","1"))+1] 69 | s = s.iloc[:,:4] 70 | 71 | s = ((s-s.mean())/s.std()).values 72 | 73 | x = _2dim(np.array([1]*s.shape[0])) 74 | 75 | model = Markov_Multivarite_Regression(s,x,None,3,1,"full",apriori=None) 76 | res = model.fit() 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | """ 105 | 106 | 107 | 108 | 109 | 110 | 111 | # res = model.fit() 112 | 113 | self = model 114 | 115 | param = start_params(y=self.y, x=self.x, z=self.z, k_regimes=self.k_regimes, cov_type=self.cov_type, 116 | cov_switch=self.cov_switch, apriori=self.apriori, mean_variance=self.mean_variance, 117 | has_delta=self.has_delta) 118 | 119 | kwargs = {} 120 | 121 | kwargs["y"] = model.y 122 | kwargs["x"] = model.x 123 | kwargs["z"] = model.z 124 | kwargs["k_regimes"] = model.k_regimes 125 | kwargs['apriori'] = model.apriori 126 | kwargs['mean_variance'] = model.mean_variance 127 | kwargs['has_delta'] = model.has_delta 128 | kwargs["cov_switch"] = model.cov_switch 129 | kwargs['cov_type'] = model.cov_type 130 | 131 | 132 | 133 | 134 | 135 | _ = np.log(s).diff(-2) 136 | 137 | _ = _ 138 | 139 | _ = s[:-10] 140 | 141 | y = data.iloc[:,2:3].astype(float) 142 | 143 | 144 | def generate_lagged_regressors(y, p): 145 | if not y.ndim == 2: 146 | y = format_data(y) 147 | 148 | _z = pd.DataFrame(np.hstack([y[i:-p + i] for i in np.arange(0, p, 1)])) 149 | y = pd.DataFrame(y) 150 | _z.columns = ["%s_%s" % (_c, p - i + 1) for i in np.arange(1, p + 1, 1) for _c in y.columns] 151 | 152 | if p > 0: 153 | warnings.warn("p>0 some Financial is dropout") 154 | 155 | return _z 156 | 157 | 158 | """ 159 | 160 | 161 | # --------------------------------------------------------------------- 162 | 163 | """ 164 | We plot the filtered and smoothed probabilities of a recession. 165 | Filtered refers to an estimate of the probability at time 𝑡 166 | based on data up to and including time 𝑡 (but excluding time 𝑡+1,...,𝑇). 167 | Smoothed refers to an estimate of the probability at time 𝑡 using all the data in the sample. 168 | """ 169 | 170 | 171 | """ 172 | 173 | # covmat_title = "Error covariance matrix" 174 | # 175 | # var = np.hsplit(var_mat, k_regimes) 176 | # 177 | # 178 | # 179 | # # error_covariance_mat = parameter_results.iloc[indices[2]:indices[3]] 180 | # # 181 | # # error_covariance_stubs = ["%s.%s"%(n,m) for i,n in enumerate(y_param_name) for j,m in enumerate(y_param_name) if j>=i] 182 | # # 183 | # # covariance_table = SimpleTable(data=error_covariance_mat.values, 184 | # # headers=["coef1", "std err", "t", "p>|t|"], stubs=error_covariance_stubs, title=covmat_title, 185 | # # txt_fmt=_fmt_params) 186 | # # summary.tables.append(covariance_table) 187 | 188 | """ 189 | import statsmodels.api as sm 190 | import pandas as pd 191 | import numpy as np 192 | data = pd.read_pickle("Multivariate_Markov_Switching_Model/test_data.pkl") 193 | model = sm.tsa.VAR(data[['M2','股市']]).fit(maxlags=3) 194 | 195 | from statsmodels.tsa.vector_ar.irf import * 196 | self = model 197 | 198 | model.irf() 199 | """ 200 | 201 | array([[[-0.22525379, 0.00593674], 202 | [-0.56635031, 0.04485926]], 203 | [[ 0.32894306, -0.00395223], 204 | [-0.44499289, 0.1234111 ]], 205 | [[ 0.30478203, 0.00154435], 206 | [ 0.59459188, 0.00716239]]]) 207 | 208 | """ 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | -------------------------------------------------------------------------------- /summaries.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | from statsmodels.tools.numdiff import approx_hess,approx_fprime 3 | from statsmodels.iolib.summary import * 4 | import numpy as np 5 | from statsmodels.iolib.table import SimpleTable 6 | from statsmodels.iolib.tableformatting import (gen_fmt, fmt_2, 7 | fmt_params, fmt_base, fmt_2cols) 8 | 9 | 10 | class MSVARResults: 11 | def __init__(self,model): 12 | self.model = model 13 | 14 | def summary(self): 15 | 16 | results = self.model.results 17 | parameters= self.model.parameters 18 | 19 | unconstrained = results['unconstrained'] 20 | constrained = results['constrained'] 21 | 22 | k_regimes = parameters.get("k_regimes") 23 | indices = parameters.get("indices") 24 | 25 | print("calculating gradian and hessian matrix..pls be patient") 26 | 27 | gradian = approx_fprime(unconstrained.squeeze(),self.model.transform_params) 28 | 29 | hess = approx_hess(unconstrained.squeeze(),self.model.llf) 30 | 31 | if np.linalg.det(hess)==0: 32 | inv_hess = np.linalg.pinv(hess) 33 | else: 34 | inv_hess = np.linalg.inv(hess) 35 | 36 | cov_beta = gradian.dot(inv_hess).dot(gradian.T) 37 | std_err = np.sqrt(np.diag(cov_beta)) 38 | # cor_beta = cov_beta/std_err/std_err.T 39 | t_student = constrained.squeeze()/std_err 40 | 41 | ddf = parameters.get("nobs") - constrained.shape[0] 42 | import scipy.stats as stats 43 | 44 | p_value = 2*(1-stats.t.cdf(np.abs(t_student),ddf)) 45 | 46 | parameter_results = pd.DataFrame(np.vstack([constrained.squeeze(), 47 | std_err,t_student,p_value])).T.round(4) 48 | 49 | 50 | 51 | splited_results = np.vsplit(parameter_results,indices) 52 | 53 | beta_sections = np.vsplit(splited_results[2],k_regimes) 54 | 55 | y_param_name = ["y%s"%i for i in np.arange(parameters.get("neqs_y"))] 56 | 57 | beta_sections_names = ["beta%s"%i for i in np.arange(parameters.get("neqs_x"))] 58 | 59 | d_ns = [] 60 | # delta_sections = np.vsplit(splited_results[4], k_regimes) 61 | 62 | delta_sections = splited_results[4] 63 | 64 | if len(splited_results[4])>0: 65 | 66 | delta_sections_names = ["delta%s"%i for i in np.arange(parameters.get("neqs_z"))] 67 | 68 | d_ns = ["%s.%s"%(y_n,b_n) for y_n in y_param_name for b_n in delta_sections_names] 69 | 70 | b_ns = ["%s.%s"%(y_n,b_n) for b_n in beta_sections_names for y_n in y_param_name] 71 | 72 | parameters["y_param_names"] = y_param_name 73 | 74 | import time 75 | time_now = time.localtime() 76 | time_of_day = [time.strftime("%H:%M:%S", time_now)] 77 | date = time.strftime("%a, %d %b %Y", time_now) 78 | 79 | # sample=["1","2"] 80 | 81 | gen_left = [ 82 | ('Dep. Variable:', [y_param_name]), 83 | ('Date:', [date]), 84 | ('Time:', [time_of_day]), 85 | # ('Sample:', [sample[0]]), 86 | # ('', [sample[1]]), 87 | ] 88 | 89 | gen_right = [ 90 | ('No. Observations:', [parameters.get("nobs")]), 91 | ('Covariance Type', [parameters.get("covariance_type")]), 92 | ('Regimes',[parameters.get("k_regimes")]), 93 | ('Log Likelihood', ["%#5.3f" % results.get("likelihoods")]), 94 | 95 | ] 96 | 97 | gen_title = "Markov Switching Multivariate Model Results" 98 | 99 | 100 | if len(gen_right) < len(gen_left): 101 | # fill up with blank lines to same length 102 | gen_right += [(' ', ' ')] * (len(gen_left) - len(gen_right)) 103 | elif len(gen_right) > len(gen_left): 104 | # fill up with blank lines to same length, just to keep it symmetric 105 | gen_left += [(' ', ' ')] * (len(gen_right) - len(gen_left)) 106 | 107 | gen_right = [('%-21s' % (' ' + k), v) for k, v in gen_right] 108 | 109 | # gen_right = gen_left 110 | 111 | stubs = [] 112 | vals = [] 113 | for stub, val in gen_right: 114 | stubs.append(stub) 115 | vals.append(val) 116 | table_right = SimpleTable(vals, txt_fmt=fmt_2cols, stubs=stubs) 117 | 118 | stubs = [] 119 | vals = [] 120 | for stub, val in gen_left: 121 | stubs.append(stub) 122 | vals.append(val) 123 | table_left = SimpleTable(vals, txt_fmt=fmt_2cols,title=gen_title, stubs=stubs) 124 | 125 | table_left.extend_right(table_right) 126 | 127 | summary = Summary() 128 | 129 | summary.tables.append(table_left) 130 | 131 | fmt2 = dict( 132 | data_fmts=["%s", "%s", "%s", "%s", "%s", "%s"], 133 | colwidths=15, 134 | ) 135 | from copy import deepcopy 136 | _fmt_params = deepcopy(fmt_params) 137 | _fmt_params.update(fmt2) 138 | 139 | for i in np.arange(k_regimes): 140 | title = "Regime %s Switching Parameters"%i 141 | 142 | tbl = SimpleTable(data=beta_sections[i].values, 143 | headers=["coef","std err","t","p>|t|"],stubs=b_ns,title=title,txt_fmt=_fmt_params) 144 | 145 | summary.tables.append(tbl) 146 | 147 | if self.model.has_delta: 148 | delta_tbl = SimpleTable(data=delta_sections.values, 149 | headers=["coef","std err","t","p>|t|"],stubs=d_ns,title="Non Switching Parameters",txt_fmt=_fmt_params) 150 | 151 | summary.tables.append(delta_tbl) 152 | 153 | # p_j, p_ij, b, d, var_mat, inv_var_mat,det_inv_var_mat =\ 154 | # Markov_Multivarite_Regression.convert_param(self.model,constrained) 155 | p_j, p_ij, b, d, var_mat, inv_var_mat,det_inv_var_mat \ 156 | = self.model.convert_param(constrained) 157 | # trans_df = pd.DataFrame(p_ij,index=np.arange(k_regimes),columns=np.arange(k_regimes)) 158 | 159 | regime_parameter = parameter_results.iloc[0:indices[1]] 160 | 161 | # trans_information = pd.Series({"%s-%s"%(i,j): "%.4f"%c for i,r in enumerate(p_ij)for j,c in enumerate(r)}) 162 | trans_stubs = ["p[%s-%s]"%(i,j) for i,r in enumerate(p_ij)for j,c in enumerate(r)][:indices[1]] 163 | 164 | regime_title = "Regime transition parameters" 165 | 166 | regime_tables = SimpleTable(data=regime_parameter.values, 167 | headers=["coef1", "std err", "t", "p>|t|"], stubs=trans_stubs, title=regime_title, 168 | txt_fmt=_fmt_params) 169 | 170 | summary.tables.append(regime_tables) 171 | 172 | parameter_results.columns = ["Estimates","Standard-errors","T","P-values"] 173 | 174 | return summary,parameter_results,p_ij,var_mat 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | -------------------------------------------------------------------------------- /core.py: -------------------------------------------------------------------------------- 1 | from Multivariate_Markov_Switching_Model.tools import * 2 | from Multivariate_Markov_Switching_Model.tools import _2dim 3 | import statsmodels.api as sm 4 | from Multivariate_Markov_Switching_Model.summaries import * 5 | 6 | 7 | class Markov_Multivarite_Regression(object): 8 | def __init__(self,y,x,z,k_regimes,variance_regimes,covariance_type,apriori,**kwargs): 9 | self.original_y = y 10 | self.original_x = x 11 | self.original_z = z 12 | 13 | self.mean_variance = False 14 | 15 | if z is None and (len(np.unique(x)) == 1 and x.flatten()[0] == 1): 16 | self.mean_variance = True 17 | 18 | self.covariance_type = covariance_type 19 | self.variance_regimes = variance_regimes 20 | self.apriori = apriori 21 | self.k_regimes = k_regimes 22 | self.has_delta = True 23 | 24 | self.x,self.y,self.z = Data(self.original_y,self.original_x,self.original_z,self.mean_variance)() 25 | 26 | if len(np.unique(self.z)) == 1 and self.z.flatten()[0] == 0: 27 | self.has_delta = False 28 | 29 | self.nobs,self.neqs_y = self.y.shape 30 | self.neqs_x = self.x.shape[1] 31 | self.neqs_z = self.z.shape[1] 32 | self.indices,self.cov_obs = slicing_parameter(self.k_regimes,self.neqs_y,self.neqs_z, 33 | self.neqs_x,self.covariance_type,self.variance_regimes) 34 | self.start_params = None 35 | if not isinstance(self.apriori,(pd.Series,np.ndarray)): 36 | self.apriori = clustering(self.y,self.k_regimes) 37 | 38 | self.kwargs = kwargs 39 | self.results = {'status': -1} 40 | self.parameters = {"nobs":self.nobs,"neqs_y":self.neqs_y,"neqs_x":self.neqs_x, 41 | "neqs_z":self.neqs_z,"k_regimes":self.k_regimes, 42 | "mean_variance":self.mean_variance,"covariance_type":covariance_type,"variance_regimes":variance_regimes, 43 | "indices":self.indices} 44 | self.current_params = None 45 | 46 | 47 | def fit(self): 48 | param = start_params(y=self.y,x=self.x,z=self.z,k_regimes=self.k_regimes,covariance_type=self.covariance_type, 49 | variance_regimes=self.variance_regimes,apriori=self.apriori,mean_variance=self.mean_variance,has_delta=self.has_delta) 50 | 51 | self.start_params = param 52 | import scipy.optimize as opt 53 | 54 | init_param = param.squeeze() 55 | 56 | maxiters = self.kwargs.setdefault("maxiters",1e+3) 57 | epsilon=self.kwargs.setdefault("eps",np.sqrt(np.finfo(float).eps)) 58 | # epsilon = self.kwargs.setdefault('epsilon', np.sqrt(np.finfo(float).eps)) 59 | 60 | gtol = self.kwargs.setdefault("gtol",1.0000000000000001e-05) 61 | norm = self.kwargs.setdefault('norm', np.Inf) 62 | 63 | proper_input = isinstance(maxiters,float) == isinstance(epsilon,float) == isinstance(gtol,float) 64 | if not proper_input: 65 | raise Exception("pls enter the correct input") 66 | 67 | options = {"maxiter":maxiters,"eps":epsilon,"gtol":gtol,"norm":norm} 68 | # options = {"maxiter":maxiters,"gtol":gtol} 69 | 70 | # gtol = self.kwargs.setdefault('gtol', 1.0000000000000001e-05) 71 | # norm = self.kwargs.setdefault('norm', np.Inf) 72 | # epsilon = self.kwargs.setdefault('epsilon', 1.4901161193847656e-08) 73 | 74 | rounds = 0 75 | 76 | while True: 77 | rounds += 1 78 | # print(rounds) 79 | # ,callback=progress_bar(maxiters) 80 | res = opt.minimize(self.llf,init_param,method="BFGS",options=options) 81 | self.results["unconstrained"] = res.x[:,None] 82 | self.results['likelihoods'] = res.fun 83 | 84 | if res.status == 0: 85 | final_parameters = res.x 86 | 87 | if final_parameters.ndim <2: 88 | final_parameters = final_parameters[:,None] 89 | parameter = self.transform_params(final_parameters) 90 | self.results['constrained'] = parameter 91 | self.results['jac'] = res.jac 92 | self.results['status'] = 0 93 | return parameter 94 | 95 | elif res.status == 2: 96 | init_param = res.x 97 | options['eps'] *= (options['gtol']) 98 | else: 99 | print(res) 100 | raise Exception("something wrong pls check ") 101 | 102 | if rounds>=10: 103 | print("out of space") 104 | return res 105 | 106 | def llf(self,param): 107 | 108 | param = _2dim(param) 109 | 110 | parameter = self.transform_params(param) 111 | 112 | results = self._filter(parameter) 113 | return results 114 | 115 | def convert_param(self,param): 116 | """transforms a vector of parameters in transition probability and ergodic matrices 117 | beta coefficient and var-cov matrices 118 | """ 119 | 120 | cut_off = self.indices 121 | from Multivariate_Markov_Switching_Model.tools import _p_transition,_cov_mat,_p_ergodic 122 | 123 | p_trans = _p_transition(param[cut_off[0]:cut_off[1]], self.k_regimes) 124 | p_ergodic = _p_ergodic(p_trans, self.k_regimes) 125 | 126 | b = param[cut_off[1]:cut_off[2]].reshape(self.neqs_x, self.neqs_y * self.k_regimes) 127 | sig_mat, inv_sig_mat, det_inv_sig_mat \ 128 | = _cov_mat(param[cut_off[2]:cut_off[3]].reshape(self.cov_obs, self.variance_regimes), self.neqs_y, self.covariance_type, self.variance_regimes) 129 | 130 | d = np.kron(np.ones((1, self.k_regimes)), param[cut_off[3]:cut_off[4]].reshape(self.neqs_z, self.neqs_y)) if self.has_delta else 0 131 | 132 | return p_ergodic, p_trans, b, d, sig_mat, inv_sig_mat, det_inv_sig_mat 133 | 134 | def _filter(self,parameter): 135 | """apply hamilton filter""" 136 | 137 | p_j, p_ij, b, d, var_mat, inv_var_mat,det_inv_var_mat = self.convert_param(parameter) 138 | self.current_params = parameter 139 | if np.sometrue(np.greater_equal(p_ij,1)): 140 | return np.inf 141 | 142 | nobs = self.nobs 143 | y_hat = np.zeros((nobs,self.neqs_y)) 144 | 145 | p_predicted_joint = np.zeros((nobs,self.k_regimes)) 146 | 147 | joint_likelihoods = np.zeros((nobs,1)) 148 | filtered_probabilities = np.zeros((nobs+1,self.k_regimes)) 149 | filtered_probabilities[0,...] = p_j.T 150 | 151 | mu = self.x.dot(b)+self.z.dot(d) 152 | 153 | _y = np.kron(np.ones((1,self.k_regimes)),self.y) 154 | 155 | residual = _y-mu 156 | 157 | if np.sometrue(np.less(det_inv_var_mat,0)): 158 | return np.inf 159 | 160 | # filtered joint probabilities 161 | for i in np.arange(nobs): 162 | 163 | cond_likelihoods = self._cond_densities(residual[i,:].T,inv_var_mat,det_inv_var_mat).T 164 | # P(S(t)=i,Y(t)|I(t-1)) 165 | p_predicted_joint[i,...] = p_ij.dot(filtered_probabilities[i,...]) 166 | 167 | tmp = cond_likelihoods*p_predicted_joint[i,...] 168 | joint_likelihoods[i] = tmp.sum() 169 | 170 | if np.isnan(joint_likelihoods[i]): 171 | return np.inf 172 | 173 | filtered_probabilities[i+1,...] = tmp/joint_likelihoods[i] 174 | 175 | y_hat[i,:] = filtered_probabilities[i+1,...].dot(mu[i,:].reshape(self.k_regimes,self.neqs_y)) 176 | 177 | resid = self.y-y_hat 178 | likelihoods = -(np.log(joint_likelihoods).sum()) 179 | 180 | if np.isnan(likelihoods): 181 | raise Exception("Please Check the Calculation ") 182 | 183 | self.results["resid"] = resid 184 | self.results["joint_likelihoods"] = joint_likelihoods 185 | self.results['filtered_probabilities'] = filtered_probabilities 186 | self.results['p_predicted_joint'] = p_predicted_joint 187 | 188 | # ,y_hat,resid,joint_likelihoods,filtered_probabilities,p_predicted_joint 189 | return likelihoods 190 | 191 | def _cond_densities(self,res,inv_var_mat, det_inv_var_mat): 192 | """compute the conditional densities """ 193 | k_regimes = self.k_regimes 194 | neqs_y = self.neqs_y 195 | _resid = res.reshape(neqs_y,k_regimes).T 196 | 197 | if self.variance_regimes == 1: 198 | sig = np.kron(np.ones((1,k_regimes)),inv_var_mat) 199 | det_sig = np.kron(np.ones((1,k_regimes)),det_inv_var_mat).T 200 | else: 201 | sig = inv_var_mat 202 | det_sig = det_inv_var_mat[:,np.newaxis] 203 | 204 | _resid = _resid.flatten(order="F")[:,np.newaxis] 205 | aux = _resid*np.kron(np.eye(k_regimes),np.ones((neqs_y,1))) 206 | sigma = np.kron(np.eye(k_regimes),np.ones((neqs_y,neqs_y)))*(np.kron(np.ones((k_regimes,1)),sig)) 207 | 208 | w = aux.T.dot(sigma).dot(aux) 209 | v = np.diag(w)[:,np.newaxis] 210 | 211 | eta = (1/np.sqrt(2*np.pi))**neqs_y*np.sqrt(det_sig)*np.exp(-0.5*v) 212 | 213 | return eta 214 | 215 | def transform_params(self,unconstrained): 216 | """create a constrained parameter g=g(theta) to enter the likelihood function""" 217 | 218 | unconstrained = _2dim(unconstrained) 219 | 220 | k_regimes = self.k_regimes 221 | neqs_y = self.neqs_y 222 | slices = self.indices 223 | aux_p = unconstrained[:(k_regimes-1)*k_regimes].reshape((k_regimes-1),k_regimes) 224 | # FIXME over flow ignore 225 | _ = np.seterr(over='ignore') 226 | B = np.exp(aux_p) 227 | 228 | masks = np.isinf(B) 229 | 230 | sumx = B.sum(axis=0)+np.ones((1,k_regimes))[0] 231 | aux_p = B/sumx 232 | 233 | aux_p = np.where(masks,1,aux_p) 234 | 235 | from copy import deepcopy 236 | c = deepcopy(unconstrained) 237 | 238 | # FIXME 239 | prob = np.hstack([aux_p.flatten()[:,np.newaxis],0.001*np.ones(((k_regimes-1)*k_regimes,1))]) 240 | # c.extend(prob.max(axis=1)) 241 | 242 | c[:(k_regimes-1)*k_regimes] = prob.max(axis=1)[:,np.newaxis] 243 | 244 | v = c[slices[2]:slices[3],:] 245 | aux_v = v.reshape(self.cov_obs,self.variance_regimes) 246 | for i in np.arange(self.variance_regimes): 247 | if self.covariance_type == 'full': 248 | _value = aux_v[:,i] 249 | 250 | m_aux = xpnd(_value) 251 | 252 | diag_mat = np.abs(np.diag(m_aux))*(np.eye(neqs_y)) 253 | 254 | rho_mat = m_aux-diag_mat 255 | rho_mat = rho_constraints(rho_mat)+np.eye(neqs_y) 256 | 257 | m_aux = diag_mat.dot(rho_mat).dot(diag_mat) 258 | aux_v[:,i] = vech(m_aux) 259 | else: 260 | aux_v[:,i] = aux_v[:,i]**2 261 | c[slices[2]:slices[3]] = vecr(aux_v)[:,np.newaxis] 262 | return c 263 | 264 | def summary(self): 265 | s = MSVARResults(self) 266 | return s.summary() 267 | 268 | def smooth_probabilities(self): 269 | results = self.results 270 | p_filtered_joint = results['filtered_probabilities'][1:] 271 | p_predicted_joint = results['p_predicted_joint'] 272 | parameter = results['constrained'] 273 | p_j, p_ij, b, d, var_mat, inv_var_mat,det_inv_var_mat = self.convert_param(parameter) 274 | 275 | _ = convert_smooth(p_filtered_joint, p_predicted_joint, p_ij) 276 | 277 | return _ 278 | 279 | 280 | i=0 281 | import time 282 | import sys 283 | 284 | 285 | class progress_bar(object): 286 | def __init__(self,iter): 287 | # self.max_sec = max_sec 288 | self.start = time.time() 289 | self.iter = iter 290 | 291 | def __call__(self, xk=None): 292 | global i 293 | i+=1 294 | 295 | elapsed = time.time()-self.start 296 | rate = i/self.iter 297 | percentage = rate*100 298 | 299 | l_bar = '{0:3.0f}%|'.format(percentage) 300 | 301 | bar_length,frac_bar = divmod(int(percentage), 10) 302 | bar = chr(0x2588) * bar_length 303 | frac_bar = chr(0x2590-frac_bar) 304 | 305 | remaining_time = elapsed/rate - elapsed 306 | 307 | speed = elapsed/i 308 | 309 | full_bar = bar + frac_bar +' ' * max(10 - bar_length, 0) 310 | r_bar = '| {0}/{1} [{2}<{3}, {4}s/iter]'.format( 311 | i, self.iter, np.round(elapsed,4),np.round(remaining_time,4),np.round(speed,4)) 312 | 313 | bar = l_bar+full_bar+r_bar 314 | 315 | sys.stdout.write(bar) 316 | sys.stdout.write('\n') 317 | 318 | 319 | 320 | # def filter_probabilities(parameter): 321 | # llf, y_hat, resid,joint_likelihoods, filtered_probabilities, p_predicted_joint = filter(parameter,K,M,covariance_type,variance_regimes,n_x,n_z) 322 | # ptrans_res = convert_param(param,K,M,n_x,n_z,covariance_type,variance_regimes) 323 | # param, K, M, n_x, n_z, covariance_type, variance_regimes 324 | # PR_SMO = MSVAR_smooth(filtered_probabilities, p_predicted_joint,ptrans_res) 325 | # 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | -------------------------------------------------------------------------------- /MAVAR.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import pandas as pd\n", 10 | "import numpy as np\n", 11 | "# from.tools import *\n", 12 | "from Multivariate_Markov_Switching_Model.tools import *\n", 13 | "from Multivariate_Markov_Switching_Model.MSVAR import *\n", 14 | "from Multivariate_Markov_Switching_Model.tools import _2dim\n", 15 | "import numpy as np\n", 16 | "import os\n", 17 | "# os.chdir(\"MSVAR\")\n", 18 | "import pandas as pd\n", 19 | "import numpy as np\n", 20 | "from statsmodels.tsa.seasonal import seasonal_decompose\n", 21 | "from scipy.interpolate import interp1d\n", 22 | "from Multivariate_Markov_Switching_Model.MSVAR import *\n", 23 | "%matplotlib inline" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": null, 29 | "metadata": {}, 30 | "outputs": [], 31 | "source": [ 32 | "import matplotlib.pyplot as plt\n", 33 | "plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签\n", 34 | "plt.rcParams['axes.unicode_minus']=False #用来正常显示负号\n" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": null, 40 | "metadata": {}, 41 | "outputs": [], 42 | "source": [ 43 | "\n", 44 | "\n", 45 | "def fill(series):\n", 46 | " # print(series.name)\n", 47 | " if any(series.isna()):\n", 48 | "\n", 49 | " nan_loc = pd.Index(series.values).get_loc(np.nan)\n", 50 | " if isinstance(nan_loc, np.ndarray):\n", 51 | " all_loc = np.arange(len(series))\n", 52 | "\n", 53 | " x = np.setdiff1d(all_loc, nan_loc)\n", 54 | " y = series.dropna().values\n", 55 | "\n", 56 | " f = interp1d(x, y, 'slinear')\n", 57 | " new_x = nan_loc[(nan_loc >= x[0]) & (nan_loc <= x[-1])]\n", 58 | " new_y = f(new_x)\n", 59 | "\n", 60 | " interpolate = pd.Series(new_y, index=new_x)\n", 61 | " ori = pd.Series(y, index=x)\n", 62 | "\n", 63 | " _ = pd.concat([interpolate, ori]).reindex(all_loc)\n", 64 | " _.index = series.index\n", 65 | " return _\n", 66 | " else:\n", 67 | " return series\n", 68 | " else:\n", 69 | " return series\n", 70 | "\n", 71 | "\n", 72 | "\n", 73 | "price = pd.read_pickle(\"Data/Financial/Index/daily/000001_daily_price.pkl\")['close']\n", 74 | "\n", 75 | "p = price.resample(\"M\").last()\n", 76 | "\n", 77 | "\n", 78 | "industry = pd.read_excel(\"Data/Financial/Macro/工业增加值-月.xls\",index_col=0,header=2,nrows=2).T\n", 79 | "\n", 80 | "industry.index = pd.DatetimeIndex(industry.index.str[:4]+\"-\"+industry.index.str[5:-1].str.zfill(2)+\"-01\")\n", 81 | "\n", 82 | "industry = industry.resample(\"M\").last()\n", 83 | "\n", 84 | "industry_increase = industry['工业增加值同比增长(%)']\n", 85 | "industry_increase = fill(industry_increase).dropna()\n", 86 | "\n", 87 | "\n", 88 | "# industry_increase.reindex(smooth_probabilities.index).plot()" 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": null, 94 | "metadata": {}, 95 | "outputs": [], 96 | "source": [] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": null, 101 | "metadata": {}, 102 | "outputs": [], 103 | "source": [ 104 | "data = pd.read_pickle(\"Multivariate_Markov_Switching_Model/test_data.pkl\")\n", 105 | "data = data[['M2',\"股市\",'实体经济']]\n", 106 | "model = pd.read_pickle(\"Multivariate_Markov_Switching_Model/m2-股市-L3-K3.pkl\").loc[0]\n", 107 | "smooth_probabilities = pd.DataFrame(model.smooth_probabilities(),index=data.index[-model.x.shape[0]:])\n", 108 | "filtered_probabilities = pd.DataFrame(model.results['filtered_probabilities'][1:],index = data.index[-model.x.shape[0]:])\n", 109 | "p_predicted_joint = pd.DataFrame(model.results['p_predicted_joint'],index=data.index[-model.x.shape[0]:])\n", 110 | "price = pd.read_pickle(\"Data/Financial/Index/daily/000001_daily_price.pkl\")['close']\n", 111 | "\n", 112 | "# p = price.resample(\"M\").last().reindex(smooth_probabilities.index)\n", 113 | "p = (industry_increase).reindex(smooth_probabilities.index)\n", 114 | "\n", 115 | "import matplotlib.pyplot as plt\n", 116 | "import seaborn as sns\n", 117 | "fig,ax = plt.subplots(smooth_probabilities.shape[1],1,sharex=True,figsize=(10,6))\n", 118 | "for i in smooth_probabilities:\n", 119 | " smooth_probabilities[i].plot(ax=ax[i],color='#984B4B')\n", 120 | " filtered_probabilities[i].plot(ax=ax[i],color=\"#4F9D9D\",ls='-.')\n", 121 | " p_predicted_joint[i].plot(ax=ax[i],color='#FF8F59',ls='--')\n", 122 | "# ax[i].set(title=\"Regime %s\"%i)\n", 123 | " ax[0].legend(['Smoothed','Filtered','Predicted'],loc='upper right') \n", 124 | " ax[i] = ax[i].twinx()\n", 125 | " p.plot(ax=ax[i],color='k',alpha=0.3)\n", 126 | " ax[0].legend(['工业同比增加'],loc='lower left') \n", 127 | "ax[0].set_title(\"紧缩\")\n", 128 | "ax[1].set_title(\"平稳\")\n", 129 | "ax[2].set_title(\"通胀\")\n", 130 | "\n", 131 | "fig.tight_layout()\n" 132 | ] 133 | }, 134 | { 135 | "cell_type": "code", 136 | "execution_count": null, 137 | "metadata": {}, 138 | "outputs": [], 139 | "source": [ 140 | "np.corrcoef(filtered_probabilities[2],p)" 141 | ] 142 | }, 143 | { 144 | "cell_type": "code", 145 | "execution_count": null, 146 | "metadata": {}, 147 | "outputs": [], 148 | "source": [ 149 | "p_j, p_ij, b, d, var_mat, inv_var_mat,det_inv_var_mat = model.convert_param(model.results['constrained'])" 150 | ] 151 | }, 152 | { 153 | "cell_type": "code", 154 | "execution_count": null, 155 | "metadata": {}, 156 | "outputs": [], 157 | "source": [ 158 | "p_ij" 159 | ] 160 | }, 161 | { 162 | "cell_type": "code", 163 | "execution_count": null, 164 | "metadata": {}, 165 | "outputs": [], 166 | "source": [ 167 | "_ = model.summary()" 168 | ] 169 | }, 170 | { 171 | "cell_type": "code", 172 | "execution_count": null, 173 | "metadata": {}, 174 | "outputs": [], 175 | "source": [ 176 | "pd.Series(_).to_pickle(\"Multivariate_Markov_Switching_Model//model1_summary.pkl\")" 177 | ] 178 | }, 179 | { 180 | "cell_type": "code", 181 | "execution_count": null, 182 | "metadata": {}, 183 | "outputs": [], 184 | "source": [] 185 | }, 186 | { 187 | "cell_type": "code", 188 | "execution_count": 1, 189 | "metadata": {}, 190 | "outputs": [], 191 | "source": [ 192 | "import warnings \n", 193 | "warnings.filterwarnings('ignore') \n", 194 | "from Multivariate_Markov_Switching_Model.MSVAR import *\n", 195 | "%matplotlib inline\n", 196 | "from Multivariate_Markov_Switching_Model.tools import _2dim\n", 197 | "\n", 198 | "\n", 199 | "data = []\n", 200 | "\n", 201 | "with open(\"Multivariate_Markov_Switching_Model/test_data/MSVARUN.txt\") as f:\n", 202 | " for _ in f.readlines():\n", 203 | " data.append(_.strip().split(\"\\t\"))\n", 204 | "data = pd.DataFrame(data)\n", 205 | "\n", 206 | "s = data.set_index([1,0]).replace(\".\",np.nan)[2].astype(float).rename_axis(['year','month'])\n", 207 | "\n", 208 | "apr = data.set_index([1,0]).replace(\".\",np.nan)[3].astype(float).rename_axis(['year','month'])\n", 209 | "\n", 210 | "apriori = apr[apr.index.get_loc((\"1967\",\"7\")):apr.index.get_loc((\"2004\",\"3\"))].values\n", 211 | "\n", 212 | "k_lag = 2\n", 213 | "\n", 214 | "_ = np.log(s).diff(k_lag)*100\n", 215 | "\n", 216 | "s = _[_.index.get_loc((\"1967\",\"2\"))+k_lag:_.index.get_loc((\"2004\",\"2\"))+1]\n", 217 | "\n", 218 | "s = ((s-s.mean())/s.std()).values[:,np.newaxis]\n", 219 | "y = s\n", 220 | "\n", 221 | "z = generate_lagged_regressors(s,3).values\n", 222 | "x = [1]*z.shape[0]\n", 223 | "x = _2dim(np.array(x))\n", 224 | "\n", 225 | "model = Markov_Multivarite_Regression(y[-z.shape[0]:],x,z,2,2,\"full\",apriori=None)\n", 226 | "# model = Multivariate_Markov_Switching_Model(y[-z.shape[0]:],x,None,2,2,\"full\",apriori=None)\n", 227 | "\n", 228 | "res = model.fit()\n", 229 | "\n" 230 | ] 231 | }, 232 | { 233 | "cell_type": "code", 234 | "execution_count": 2, 235 | "metadata": {}, 236 | "outputs": [ 237 | { 238 | "data": { 239 | "text/plain": [ 240 | "array([[ 0.85089924],\n", 241 | " [ 0.97339873],\n", 242 | " [-0.80059507],\n", 243 | " [ 0.14887296],\n", 244 | " [ 0.70574205],\n", 245 | " [ 0.34950403],\n", 246 | " [ 0.6414498 ],\n", 247 | " [-0.45878331],\n", 248 | " [ 0.34911898]])" 249 | ] 250 | }, 251 | "execution_count": 2, 252 | "metadata": {}, 253 | "output_type": "execute_result" 254 | } 255 | ], 256 | "source": [ 257 | "res" 258 | ] 259 | }, 260 | { 261 | "cell_type": "code", 262 | "execution_count": 3, 263 | "metadata": {}, 264 | "outputs": [ 265 | { 266 | "name": "stdout", 267 | "output_type": "stream", 268 | "text": [ 269 | "calculating gradian and hessian matrix..pls be patient\n" 270 | ] 271 | } 272 | ], 273 | "source": [ 274 | "summary = model.summary()" 275 | ] 276 | }, 277 | { 278 | "cell_type": "code", 279 | "execution_count": 4, 280 | "metadata": {}, 281 | "outputs": [ 282 | { 283 | "data": { 284 | "text/html": [ 285 | "\n", 286 | "\n", 287 | "\n", 288 | " \n", 289 | "\n", 290 | "\n", 291 | " \n", 292 | "\n", 293 | "\n", 294 | " \n", 295 | "\n", 296 | "\n", 297 | " \n", 298 | "\n", 299 | "
Markov Switching Multivariate Model Results
Dep. Variable: ['y0'] No. Observations: 440
Date: Fri, 17 Apr 2020 Covariance Type full
Time: ['21:34:54'] Regimes 2
Log Likelihood 449.278
\n", 300 | "\n", 301 | "\n", 302 | "\n", 303 | " \n", 304 | "\n", 305 | "\n", 306 | " \n", 307 | "\n", 308 | "
Regime 0 Switching Parameters
coef std err t p>|t|
y0.beta0 -0.8006 0.2243 -3.5699 0.0004
\n", 309 | "\n", 310 | "\n", 311 | "\n", 312 | " \n", 313 | "\n", 314 | "\n", 315 | " \n", 316 | "\n", 317 | "
Regime 1 Switching Parameters
coef std err t p>|t|
y0.beta0 0.1489 0.0519 2.8709 0.0043
\n", 318 | "\n", 319 | "\n", 320 | "\n", 321 | " \n", 322 | "\n", 323 | "\n", 324 | " \n", 325 | "\n", 326 | "\n", 327 | " \n", 328 | "\n", 329 | "\n", 330 | " \n", 331 | "\n", 332 | "
Non Switching Parameters
coef std err t p>|t|
y0.delta0 0.6414 0.0578 11.1001 0.0
y0.delta1 -0.4588 0.0512 -8.9583 0.0
y0.delta2 0.3491 0.051 6.8521 0.0
\n", 333 | "\n", 334 | "\n", 335 | "\n", 336 | " \n", 337 | "\n", 338 | "\n", 339 | " \n", 340 | "\n", 341 | "\n", 342 | " \n", 343 | "\n", 344 | "
Regime transition parameters
coef1 std err t p>|t|
p[0-0] 0.8509 0.0797 10.6763 0.0
p[0-1] 0.9734 0.0129 75.6457 0.0
" 345 | ], 346 | "text/plain": [ 347 | "\n", 348 | "\"\"\"\n", 349 | " Markov Switching Multivariate Model Results \n", 350 | "==============================================================================\n", 351 | "Dep. Variable: ['y0'] No. Observations: 440\n", 352 | "Date: Fri, 17 Apr 2020 Covariance Type full\n", 353 | "Time: ['21:34:54'] Regimes 2\n", 354 | " Log Likelihood 449.278\n", 355 | " Regime 0 Switching Parameters \n", 356 | "===============================================================================\n", 357 | " coef std err t p>|t|\n", 358 | "-------------------------------------------------------------------------------\n", 359 | "y0.beta0 -0.8006 0.2243 -3.5699 0.0004\n", 360 | " Regime 1 Switching Parameters \n", 361 | "===============================================================================\n", 362 | " coef std err t p>|t|\n", 363 | "-------------------------------------------------------------------------------\n", 364 | "y0.beta0 0.1489 0.0519 2.8709 0.0043\n", 365 | " Non Switching Parameters \n", 366 | "===============================================================================\n", 367 | " coef std err t p>|t|\n", 368 | "-------------------------------------------------------------------------------\n", 369 | "y0.delta0 0.6414 0.0578 11.1001 0.0\n", 370 | "y0.delta1 -0.4588 0.0512 -8.9583 0.0\n", 371 | "y0.delta2 0.3491 0.051 6.8521 0.0\n", 372 | " Regime transition parameters \n", 373 | "===============================================================================\n", 374 | " coef1 std err t p>|t|\n", 375 | "-------------------------------------------------------------------------------\n", 376 | "p[0-0] 0.8509 0.0797 10.6763 0.0\n", 377 | "p[0-1] 0.9734 0.0129 75.6457 0.0\n", 378 | "===============================================================================\n", 379 | "\"\"\"" 380 | ] 381 | }, 382 | "execution_count": 4, 383 | "metadata": {}, 384 | "output_type": "execute_result" 385 | } 386 | ], 387 | "source": [ 388 | "summary[0]" 389 | ] 390 | }, 391 | { 392 | "cell_type": "code", 393 | "execution_count": 5, 394 | "metadata": {}, 395 | "outputs": [ 396 | { 397 | "data": { 398 | "text/html": [ 399 | "
\n", 400 | "\n", 413 | "\n", 414 | " \n", 415 | " \n", 416 | " \n", 417 | " \n", 418 | " \n", 419 | " \n", 420 | " \n", 421 | " \n", 422 | " \n", 423 | " \n", 424 | " \n", 425 | " \n", 426 | " \n", 427 | " \n", 428 | " \n", 429 | " \n", 430 | " \n", 431 | " \n", 432 | " \n", 433 | " \n", 434 | " \n", 435 | " \n", 436 | " \n", 437 | " \n", 438 | " \n", 439 | " \n", 440 | " \n", 441 | " \n", 442 | " \n", 443 | " \n", 444 | " \n", 445 | " \n", 446 | " \n", 447 | " \n", 448 | " \n", 449 | " \n", 450 | " \n", 451 | " \n", 452 | " \n", 453 | " \n", 454 | " \n", 455 | " \n", 456 | " \n", 457 | " \n", 458 | " \n", 459 | " \n", 460 | " \n", 461 | " \n", 462 | " \n", 463 | " \n", 464 | " \n", 465 | " \n", 466 | " \n", 467 | " \n", 468 | " \n", 469 | " \n", 470 | " \n", 471 | " \n", 472 | " \n", 473 | " \n", 474 | " \n", 475 | " \n", 476 | " \n", 477 | " \n", 478 | " \n", 479 | " \n", 480 | " \n", 481 | " \n", 482 | " \n", 483 | " \n", 484 | " \n", 485 | " \n", 486 | " \n", 487 | " \n", 488 | "
EstimatesStandard-errorsTP-values
00.85090.079710.67630.0000
10.97340.012975.64570.0000
2-0.80060.2243-3.56990.0004
30.14890.05192.87090.0043
40.70570.20043.52160.0005
50.34950.031411.11780.0000
60.64140.057811.10010.0000
7-0.45880.0512-8.95830.0000
80.34910.05106.85210.0000
\n", 489 | "
" 490 | ], 491 | "text/plain": [ 492 | " Estimates Standard-errors T P-values\n", 493 | "0 0.8509 0.0797 10.6763 0.0000\n", 494 | "1 0.9734 0.0129 75.6457 0.0000\n", 495 | "2 -0.8006 0.2243 -3.5699 0.0004\n", 496 | "3 0.1489 0.0519 2.8709 0.0043\n", 497 | "4 0.7057 0.2004 3.5216 0.0005\n", 498 | "5 0.3495 0.0314 11.1178 0.0000\n", 499 | "6 0.6414 0.0578 11.1001 0.0000\n", 500 | "7 -0.4588 0.0512 -8.9583 0.0000\n", 501 | "8 0.3491 0.0510 6.8521 0.0000" 502 | ] 503 | }, 504 | "execution_count": 5, 505 | "metadata": {}, 506 | "output_type": "execute_result" 507 | } 508 | ], 509 | "source": [ 510 | "summary[1]" 511 | ] 512 | }, 513 | { 514 | "cell_type": "code", 515 | "execution_count": 6, 516 | "metadata": {}, 517 | "outputs": [ 518 | { 519 | "name": "stdout", 520 | "output_type": "stream", 521 | "text": [ 522 | "==============================Transition Matrix==============================\n", 523 | " 0 1\n", 524 | "0 0.850899 0.026601\n", 525 | "1 0.149101 0.973399\n" 526 | ] 527 | } 528 | ], 529 | "source": [ 530 | "print(\"=\"*30+\"Transition Matrix\"+\"=\"*30)\n", 531 | "print(pd.DataFrame(summary[2]))" 532 | ] 533 | }, 534 | { 535 | "cell_type": "code", 536 | "execution_count": 7, 537 | "metadata": {}, 538 | "outputs": [ 539 | { 540 | "name": "stdout", 541 | "output_type": "stream", 542 | "text": [ 543 | "==============================Sigma==============================\n", 544 | "[[0.70574205 0.34950403]]\n" 545 | ] 546 | } 547 | ], 548 | "source": [ 549 | "print(\"=\"*30+\"Sigma\"+\"=\"*30)\n", 550 | "print(summary[3])" 551 | ] 552 | }, 553 | { 554 | "cell_type": "code", 555 | "execution_count": 8, 556 | "metadata": {}, 557 | "outputs": [ 558 | { 559 | "data": { 560 | "text/plain": [ 561 | "" 562 | ] 563 | }, 564 | "execution_count": 8, 565 | "metadata": {}, 566 | "output_type": "execute_result" 567 | }, 568 | { 569 | "data": { 570 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAlIAAAEGCAYAAACuKHsPAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nOy9d3xkV3n//z7TZySN6koraYu2r3fXXnt3XRYb22CwKTbdgQA2hgRDEhLIL/kSkpDY1FBMqCH5ElcgAZsvGDdcsLGNt9hbvL33Ve+aGWn6vef3x5070molTV9pNOf9epkVc9u5/XM/z3OeI6SUKBQKhUKhUCgyxzLdDVAoFAqFQqEoVpSQUigUCoVCocgSJaQUCoVCoVAoskQJKYVCoVAoFIosUUJKoVAoFAqFIkuUkFIoFAqFQqHIEiWkFIoiRQhxuRBiuxAiIIR4WQixeJracb0Q4nQe1tMihEhZjyWxPZn4LyaE2C+EeEeO275DCPFSIZZLtV+J/WjJdJpCoZgZKCGlUBQhQgg38ARwH3ARcBa4/wJs9yUhxB2F3k4ajADVwALg+8CvhBDzp7dJk3IWo63ZUJ1Y/hyEEHcLIR7MpVEKhSI/KCGlUBQnq4A64CdSyjbgy4AmhLBOb7MuHFLKISllp5Tyv4GTwPXT3KQJkVLqUsqhLJcdklLq+W6TQqHIH0pIKRTFyVkgCtwlhHBIKY9JKW+QUmoJ1+gBIUSrEOJBIcRPhBBDQoh3AQgh1gghNgkhfEKI3wkh5pkrnWyaEOLeRHjqOuCBRMjpwbENEkK8SwhxRggxIIT4zJjf1wkhtiTW+ZQQYs6YaTcLIY4LIfqAW3M4HnHAkVjngwnH5sNCiMNCiM+l2r8ENiHEz4UQw4lp9WOWe4MQYpcQIiiE2CaEWJXOcoll0wpZTsT40J4Q4qOJdd0FfCwx/XRi2gIhRFwI0TBm/heEEH+XzbYVCkV6KCGlUBQhUspe4MPAXwMnhBCfFEKIMbMsSkz7GLAXeBK4RQhRDjwH/B5YC7QDjwkhLFNNS6yrGtgM/FXi778cs71a4B+AdwD/CnxHCOESQlQCzwAvABcDOvCfAIkX/sPAd4CrgPdncyyEEG/FCG9uGvPzjcDnEm36dWK+qfYP4GrgCHAJIIAfJZYTwK+A3wCLgZeBe8Zsa8LlCsTDGMf+m8AvEn9fAiClPAu8Brw30e5q4BrgkQK2R6EoeWzT3QCFQpEdUsrfCiFewBA53wU2Ap9ITP4lsDvx970YYcAW4BYgCHxZSimFEH8D9AFXYIivCadJKV8FQkKIOBCcIFRVDnxaSnlACHEM+CHQgPEiB7hLSqkLIb4J/D4Rgnwb0CqlNIXV3cDTae5+mRBiCHBhOHN/I6U8Mmb6MmC5lHJwzG9T7TtAJ/C1RDu/BLySaKcOrAcGgTVABbBizHonXE5KqaW5L2kjpYwBQ0KIMBCd4Dw8DHwA+C/gZmCblLI13+1QKBSjKCGlUBQhQogmwCOlPA58XQjxe+BVIcQPE7OEzXmllOExZtV84JRMjFYupQwJIToxkranmvZqiiYNSin3JZaLJrYngHlADTCQ+M2CIX7mAI2cm0h9KoNDEAQuBWJAh9nmMTw0TkSRYv8AzozJRzqL8Xysk1J2J0TXJxNtbAXG5qJNuBzQncH+5ItfAd8WQtRiOFO/nIY2KBQlhRJSCkVx8kHgfcAbAaSU2xMOTareYWcxnCcg2fuvETiDIXImm2aiYwik8fgn2V4bhjP2gTG/VQEDQE9i/SaZ9LqTUsrTU0wfnuC3qfb9IqBZCCESQqsJ0IB+IcR1wGeBxQlR9Q4Mh8pkwuUy2JdsmPA8SCk7hRBbgQ8BNwCfLnA7FIqSR+VIKRTFye+BK4QQtwkhmoQQn8d4ue5MsdyTgEcIcZcQYiHwA+AwsD3FNJPjwA1CiEYhxJuFEM40tteEEXaMA+8B/ojxEfccsEwI8Qlh1MC6K+29z45U+zcf+D+J5O5/BZ6SUsYBLyCBKiHEGzByusaKmMmWKyTHgSuFEPOEEJcKIRaNmfYw8BWMsF5PgduhUJQ8SkgpFEWIlHI/cBvwz8AxjETtW6SUvhTLDQM3YSRj78MIvb070UV/0mljVvEVjFyrU8B/k8LVTrTnFuBvMBKyb0+0M5go2/AR4IsYSexb093/bEhj/7Zj5HTtxQg/msn0TwOPYYjU/4uRc9Y0pnfcZMsVkkcS2z0MPAs0j5n2awzxp8J6CsUFQJyfWqBQKBSKYkQYRUnLMHLaFk2QJ6ZQKPKMcqQUCoVi9vAPwOsYvQiViFIoLgDKkVIoFAqFQqHIEuVIKRQKhUKhUGSJElIKhUKhUCgUWTItdaTq6upkS0vLdGxaoVAoFAqFIiN27tzZJ6WcM9G0aRFSLS0t7NixYzo2rVAoFAqFQpERQogzk01ToT2FQqFQKBSKLElLSAkhGoQQr6SY5z4hxFYhxBfz0zSFQqFQKBSKmU3K0J4Qohp4CKPI22TzvA+wSik3CiHuF0Isk1Iey2M7C87etiH+8Tf7CEU1YrrO8voK7rx2MVcurp3upk07gXCMbz5zmJoyJ6+fGeR4jzGMmdNu4T8/sp5VTd5pbmHxEdN0Pv7AdtqHQnzkygX8+RsXT3eTFAqFYlp59kAXT+3tJBrXWbewijvesAiHbeYHztLJkdIwBkh9bIp5rscYsgCM8bOuwRi2IokQ4k7gToAFCxYw09h+epADHX7etnouDpuFrSf7+eRPd7DrX2/EaplojFZDYFgtAo9jdo/9/NyBbn7+6lkA5te4uWZZHXFN57e7O9jVOqiEVBa0D4bYdLwPgBeP9CghpVAoCkYsFqOtrY1wODzdTZmU4UgcSzDGexYJLMJCTPOxZ98Byl0X9v3qcrmYN28edrs97WVStlBK6QcQYmIxkaAMaE/8PQCsm2A9PwF+ArBhw4YZVwU0GjeG2/ruBy/F7bDym9fb+P8e2cPR7gAXNZ4rFA50+PjxSyf4/YFu1i+s5hd3XjUdTb5gvHqynyqPnc3/8GbcdisWiyAaN4RU/3B0uptXlPQORwCwWQT+UKHHt1UoFKVMW1sbFRUVtLS0pHqXTwvhmMax7gDLXHYW1HiwWARHugLYrYLFc8ovWDuklPT399PW1saiRYtSL5AgX57ZMOBO/F2ex/VeMEwhZdqIGxbWALDjzLmjLBzs8HPLDzfxx6O9LKz1sLt1CF2fcbowr2w92c+Vi2ooc9qwJNw5h81ChcvGwIgSUtnQ4zeE1JI55QTCsYJs47u/P8rmhOulUChKl3A4TG1t7bSKqFBUozcQRpvgfdnjjyCEoLnanXzHVLhsjES1CecvFEIIamtrM3bu8iV4dmKE8wDWAqfztN4LRlTTsFpEMow3v8ZNXbmREzSWV471okt47m+v5c+uWUQoptE2GJqOJl8QWgeCtA2GuGqCXLG6cid9CWdFkRk9AeNGXVJfhj+cf0eqNxDh+y8c4zevt6eeWaFQzHqm24nqH47Q6QtztDtATNOTv0diGkOhKHXlDuzWUUniddmQUjISubCOfTbHKWMhJYRYJYT46riffwvcJoT4d+BPgKcybsk0E43rOMacRCEEGxZWs+PMwDnzvX52kIW1Hhor3SyfWwHA0e7ABW3rhWL76QG+8fRhADYuOV9I1ZY5VGgvS3oDEWwWwYKaMvyhGPke83LLCcOJMgWbQqFQzATimqTHP/pcGk4IpeoyxznzeZw2LEIkp89k0hZSUsrrE/8elFJ+cdw0P0bC+avAm6SUvjy28YIQjevn9Q5Yv7Ca1oEQ3YmTLqXk9bNDXDa/CoBl9Ubs9sgsFVL/51d7ePZAF1e01LC8vuK86TVlDvpHlCOVDT2BCHXlTqo8duK6JBTT8rp+M6TX7VdCSqFQTC933HEHb7t+I7e/50b+8a8+TrcvSE8gzEgkzkhUw261nGNkAFiEwG4VxDVJV1cX3/jGN/LWnpdffplPfvKTeVtf3nKZpJSDUspHpJRd+VrnhSSqnS+kTBdm0zHjpdQ+FKI3EGHdwmoAKlx2mqvcs9KR6vGHOd0f5PNvW8Ejn96YjFuPpbbcqXKksqQ3EKHe66Qi0SMlkMfwnpSSzcf7Aej2K6GrUCimny/92z08/OQL1FZ5ee2Vl+jyhTk7EGQkEsfjsE4YUhMIJJK5c+fyhS98IS/tePXVV/nSl75ELJa/3NTZ3W8/AyLjQnsAqxq91JU7ePloL+9fP4/Xzw4BsG5BdXKe5Q3lHOmafUJq+2kjN+zylppJ56krdzAwEkXT5aQlIhQT0xOI0Fzlwusyutj6QzEavK68rLt1IET7UIimShcdvjDhmIbLbs3LuhUKRXHzpScOcLDDn9d1rmryctctq6ecRyb+NxgcYUlDJa5YgE/c9nGGA35uvvkWvnr3v9Dd3c2tt95KOBxmxYoVrLzsSj5y+8c5ffo0d999Nw8++CAAixcvpqmpiebmZo4cOcLXv/51li5dyqc+9SmCwSB/9Vd/xe233z5hO+bPn8+9997Ll7/85bztf9H1risU0biOc5wjZbEIrl02h1eO9aLpkucOdFHutLFi7miYa/ncCk72jpyTPDcb2H56ALfdyprmyknnqSlzoEsYCipXKlN6AxHmVDjxuhNCKo89984OBAG4emkdoMJ7CoVi+rnrC3/PmzesoaGhgbe+9S38x/fu4Z3vfj8//e1zPPu7J+jv72fLli3cdNNNPProowwNDfHBj36MibJHpZQ89NBDdHd3853vfIft27fz+c9/nrvuuotXXnmFb37zm5PmnTY3N2Ox5Ff6KEcqwUQ5UgDXrZjDb3a18+iudp7a18mnrl1yTs+CuV4XUU1nOBw/L1mumNl2aoDLFlSds6/jqS13AjAwEk3+rUhNXNPpH4kwp8KFNxHay2ctqd5hQzitaa7kVzvb6PZHWFg76cAEihLibH+Q3x/q5hNXz8x6QorCk8o5Kth2v/5ttr+2laZaL0IIjh49yqYtW3n0kf8lFAzS0dHB4sWL+fKXv8zTTz/N3XffbYT2pGT8lbpw4UKsVistLS1YrVaklBw5coS77roLIQSapjE0NER1dfWEbck3ypFKMFGOFMAbl82hzGHl73+1B6fNwp+/8dwiXbaE0Ijps8eRCsc0Dnf52bBw6ouwLiEc+1TPvYzoH4kiJQVzpHoDRl7UmmajkKxypBQm928+xVeePMjzh3qmuymKEuRPb/8E9913H5qmsWLFCu751jfZtuUVvvCFL1BTU8Njjz3G/fffz6ZNm3jLW94CAtLt0LxixQoefPBBXnrpJT7zmc/gcFw4Y0MJqQTjyx+Y1JQ5eOwz1/CB9fP4x7dfRN0458WeyA2Ka7OnKGcgHEdPvOinoqbcuFBVz73MMIVOfcVosnk+a0n1BiK47BYW1xm9SpWQUpi8etLohPCd547M+kLCipmFBKqqq3nzm9/Mr3/9a77whS9wzz33cPXVV/PMM8/Q0NDA+vXref/7388NN9zA7bffTndnx4ShvYn4xje+wSc/+UmuuuoqTp06RVnZhXPhVWgvwWShPYCl9eXcc+vaCaeZjtRsElKhqNEV351iDMHaMkNoqVpSmWHWdppT4Twn2TxfmPlXVR47DpuFnoASugojl/FId4DVTV4OdPh55Xgf1y2fM93NUpQADz74IMd7Aggh+MEPfpD8/amnzi05uX37dpYsWYLVamVgYIBhv485DY20tLQkE80BXnrppeR6Aa6//noAnn/++bTaM359uaKEVIKopmc1OKLdajhSsym0F4wZ7ojHMXVPr2qPHSGMUJUifXadHcIioKW2DJfdisNmyW9obzjCnHInQggavE7lSCkAI+9RSvj821byZw9uZ9upfiWkFBcMKTkv12k8d9999zn//0z/CJH4zH+3qtBegslCe6mwWWafIxU0HakUXeZtVgtVbjv9apiYtJFS8sSeDt6wpI6aRI6Z12XPax0p05ECaKhwKSGlAOC1UwM4bRauWlzDRY1eXj8zNN1NUlxA8j16Qubbh0z7NwjSz5HKF9kcJyWkEkwV2psKm+lIzaLyB+FkaC917aFKt70gY8XNRs72B3lmfxen+4PcsrYx+bvXZStIaA+g3utMDpCsKG0Od/m5qNGL02Zl3YIq9rQNEZ9Fzy3F5LhcLvr7+6dVTEmMApuZIIRRkPNCIaWkv78flyuzmn4qtJcgkqWQMkN78VmUuGk6UqlCewBlTtsFH1SyWPnYA9s41TeC3Sq4afXc5O8VeRSjMU1nMBhLdoqo9jgYVHW+FEA4plPuNB756xZW89DWM4mcqclrxSlmB/PmzaOtrY3e3t5pa0OXL4zDZmGkJ/3edIPBKOGYjhzMT7HidHC5XMybNy+jZZSQShDVzi/ImQ6job3Z82UXjGUmpIphUMmZwGAwyppmL3e8YRFVntGHiddlI5CnHCkz8d90pKo9DnyhGLouJxzmR1E6ROIalYlyG+boDK+fHVJCqgSw2+0sWrQo9YwF5GNfe543r6znG++/KO1l/vnRfTyzv4ed//LWArYsd1RoL0HWOVLJ0N7scaTM0F46w4qUK0cqbaJxnasW1fKB9ed+7Xjd9ryF9szSCnMSjlSVx44u8zuWn6I4GfuMm1ftpq7cwZ5WlSeluDDEdTllgeeJsFstRZE2o4RUgmxzpMwLIz6beu1FzV57qQ1Lj8OaDAUqpmaya8zrsuUttGdWNTcdKdP5UuE9xdjrTwjBRY1eDnXmd8w1hWIyYnE9aTyki90qisKkUEIqwWSVzVNhm4UFOTMJ7ZWr0F5aaLokrstJhFQBHKlkaM8I5QzlMZldUZyMF/Krmrwc6x4uii9+RfET1TKP+ihHqojQdImmSxzW1MJhPKYjVQwnO13CUQ0hSCtnTCWbp0c0UQtlIiFV5rQRiet5ybMzh+upK1eOlOJcxn8srmr0EtV0TvQOT2OrFKVCNqE9m9VCXJfTXrohFUpIMfVLLhW2Wdprz223pjWoaZnTRjCqqeEmUmBeY07b+WLddP5MJzAX/OEYDpslmd9WZTpSSkiVPJFxeaCrGo2xGFV4T1FoTLMi09Ceo0hykJWQIkchZZl9jlQwpqUV1gModxrzjUSVKzUVEc0QSZM5UgDBSO5CKhCO4x1Tob864UgNBVVor9SJxs/tmbyorgyHzcLBDiWkFIXFfD9mk2w+dvmZihJSTP2SS0WyjtQMV8wTcbwnwF2P7T8vxykc1dLqsQejImAkDyJgNpN0pCZ4kJiiNR9iNBCOU5EYvw9IdncfVEKqpJFSnlfixWa1sHJuBYc6A9PYMkUpYEZsMs2RKpaxbJWQYuqXXCpsRdxr7+7HD/LQ1jP83SO7zwnNBaOZOFKGkFIJ51MTmSpHypE/R8ofilExxpGyWgRel02F9kocI8/k/OtveUMFx3qUkFIUllji+ZdtaC+qHKmZTy6hPbulOGK449lxeoBNx/u4dH4Vzx7o5oXDPclpwZiGO43SBzAqAlTC+dRMdY158hgeDYTPFVIA1WUOFdorcSYT8vOrPXT7I4TzkJ+nUExGTFehvVmPqXazSzYvzsrmP3/1DNUeOz/808sA6PSFktNC0TiejEN7SkhNxWiy+RSOVL5Ce077Ob9VqWFiSp6kkB/3Iptf4wagfSh03jIKRb4wjQZ7ho6UCu0VEZM9ZNKhWHvtdfjCLG+ooN5rdJMfW8coFNPSGrAYRkN7I6oo55RMJdbLTEcqT8nm5zlSHrtypEqcUUf03Pt6fo0HgNaB4AVvk6J0MEN7mTtSKrRXNOQW2jOtx+ISUgMjUWrKHDhtVpw2yzlDiASj6QupURGgHKmpmEqse/LqSMXOSTYHqHLblSNV4kz2jJtfbQiptkHlSCkKRzzL0J5DhfaKh7zUkZrhJ3o8gyNRqsuMrvEVLjv+MYPmhqJa2qE9lWyeHpH4FOUPHOYxzM2Rims6I1ENr/tcR6rK48CnHKmSJjpJz+T6CicOq4XWQeVIKQpHNK5Ce7OeSC45UmayeRGF9nRdMhiMUpOoMeR1nzvWWyahPZUjlR5TFeQ0j3Uwx2NoitnxjlS1x0EgEp/xX3WKwhGZxBG1WATN1W7aBpQjpSgc2deRUqG9oiGXHCkhBDaLKCpHyh+OoUuoGetIjcmRyiS053FYEUIJqVRMVf7AYbPgsFpyzjMzw7Pjc6RGq5srV6pUSQp5+/nX37xqt3KkFAVFhfZKgKl6VKWDzSqKKtl8YMTIlzGFlNdlS76ENV0Sjet47OmVPxBCUOaw5RyWmu2kusY8TmvOOVJmeNY7Tkg1Vxk9s86qhOKSZapaefNrPCrZXFFQzNBepnWkVGiviMglRwqMhPOZrpjHYgqp6qSQGs2RCiXqybgd6R8Lj8OqHKkUTOVIgZEnlWuvvVFH6tzQ3rKGcsCoZK8oTaa6/uZVuxkMxko+z1FKyc4zg9PdjFmJ+X7MNOpjT461N7Pfr0pIkVsdKUg4UjNcMY8l6UiNyZEyX8KmK5JuQU4wEs6H1Vh7U5IqfFyWB0dqstDevGoPLruFo93DOa1fUbxM9bFoOpYdJV5L6rVTA7z/P7eoQZwLgBnas6mCnLOXXHKkwLg4immIGLMrfHWZ4VyMzZEKJfJ00u21B0bCuXKkpsYU6xPlqIBRAiH3HCnjHI53pKwWwZI55RzrUUKqVJnqY3Gu1wVAtz98Qds00xhMfGCqXML8k22vvVEhNbONCiWkyEdoT8z4Ez2WgRHjQVFbZhTj9LpsROI6kbiWDO2lO9YeJNwUlSM1JWk5UjmKUVMMj8+RgsSYat0qtFeqTHX9za00hFSXr7SFVDhRosT8V5E/TKNBhfZmMbmH9ixF1WtvYCSCy25J9swzHYxAOE4w4Yq4MhBS5U5byedXpCIS17CIya3t/DhSE+dIASytL6fTF066VorSYqqPxYaEI9UTiFzQNs00IjH9nH8V+cMUQiq0N4uZrMZKutisoqjqSA2MxJL5UUCygGMgHM8+tKdypKYkGtenFOpljjzkSEXiOG2WCbezvKECgOMqvFeSTFUrz2W3Uum2K0cq4cZHlCOVd2IqtDf7icZ1HFYLQmR2kk3sluJypAaDo1XNgeQgt/5QbFRIZZBs7h1Xh0pxPtG4PmExThNPHvLMJhoexmRZvdFzT+VJlSZTFYQFaPA6Sz5HKhxXjlShiKnQ3uwnlVuQimLstVdTNtaRGg3tmfa+mYieDlUeO75QDL2IXLkLTVRL7UjlWv7AH45PmB8F0FTlxiLUmGqlSqo6Zg1elxJSMZUjVSjMQYszDu3ZVGivaIhqWo5CylJkob1zhZTZXd4fjnGidxi33UpTpTvt9VW67ejSCC0pJiYS06f8GvM4bIRiGloO11EgHD+v9IGJw2ahweuiTVWwLklSdXYwhFRp50iFVY5UwTBDcxmH9iyzKLQnhLhPCLFVCPHFSabbhBBnhRAvJf67OL/NLCyxuMw6PwqMXntFF9rzTORIxTjeM8ziOWVYLOlf8FWJdamBcScnoulTVs4vcxohF7PXZDaMROLJsQ8nYl61m3blSJUkkbiGzSImva/nel30DkdyEvLFTtKRyuEeVExMLMshYmZNaE8I8T7AKqXcCCwWQiybYLZLgF9IKa9P/Lcv3w0tJKnCLqkottBeMKqdU94g6UiF4pzoHWbJnPKM1ledGMvNrE+lOJ9U4WMzJy2XEgjGeZ1cSDVXuVVor0RJdf01eJ1ouqRvuHRdKbPTkfmvIn+MJptn9p61WgRCMOONinT26nrgkcTfzwHXTDDPVcDNQohtCffqvKe5EOJOIcQOIcSO3t7erBtcCHLNkbJbLUnFPdOJaTqaLnGP6ZVX7rAhBPQEwrQPhTIWUslBcVXC+aQYyeapHalcSiCEovEp63/Nq/bQ5Q/P+IeSIv+k+lhsUEU5iShHqmDEdR2LMIRRJgghsFssRGe4UZGOeigD2hN/DwANE8yzHXiLlPIKwA68Y/wMUsqfSCk3SCk3zJkzJ9v2FoRgNI5rkorT6WCzFI8jZT4kXGOElMUiKHfa2NPmQ0pYUl+W0Tor3UZob0g5UpOSriOVS8+9kXFO43jmVbvRdElXCb8sSxWzZ/JkmEKqlEsgmEnmypHKP1FNzzjR3MRuFcUf2gOGATPzuHySZfZKKTsTf+8AJgr/zVi6/BEaKlxZL2+zFs+gxaGkkDr3NNaWOdjTOgSQdWhPDa0wOZH41B0ayvIgpEJRLVlkdSKaq43bWOVJlR6phPz8Gg9CwP523wVs1czCTDZXjlT+ySUPuRgKXqezZzsZDeetBU5PMM/PhBBrhRBW4D3Anvw078LQ5QvRWJW9kLJbBfEiSdI0e6Q4xxXc/OxblhGJ6wgBi+oydaSUkEpFVJvaEXA7jGnhLL+GpZQE0wjtgSqBUIqk6uxQU+bgmqV1/Pr19pItYzJakHNmv7SLkbiuZ9xjz8RunR2hvd8Ctwkh/h34E+CAEOKr4+b5MvAzYDewVUr5fH6bWThCUY3BYIzGDLr7j8dWRAU5zYeFe5yQeu9l8/jrNy/lhpX154T90sFmtVDhtDEUUqG9yUhVkNOclu3XcCSuo8upC6k2JsZUax9SQqrUMBypqe/rWzfMp30oxJYT/ReoVTML1WuvcMRyCO05iiC0l7J8tZTSL4S4Hngr8C0pZRfjHCcp5X6MnntFR6fPeKmYL5lssFmLZ9Bi076eSCz93Y0rsl5vVZldOVJTkCq0Yobksn2Ij1akn/xl6bJbqa9wcnZA1ZIqNdLpUHPjqga8LhuP72nnmmV1F6hlMwfTicrWFVZMTlSF9kBKOSilfCQhooqe030j/GLbWQA6E8mVuThSdoslObr1TGeyHKlcqXI7VLL5FERSCamEsA1l2WsvGEstpAAumVfF1hP9SFkcwl+RHyJxDWeKF5nLbmVZQwWtA6XpWCZDe8qRyju5hfZmvlFRkpXNH97Ryj/+Zh9tg0E6EmGOphxypIqpjtRkob1cqfLYVfmDKUjlCJgOYbaOlFl/yp1ijMQbVzfQPhTiQIc/q+0oipN0S7zUlTtKtpZUMtlcOVJ5J5fQnpEjNbPPSUkKKTME9cejfUlHam4OoT17EfXam6j8QT6o8jhUaG8KUgMzfrwAACAASURBVNWRSjpSWQ5PETRDeynO6w0r67EIeO7ArDCXFWmSbtHhunJnyQqpSFw5UoUiGpcZF+M0sc+W0N5sw59wTl4+2kOnL0xduWPKROBU2CzF02vP/NrKf2jPrkJ7UxBJ8SIzRVbWjpQppJxTX8e15U42tNTw3MHurLajKE5S1ZEymVPhZDAYK5oPw3ySHGtPOVJ5R4X2ZiFm77LNx/tpHQjm5EaBmQw3s0+0STjxws1FOE5ElceOLxQr2a7TUyGlNBypKV5kFovAabNkn2weM0J7U/XaM3nzynoOdwXoUYU5S4b0Q3tOwBjYvNRQOVKFI6bpOTlSM13Yl6SQ8oViOG0WhiNxXj3Zn1OiOSQUc5Ekm5vVe6cq3JgNVR4HuoRADgUlZytmfD/Vi8ztsGY9aHEwjV57JhsX1wKw9WRpdnMvRVKFlk1MIdUbKK3wXlzTk1EFlSOVf2KazKmOlBJSM5ChYIybVs/l5ksaieuS5qrchJTNYkFKimLk9ILlSCWLcpbel2wqookHcyoX0GWz5hzaS6cTweomLxVOG68qIVUypJsjNafCGO6p1PKkxobzlCOVf3JzpGZ+aC91HGAW4gvFqClzcNctq3jbmrmsW1Cd0/psCaUd03SslvwKlHyTrCOVwyDNE1HhMi6lQFg5UuMxhVR6jlSWyeYJJ7DMmfqWtlktXLGohq0lWnixFElVfsPEdKT6hkvrg8j8gKlw2ZIfJYr8oUJ7swxNlwTCcSrddoQQ3HxJE005OlKmZVkMCeehmIbNIrLuijoZ5YkX+LAK7Z1HuqE9lz0HRyrNOlImG5fUcro/mCxIq5jdZC6kSsuRMsN5lW47mi5nfC+xYiOuQnuzC7PHXlVioN18YLMYh7EYbr5wTMt7DSkYdUJyGXR3tmKOb5iq15TLnkOyeVRDCNLKgwFDSAHKlSoBpJTEtKk7O5iUOW247Vb6SixHyrzvzHFDVZ5UfonmVEdq5of2Sk5I+RJCyrxh8oE9Gdqb2ScbjNDe+AGL80GZcqQmJZm/lMItctut2Vc2j2p47FaESO+r76K5Xqo8diWkSoCeQAQpjYGJ06GuovSKco4XUipPKr8EI1rKGneToepIzUCGCiCkTKVdDMPERGJa3mtIwWhobySiHkDj6U6UGWjwTl1mw2W3JntVZkowqqWsaj4Wi0Vw5aIa1XOvBDjcFQBgxVxvWvMbRTlLK0fKTDY3IxXKkcovQ6Eo1WkK+fE47ZasezNfKEpOSPkKEtpL5EgVgSMVKlhoz1inCu2dT5c/ver5uThSoWg8eQ7SZePiWtoGQ7SqQYxnNYc7jeGAVs6tSGv+UqxurhypwhGOaYRjetbmhddlJxCOz+jxQUtWSOU3tGccxpmeEAfGRZ3v0gcAZQk3RNWROp9OXxghoL7COeV8RrJ5dtfQSDRzgbxxSR0Az44bLmbbqYGSLMg4WznSFaDB60zbEShFIWXmMVa6jWOU7X2oOJ9czQuv205clzPalSo9IZWoc2TeMPnAVmQ5UoUI7VksgjKHVTlSE9DlCzGn3Jmy+2+uyebp9tgzWd5QzsbFtfzb04d5Zn8nAPdvOsWf/N+t3PX4gazaoZh5HO4KpB3WA2Pg4oGRaEmNUnCeI5VliF1xPoOJd25Vlu9cr8s4J/7QzH23lJ6QKkSOlKWIHKl4YRwpMBLOlZA6n05fmMY0hiFy23OpbB5Pa3iYsQghuPdjG1jV6OWuxw+w5UQfX37yIOVOG88f7CYYVeey2IlrOsd7hrkozbAeGEnpuhzNJy0FzNzEZK895UjlDXMw++wdKeO55g/P3Oux5ITUUDCG225Nq6ZKuhRVHalo4YRUudOmeu1NQJcvnNZ4jm6HUUcqm1wAI9k88/Na5rTxmTcvpdsf4XO/3E1tmYMfffgyQjGNFw71ZLw+xcziVN8IUU1nRQZCqjY53l7phPfCsdE6UqAcqXySs5BKOFK+GSzsS05I+UKxvCaaw5hee0XgSEXiunKkLjBd/nBa4zm67FZ0OVrAMxNCMY2yLMdPvGFlPQ1eJz2BCLdvbOGNy+bQ4HXyxJ6OrNY3k3hsdzu+4Mx9ABeaPW0+AFY1pR/aq03kUvWXUM89M7k82WtPOVJ5wxdKhPY82YX2THHrV0Jq5uALxfIa1gOwW4opR0rL+/AwJmVOq3KkxjEciRMIx9NypEyBm81DfCSSWfmDsdisFm7f2ILXZeO2jQuxWgRvWFLH/nZfVuubKXQMhfjsL3dz9xOlm+/16sl+qj12ltdnFtoD6C+hDgdjK5uDcqTySdKRyrbXnimkVGhv5jAUjCVPTL4opjpSheq1B2ZoTz2AxtLlM0ofpJMjZXYCyCbhPBSNZ5xsPpa/uG4Jm7/w5uRLtKnKRXcgUhQDcU9Gb6I696O72tnTOjTNrZkeXj3Zz5WLarFY0h+eo7YUhVTinjPDSBHlSOWNoVAMu1Vk/XzyJsZxVcnmMwRdlxzq8rO0vjyv6zV77RVNHakcXrhToUJ752MKqVTFOIFk+YJMa0lJaXQNzkVIWSyCCtfoB8bcSjeaLou6G/zYEg73bTo1jS2ZHloHgrQNhpLDAaWLWSZhoIRCe+GYbrzsE7XYlCOVP4aCMSrdjrRHXRhPhUuF9mYUR3sCBMJxNiyszut67UXSa09KaZQ/KFBor1wJKQB6EgU4geSgwOn22gMyrm6+v92PLqGltiyj5aaiMSH8On3hFHPOXExHZUGNhzMlWHT0tVMDAFy1ODMhZbda8LpsJZVsPhIxer3mEl5XTIwvFM0pL9lhs+C2W1Wy+Uxh55lBANbnWUjZiqTXnjkMQiHG2gPVaw9g19lBrvj6C/zm9TYAtp7sp8JpSzvZHDJ3pF443I0Q8KaV9Zk3eBIaqwwh1ZUQgsWIKQTWNHvpHCre/ciW/e0+yp02lmXhwNeWO0sqtNflDzPX60oO+j2iSn/kjaFgLOv8KJNKt13lSM0Udp4epK7cyYIaT17Xa+ZczWTFDKNx/0IMEQNGaC8S12e8M1dItp82XIC7Hz/Aqb4RntnfxTsubkyr3Ea2X8MvHOph3YLqtAelTQdT+BWzIzUwYuRmLKuvoCcQKblwTbffKLuRSX6USW2Zo6R67ZklSuxWC3O9Ls6WoINZKAaDsax77Jl43TaVIzVT2HFmkA0Lq7OO1U5GfYUTIZjxX71mscdClj+A0h5vb2+bj2qPnaim8+4fbSIY1Xjvuua0ls0m2bzbH2Zfu48bLsqfGwVQ7bHjsFmSOV7FyMBIhJoyB81Vhijs9s2cUFWPP1xwYdcTiKQclmgyasocJTVM0NiiuYvnlHGyd2SaWzR78AVzC+2B0QlAOVIzgKPdAc4OBLliUU3e1223WqivcNIxw1864aSQKlSOlCHQSjm8t6/dx1WLa3ngjiuQEuZVu7miJb1rzuwEkEl18y0n+gC4bvmczBs7BUIIGitdM/6anoqBkSg1ZU6aEkKqY4aEKXVdctP3/shPXj5Z0O30BMJZC6nackfJhPaicZ3+kUiyQ4ghpIZn9CC5xcRQKPfQnneGh/ayKzxThDyw+RROm4X3XpaeO5ApjZXuGf/1biYxF96RKq0QiokvGONMf5APXj6fjUtqefZvr0XTZdqhlWSyeQZCavfZITwOKyszGEstXeZ6XUWdI9U/EqW2zJHM9+qYIY5xTyDCYDDGke5AwbYhpaTHH6E+jd6iE1FT5mAwaIy3l01osJjoCYSRcrRDyOK6cvzhOH3DUeZkKUQVBpG4RjCq5exIVbrtHOsp3P2SK0XjSEXiGoNZfiENjET5zevtvG9dc9ojoGdKU5VrxnzxToYpcAqZIwWl60jtSxSwvKS5CoCmKjfzM8jHSyabZyKkWoe4uLkSawFedk1V7iLPkYpSXeagaYble7UNGvk37QUUdv5wnEhczyG050TT5Yx2AfKF+QE8d0xoD+Bk7/C0tWm2YI4qUJlrjpRL5Ujlhe89f4wbv/dHovHME5lfONRNJK7zkSsXFqBlBnO9bjqHwjPaDj7c5QfIex0tk4oSz5Ha224Ufby4uTKr5TNNNo/ENQ52+rl0QVVW20vF3EoX3f4w+gzvjToZA8OGI+V2WKn22AsqXDKhbdBoR/tg4dpjluDI1lExi3L2lUDCeZffLJprCO4lc4zn48k+lSeVK+YxnFedutfyVHjddgLhWN6eRbou+cSD2/ndvs68rK9ohNTO04P0BiLJnJBM2NM2RLnTxqrG/Ic/TJqqXIRi2oxWzbvODlFX7sj5op6MUk8239fmY2Gth8osbexMk80PdviJaZLL5hdGSDVVuohpkt4iLMoZiWsEIvExldrdM6YzSGuiR1ghexL2JKq611dkF9ozXZnXzw7mrU0zlaQjlQiDNlW5cdgseXWkjnQF+PTPdvLSkR6OdgeyGr0gFVJKvvXM4WSZn+kgrum860ebuD9RANccZmpNU3YflyZelx1d5q8sxe62If5wuId7nj2SF3FWFEJKSsmhTsNNeWZ/V8bL723zcXFzZUFj/ebXzEwO7+06O8il8/Pfa9GkPCGkAiUqpMzrLFscVgsehzU5tEkqdieGPbl0fn7ropmYX+bHe4ovxGGO72UKqcZKNx1DMyW0N/qM6CxQm3oCxnrrvdk5Uhc3V7Kw1sNju9vz2awZSacvjNtuxes2nl9Wi2BRbRl72nx5izA8trudZw50cccD27nxu3/krsfyP/7jid4RfvzSCX70h2N5X3e6/P5gN3vbfDyeGPD8QIefBq8z51wz89z4w/l5t7xwqBswHLOXj/bmvL6iEFJtgyECkThuu5VnD3QRz6BOUSSucajTzyXzc1PEqTDj650zVEgNBaOc6B3hsgKFgWB0nKpcu03vb/fxxm/9gTP9xWOt9w9HaB8Kccm87K8zIQQXNXo52OFPa/7XTg7QXOVOa0DkbFjWYAx0e6Rr5iZ5ToZZA8kMUS2s9XCqbyQrRzvftA0FkzltbQUK7/X4DTGeztBEEyGE4N2XNrPlRD/d/pkhQAtFV6L0wdgPzPeua2bbqQG++/ujednGgQ4/y+rL+dGHL2Pt/Cp2FsDp+8NhQxxsOt53QWsaPrz9LJ//f3t4fE8H9282nKi9bUP4wzH2t/tydqMA6soNIdaWp/pezx/sYcPCauornPx06+mc11cUQupA4sVy+8aFDAZjvH42/QFID3cGiGmStfMKJyDACO3BzEloHY/pXhRSSFV67MyvcbMrx4fEf7x4nNaBUFbu43RhJppf3Jzb8V3T5OVAhy+l3azpki0n+rh6aWbDf2RCXbmDmjIHRwvYu6xQmGLedKQ+dd1iWuo8fPyB7Zztn95ii22DoaRz2T5UmLb0BCJ4HNakS5wN77m0CSnht7tmtyvVPhQ672PkU9cu5n3rmvnhi8eT7l4uHOjwc8m8Km6+pInrls/hZO9wxiMYpOKFQz1UuGzENJl0XAqNlJJ7njvKIzva+Jtf7GL76UGuXzEHXcLLR3o50TvM6hxcepMNC2uwCNhyoj/tZXyhGC8e6Tnv4+lsf5Aj3QHetmYu7760ic3H+3NORykKIXWo049FwB1XtyAEvHYy/YO5t80QELk4BelQX+HCahEFs+pz5bVTA1gEXFJgQXl5Sw07Tg9mbYmf7Q/y7AFDQP3xWO6W64ViX5sPIYzhSHJhdXMlI1GN0yncuH3tPvzhONcsy2/9qLEIIVjeUF6UQsp0UWrLDSFVX+Hi3tsvJxLXee7g9Al0TZd0DIW4vKUaiyhcwnkuxThNFs8pZ/3Cah7e0Trp/dw+FOLD//0qLx7uyWlb08WWE33sbh3i8nG13oQQfPwNi5AStmbw8p6IHn+YvuEIq5uMZ8PqJi+6hENd6TnPU9HlC9PtD9M/HGHHmUFuu2ohjZUu7nrsAB/6ydaCO1PHe4bpDUT42nvX8Ju/fANfefdqvv/By3DYLNy76RS6ND4Oc6XSY+fieVVsOp6+o/z3v9rDxx/Yzof/+zV2nhlI/v74HuPD4KbVc3nTinqimp6RQJuIaRdSPf5wyvpLBzv9tNSV0VjpZkVDRXIwzlRIKXl6fxcNXmeyunGhsFoELbUeNp/om3E996SUPL2vkzcsqcvpCzUdrmipoX/ECCNmw/2bT2G1CG5Z28T2U4MEZ8iYV68c6+U9/7F50u7ge9p8LK4rS45Uni2mDb4/RXhvU0JkXr2kcI4UwIqGCo52F1dxQiklP3/tDE2VLhbUjA7kvKDWw9L68rzkRGRLtz9MTJMsqiunweuirUAJ8D3+cNaJ5mP50ysWcLJ3hG0TPHNDUY07f7qDLSf6+Yv/2XleknMgHGPX2cG0c/4uNJG4xj/9Zh8Laz38xfVLzpu+qslLpdvO5gxe3hNhRlRMIbUm4dAcSLjY2RKOabz3x5t547de5OYfbkJKyc2XNPHFd67iuhVzeC2PocnJMIXNtcvmsG5BNbdtbKHSY2fDwmr2tA5hEbA2T51hrllay+7WobRKcpzpH+H5Q918+MoFuO1W/t9OQzxJKfn16+1csaiG+TUeNrTUUO608eKR3D4EplVItQ4EeccPXuE9/7GZwCQHZzgSZ9upAS5JXHxXLa5l55nBtMZze+VYH1tO9POpa5cULMF6LHdcvYhdZ4dyVrf55kCHn9P9QW6+pLHg27o8UTneHHMuE3zBGI/saOWWtU38yYZ5RDWd105mvp5cuPeVk+fFzKWUfOe5o+xuHeKX286et0xvIMIfj/Zy9dK6nLe/rKEch9Vy3kP2tZP9PLD5FOGYRjSu8/T+LlY3eaktL2zBwGUNFQxH4gWpcH6id5j3/XgzP916OqO8x1S8dKSXXWeH+Mybl503xuF1y+ew7dRAQXpNpYP54mmp9dBc5eZUii72dz9+gD9/aDv/+9pZdpweSEvQ9vjD7G3zJXve5cI7L26kwmXjvk2nztn24EiU2+57jYOdfr79gUuY63XxiQe3cyzhXvqCMd7+/Vd474+3cP23X0z2VJxJPLmnk9P9Qe66ZdWERYqtFsHGxbVsPt6f04fEgQ7jXl6VEFJNlS6qPPakwMqW+zefotMXZuPiWrwuO498aiOrmry885JGfvThdXzkygX8dOvptHMu0+V4zzC/3dWOlJLNx/tZUOM5r17eV96zhntuXcuzn7s26zy98VyzdA6aLnk2jZSPh7acwSoEn71hGW9fM5cn93YQjmnsODPIqb4RPrBuHgAOm4Vrltbx4uGenHrvTYuQCsc09rf7uO2+14jEdLoDYe559siE8z64+RS+UIyPX70IgCsX1RCKaextm1rN72vz8c+/3cf8GjcfuWpB3vdhIm5dP48Gr5NvPnP4HCelbzjCI9tb+dpTB6eluvJvd7VjswhuWj234NtaXFdGXbmD5w92Z/Tw0XXJfZtPEYxq/Pk1i7m8pYZKt51vP3vkgrlSW0708dWnDnHX4wfO+bp+/ewgu1uNCuIPbD59noj/2dbTxHSdO97QknMb7FYLKxsr+MPhnqQt3xuI8Kmf7+RLTxzk2m+9yAd/spUDHX7uvHZxzttLxYq5RsL56wXoUv2VJw+yq3WIf33sAJ/++etpD3btC8Z4fE/HhC9nXzDGvz6+nwU1Hm7dMO+86dcun0MkruccrsmUmKazr83H1546xLoFVVy5uJY3raxn19khfvN6W3K+3+3r5IcvHCOu6bx4pIcHt5zmtVMD/NOj+/jAf23lzp/tpMsXZvvpAb797GEe3dXGl584yI9fOp48Ht99/hhxXefT153vsmSK22HlU9cu5rmD3Xz72SN865nDfOe5I7z1u39kb7uPH/3pOm7dMJ+ffuJK7FYL7/rRZu54YBt3PLiNLl+Yr713DZqU/NvTh3JuSz6RUnLfplMsqy/nTSsmH6fy6qW1tA+FONqdXc/V4UicJ/d2nuNWCyFY01TJ7tahlC/vkUic18+Opkq8fLSXH7xwjCf2dPDjF09ww8p6HvrEFTz7t9eyYVx48u9vXEGVx8G/PrY/7Wfxyd5hHt/TMWm7fMEYH7t/G597eDd3/mwnm49PnKe5ZE45H1g/L9lhJR+sX1jNioYKPv/rvbz7R5v4+APbJvwQ2XSsj5+/eoZb1jbR4HXxvnXzCITjvPW7L/Ohn7xKhcvG2y8efRe+85JGOn1hHtnROum2U3W4EekcYCHEfcAq4Ckp5VezncfE2bhMNn7se8ypcPJfH13H47s7eGjrGT75xkXcsraJSFynyxfmWHeABzaf5opFNdx3x+WA0Tvq8q89z9r5VXzuLcuJxXVeO9XPE3s66R+J4LZbcdqNLuRzvS7+4yOXsX5h/sfXm4yn9nby1794neUNFSys9XAmkdhmHub6Ciefum4JR7sC7DgzwNL6ct62Zi4rGrwMR+IMjETxOKwMR+L0j0SxCFg5twJNN76QIjGNcFxjWX0FbocVAQwGo2w9YRyDvuEICGiqdHPV4hoOdQV4am8nb18zl//86PoLcgx+8MIx/v33R/nL65fwnsua0XTJ2YEg4ZhGTZmD2jInteUO7FYLfcMRXjzcw72bTtEbiHD9ijk8+PErAHjxcA+feGg7S+aUs7rJS0zTWVpfwWULqlhQ40HTJS6bFbfDSlTTOdk7zLHuYRbNKaPCaSRdSimJxHX+eKyXBq+Ly1tqcFgtWCxgs1jQpSSm6ZzpD/KNpw9jswrimkTTJe+8pBFdSn63r5NwTOfr772Yv/rf11lcV8ZNa+aydl4lZweC/PAPx7lqcS3/ffuGvBy/3x/s5i//ZydNVW6uXlrH/nYfh7sCfP29F/P0vk5ePdnP596ynE9eACEVjmm8/fuv0BuI8C83X8SqxkpsVsFQMIZE4rRZsFstOMx/x/xtTxzLSFynL9Gr0W23Uua0se3UAN985jD/9I6V2CwWvvzkQZqr3NSUOXjX2iYkMuEc6Vy9tI5uf5hjPQEiMZ3jvcPJ8gY3rW7gQ5cvIBLXaRsM8uTeTva3+3jk0xtZt+D8shDhmMYbvvEHLELwxXdehMdh5Ux/EJtVUF/hYkGNh3qvk5FIPHHN6rgdVlw2Cy67NfG3FatVEI5pjETi7Gv3EY3rrFtQjctu5VTfMMGo4RwOBKM4rBbu33SKDl8Yl93Ck3/9RpbWlxPXdD5872vsPjvEjasbsFstPJpI7F63oIr2oRBlThtPf/aNdPsiPHugi28/ewRNGtenicNmSRYqbvA66fZHuOMNLdz9rtV5uQY0XXLHA9t45VgfVotA0yWXzq/iq+9ZkwxTgeEwPrTlNK+dHKDLH+bvb1zObRtb+P7zx/ju80e57aqF3LR6LlUeO1aL4EhXgMNdAeZUOFm/sBq71Vj3tlMDdPvDVLjsSdfV67JhEYJOX5iDnX7mVRvXyrZTA2w+3scl86pYO6+S5mo3Xpcdj8OKPxzjeM8wcV2yoMaDZUxU4vlD3Xzv+WP82/su5k+vmPxDu2MoxFv//WWcdkNQet12TveNENMkteUOGrwuyp1WTvSO8NjudqrcDtYtNPLfnjnQRSiq0ROIcO/tG3jTylHB9tCW09z1+AHefWkTH71qIZVuOzaLoMsfZufpQWrLndisgv966QQn+0Z496VNtNSW8aMXjyfP/YqGCu792IYpR094ZHsrn//1Xv78mkW885JGrBZBOKaz+XgfNotgWUM57UNhWgeCnOobYdPxPuPZd3Ej77i4kbmVTrwuO0OhGJ2+MA9tOc2e1iFuWdvEo7vaWb+wmntuXcuiutzdz3QIRuPc8+xRjnYHkvfdBy+fT0utB2vi+N2/6TQLaz08fOdGKj12NN2or9U6GGRBTRkfvHz+Oe2VUvKhn7zKoU4/n3/bSlbOraC52o1AENeND6B/+PVe9n3pbTullBM+5FMKKSHE+4B3SSnvEELcD/yblPJYpvOMZemqtfLvfvwb/mTDPGrLnUTjOl958iA/e/XMOfNZhJGt/80PXHLOjj+xp4N/enQfgURNCZtFcP2KepY1lDMSiROMaqycW8Gt6+dnXRwxF57e18l3fn8Ui4DmKjeXzq/mLavqsVks/MX/7ORk7wguu4WrFtdyrHs4bxWXV86tYGl9ORI43OnnRO8IFU4bH924kM/esKxgY+yNR9cln3t4d7KWSDpcs7SOWzfM4y0XNSQLe4Lhpv1y+1naBkPYrRbO9I+QjQM79mUzGQtrPXzvg5ciga8/dYi9iQTyKxbV8Dc3LGPDwmp+tbONx3d38OrJfuKJhly2oIp7bl2brLuUDzYd6+N7zx/lWM8w5U4bn71hGX9y+fy8rT8TunxhPnrfa3mvJ7V+YTX/+8krcdqs/GLbWV460kOnL5x0mxfUGA/HU30jlDmsLK0vp8xpo9Jt5yNXLmTb6QHufeUkwTG9nxorXfzdjSv4wPrz3SiTY90BPvHQdloHLpw7vLrJy59ds4jLW2rOefH1D0f4/gvH+N2+LiIxjZvXNrKqqZL/eukEteUO7n7X6nME4dn+IA/vOIvLZuW2jQtpGwyxZE45fcMRntrXyb42H5e3VPOhKxbk9X4fjsTZ2zaUbIvTZkk7XSIc0/jqUwf5xbbWcwQgGM/u+AQ3tNtuJRzXSMdIWVZfzqm+kQnXMxU3rKznPz6yLuVxOt4zzN8+vDvZM9dhs2C3CEbG9bq7oqWGqKZzoMNHXJdcs7QOm0Vw64b5vOPic9MqpJT88A/H+fcUOUz1FU7ecXEjP916Gl3CG5fV8Y9vv4hjPQFuWj03Zdt1XfLXv9jFU+MqeFsESEge33Knjfk1Hq5aXEO1x8F3nz864bGvK3fyD29bwa0b5jOYGIJpuuj0hfjm04d5al8nMW20sW9fM5cvvXt1RjmCJ3qH+fB/v0q3f+J8vsV1Zbz4f96Uk5D6AfCMlPJ3QogPAW4p5QNZzHMncCfAggUL1p85c65oAqN3XutAEJfdSoPXRVOVa9Lk3YGRKEe7A9gsglVNXjyO4hh/WUpJbyCCunNoHgAAIABJREFUy2E1qrXqkl2tg/QGDCeqpsxBKKZR7rRRW+YgEtc51hPAYbUS1/Xk1/7xnuFkKKTcaWN1UyXLG8rPebj5gjG8btsFyQ8bj65LDnb6OdE7jN1qobnKTZnTxsBIlP7hCP0jUTRdUum2s6bZy9L69CzgkUicPW1D9Pgjia8rjVBMw2G10FTlZuXcCk71jRDVdKwWgUUIdGl8QfcPRznWE0DTja9sTZdYLUY4rcJlZ/3C6rTHrPMFY7QOBqkucxS8I8NMQNMlx3oCnO0PJs8bAmKaJBbXiWk6UU0nGteJaZJoXCOmSWxWgcNmodrjYH61h6im4Q/Haa5ys6y+fMJrs3UgSLnTRnWZAyklAyNRasocE847MBLlVN8wTpuVuZWuZL2ZVIRjGid6h4nGdRbVlaHpki5/mNaBEH3DRumAedUeypxWwjGNcEwnFDXc4FBUQ9Ol4U7ZrSxvqMBuFRzo8BOJ6yys8VDlsWOzWqj22BkMxmj0umb94L+p6PKFOTsQZDAYJRrXWd5QweI5ZXQMhTjWPYwmJVIaPV/nVXsYjsQ50uVnKBgjEI6j6YYLtKrRS9tQiGBEo7nazaK6MsIxjWPdw3T7w/jDMUaiGhVOG4vqyrBbLbQPhc4Jb82r9iRzltKlNxAhFNWYV+3Gknj2dPnCjETj1JU7k7lAplOZTv5ily/MoU4/I9E4cU1S7rRx5eIafKEYmi5p8Lpw2a0MBaPENEld+cT3QSpaB4Ic6QogBFiEYO38KnRp9CCdV+2h2mM/Z729gQh9wxE6fSGGIxrVHjvVHgcr5lZgt057H7VzCIRjxDRJXNeRMvvaaVJK2odCHOkKJEcGEMD8Gg/rFlTjcdpyElL3AT+QUu4RQtwIrJNSfiPTecayYcMGuWPHjox2UqFQKBQKhWI6EEJMKqTSkZbDgPnJXT7JMunMo1AoFAqFQjGrSEfw7ASuSfy9Fjid5TwKhUKhUCgUs4p0Qnte4BXgBeDtwIeAW6WUX5xinquklJPWJxBCBICJ6x2UBnXA9A/6NT2U8r5Dae9/Ke87qP0v5f0v5X2H2bH/C6WUEw4lkW75g2rgrcAfpZQTVsNKZ54x8+6YLNZYCpTy/pfyvkNp738p7zuo/S/l/S/lfYfZv/9pdXWTUg4Cj+Q6j0KhUCgUCsVsQiWFKxQKhUKhUGTJdAmpn0zTdmcKpbz/pbzvUNr7X8r7Dmr/S3n/S3nfYZbvf1o5UgqFQqFQKBSK81GhPYVCoVAoFIosUUJKoVAoFAqFIkuUkFIoFAqFQqHIEiWkFAqFQqFQKLJECSmFQqFQKBSKLFFCSqFQKBQKhSJLlJBSKBQKhUKhyBIlpBQKhUKhUCiyRAkphUKhUCgUiixRQkqhUCgUCoUiS5SQUigUCoVCocgSJaQUCoVCoVAoskQJKYVCoVAoFIosUUJKoVAoFAqFIkts07HRuro62dLSMh2bVigUCoVCociInTt39kkp50w0bVqEVEtLCzt27JiOTSsUCoVCoVBkhBDizGTT0grtCSEahBCvpJjnPiHEViHEFzNtoEKhUCgUCkUxktKREkJUAw8BZVPM8z7AKqXcKIS4XwixTEp5LOPWhIMw1A92J1RWg80++by6BgE/WK1Q7s14U9OKlCDE6P8PDBn74nRBRSVEI8bfdgdoGvR3G8dC14x/rTboaoV4zFje5YGmhcYyM4lwCHo6jHNUM8do30gA/EMQ8Bn746mApgXgcKa/Xt+AcZ1YrMaxioaN41LbYGwnMASxGFgsICyABG+1cbyG+o1jqusgdeM8WO3g9oC3Kv02SAmxqHGOxp7L2Uw0AgM9xvErqzB+0+IQjxvHNh4z/tbixvHX4sa5t9mNe7RurvF7eATKK8Hlnng74++PqdB1CI0Y5yGTawiM8xePgbtsdP/6uo3rx+kyrieXGyIRiEUS11riP10ztudwQV2DcZ31dhrrq2sYXadiFF0z7v/hgHGcGpqNYxiLwkCfMV1KqG8cffab84dGjPu1otI4L6ER4/lS7h097+Eg+AYhOAyRsHFP1zcZz8uBXkCOtsVbDZ7yzNovpdEGi3XMPunGdW53ZHlMdOjvMdquacZ1U9+Y/2eKeYzBeC7W1ht/RyOT34fxuHG/h0PG/V7unXnvmPFk8uyYCF2H3i7jHQMgMJ5bVbVTLpZOaE8DPgg8NsU81wOPJP5+DrgGOEdICSHuBO4EWDKvGXZvhTUbjBtGSnjhMfjVvcZFaVJdBxdfDu/9GFSMecmdPAz3fRu6243/P6cR1r8RGudDJGQ8+OYvgosuMx7kF5rTR+GpXxoXbE09LF4Ja9YbL5Gf/QAO7zEuyks3QvtpOLTbuEHH4/YYN1c0knqbNruxvsb5xv9vOwUnDhkP9etvho03XNgX/uM/hyf+xzi3JsIy8X7a7HDt2+Hqt8L8JcZxMzl+ELa+YDxsbFZoPWn8PRluD4SC5//e0Az+wYmnmay5HD7yl4CA3/3SOI8IWLYa3vo+mDPXaM+2l2DXFhjsMx7iG66FD/xZZkIsFZ2t8NyvoeOM8XC98X2wal3+1p8J4RDc+y3Y+5rxoMkHNjtc9Sa4/XPG+T68Bw6+brzwdrxinMeW5cb9e/ygcR03LgSXy3ioX/dOOLYfHn3IEDBg/L5gKbzzQ7By7eTbDgzB//03Y5tgPFukDsP+7PbF7jBe1uEx15bFMiogh/1w6VXGNdTccq7gi0XhlWdg5ybjPr/8WuMeeOZXhmh410cNMWASCcPrm4yPzfXXjH50xaKwfyecOQbL1xjPvnze77puHLfKmuyWffEJeOJ/Ydg3+rvFAvXNxn0UCY3+7vbw/7d35nFyFOX//9Rce2fvZJNsrs2xIYFchNzGEAL8oiIoLwyIwSAKCOhXRCEoGvAiCIKCCqJgQBFBUVA5hCgJBAg5JAkJZBNybza72fs+Z+r3x9O1Mzs7R08fs93T9X699tW7M73dVdM1VZ96nqeeQvEoul9j3eDrhX7H0zKobz1+KNgOwmFsYD8E0DNbfhFw6ZcGCqNItLUAf34E2LONPucRowGPhyaDTQ00ZmVkUj/Q1wcc/pDE3LxldO15HwcmlA++7rbNwB8fonNDySuk1/x9wPhy+p7862m694LlNB7WnqJ2ouYZP/8kja+d7cHXcgsUY0RzcJJTPBIon0F///GhyN+HSdOAS74Y+/uVLLq7gNf+Bmz5N/VRfj99Hud+CvjE5YmJvuZG4Lf30LOLNN5Oj933Mh7ewKKdyNgmzvmyKO89BuBBzvluxtgFAOZwztdHu9bc4ly+4+KFwNiJwPXfBf73FvDXx4AZ86kj6e0hy0HVMeC9d6jxXP1N+ufOduCWz9OM9vzPUGOr2APs2zm4k59QDnzltoEdkdkc3Af8/A76omYPI2tSbw91tBmZ9JAWLAdOHiNBOGI0MGcxUDqB6tbeQrPcrs5gpzN6PNXN7aZr9fYAI8cqDYVRh1Oxh76Y4n/yi+hLcfIYcOIQsOIS4PLrk/MZvPUa8PufUUd/zsep7HWngJ4eGhxy8ujo8ZB1as82YOt/6Ivwsf8HfPEbdJ3jHwHrb6F6F4+kTmrUOBKmxSV0vi+NPoe+XqC6ktrMiNKgCOUB+rz27QRyC4EpZ9F9XS764aD/PV0FbPw7UDKG7lNTSedyTp9tbj7w5VuBe75F95x+Ng30tVXA1teB+ecG26hejlRQG/L76TtSe4o6jW/8iAbcij3AJ1ZRuzEbvx/42Vpq1xd8RhG6brIUAIBXsZB6vWTZ83hIQHg89LrfD/T10HOur6G2nZ5B13vrVeCab5MA+tVddG5aBg08nJNQ6ukmUdBUD5w6Ts+yvS0oyEePBxadD/h7yZq0dyd9j773UOTvvd8PrLuOxPgFn6X7na6iMufmUzvLzafP+/QpKrtPsQ77fMHf3W5qz10dJF76+qhd+nxA9Ukqd28PDUZeL7D1v/RaXiGVLbeA6vjbe0iYl06gMhw9QOXML6LBdEwZcOt99NreHcCGB2hCAFA5mxuVSULTwIHys1dTGzGKDQ/QgDV8FPW55TOBS68eKKzaWoFtr1P7bKonQTtjPrD5JZpATp0FzF5I/SJzAVVHgcqjVI+J06jN+P3AgffJIpCRRfUflg9kZtH/NNZRv1BUQtc5uBf44D1gwhQSHYXFZOX2pdHnceoElbe4ZKBg2v0ufe5fvYP6qWi0tQA/vIk+5wXnUplOV1E5c3LpeaZnUtsUE4CJ02hA37WVLBq+dODWe+m7LNi5BXjkx9RmFl9A3wG3G2isBz7aR5Myl5tEdkcbjWVFJcD2zdRO+nrps73mW0HrcCT2vAs8uA69c5ei8pwV6HJ7qM/r7aH3xWce8AePAN3Dm6b0kwwIcHqvu4varRCzvjSy7LmSlACAcyqDv4/qIKyBbsUmFFAMD940ej5CaHZ10ntuN5WZhZW3tbnfOpfOOErTPPC6XfSZHD0A/PMpsEdf2sk5nxupWEYJqV8AeJpzvlVx803lnP8k2rXmnjGV79jwMPCnX9MDaW4k69RX7xj8QP78G+C/LwA//B0wYhTw/nbgF98DbrmbOliBMP/60qjj2v0u8PTD1PjueDA5DzoQANZdT4381nupMwz4yTK0aysN8hd9AShTZicBf/zZUMJl8ANgwfoGAmRN2PUO8MAzyTHN3nYVdTDfvpe+qGpobgT+9nvg7Y3A3Y8D+cXAd79EDfmOB7XNhBPl3ddpYAOAG74XFCq7tgK/vJPK0NsDrN8w0C3w1K+ow7vnCWPK+dNvk3i69V4a2KtPAHfdGBTkObnUwX/jR+bPDI9UAD/+P+CKrwLnXWzcdQMB4Cf/R1bl7i4SaLesJ5EV77tadQzY/gYw8YzBVue6auAHN5G4+M7PB8/YD+4D7rmFBqCFK4yrTzya6skCtuEBsrLf8D3g7deA398PXLwauOhKGiRe/DMNylfeRJanDQ+Qla3qGPUro8fTszhdRX3hqLHAsY9ocjJ/GX0mv/0piZGfPG6MlTR0YhQI0PPZtZW+A1+/iwb59laaZFQdI+thgAOdbcBNdwIP/5gs5bfeax03eMAPfOcaIK8AWHt/9PNE3W/+SVyrBPp66fsp6tjXR6L37pvp+Xz/l8FzH1xHz/nOh2P3yfWnyWOxYDn1pf/9B1loS0qBF58mT8OaKBO43h7g+9cBbjeOfOl25AzLRWFhIVi0Z8A5iaOeLhKvkb6Hvb3AqWPUDrxpNNHIyaOQCrPhnNp9Z7si8Nzk5s3IHHheazNN2oblU7m6u+izFni8NCEX9etsp34orxA8twD19fVobW3FhAkTgv+zdwfYWedEFVJGrdrbCXLnbQUwE0BFzLOzsmkGXzwSuO82aiBX3hj5wa28DHjjJXJzrP4aUPE+NdayMwael51DP4KF59HxsXtJxc8/V0f1VPK/LfTArr2dRBRAD3vymfQTjtEiKtI1XS5ym23bRJafc5Yaf89QGmrpy3/+Z9WLKIBmpRevJsvUxheAuR8jC8O1a5MjogAyxVfsoRlOqLVnxjwamGtO0iw/PLZixWeATf+iTu4za/SVIRAgC8fiC+j7AZCV7IvfIBHwyctphvujrwHPPxF7EDCCk8pClTMj9h/acbmAVdcDD60j1/PFq8nqoIZR4+j8SBSVAKuuJYHy3tuDrXb7dtC9Zy7QV/5EySukwbCxDnjucRKo7/yHhNEnL6dzGAM+dUXwfxadT1bmumr6jEaPo2t4fSSgl66MfK/LvkxWt1f+AnzuK/rK7ffTBGfSNOC624P9S9UxEgP33gp8826q0+kqEvdnzqWB7K4b6X3GgCuut46IAqge510MPPMb4HBFcHIbzv5dNHE5Y1b8a4bH9Ho8NJAvPh946RmyeAi37vGP6BnGm9gWDgeWXBD8e/mn6QcgAbDxBbKSNdTSsy4cETz3lb/QhOybP0FXdw/GxxJRAD2fzKzY30Ovl9yuXR0kQmuqIodLCEu0sGoZQU831TmvkMaEaHXJySULVGszndfWQueWltH/11XTUVjy2lqpPQzLB2MMhYWFqK2tHXjNOP1fwjVkjE1jjP0o7OXnAaxmjN0P4HMAXlR1sbKpNEu5+e7owVy5BeRiOfwh/X1gD7lU1FhW5p9LpuF//klVcXTzyl9p0Jsbw1Q8FEw5k4TK9s3m3+vgXjpOnp74/xYUU5zBm68AO94g8+u0s40tXywYA65SrC+huFw0wGVmBzuxUEaMIlfHnu36y3BasdCMmzTw9QXLaSJRUEwThnOWkms41J1jBlXHaOAuLjH+2pOnAw/+Ffj8DbHdE4my4DwSvi/8YbC7f+8O6ncSDTQ2irkfo2PVcZoojB4ffULlcgHf/AlZli6/jtzeaoKaR44BJkylwVove7aRm+3CywaWc9Q44Pb7yb12z7fIHXXNt4MDTuEIsghefQsdx06KfP2hZMkFFCLy9K+DLq1QOCe34dRZ+sTAmInUDiuP0t/NjWSh1PuZfPIKihl87e/kgbnzBgqUPvQhtf2XnqH2psRWxhRRiZCRSYYC5qLfe7vJ+hZKfQ25VSsPk6gyAiHYQl120Rgm4h6byVqamU2W66wcMsSI+C/OqQ/NyOx/xlo+J9WtQ7j1OOcfcM7vCHuvBRRwvhXAuZzz5kEXiMb4KdFnA4LSMup42ltptl5+lrpru1xkmao+QY3XTAIBCoSetcAcS5MeXG4Kxn9/e9A3bhYH9lLMwJgybf9/4aUUePqfFyjuIdvAAVYPC1cAP382uuAvm0oxH2oWBsTimDL4xetkp82hNlfxvr77xePkUYrHs1qbjoXbTVbCk0cHBiC3NtHna7R1LRHEAFRbBTTWBldPGU1eAQVC6+WNl2gyO2Pe4PdyC4Abv0+D1hVfHWztLikla0ykQGsrkJFFlrIjFcCmCHP/UydIRKqxRsVCfJdPKN/tE4eU1ydGPl8t2cPI5bj2fuD7vyJBsH0zWWP/+RSJhs9dq+8e8UhX3Gpi1WFnB4mTrg4S/YEAuQqNoEuJyXKr8HSkpVP8Y6OyGlRM1Bij37s6KL5KrMDVucrWsMAhznkj5/xZznm1UdfsZ2wZVfqNV+hhTVEppAAKQASCQZxm0dpMZUyGr1gLU2eSiDp+yNz7HNxLcRpaB96xk6isnFNAt5WINSsdP5naZuURffc4/hG5CEaOjX3epGnUqXzwP333i0fVMXIp2Q1hQWtpomN3F8UKcp58t14oHi+QXwgc2k/tJdQVYyS5BcEl3FpprCML3pILoq9+HjcZuO+pyJZaOzBvGVkFd20d/N7W/9BRr5AqGkEWEdH3CkuhXiEF0ARu0jSKlRs7iVZHVp+ghUX3PGn+eORLo76+oZYEYk0lhXYEAhSjBAA93VizZg1mz56NhQsX4rLLLkNvb29Ct6muqsL6B34eFG5qKBpBsbYFwwcIpfc+OozFl67C0qVLcded6wAw3UJqSDKbJ0ypYt34919JaSYipMZNohng0QPAzPnmlA+g2SVAD86KlE2l4+H9JHTMoKuDBl69cVgrV5Egm73ImHIlg/FT6Hj0QPCz1sKxQ8oKrjhfTa+P4u4+eE/7veLR0UaD6ajx5t3DLLJz6ShWsb78LH1Wa27Wbi01iqIS4NAHyu8mCam8ArJQdHdpX2CybTMJz3hB+VaKfUoUxmglYk3lwNfffZ1cYwuWB2MV9dxjTBkJqROHyYpcPNJ49/LM+WSJYoxcetHE758fMXZCLXKCXfolJe+X8p3LzAKavdQGATz00ENYsmQJrr76amzcuBErV0aJ8YtASX4u1n712sGB5bHw+oDcwa7wR373GP7+u99g+MhRmL70XHxjzVXI1ZkmyR6bFpcoidvamoGz5iWWeC8tndT6EZMtUg1CSBWZex+t5BWSG+HwfvPuIZbEx0leFpfpc4Bf/NWYGVuyyC+i1StHE89DO4DjH6mv99SZNPvUmv8oHiLQ3I4WqRxFSLUqnfqp45QWY8mFQ1cmQeGIoIu9wCTXnligoccq9e5/ydJaUmpMmaxKfhGlHQjl1b+R+FlzszH3GDuRXIh33UCpWMZNNua6oQhDwaTp+vvgRPB4yV2WVxi0QnkVF5wvbUC4A+ccbW1t8Pl8qKmpwcqVK7Fo0SLcfffdAICamhosXboU8+bNw+rVq/G73/0OAHD08CGs+dZawEPCqKysDEuWLMGqVaswa9YsvPTSSzhw4ADOPfdczJ8/H08++WTU4v7m0UcxfMw49LY0oa+3F5nD9cd/2sMi5XJTcOPRA9oCucdPoWA8vVlPYyESx1nVtQfQSkcRtG8GXUpSvUTMr9GIlm3XqjBGg84xHUKqr4+sQGrbkIg9OVJBS+qNRiwZHhXHzWhFwoVU/WnrfDdDrVBmxUiFCiktefROnSCrxarrjC2XFckvUjKld1DfxTnlpFt8fuzdNRJh9iLKcbZ0JbVDM7wCYyfRfcSK9WiYmU8wK4cC6cXKv7R06tM4x9e+9jU0NDTgoosuwvLly3HzzTdj1apVWLNmDebPn49rr70Wb7/9Ni688EKsWbMG119/Pb785S/TdQJKmiYlvIJzjieeeALXXHMNfvazn2HLli149NFHsW7dOixatAizZ8/G6tWroweOZ2bh/nt/is9fcjG8efm6q20PIQWQGKo6RtmntfzvW69Sgr0RJiXnbKilL53owK1I2VQKRmyqN2fGIjI7J2J+TSXGT6HOUqs7Rczc1Fpcx08ht/Xh/eYIqYbTSnZ+iwiQRBCJWoWbobGWXKZWQAip7Fzz8rrptUidOEzHabNjn5cKCC9CYz0wMpP6x+5OYy1xU84CfviocdeLhMtFwf9DictFFmyR8FL0ZQE/HnroIWzZsgVpaWlgjKGiogLvvPMONmzYgPb2dlRVVaGsrAw/+MEP8PLLL+POO+8MXlck4FWE1Lhx4+B2uzF+/Hi43W5wzlFRUYF169aBMQa/34+mpibk50cWSe/u3oOXNr2JjS/+c3ByTi3V1n2FZHHxauD2B7RZKmacQx/Wm68YXy5BY62yIsfC8QJiSb3egOhoCItUms2sSUYxbjJ94bUuO+8VQkrl4JqeobitY6dt00xDHQ3IdlqxF0pOLlmkento1a5VBKEIMDfLGgUEJ0paV+61KkH6OQYk9LQ6/UJKCc8QW4+lukvTLFzu4Dgo0nUoaUiuu+46PPbYY/D7/SgvL8f69euxadMmrF27FgUFBXjhhRfw+OOPY8uWLVixIiQ2z++nLPExxtfy8nJs2LABmzZtwk033QSfL3KqkKNHj+KGG2/Cn577G7wGfQftI6RycrUHiRaOAOYsoqW83QYtxQynoda68VECsTLBrM9A5Pmwm1vOKMYrcQ8iTqq3Z+D+a/EQFqlENkAtm0pCSuUOBQnRWGf9Nh2LbEVINSnxL2bFIyVKURKEVPYwilHRapFqbaZByyrpR8wk1CIFkFsPoJyAEn2ISZjSP+Xn52P58uV47rnnsHbtWtx3331YvHgxXnnlFYwYMQJnn302Lr30Upx33nm46qqrcPKkImoDHPHkyvr16/GVr3wFCxYswJEjR5CVFXkl3m233YaGhgZceeWVWLZsGSoq9E9E7ePa08uKS2h/o+2bzQk4bayLnL3cSggzq1m5pIyMkbIjeYX0c/QAdcY/v4MGou8+qM5SKYRUWgKLKSaUk6W15qTxM+jGOnsGmgtycskSJRaCFFhEFOYXk1g2cw9QxpS9+HQIqaxh9rVGJoKw3ok41+pK6iuTGbCdqrhcAGPY8MsH+y3CDz74YP/bL744MH/X9u3bMXHiRLjdbjQ0NKCpqQmjR4/G+DGjseEXP+s/b9OmTQCADRs2AACWLVsGANi4cWPcIj3zzDM6KhQZ5wipSdPJTfHhLuOFVMBPs16ruA6iISwdepNGRqPL4RYpgKxSB/fSfnmtzbQdwYnD6lbi9VukEhBS5TPo+MH/jBVSnJOrYyiTV+olO5eScjacpr+tYpFyu2kfyuE6l9XHQ08uqbZma8d7GokvjSx4oUJqRGnyNuJNdVzuwTsMRGFAXFQoAb+ln4d1S2Y0jFHiMpG/xUhamsiHa3U3iLBImSakhEXKwUJq3GSygHS00cbabg/tqaaGRIPNAcrfUlIK7I6QUFAPIgeR1dt0LESMVL0FU5OUldPgbSa5OrKbtzpISAFKCgRFSNVUpmR8FDfD/a8GlzvyFjyJEAgkzTqq5XNyjpACgInTaH+rpvr45yaCyONj9Y5HWKTMdO15vInF+KQaYjPti66kPE8z5gHbXlfXkYjnkoiQAoAZ8ynJXyLxWPEQg4qVxEei5OTSZ1p9wtwVclYlt4D6Oi0DqNOEVF4h0KRsJ1JXY97q7iEiPT0d9fX1QyOm3C4DhFRyLFKcc9TX1yM9PbG+wjmuPYDcewDw0QfBzUONwK9s2Og2KOeIWZjt2uvucLY1CqDl4t+6hzaKBsg19t7bFMgaL7hYLAJIVEjNnA+8+hyw73/A2QZtmJ0qQgqgVZRWiY9KJqXjgc0vkns50ezcrc3B7PBOIL+IYht7emjlrc4tQ6xGaWkpKisrUVtbm/ybtyoem8Y27ddoqKWJUK3Je+aCRGdpaWIWSWcJqbETaZAyXEgpaltnmnnTcblITJnp2nO6kGKMLFECIZ4a6+ILKa0WKTFBqDxinJCyWoC2FoQQOFVJm4k7DRE/V7EnMSEV8APtLbQZsVPIzKZVx70aVs7aAK/XiwkThiiP2oYHaM/G+57S9v9+P3DdzcCnv0A/FsRZrj2Ph5LyGZ1Hqd8iZQNd6vWZ59rr7HBuDqlo9C+trot/rpb0BwAJeF+asWktGuuUlV82XrkkLFI8AHzMAlvDJJuRYykP1P7dif1fWyu5A53k2vP6aM84rd9BSXSycoLbh2lBpNUxem9CA3GWkAKoc9DzUCNhF4sUMGjvI0Pp6nRu6oNo9C+tVmFS70kwIWcoaRn6hNRbrwIpb2H6AAAcvklEQVTfvy54jcZa2jcr3ubJVkYIgWlzaI9Op8EYWaUq9iQWJyWScTrJtSeEU0f7wL8l+snKocm71nGnQxmvLexudZ6QytSpjiNhJ4uUqUKqw7nbw0QjM5s+80QsUonkkRKkpdO2FlrgHHj5WdqC6a1X6e+D+2h/SztTVAJ86gpg9desveOAmZTPoLZXe0r9/4j9CZ1kkRLudDE2SCFlHFlKUlet464Qt1nSImUdsnJoabqR2ElImenakzFSg2Fs4NLqWPR00/laNkpNS9dukTrwPuXOSUsHXvs7bbxccxI4Z6m261kFlwu45IuJB1qnEhOn0vFYAtsWtTlQSAnhJIWU8QghJVa3J0qnMl5L156FyMomy0lfn3HXFK49j8Nde91SSEUkvzi4/UQserqpA9diPUlLB3o0CKmAn6xRmdnA6q+T5eKRH5Obes7ixK8nsRYjx5KgPJlAXGi/RcpBweZiXzYxyU50wYckOkZZpKRrz0IIVdtpoFVKWqSIrg4ZIxUJtRap3m7tHbhPo0Vqw89pRc2nvwDMPxdY9inKozNtjvkJIyXm4/VRlu5EFtgIIeWk5y92ExBCymvxVDZ2QrQjzULK+hYpG4z8BtOvjtuMm3HZKtg8HWhrMv66nEvXXjTyC4HmeiWpXIw20q1DSKWnA/UJdlS11cDbrwEXXkp7UQLAlTdSmhCr7xspUc/o8ZQjSS2tTdRP2qE/M4pBrj1pkTIM3RYpIaSkRco6CFVrZJxUn40sUj4fJZ0zmu4uElNp0iI1iPwiEtstcQRsb49Oi1SCweb7d9Fx8QXB1xgDlq4ERo7RVg6J9SgdT0k51Wa+b2miFZtOQrj22oVFSsZIGUao8UILHW0Ac1na2+E8IaVXHUdCuvaCnbRctTcYtbmkerq0z4S1BJvv300D5six2u4psQejlUSMJ4+pO7+l0VnJOIHBrj2fFFKG4UujBTR6YqQyMi298taBQsoEi5StXHtp2oKS4yE3LI5OnlohpcO1l2iwOeeUX6h8hqU7KIkBlCpCSm2clJMtUiJnkUcKKcNgjMbdDo1Cqrfb8vtkOk9IZTrcIuVLM8e1J4VUdISVLp7rradH+0xYBJurTbxYc5I2tJ06Q9v9JPZBbE2kdrN2J1ukxLggLVLGkp4ZzFCeKH19lh9bHSikFIuUoULKRhYpb5q5rj0L+7GHDJEXqrc39nl6LVKBAG1zoYYKZduQ8pmxz5PYH5eL2mC89gdQ39DZ4VyLlIyRMgePN2hwSJS+PsvvsOA8IeXx0HYawrV34jDQ2a7vmraySCl7SgX8xl5XWqSiIzrleCKnt1vb9jBA0PStNk5q/x7avmbEaG33k9gLj1edyG5ppKPTLFKekFV7zGWPvtxOuN3aczf6pUXKmohNFF/4A3DXDZSQUA92ElLChG20e09apKIjLFLxBjKRkFMLiQgpGR/lPLwqhVSzsrLUqRapznb6rOT3wlg8XsCv0loejg2ElLVLZxZZ2cDud4PuvZqT+q4nXHsuG+hSsY9bb7ex1iOR/t9JSfzU4k3Atadlnz0gMSF16jhZHqZKt55j8HiBPhWTp5YGOjrNIiUmmJzLrOZm4PYEx8lEka49i5KZTSLK4wUmTlOXdToWQjHbYRYjLB5GW6SEKLVw0rQhQ8ymVFmkdOSRAtSt3NuvxEdJIeUc1MZItTjUIuXxBCfCMj7KeNwe9fGb4fj7tO0/mkScKaRELqkpZwElpUBDrb7r+f32CDQHgrOtXoP322tvJYEaK3O3U1ET7Mu5/mBzIBirFou9O4CiEUBRibZ7SeyHWteeU2OkgOAkRgop4/F4tMdI9fVZfnx1ppASK/fOPBsoKAaaG/RtYmwDH24//RYpE4SUEKiSwcQL9hUrKfUKqXgWqa4O4IP3gFmL7GFBlRhDIhapzGxnigkRJ+XEupuNR4drz98LuKVFynqIAf/MuZR1mnMSU1rx++0jpHwmBZtLIRWbeEKqxyAh1R1HIO/dQeWYs0jbfST2JJFVe060RgFBASWFlPG4PTqCzf2Wj5GydunM4uwltPx/5NigW6+hNpi4LlH81jc99mOma08Kqeh4vbHzdwlLkm4hFcci9d47QHYuxQZKnINqIeXArOYCIaBksLnxuFPbtedMIVU2lX6AkH3QdMRJ2dG1F89ykSjtrUDxSGOvmUqode3pTX8Qz7V3cB8wbZblOyaJwXi98TNLB/xATaVzk7QKAeW1thvJlrg9OhJy9spgc8tTUExHPQHntgw2j2Adees14NnfartuW4tMfRCLeMG+ImZN62zYpyLYvK+PVqgOl0k4HYfXFz9G6oP3gOZGYM7i5JTJavS79qRFynD0BJvbIHRGCqmMLNoLTZeQspFFqj9GKswitX838MQDwH+eT7zBB/yUyE669qITL9hXWJK0bs7pS6Pg8VgWqaY6gAe0u7Al9kWNa2/Lv2kyNHN+cspkNXxy1Z5p6A02t3iMlBRSAJBfrC+XlJ0sUqKTCLdIPf0wHf1+oO5UYtfs6KCAfSmkouOJFyOl07XHWHDj4mjU1dCxaIS2e0jsSzwh1dlO8XMLljtXSMhgc/PQE2yeKpsWM8YeY4y9wxi7I8r7HsbYccbYJuXnLGOLaTL5RTqFlPUfdD/9FqmwAbepHhg3mX4/dSKxa7YrWc2lkIpOvIGsW3HJpenINp8WR0jVn6ZjgRRSjiOekK+tpn5s8pnJK5PVkELKPPQEm6eCa48x9lkAbs75QgBljLHJEU6bAeBpzvky5ed9owtqKukZ6jJCR8Nv/RT2/UTKbM45zUgnlNPfCQspJau5FFLR8friCCml/aVrdO0BKoRUDVmuCoq030NiT+LF6DUpE8m8wuSUx4r0r9qTQspwPHqDza09vqqxSC0DIHb1fRXAkgjnLADwKcbYNsV6NajWjLFrGWM7GGM7amt1ZhI3GrXJ6qJhJ9eex0u7m4emP+juAgIBCrzPKwSqpZAynHgDWZcBFilfWnyLVG6BnHE7kXh9XJOSR8/JQkrGSJmH20NjTEBDnJQNDBVqhFQWALGrbwOASH6B7QBWcM7nAfAC+ET4CZzzRznncznnc4uLi7WW1xzU5liJhp1ce4wpA26IkOpoo2NGFlAyBqiuTOyacsPi+MRzrSTFtVcDFEq3niOJ18eJ0IbcguSUx4pI1555CCGUaMB5wE8eE4uPr2qEVBsA0btnR/mfPZxzEaG8A0Ak95910S2kbGSRAoDsnGBcE0BuPYC2hhhZSq49ztVfT1qk4hM3Rkrnqj2ARFh3jPQHdTVyxZ5T8XhpwhcIRH6/qR7IybP8zN9UpEXKPMQWL4m690RcVQoIqZ0IuvNmAjga4Zw/MMZmMsbcAC4BsNuY4iUJtRt6RsMGqwoGkJ0LtIYIqQ5FSGVkkkWqsz2xLXPaW8nSlZllbDlTiXh5fLo66Rw9gjwzK3rSxYCfks7KFXvOxBtnIGuqB/Id7NYDZGZzMxH9WqIB5+J8iwt8NULqeQCrGWP3A/gcgH2MsR+FnfMDAH8AsAvAO5zzjcYW02R0x0jZTEjl5AJtzcG/Qy1SBYrFIlEhlZEFuGxklUs2aixSetx6AD0D4aYNp7GeLKfSIuVMPCLtSZQ22FTv7PgoICikLJ5F25Z4NFqk/PawSMUtHee8hTG2DMD5AH7KOa9GmMWJc74XtHLPnohBjnOyrCSK7Vx7wwYGlAshlZEFdCkWjfCEnbHoaCMRJomOmvQH6QYIKfEswzl1nI4jx+q7h8SeCItUtDbYVB9ctetUhCVKWqSMR6tFym8Pi5Sq0nHOGxFcuZd6hKplLbMRu1mkorn2MrOC8U7xNr8NpcsAEZDqxNu0uKtTX3wUQM+vp5s6q/COp+oYHaWQciaiX4vUBnt7gNbm4L6jTkUGm5uH6I8Sdu0pwt9tbSuhzGwOxJ+txcOOFqnuzmCn2hmyak8M5okKKb1uqVTH64u9/Le7yxiLFBC0KoZSdZyCiXNy9d1DYk88Mfq4lkY6OnnFHhDMHyWFlPFoDTYXq/wsPr5KIQWEzNa0CimbWaTEYCrSFnR00Gfg9QU3v03EtdfVIS1S8YjXxroNEKMZmXSM5N6rOgaMktYoxxJrsthYT0fHW6Tkqj3TEEIo4VV7Snu1eNyaFFJA7NmaGmyQwn4AIt9TqxJw3tlGgzBjQFqULWRiIV178YnXxoxw7QmLVLiQ4pxipKSQci6xhHyTIqScHmwu+jBpXTcerWOssEhZPEZKCinAACHVZ3nT4wD6LVJCSLUHg8V9Glx73Z1AeqZx5UtFYsWoAMYFmwPBmDdBYx2lRRg1Tt/1JfYlVh/XoOzBmG+xRMnJZuosYM3NwHh7pUG0BVoTcvbnkbL2+GptmZcsvA5z7QmLVL9rrz3oFhIrVmSwubHEi8PrMiD9QWYUi5QMNJfEElJ1NfT9z3L4yluPB1hy4VCXIjUR42PCFikZbG4fDHHtWVsxDyA8RqqzHchQOlGPhxq92hgpzqWQUoOIu4jWxroNdO2FW6Tqaug4YrS+60vsS6z2V1cNFJVoS/0ikahBCCmtwebStWcD9Agpzu1nkcrMoU5TxEh1tA/MSh5vz7ZQeroBHpCuvXjEilHx+8nlZ5RrL9wiJfdClMSyugshJZGYhVYh1Z/+wNrjqxRSgL70B2LvKjtZpNxuiokKjZHKCBNSaoPNu5S93aRFKjaxhJQR++wB0YVUewtdW65Gci7RYvQ4V/ZglFsHSUxEcx4peyTklEIK0Jf+wCYp7AeRPSyYlLOjbaCQ8qWpd+1JIaWOWFZPsdGwXquex0PPLny/vbZWuaG004nW/lqb6bsu92CUmInWYHObjK9SSAH6XHs2edCDyM4ll09fH3Wkoa49XwKuvW5l0JZLhmPTH6MSYdWeEFJ6LVIABQ0Pski1AlnSredoovVxddV0lK49iZloDja3x/gqhRSgU0jZI/PqIHLzgZpKcvsAYa69NKBbWqQMJVYb6xKuPQM+w4zsyK69bGmRcjTRwheEkCqWQkpiIh6tMVLStWcf9MRI2UQxD2LhCsov9PTD9PewvOB7vkRipBSLlAw2j02sYN9uA8VoZtbgVXttLdIi5XSihS8IISVjpCRmonnVnj3GVymkAJ0xUja1SM1aAIyZCOx4k3Z9n70o+F4iq/akRUodamKkTHXtSYuUo4nq2quhdCjy+ysxE7cMNk99nBgjxRhwxfXAGbOAG743cEWXpmBzaZGKSSyLlKGuvayBQioQANrbpGvP6UTr46qOASWlyS+PxFloXbXXP77KhJzWxxMnWWIs/PZQzBGZchZwy/rBm5UmZJESrj05o42JqlV7JgipznbK8yVde86GMWqDoUI+EAAqj5JlWiIxE9H/aXXteazt8ZFCCtC3RYxdXXux8KUnbpGSq/ZiE0usG5VHClCEVEj6g7ZWOkrXnsTrHdj+6qppIlQ6YejKJHEGYnzUGmxucY+PFFJAiLUgyoaysbCray8WaWk0uHMe/9yuTnIFppKQNANvlISIQIgYNUBIZWaRCBYDZrsipGRWc4nHO7D9nThMx7HSIiUxGZcbYC6Z2TylcSsPWYtrry8FLVJp6eQOUvN5dHVIa5QaYqY/6KT3PQbEAYh9FMX2PyK9hYyRknjCLFInDlO/N2rc0JVJ4hzcbg0xUn7A5aIfC2Pt0iWTcLO3WlLRIuVTLCNqckl1d8n4KDW43dQZRHIfh2/Ro4dhBXRsbqSj2GdPuvYk4UKq8jAwspQsyhKJ2Xi8GoRUrzETTJORQkoQHoiplpQUUkrHqiaXVFeHFFJqCR/IBJ1tAzPL6yE3n44tDXQUrj0ZbC4JnywePwyUlg1deSTOwuPRFiNlg7FVCilBtEEuHv3B5tZ/2KoRsTpqVu51dUohpRaPl9wpB/YOfL3DQIuUEFLCItUvpLKNub7EvoROFpsbgIbTwPjJQ1smiXNwuzWs2vPbYmyVQkqgWUilokVKEVKqLFKdQJrMIaWK9Azgw/eAX9wxUKR2tgOZBgmdYWFCqq2Fru1KoRg+iTZC+7hDH9Jx4hlDVx6Js3BrGGP7em2RWkgKKYHmGCnFImXxPBcJkaa49tTESEnXnnqu+TbwmTUkot7fFny9o50ykhuB10fCqUVYpFpkfJSE8PqCk6NDH5KwGjtpaMskcQ4eT3C8VIu/TwopWyFjpIKkJWCR6uwwLr4n1SmfAay8jNxv2zYHX+9oM84iBZBVSgip5kYgr8C4a0vsS0kpcPIoEPADhz+ktAehOxpIJGbi9iRurPDLGCl7odu1l0IWKZ/KGKlAAGhrBrJzzS9TquByA3OXAnu2BbPCd7YbK0aH5QVde031QG6hcdeW2JcpZ9HE58gB4OhB6daTJBctFikZbG4zZLB5ELUxUh1tJKaG5ZlfplRi6ixqa9WVdOzpBjIMtEjlFgQtUk0NQJ4UUhKQRRQA/vFHSsw5cdrQlkfiLNwebZsWS9eejYgVI9XRDrz8F2DX1sHvpaRrT2WMVEsTHXOkRSohckNyPYl98Yy0SOXm07W7OmgfP+nakwAkqIePAvbtBAqGAzPnD3WJJE7C7aG8UIlgE9ee9UuYLDze4FYdoXR1AuuuAxrrKGj3nicHBlen4l576Urgs0jmGI1WKaQ0IYRNcwOJdMC49AcAxUh1dQA1J5X7SYuURGHKWcDpKuCiz8v4KElykcHmDiCaa2//LhJRn7yccvJsfnHg+6lokUrPoMDUw/tjnye2IcmRrr2EEK7Q5gZyjwLGBpuLXFLHD9FRCimJ4OOfAJauBBauGOqSSJxGpGDzXVuBX95FISKR6Ou1xdgqhZQgmpDau5NWsV10JXDGbODV5wY+9NZm2q/KiA1nrcSk6cBH+6I3cCBokZIxUonh8dImwqa59hSL1/GP6ChdexLBhHLgqv+zxSxfkmJ4wmKkOAeefwLY9Q5QfSLy/8iEnDYjUowU58De7cAZs2jwm38uDX7VlcFzTh4FRoxKPTP55DPJWlJ1LPo5IkZKrtpLnGH55rn2CorpuH8PHaVFSiKRDDXusC1iDu4DKo8Ef4+EDDa3GZHySNVUAnU1wPS59LdYLnz4w+A5VceA0eOTUsSkMuVMOh7cG/2ctmaKG0ul+LBkkVtgnmuvZAzFrZ06DqRlBGPeJBKJZKgQQqq9FVi7BnjgO9TvZecCH30Q+X/80rVnLyK59j7cTcdpc+g4YjQ9eLG9Qk83BW6OGpe8ciaLohIa7P/xFPDkL8g6F05Lk4yP0kquYpEyw7XncpEVFQDypTVKIpFYAOHae+1vQF015dP7wk3AZCWMJBJ+v7RI2YpIQuqjfTTgDR9Jf7tcQNnUYBB29QkSGKlokWIM+NxXgOIS4I2XgdpTg89pbZbxUVrJLSA3cUebEmNn8DY7UxUhJd16EonECng8JKBeex44ewlwzbeAectISNWeouTBoQT8NMbYwKIuhZQgUozUoQ8paR1jwdcmnkHuvI52io8CUtMiBVBM2Jpv0u8Vewa/39IkUx9oJTef2ltdDe2zF9rGjGDabOU+MtBcIpFYgIDi1eAB4OKrgq9PnUnHbZsGnn/0IE00RSJZCyOFlMDjJTOiWKXWVE/qeVJY9t/ymWSFWn8zsOVV+r/ho5Jf3mQxcgwFRu/fPfi9tmbp2tOKEDjVlcbGRwmKSoBzPg6cdY7x15ZIJJJEmb8MWHIBcNdvgFFjg6+PnUQr4l/+y8Bcju9vJ2v99LOTXtREUSWkGGOPMcbeYYzdoeccS+Px0lFYpUQc1KTpA8+bciZw/Xdoz7SKPeTWs4EPVzOM0YzgwPsD46T8fkrYKS1S2hBC6tRx8zZ9vu52YMFyc64tkUgkiTD9bPJwFJcMfu+SqyidznOPB8eZ97cDZeWUKsbixFUAjLHPAnBzzhcyxh5njE3mnB9M9BzLI4TUv/5EqQx2bqHXxk4cfO7cpcDZH6Olmzbw3+qmfAawfTNw21XkxiyfCfT10HsyRkobQkj1dJtjkZJIJBK7MPEMYMVngI1/B04cotXgxw4Cn/7CUJdMFWpMKcsAPKv8/iqAJQDCRVLccxhj1wK4FgDGjh0LyzF6HAmol56hv4ePAlZ/PSiwwmEMGFOWvPINJbMXAjveoJnBoQ+BvTvodeZKzUD7ZFA4HMgvoqz5YyKIdYlEInESq66l2NHtm4H2NmDx+cDyTw91qVTBeKRl7aEnMPYYgAc557sZYxcAmMM5X5/oOaHMnTuX79ixw4Dim0AgoOzv4zU+ADgV4Bzo7qLfXS7Alza05bE7gQB9jhKJRCKxLIyxnZzzuZHeU2ORagMg1mZnI3JclZpz7IHLBbhSLEu5kTA2cNNmiT6kiJJIJBJbo6YX3wly1QHATABHNZ4jkUgkEolEklKosUg9D+BNxtgoACsBXM4Y+xHn/I4Y5ywwvqgSiUQikUgk1iJujBQAMMbyAZwP4A3OebXWc0LObQVQkXhxU4YiAHVDXYghwsl1B5xdfyfXHZD1d3L9nVx3IDXqP45zXhzpDVVCymgYYzuiBW05ASfX38l1B5xdfyfXHZD1d3L9nVx3IPXrLyNdJRKJRCKRSDQihZREIpFIJBKJRoZKSD06RPe1Ck6uv5PrDji7/k6uOyDr7+T6O7nuQIrXf0hipCQSiUQikUhSAenak0gkEolEItGIFFISiUQiMQTGWAFj7HzGWNFQl2UocHr9nUrShRRj7DHG2DuMsTvin21/GGMexthxxtgm5ecsp3wGjLERjLE3Q/4eVO9U/SxC6x6pDSivp1zdGWO5jLGXGWOvMsb+zhjzOey5R6q/U559PoB/AZgH4HXGWLHDnn2k+jvi2QuUfu895XfHPPukCinG2GcBuDnnCwGUMcYmJ/P+Q8QMAE9zzpdxzpcBmAwHfAZKp/IEgCzl70HPPlXbQ3jdEdYGOOfvp2rdAVwJ4H7O+QUAqgFcDoc8d4Xw+q+Fc579DADf5Jz/GMC/ASyHs559eP2/BOc8e8F9ADKc1N8DybdILQPwrPL7qwjuz5fKLADwKcbYNsbYYwBWwBmfgR/AKgAtyt/LMLjekV5LBcLrPqANMMY8SNG6c85/zTl/TfmzGMAX4JznHqn+fXDOs9/MOd/KGFsKsspcCGc9+/D6d8Ihzx4AGGPLAbSDJhDL4KBnn2whlQXgpPJ7A4ARSb7/ULAdwArO+TwAXtBehCn/GXDOWzjnzSEvRXr2KdkeItQ9vA18AiladwFjbCGAfAAn4JDnHkpI/V+Dg549Y4yBJhGNADgc9uzD6v8eHPLsGWM+AN8DWWABB/X3QPKFVBuADOX37CG4/1Cwh3N+Svl9B2jPIad9BkDkZ++U9hDeBiYjhevOGCsA8BDIteG45x5Wf0c9e07cCGAPgEVw2LMPq/8oBz37tQB+zTlvUv521Pc+2RXZiaA5byaAo0m+/1DwB8bYTMaYG8AlAG6E8z4DIPKzd0p7CG8Du5GidVdmpn8BcDvn/Bgc9twj1N9Jz/42xthVyp95ANbDWc8+vP6POOXZg0JWbmSMbQIwC8BFcNCz9yT5fs8DeJMxNgrk4lqQ5PsPBT8A8CcADMA/4MzPAIhcbx7htVRkQBvgnG9kjA1Datb9GgBzAHyXMfZdAL8HsNpBzz28/q8D+AOc8ewfBfAsY+zLAPaCvvNvOOjZh9d/KYCn4IBnzzlfKn5XxNSn4aD+PumZzZUVTecDeINzXp3Um1sEp34Gkert1M8CcE7d5XMfjFPqL5/9YJxSfyc9e7lFjEQikUgkEolGUibYSyKRSCQSiSTZSCElkUgkEolEohEppCQSiUQikUg0IoWURCKRSCQSiUakkJJIJBKJRCLRyP8Hph+a4jiX33AAAAAASUVORK5CYII=\n", 571 | "text/plain": [ 572 | "
" 573 | ] 574 | }, 575 | "metadata": { 576 | "needs_background": "light" 577 | }, 578 | "output_type": "display_data" 579 | } 580 | ], 581 | "source": [ 582 | "_sp = pd.DataFrame(model.smooth_probabilities())\n", 583 | "fig,ax = plt.subplots(2,1,figsize=(10,4),sharex=True)\n", 584 | "_sp[0].plot(ax=ax[0])\n", 585 | "_sp[1].plot(ax=ax[1],color='tomato')\n", 586 | "_ = ax[0].set_title(\"Smoothed Probability\",fontsize=14)\n", 587 | "ax[0].legend([\"Regime 1\"],loc='upper right')\n", 588 | "ax[1].legend([\"Regime 2\"],loc='upper right')\n" 589 | ] 590 | }, 591 | { 592 | "cell_type": "code", 593 | "execution_count": null, 594 | "metadata": {}, 595 | "outputs": [], 596 | "source": [] 597 | } 598 | ], 599 | "metadata": { 600 | "kernelspec": { 601 | "display_name": "Python 3", 602 | "language": "python", 603 | "name": "python3" 604 | }, 605 | "language_info": { 606 | "codemirror_mode": { 607 | "name": "ipython", 608 | "version": 3 609 | }, 610 | "file_extension": ".py", 611 | "mimetype": "text/x-python", 612 | "name": "python", 613 | "nbconvert_exporter": "python", 614 | "pygments_lexer": "ipython3", 615 | "version": "3.7.3" 616 | } 617 | }, 618 | "nbformat": 4, 619 | "nbformat_minor": 2 620 | } 621 | --------------------------------------------------------------------------------