├── data ├── pca_dates.xlsx ├── parameters_data.xlsx ├── pca_model_dates.xlsx └── data_xrates_yields.xlsx ├── imports.py ├── README.md ├── forecasting_model_scores.csv ├── random_walk_scores.csv └── main.py /data/pca_dates.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asaficontact/FX_forecasting_model/HEAD/data/pca_dates.xlsx -------------------------------------------------------------------------------- /data/parameters_data.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asaficontact/FX_forecasting_model/HEAD/data/parameters_data.xlsx -------------------------------------------------------------------------------- /data/pca_model_dates.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asaficontact/FX_forecasting_model/HEAD/data/pca_model_dates.xlsx -------------------------------------------------------------------------------- /data/data_xrates_yields.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asaficontact/FX_forecasting_model/HEAD/data/data_xrates_yields.xlsx -------------------------------------------------------------------------------- /imports.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | import seaborn as sns 5 | import warnings 6 | warnings.filterwarnings("ignore") 7 | from statistics import * 8 | from sklearn.decomposition import PCA 9 | from sklearn.preprocessing import StandardScaler 10 | from sklearn import preprocessing 11 | from sklearn import metrics 12 | from scipy.stats import pearsonr 13 | import itertools 14 | import math 15 | import tqdm 16 | import datetime 17 | import calendar 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Foreign Exchange Forecasting Model (for the paper): Can Interest Rate Factors Explain Exchange Rate Fluctuations? 2 | The level, slope, and curvature of the yield curve are known predictors of excess bond 3 | returns and economic activity, reflecting time variation in investors’ risk premia. In this 4 | paper, I develop a term structure model under complete markets and no arbitrage that 5 | describes exchange rate fluctuations as a function of these interest rate factors. The Gaussian 6 | properties of the stochastic discount factors imply non-linearities in exchange rate risk premia 7 | that can account for up to half of the in-sample variation in one-year currency returns for 8 | different country pairs during the 1980s–2016 period. Interest rate factors can help explain 9 | exchange rate fluctuations in and out of sample, particularly at longer horizons, and yield 10 | profitable currency portfolios relative to standard carry trade strategies. 11 | 12 | ## Understanding the Code Files 13 | * **main.py** contains the code for foreign exchange forecasting model. 14 | * **data** folder contains all the data files required for running the forecasting model. 15 | * **imports.py** contains imports of all python packages necessary for running the foreign exchange forecasting model code. 16 | 17 | ## More Info 18 | * This code reproduces the out-of-sample forecasting exercise in Section 7, following Equation (B.37) derived in the [Online Appendix.](https://www.sciencedirect.com/science/article/abs/pii/S0927539821000050) 19 | * **If you use the code, please cite the paper as follows:** 20 | Yung, J., 2021. Can interest rate factors explain exchange rate fluctuations? Journal of Empirical Finance 61, 34-56. 21 | -------------------------------------------------------------------------------- /forecasting_model_scores.csv: -------------------------------------------------------------------------------- 1 | ,,root mean squared error,median absolute error,accuracy classification score,f1 score,precision,recall 2 | AUS,one_month,1.2409265281745607,0.688254227516444,0.6052631578947368,0.4827586206896552,0.5384615384615384,0.4375 3 | AUS,two_month,1.3599549663423274,0.9287709693234063,0.6052631578947368,0.4827586206896552,0.5384615384615384,0.4375 4 | AUS,three_month,1.36622924716258,0.865357290770102,0.6052631578947368,0.5161290322580646,0.5714285714285714,0.47058823529411764 5 | AUS,four_month,1.3405707482015392,0.7598403898933901,0.5263157894736842,0.47058823529411764,0.5333333333333333,0.42105263157894735 6 | AUS,five_month,1.2279614019218625,0.7774304917572148,0.5789473684210527,0.5294117647058824,0.6428571428571429,0.45 7 | AUS,six_month,1.1808715627981927,0.8197681436593693,0.6578947368421053,0.6285714285714286,0.7857142857142857,0.5238095238095238 8 | AUS,seven_month,1.185342972766167,0.7601537342058382,0.6578947368421053,0.5517241379310345,0.6153846153846154,0.5 9 | AUS,eight_month,1.1365869061647522,0.49667348734806643,0.631578947368421,0.5333333333333333,0.6153846153846154,0.47058823529411764 10 | AUS,nine_month,1.10349118318828,0.6960534040295829,0.7105263157894737,0.6451612903225806,0.7142857142857143,0.5882352941176471 11 | AUS,ten_month,0.991514001525989,0.48326484673089665,0.7368421052631579,0.6875000000000001,0.7857142857142857,0.6111111111111112 12 | AUS,eleven_month,0.8579290605236181,0.4997833033105449,0.7631578947368421,0.7272727272727273,0.8571428571428571,0.631578947368421 13 | AUS,twelve_month,0.8364245664819715,0.516485112968291,0.8157894736842105,0.7878787878787878,0.9285714285714286,0.6842105263157895 14 | CAN,one_month,1.436493353794607,1.026191252506992,0.39473684210526316,0.41025641025641024,0.32,0.5714285714285714 15 | CAN,two_month,1.568567925959234,0.9806211466093866,0.3684210526315789,0.4,0.32,0.5333333333333333 16 | CAN,three_month,1.6470962348493388,1.0832783586799195,0.3157894736842105,0.35000000000000003,0.28,0.4666666666666667 17 | CAN,four_month,1.7055975732609066,1.0263378479554839,0.3157894736842105,0.35000000000000003,0.28,0.4666666666666667 18 | CAN,five_month,1.702817240586828,0.9877629197901037,0.3157894736842105,0.35000000000000003,0.28,0.4666666666666667 19 | CAN,six_month,1.7328771304741148,1.157587165017651,0.2894736842105263,0.30769230769230765,0.24,0.42857142857142855 20 | CAN,seven_month,1.7255267910673384,1.2573755752440465,0.21052631578947367,0.2105263157894737,0.16,0.3076923076923077 21 | CAN,eight_month,1.720047384180173,1.3102280809738516,0.23684210526315788,0.2926829268292683,0.24,0.375 22 | CAN,nine_month,1.698449946187906,1.2451335620498087,0.2894736842105263,0.3076923076923077,0.25,0.4 23 | CAN,ten_month,1.6182468339592135,1.0871494075654744,0.3684210526315789,0.3684210526315789,0.3181818181818182,0.4375 24 | CAN,eleven_month,1.528350790343254,1.2048856417314813,0.5263157894736842,0.5,0.5,0.5 25 | CAN,twelve_month,1.5068079242224557,0.9742834472020688,0.47368421052631576,0.4117647058823529,0.4117647058823529,0.4117647058823529 26 | JAP,one_month,1.4380743326388015,0.7812322754743326,0.42105263157894735,0.35294117647058826,0.46153846153846156,0.2857142857142857 27 | JAP,two_month,1.5085208322927794,0.8071886328628068,0.42105263157894735,0.3125,0.38461538461538464,0.2631578947368421 28 | JAP,three_month,1.525288716994546,0.878341506951501,0.47368421052631576,0.4117647058823529,0.4666666666666667,0.3684210526315789 29 | JAP,four_month,1.542041614390617,0.9888508431399189,0.4473684210526316,0.39999999999999997,0.4375,0.3684210526315789 30 | JAP,five_month,1.5082604847417997,1.007418113318837,0.4473684210526316,0.46153846153846156,0.5294117647058824,0.4090909090909091 31 | JAP,six_month,1.5078907911039805,0.7148279687891448,0.5,0.4864864864864864,0.5625,0.42857142857142855 32 | JAP,seven_month,1.4662625484392375,0.640690386505379,0.5263157894736842,0.5,0.5625,0.45 33 | JAP,eight_month,1.4583314548289572,0.7712213865223185,0.5263157894736842,0.47058823529411764,0.5333333333333333,0.42105263157894735 34 | JAP,nine_month,1.4768933115928118,0.645379134474231,0.5,0.4571428571428572,0.5333333333333333,0.4 35 | JAP,ten_month,1.4788473385184202,0.6624184150518024,0.4473684210526316,0.3636363636363636,0.4,0.3333333333333333 36 | JAP,eleven_month,1.4701313463771482,0.7693451783024601,0.42105263157894735,0.4210526315789474,0.5,0.36363636363636365 37 | JAP,twelve_month,1.468278750936091,0.6501568229723945,0.4473684210526316,0.46153846153846156,0.5625,0.391304347826087 38 | NOR,one_month,1.27514782561265,0.71444065560909,0.5263157894736842,0.55,0.4782608695652174,0.6470588235294118 39 | NOR,two_month,1.2755002071200086,0.7617601629889501,0.631578947368421,0.6666666666666666,0.5833333333333334,0.7777777777777778 40 | NOR,three_month,1.222564894750119,0.8665571692943811,0.5789473684210527,0.6190476190476191,0.52,0.7647058823529411 41 | NOR,four_month,1.129841823559891,0.7861256138203596,0.6578947368421053,0.6666666666666667,0.5652173913043478,0.8125 42 | NOR,five_month,1.0381059894354667,0.8111257444538423,0.6842105263157895,0.7,0.6086956521739131,0.8235294117647058 43 | NOR,six_month,1.092023775226293,0.5983155744188788,0.7105263157894737,0.7441860465116279,0.6956521739130435,0.8 44 | NOR,seven_month,1.1009372707479208,0.5616853783265288,0.6842105263157895,0.7142857142857143,0.6521739130434783,0.7894736842105263 45 | NOR,eight_month,1.027651697887449,0.6368492990354317,0.7105263157894737,0.717948717948718,0.6086956521739131,0.875 46 | NOR,nine_month,0.9709165419429714,0.5337138034662838,0.6842105263157895,0.6842105263157895,0.5652173913043478,0.8666666666666667 47 | NOR,ten_month,0.899819665745497,0.6027511979177101,0.6842105263157895,0.7,0.6086956521739131,0.8235294117647058 48 | NOR,eleven_month,0.7942690043925116,0.4794079577383641,0.7368421052631579,0.761904761904762,0.6956521739130435,0.8421052631578947 49 | NOR,twelve_month,0.8668339374436905,0.6575161629504488,0.7105263157894737,0.7317073170731708,0.6521739130434783,0.8333333333333334 50 | SWE,one_month,1.457055225910744,1.122109863569309,0.4473684210526316,0.46153846153846156,0.47368421052631576,0.45 51 | SWE,two_month,1.5566349559121992,0.9524279545064603,0.5,0.45714285714285713,0.42105263157894735,0.5 52 | SWE,three_month,1.564658863617082,0.9965009952297486,0.42105263157894735,0.42105263157894735,0.42105263157894735,0.42105263157894735 53 | SWE,four_month,1.5274756880038223,0.9332406090962315,0.4473684210526316,0.43243243243243246,0.42105263157894735,0.4444444444444444 54 | SWE,five_month,1.4288014888507825,1.0813948423363722,0.3684210526315789,0.3684210526315789,0.3684210526315789,0.3684210526315789 55 | SWE,six_month,1.3666384376742071,1.3380530191592221,0.47368421052631576,0.4117647058823529,0.3684210526315789,0.4666666666666667 56 | SWE,seven_month,1.3165662420407458,1.1411902748395473,0.5526315789473685,0.5142857142857142,0.47368421052631576,0.5625 57 | SWE,eight_month,1.359645745729617,1.0118056893844103,0.47368421052631576,0.4117647058823529,0.3684210526315789,0.4666666666666667 58 | SWE,nine_month,1.294366463405649,1.0993538242992518,0.5,0.3870967741935484,0.3157894736842105,0.5 59 | SWE,ten_month,1.226775053465949,0.914145412599736,0.6052631578947368,0.5161290322580646,0.42105263157894735,0.6666666666666666 60 | SWE,eleven_month,1.1412453560598323,0.8863497433875723,0.6578947368421053,0.6060606060606061,0.5263157894736842,0.7142857142857143 61 | SWE,twelve_month,1.0889255038103052,0.958671044208828,0.5789473684210527,0.5,0.42105263157894735,0.6153846153846154 62 | SWI,one_month,1.2782776768208917,1.0450372695152328,0.47368421052631576,0.5652173913043479,0.5,0.65 63 | SWI,two_month,1.2961609865264307,0.9564076545641781,0.5,0.558139534883721,0.46153846153846156,0.7058823529411765 64 | SWI,three_month,1.327144408462548,0.9347259159279241,0.42105263157894735,0.5217391304347826,0.46153846153846156,0.6 65 | SWI,four_month,1.420728559506046,1.038617375892999,0.3684210526315789,0.4545454545454546,0.38461538461538464,0.5555555555555556 66 | SWI,five_month,1.4066524708841897,0.9755367162754391,0.4473684210526316,0.5116279069767442,0.4230769230769231,0.6470588235294118 67 | SWI,six_month,1.4641275265066531,0.9717897345747452,0.47368421052631576,0.5238095238095238,0.4230769230769231,0.6875 68 | SWI,seven_month,1.49195242363214,0.9944141032232278,0.5,0.5777777777777778,0.5,0.6842105263157895 69 | SWI,eight_month,1.4187251822099542,0.837794938654902,0.47368421052631576,0.5652173913043479,0.5,0.65 70 | SWI,nine_month,1.3454078170706052,0.8705606463901918,0.5526315789473685,0.6222222222222222,0.5384615384615384,0.7368421052631579 71 | SWI,ten_month,1.3789559586545213,0.8323580019908596,0.4473684210526316,0.5116279069767442,0.4230769230769231,0.6470588235294118 72 | SWI,eleven_month,1.3908960163253954,0.725741327955049,0.5263157894736842,0.608695652173913,0.5384615384615384,0.7 73 | SWI,twelve_month,1.38564949196922,0.5584204676248299,0.4473684210526316,0.5116279069767442,0.4230769230769231,0.6470588235294118 74 | UK,one_month,1.2145045023732204,0.9460147196238828,0.5789473684210527,0.6363636363636365,0.5833333333333334,0.7 75 | UK,two_month,1.2282702069237275,0.8726285062950991,0.39473684210526316,0.4888888888888889,0.4583333333333333,0.5238095238095238 76 | UK,three_month,1.3176505091665236,0.8411208376733109,0.47368421052631576,0.5454545454545454,0.5,0.6 77 | UK,four_month,1.3392960074193037,0.8414600865924398,0.5,0.5777777777777778,0.5416666666666666,0.6190476190476191 78 | UK,five_month,1.246551977590231,0.7503272426705786,0.5789473684210527,0.6190476190476191,0.5652173913043478,0.6842105263157895 79 | UK,six_month,1.1125846781669482,0.8580789400253874,0.6052631578947368,0.6511627906976744,0.6086956521739131,0.7 80 | UK,seven_month,1.103715553906927,0.7823148135279261,0.6578947368421053,0.6976744186046512,0.6521739130434783,0.75 81 | UK,eight_month,1.0799654953468063,0.9109779779692689,0.6578947368421053,0.6976744186046512,0.6521739130434783,0.75 82 | UK,nine_month,1.0142997940402412,0.886018291692915,0.631578947368421,0.6666666666666666,0.6086956521739131,0.7368421052631579 83 | UK,ten_month,0.9304099064795609,0.7358138880256144,0.6842105263157895,0.7142857142857143,0.6521739130434783,0.7894736842105263 84 | UK,eleven_month,0.9516437967915528,0.6537773237499118,0.6842105263157895,0.7142857142857143,0.6521739130434783,0.7894736842105263 85 | UK,twelve_month,0.9797842720572735,0.6313891197517778,0.7368421052631579,0.761904761904762,0.6956521739130435,0.8421052631578947 86 | -------------------------------------------------------------------------------- /random_walk_scores.csv: -------------------------------------------------------------------------------- 1 | ,,root mean squared error,median absolute error,accuracy classification score,f1 score,precision,recall 2 | AUS,one_month,1.4998531977792002,1.164926434628005,0.39473684210526316,0.30303030303030304,0.29411764705882354,0.3125 3 | AUS,two_month,1.7458772829885423,1.066560619776212,0.3684210526315789,0.25,0.25,0.25 4 | AUS,three_month,1.6946639729553419,1.5035610934519028,0.3157894736842105,0.23529411764705882,0.23529411764705882,0.23529411764705882 5 | AUS,four_month,1.3120118669633594,0.7978073767797916,0.5263157894736842,0.5263157894736842,0.5263157894736842,0.5263157894736842 6 | AUS,five_month,1.3858257013298287,1.1050412988803022,0.5789473684210527,0.6,0.6,0.6 7 | AUS,six_month,1.3212324162079323,1.053129456242886,0.5526315789473685,0.5853658536585366,0.6,0.5714285714285714 8 | AUS,seven_month,1.4680044924886295,1.071075151604541,0.6052631578947368,0.5714285714285714,0.5263157894736842,0.625 9 | AUS,eight_month,1.5732097704476609,0.9338385249775567,0.5263157894736842,0.5,0.47368421052631576,0.5294117647058824 10 | AUS,nine_month,1.4849333499541797,0.9792929523038254,0.5526315789473685,0.5405405405405405,0.5,0.5882352941176471 11 | AUS,ten_month,1.3599448416074464,0.8354887047010352,0.5526315789473685,0.5641025641025642,0.5238095238095238,0.6111111111111112 12 | AUS,eleven_month,1.3756191499933457,0.852872532691237,0.5789473684210527,0.6190476190476191,0.5652173913043478,0.6842105263157895 13 | AUS,twelve_month,1.4423036728848235,0.8474110565166997,0.4473684210526316,0.4878048780487805,0.45454545454545453,0.5263157894736842 14 | CAN,one_month,1.3501455829557245,0.8806324259200071,0.5,0.3870967741935484,0.35294117647058826,0.42857142857142855 15 | CAN,two_month,1.6757712996401553,1.1260187329225433,0.34210526315789475,0.1379310344827586,0.14285714285714285,0.13333333333333333 16 | CAN,three_month,1.7669332686923265,0.8531170301302884,0.3684210526315789,0.14285714285714288,0.15384615384615385,0.13333333333333333 17 | CAN,four_month,1.6414037937460308,0.9257682363662256,0.42105263157894735,0.3125,0.29411764705882354,0.3333333333333333 18 | CAN,five_month,1.6431431587470549,0.9968900092475159,0.4473684210526316,0.3225806451612903,0.3125,0.3333333333333333 19 | CAN,six_month,1.671495599222858,1.15677221501999,0.47368421052631576,0.3333333333333333,0.3125,0.35714285714285715 20 | CAN,seven_month,1.7694403180475482,1.3836530162224947,0.3157894736842105,0.13333333333333333,0.11764705882352941,0.15384615384615385 21 | CAN,eight_month,1.7851129480779915,1.035572605067125,0.3157894736842105,0.23529411764705882,0.2222222222222222,0.25 22 | CAN,nine_month,1.7214054305964839,1.197611944586478,0.34210526315789475,0.2424242424242424,0.2222222222222222,0.26666666666666666 23 | CAN,ten_month,1.694972018154327,1.2707456582450503,0.39473684210526316,0.37837837837837834,0.3333333333333333,0.4375 24 | CAN,eleven_month,1.6941037010437976,1.3688568253093576,0.39473684210526316,0.41025641025641024,0.38095238095238093,0.4444444444444444 25 | CAN,twelve_month,1.6775427772545404,1.13373903977253,0.42105263157894735,0.3888888888888889,0.3684210526315789,0.4117647058823529 26 | JAP,one_month,1.4438442345601001,1.0082671080742078,0.3684210526315789,0.42857142857142855,0.42857142857142855,0.42857142857142855 27 | JAP,two_month,1.3929638654443481,0.9551779749435315,0.5789473684210527,0.5789473684210527,0.5789473684210527,0.5789473684210527 28 | JAP,three_month,1.493136357457117,1.0727401402033312,0.4473684210526316,0.43243243243243246,0.4444444444444444,0.42105263157894735 29 | JAP,four_month,1.5287295556371838,0.7971455393806264,0.3157894736842105,0.3157894736842105,0.3157894736842105,0.3157894736842105 30 | JAP,five_month,1.6468205600600176,1.1115760063051279,0.3157894736842105,0.380952380952381,0.4,0.36363636363636365 31 | JAP,six_month,1.6694379715802663,1.0635415368247654,0.3157894736842105,0.38095238095238093,0.38095238095238093,0.38095238095238093 32 | JAP,seven_month,1.6711612751965153,1.2606828438530129,0.34210526315789475,0.358974358974359,0.3684210526315789,0.35 33 | JAP,eight_month,1.7588199104311242,1.1486506062895732,0.2894736842105263,0.22857142857142856,0.25,0.21052631578947367 34 | JAP,nine_month,1.8244320231904902,1.1561242687608906,0.23684210526315788,0.12121212121212123,0.15384615384615385,0.1 35 | JAP,ten_month,1.8529286116392247,1.0649498691950519,0.2631578947368421,0.125,0.14285714285714285,0.1111111111111111 36 | JAP,eleven_month,1.8746521641992673,1.1635376681275607,0.23684210526315788,0.21621621621621623,0.26666666666666666,0.18181818181818182 37 | JAP,twelve_month,1.819489474051063,1.2814039805707982,0.34210526315789475,0.358974358974359,0.4375,0.30434782608695654 38 | NOR,one_month,1.4215030848292878,1.0899197341119495,0.5263157894736842,0.47058823529411764,0.47058823529411764,0.47058823529411764 39 | NOR,two_month,1.6615978588400804,1.4339207365749784,0.34210526315789475,0.28571428571428575,0.29411764705882354,0.2777777777777778 40 | NOR,three_month,1.762538463885232,1.5194319805767242,0.2631578947368421,0.17647058823529413,0.17647058823529413,0.17647058823529413 41 | NOR,four_month,1.613107797930994,1.0437193763980763,0.42105263157894735,0.3125,0.3125,0.3125 42 | NOR,five_month,1.52675217100926,1.1154529640827906,0.4473684210526316,0.39999999999999997,0.3888888888888889,0.4117647058823529 43 | NOR,six_month,1.539710397818692,1.219002383097632,0.5,0.5365853658536585,0.5238095238095238,0.55 44 | NOR,seven_month,1.6126034889635301,1.0773152260323333,0.4473684210526316,0.4878048780487805,0.45454545454545453,0.5263157894736842 45 | NOR,eight_month,1.6879772206435883,1.1421893743418887,0.42105263157894735,0.38888888888888884,0.35,0.4375 46 | NOR,nine_month,1.6159463115534476,0.8119584740681414,0.39473684210526316,0.34285714285714286,0.3,0.4 47 | NOR,ten_month,1.5364095297237848,0.9743993294964233,0.5526315789473685,0.5405405405405405,0.5,0.5882352941176471 48 | NOR,eleven_month,1.5482647742985807,0.9338920634587281,0.5,0.5128205128205129,0.5,0.5263157894736842 49 | NOR,twelve_month,1.5747090257498935,0.988184158431392,0.4473684210526316,0.4615384615384615,0.42857142857142855,0.5 50 | SWE,one_month,1.393478395056861,1.1306230337520615,0.5263157894736842,0.55,0.55,0.55 51 | SWE,two_month,1.5275096188905561,1.0561864103990972,0.4473684210526316,0.3636363636363636,0.35294117647058826,0.375 52 | SWE,three_month,1.5455264353741573,1.1035958769118603,0.34210526315789475,0.358974358974359,0.35,0.3684210526315789 53 | SWE,four_month,1.4271845660099864,1.0751396282286798,0.4473684210526316,0.43243243243243246,0.42105263157894735,0.4444444444444444 54 | SWE,five_month,1.4799119358096764,1.0443751768953449,0.5,0.4864864864864865,0.5,0.47368421052631576 55 | SWE,six_month,1.5864718892374083,0.9118322871274561,0.39473684210526316,0.303030303030303,0.2777777777777778,0.3333333333333333 56 | SWE,seven_month,1.6669189067368824,1.0052278286264207,0.3157894736842105,0.23529411764705882,0.2222222222222222,0.25 57 | SWE,eight_month,1.7442230281116287,1.411982827202751,0.34210526315789475,0.2424242424242424,0.2222222222222222,0.26666666666666666 58 | SWE,nine_month,1.734507591048003,1.0686320018965474,0.42105263157894735,0.26666666666666666,0.2222222222222222,0.3333333333333333 59 | SWE,ten_month,1.719561409196832,1.1955221414612838,0.3157894736842105,0.13333333333333333,0.1111111111111111,0.16666666666666666 60 | SWE,eleven_month,1.7268657120355382,1.3938122011120866,0.3684210526315789,0.25,0.2222222222222222,0.2857142857142857 61 | SWE,twelve_month,1.694517228124053,1.408914109269286,0.34210526315789475,0.13793103448275862,0.125,0.15384615384615385 62 | SWI,one_month,1.4402549072271287,1.2148669210296394,0.4473684210526316,0.4878048780487805,0.47619047619047616,0.5 63 | SWI,two_month,1.657253843492726,1.2967917703913043,0.39473684210526316,0.34285714285714286,0.3333333333333333,0.35294117647058826 64 | SWI,three_month,1.773971306097116,1.364046870250982,0.23684210526315788,0.25641025641025644,0.2631578947368421,0.25 65 | SWI,four_month,1.702702866551779,1.3596938523576791,0.34210526315789475,0.28571428571428575,0.29411764705882354,0.2777777777777778 66 | SWI,five_month,1.7331572405713314,1.4883519610482745,0.3157894736842105,0.23529411764705882,0.23529411764705882,0.23529411764705882 67 | SWI,six_month,1.7180913200324384,1.110058080941322,0.34210526315789475,0.24242424242424243,0.23529411764705882,0.25 68 | SWI,seven_month,1.6893359099400607,1.17305843061981,0.3157894736842105,0.3157894736842105,0.3157894736842105,0.3157894736842105 69 | SWI,eight_month,1.7457731695656111,1.1378865397354527,0.3157894736842105,0.380952380952381,0.36363636363636365,0.4 70 | SWI,nine_month,1.6811237632901148,1.0106577731987998,0.4473684210526316,0.46153846153846156,0.45,0.47368421052631576 71 | SWI,ten_month,1.6015438882384632,1.0495944026983224,0.5,0.45714285714285713,0.4444444444444444,0.47058823529411764 72 | SWI,eleven_month,1.6594998109424977,1.1153396764023433,0.42105263157894735,0.45,0.45,0.45 73 | SWI,twelve_month,1.752299007579332,1.0814691384980355,0.3157894736842105,0.23529411764705882,0.23529411764705882,0.23529411764705882 74 | UK,one_month,1.4825418988512968,0.9585503136203651,0.5,0.5128205128205129,0.5263157894736842,0.5 75 | UK,two_month,1.4386898839229947,0.9216655906593278,0.631578947368421,0.6818181818181819,0.6521739130434783,0.7142857142857143 76 | UK,three_month,1.4002935629549722,0.9430422021496541,0.6052631578947368,0.6153846153846154,0.631578947368421,0.6 77 | UK,four_month,1.2847813558146859,0.8424245052483365,0.5789473684210527,0.6,0.631578947368421,0.5714285714285714 78 | UK,five_month,1.3387321200864142,0.7718431858314407,0.5263157894736842,0.5,0.5294117647058824,0.47368421052631576 79 | UK,six_month,1.3735264633642077,0.9613332416870695,0.47368421052631576,0.4444444444444445,0.5,0.4 80 | UK,seven_month,1.4292926621254827,0.9391306639389847,0.5,0.48648648648648646,0.5294117647058824,0.45 81 | UK,eight_month,1.440204332039086,1.0966435134025714,0.5526315789473685,0.5405405405405405,0.5882352941176471,0.5 82 | UK,nine_month,1.5234456757748445,1.3171839068432742,0.5526315789473685,0.5405405405405405,0.5555555555555556,0.5263157894736842 83 | UK,ten_month,1.6161242469392774,1.3088752926045566,0.5,0.4864864864864865,0.5,0.47368421052631576 84 | UK,eleven_month,1.7084125932755208,1.3906011354885546,0.34210526315789475,0.3243243243243243,0.3333333333333333,0.3157894736842105 85 | UK,twelve_month,1.747564377804257,1.4318565600235844,0.23684210526315788,0.21621621621621623,0.2222222222222222,0.21052631578947367 86 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | from imports import * 2 | 3 | list_of_countries = ['AUS', 'CAN', 'JAP', 'NOR', 'SWE', 'SWI', 'UK','USA'] 4 | list_of_currencies = ['AUD', 'CAD', 'JPY', 'NOK', 'SEK', 'CHF', 'GBP','USD'] 5 | 6 | 7 | 8 | ##################### 9 | #Load Data 10 | ##################### 11 | 12 | xls = pd.ExcelFile('data/parameters_data.xlsx') 13 | x = pd.read_excel(xls, 'AUS') 14 | x.head() 15 | x.loc[:,'Sigma_2_AUS':'Unnamed: 25'] 16 | 17 | #Extract K0P_1 18 | K0P_1 = {} 19 | for country in list_of_countries[:-1]: 20 | df = pd.read_excel(xls, country) 21 | location = 'K0P_1_' + country 22 | K0P_1[country] = np.matrix(df[location]).reshape((3,1)) 23 | 24 | 25 | K0P_1['AUS'].shape 26 | 27 | #Extract K0P_2 28 | K0P_2 = {} 29 | for country in list_of_countries[:-1]: 30 | df = pd.read_excel(xls, country) 31 | location = 'K0P_2_' + country 32 | K0P_2[country] = np.matrix(df[location]).reshape((3,1)) 33 | 34 | K0P_2['AUS'].shape 35 | 36 | #Extract K1P_1 37 | K1P_1 = {} 38 | for country in list_of_countries[:-1]: 39 | df = pd.read_excel(xls, country) 40 | K1P_1[country] = np.matrix(df.iloc[:,2:5]) 41 | 42 | K1P_1['AUS'].shape 43 | 44 | #Extract K1P_1 45 | K1P_2 = {} 46 | for country in list_of_countries[:-1]: 47 | df = pd.read_excel(xls, country) 48 | K1P_2[country] = np.matrix(df.iloc[:,5:8]) 49 | 50 | K1P_2['AUS'].shape 51 | 52 | #Extract roh0_1 53 | rho0_1 = {} 54 | for country in list_of_countries[:-1]: 55 | df = pd.read_excel(xls, country) 56 | location = 'rho0_1_' + country 57 | rho0_1[country] = np.matrix(df[location].dropna()).reshape((1,1)) 58 | 59 | rho0_1['AUS'].shape 60 | rho0_1['AUS'] 61 | 62 | 63 | #Extract roh0_2 64 | rho0_2 = {} 65 | for country in list_of_countries[:-1]: 66 | df = pd.read_excel(xls, country) 67 | location = 'rho0_2_' + country 68 | rho0_2[country] = np.matrix(df[location].dropna()).reshape((1,1)) 69 | 70 | rho0_2['AUS'].shape 71 | 72 | #Extract roh1_1 73 | rho1_1 = {} 74 | for country in list_of_countries[:-1]: 75 | df = pd.read_excel(xls, country) 76 | location = 'rho1_1_' + country 77 | rho1_1[country] = np.matrix(df[location].dropna()).reshape((3,1)) 78 | 79 | rho1_1['AUS'].shape 80 | 81 | #Extract roh1_2 82 | rho1_2 = {} 83 | for country in list_of_countries[:-1]: 84 | df = pd.read_excel(xls, country) 85 | location = 'rho1_2_' + country 86 | rho1_2[country] = np.matrix(df[location].dropna()).reshape((3,1)) 87 | 88 | rho1_2['AUS'].shape 89 | 90 | #Extract K0Q_1 91 | K0Q_1 = {} 92 | for country in list_of_countries[:-1]: 93 | df = pd.read_excel(xls, country) 94 | location = 'K0Q_1_' + country 95 | K0Q_1[country] = np.matrix(df[location].dropna()).reshape((3,1)) 96 | 97 | K0Q_1['AUS'].shape 98 | 99 | #Extract K0Q_2 100 | K0Q_2 = {} 101 | for country in list_of_countries[:-1]: 102 | df = pd.read_excel(xls, country) 103 | location = 'K0Q_2_' + country 104 | K0Q_2[country] = np.matrix(df[location].dropna()).reshape((3,1)) 105 | 106 | K0Q_2["AUS"].shape 107 | 108 | #Extract K1Q_1 109 | K1Q_1 = {} 110 | for country in list_of_countries[:-1]: 111 | df = pd.read_excel(xls, country) 112 | location = 'K1Q_1_' + country 113 | K1Q_1[country] = np.matrix(df.loc[:,location:'Unnamed: 16'].dropna()) 114 | 115 | K1Q_1['AUS'].shape 116 | 117 | #Extract K1Q_2 118 | K1Q_2 = {} 119 | for country in list_of_countries[:-1]: 120 | df = pd.read_excel(xls, country) 121 | location = 'K1Q_2_' + country 122 | K1Q_2[country] = np.matrix(df.loc[:,location:'Unnamed: 19'].dropna()) 123 | 124 | K1Q_2['AUS'].shape 125 | 126 | #Extract Sigma_1 127 | Sigma_1 = {} 128 | for country in list_of_countries[:-1]: 129 | df = pd.read_excel(xls, country) 130 | location = 'Sigma_1_' + country 131 | Sigma_1[country] = np.matrix(df.loc[:,location:'Unnamed: 22'].dropna()) 132 | 133 | Sigma_1['AUS'].shape 134 | 135 | #Extract Sigma_2 136 | Sigma_2 = {} 137 | for country in list_of_countries[:-1]: 138 | df = pd.read_excel(xls, country) 139 | location = 'Sigma_2_' + country 140 | Sigma_2[country] = np.matrix(df.loc[:,location:'Unnamed: 25'].dropna()) 141 | 142 | Sigma_2['AUS'].shape 143 | 144 | #Create lambda_0_1 145 | lambda_0_1 = {} 146 | for country in list_of_countries[:-1]: 147 | lambda_0_1[country] = K0P_1[country] - K0Q_1[country] 148 | 149 | lambda_0_1['AUS'].shape 150 | 151 | #Create lambda_0_2 152 | lambda_0_2 = {} 153 | for country in list_of_countries[:-1]: 154 | lambda_0_2[country] = K0P_2[country] - K0Q_2[country] 155 | 156 | lambda_0_2['AUS'].shape 157 | 158 | #Create lambda_1_1 159 | lambda_1_1 = {} 160 | for country in list_of_countries[:-1]: 161 | lambda_1_1[country] = K1P_1[country] - K1Q_1[country] 162 | 163 | lambda_1_1['AUS'].shape 164 | 165 | #Create lambda_1_2 166 | lambda_1_2 = {} 167 | for country in list_of_countries[:-1]: 168 | lambda_1_2[country] = K1P_2[country] - K1Q_2[country] 169 | 170 | lambda_1_2['AUS'].shape 171 | 172 | ##################### 173 | #End of Load Data 174 | ##################### 175 | 176 | ##################### 177 | #Equations 178 | ##################### 179 | 180 | #Defining the omega_2 Functions 181 | 182 | def omega_2_1(country, k): 183 | identity = np.identity(3) 184 | part1 = lambda_1_1[country].T * np.linalg.inv(Sigma_1[country].T) 185 | final_calc = np.zeros((3,3)) 186 | for j in list(range(2,k+1)): 187 | calc1 = np.power((identity + K1P_1[country]).T,j-1) 188 | calc2 = np.power((identity + K1P_1[country]),j-1) 189 | calc3 = calc1 * calc2 190 | final_calc += calc3 191 | part2 = identity + final_calc 192 | part3 = np.linalg.inv(Sigma_1[country]) * lambda_1_1[country] 193 | result = part1 * part2 * part3 194 | return result 195 | 196 | omega_2_1("JAP", 1) 197 | 198 | def omega_2_2(country, k): 199 | identity = np.identity(3) 200 | part1 = lambda_1_2[country].T * np.linalg.inv(Sigma_2[country].T) 201 | final_calc = np.zeros((3,3)) 202 | for j in list(range(2,k+1)): 203 | calc1 = np.power((identity + K1P_2[country]).T,j-1) 204 | calc2 = np.power((identity + K1P_2[country]),j-1) 205 | calc3 = calc1 * calc2 206 | final_calc += calc3 207 | part2 = identity + final_calc 208 | part3 = np.linalg.inv(Sigma_2[country]) * lambda_1_2[country] 209 | result = part1 * part2 * part3 210 | return result 211 | 212 | 213 | omega_2_2('CAN', 1) 214 | 215 | 216 | #Defining the omega_1 Functions 217 | 218 | def omega_1_1(country, k): 219 | identity = np.identity(3) 220 | part1 = rho1_1[country].T + (lambda_0_1[country].T * np.linalg.inv(Sigma_1[country].T) * np.linalg.inv(Sigma_1[country]) * lambda_1_1[country]) 221 | 222 | final_calc = np.zeros((3,3)) 223 | for j in list(range(2,k+1)): 224 | calc1 = np.power((identity + K1P_1[country]),j-1) 225 | final_calc += calc1 226 | part2 = identity + final_calc 227 | 228 | final_calc_2 = np.zeros((1,3)) 229 | for j in list(range(2,k+1)): 230 | for i in list(range(1, j)): 231 | calc2 = (K0P_1[country].T) * np.power((identity + K1P_1[country]).T, i-1) * (lambda_1_1[country].T * np.linalg.inv(Sigma_1[country].T) \ 232 | * np.linalg.inv(Sigma_1[country]) * lambda_1_1[country]) * np.power((identity + K1P_1[country]), j-1) 233 | final_calc_2 += calc2 234 | 235 | result = (part1 * part2) + final_calc_2 236 | return result 237 | 238 | omega_1_1('CAN', 1) 239 | omega_1_1('JAP', 1).shape 240 | 241 | def omega_1_2(country, k): 242 | identity = np.identity(3) 243 | part1 = rho1_2[country].T + (lambda_0_2[country].T * np.linalg.inv(Sigma_2[country].T) * np.linalg.inv(Sigma_2[country]) * lambda_1_2[country]) 244 | 245 | final_calc = np.zeros((3,3)) 246 | for j in list(range(2,k+1)): 247 | calc1 = np.power((identity + K1P_2[country]),j-1) 248 | final_calc += calc1 249 | part2 = identity + final_calc 250 | 251 | final_calc_2 = np.zeros((1,3)) 252 | for j in list(range(2,k+1)): 253 | for i in list(range(1, j)): 254 | calc2 = (K0P_2[country].T) * np.power((identity + K1P_2[country]).T, i-1) * (lambda_1_2[country].T * np.linalg.inv(Sigma_2[country].T) \ 255 | * np.linalg.inv(Sigma_2[country]) * lambda_1_2[country]) * np.power((identity + K1P_2[country]), j-1) 256 | final_calc_2 += calc2 257 | result = (part1 * part2) + final_calc_2 258 | return result 259 | 260 | omega_1_2('AUS', 3) 261 | 262 | 263 | def omega_0(country, k): #Does the structure make a difference? 264 | identity = np.identity(3) 265 | final_calc_1 = np.zeros((3,1)) 266 | for j in list(range(2,k+1)): 267 | for i in list(range(1, j)): 268 | calc1 = np.power((identity + K1P_1[country]), i-1) * K0P_1[country] 269 | final_calc_1 += calc1 270 | mini_part1_1 = (k * (rho0_1[country] - rho0_2[country])) + (rho1_1[country].T * final_calc_1) 271 | 272 | final_calc_2 = np.zeros((3,1)) 273 | for j in list(range(2,k+1)): 274 | for i in list(range(1, j)): 275 | calc2 = np.power((identity + K1P_2[country]), i-1) * K0P_2[country] 276 | final_calc_2 += calc2 277 | mini_part1_2 = rho1_2[country].T * final_calc_2 278 | part1 = mini_part1_1 - mini_part1_2 279 | 280 | if k == 1: 281 | mini_part2_1 = (1/2) * lambda_0_1[country].T * np.linalg.inv(Sigma_1[country].T) * np.linalg.inv(Sigma_1[country]) * lambda_0_1[country] 282 | mini_part2_2 = (1/2) * lambda_0_2[country].T * np.linalg.inv(Sigma_2[country].T) * np.linalg.inv(Sigma_2[country]) * lambda_0_2[country] 283 | else: 284 | mini_part2_1 = ((1+k)/2) * lambda_0_1[country].T * np.linalg.inv(Sigma_1[country].T) * np.linalg.inv(Sigma_1[country]) * lambda_0_1[country] 285 | mini_part2_2 = ((1+k)/2) * lambda_0_2[country].T * np.linalg.inv(Sigma_2[country].T) * np.linalg.inv(Sigma_2[country]) * lambda_0_2[country] 286 | part2 = mini_part2_1 - mini_part2_2 287 | 288 | 289 | mini_part3_1 = lambda_0_1[country].T * np.linalg.inv(Sigma_1[country].T) * np.linalg.inv(Sigma_1[country]) * lambda_1_1[country] * final_calc_1 290 | mini_part3_2 = lambda_0_2[country].T * np.linalg.inv(Sigma_2[country].T) * np.linalg.inv(Sigma_2[country]) * lambda_1_2[country] * final_calc_2 291 | part3 = mini_part3_1 - mini_part3_2 292 | 293 | final_calc_3 = np.zeros((1,1)) 294 | for j in list(range(2,k+1)): 295 | for i in list(range(1, j)): 296 | calc3 = K0P_1[country].T * np.power((identity + K1P_1[country]).T, i-1) * lambda_1_1[country].T * np.linalg.inv(Sigma_1[country].T) \ 297 | * np.linalg.inv(Sigma_1[country]) * lambda_1_1[country] * np.power((identity + K1P_1[country]), i-1) * K0P_1[country] 298 | final_calc_3 += calc3 299 | 300 | 301 | mini_part4_1 = 1/2 * final_calc_3 302 | 303 | final_calc_5 = np.zeros((1,1)) 304 | for j in list(range(2,k+1)): 305 | for i in list(range(1, j)): 306 | calc5 = K0P_2[country].T * np.power((identity + K1P_2[country]).T, i-1) * lambda_1_2[country].T * np.linalg.inv(Sigma_2[country].T) \ 307 | * np.linalg.inv(Sigma_2[country]) * lambda_1_2[country] * np.power((identity + K1P_2[country]), i-1) * K0P_2[country] 308 | final_calc_5 += calc5 309 | 310 | mini_part4_2 = 1/2 * final_calc_5 311 | part4 = mini_part4_1 - mini_part4_2 312 | 313 | result = part1 + part2 + part3 + part4 314 | return result 315 | 316 | omega_0('AUS',4) 317 | 318 | 319 | def xi(country, k): 320 | identity = np.identity(3) 321 | final_calc_1 = np.zeros((3,3)) 322 | for j in list(range(2,k+1)): 323 | for i in list(range(1, j)): 324 | calc1 = Sigma_1[country].T * np.power((identity + K1P_1[country]).T, i-1) * lambda_1_1[country].T * np.linalg.inv(Sigma_1[country].T) \ 325 | * np.linalg.inv(Sigma_1[country]) * lambda_1_1[country] * np.power((identity + K1P_1[country]), i-1) * Sigma_1[country] 326 | final_calc_1 += calc1 327 | 328 | part1 = np.trace(1/2 * final_calc_1) 329 | 330 | final_calc_3 = np.zeros((3,3)) 331 | for j in list(range(2,k+1)): 332 | for i in list(range(1, j)): 333 | calc3 = Sigma_2[country].T * np.power((identity + K1P_2[country]).T, i-1) * lambda_1_2[country].T * np.linalg.inv(Sigma_2[country].T) \ 334 | * np.linalg.inv(Sigma_2[country]) * lambda_1_2[country] * np.power((identity + K1P_2[country]), i-1) * Sigma_2[country] 335 | final_calc_3 += calc3 336 | 337 | part2 = np.trace(1/2 * final_calc_3) 338 | 339 | result = part1 - part2 340 | return result 341 | 342 | xi('AUS', 1) 343 | 344 | 345 | ################# 346 | #PCA Calculator 347 | ################ 348 | 349 | ylds_start_date = {} 350 | ylds_end_date = {} 351 | 352 | xlsx = pd.ExcelFile('data/data_xrates_yields.xlsx') 353 | 354 | yields_data = {} 355 | 356 | for country in list_of_countries: 357 | yields_data[country] = pd.read_excel(xlsx, 'yields_'+country) 358 | yields_data[country]['date'] = yields_data[country].iloc[:,0] #Set first column as date 359 | yields_data[country] = yields_data[country].set_index('date') 360 | yields_data[country] = yields_data[country].iloc[:,1:] 361 | ylds_start_date.update({country: yields_data[country].index[0]}) 362 | ylds_end_date.update({country: yields_data[country].index[-1]}) 363 | 364 | 365 | 366 | 367 | ylds_start_date 368 | 369 | ylds_end_date 370 | 371 | pca_dates = pd.read_excel('data/pca_model_dates.xlsx') #Load the pca model dates to be used 372 | pca_dates['NOR'] 373 | 374 | #Adjust the Dates as per the peremeter estimation Dates 375 | for country in list_of_countries: 376 | yields_data[country] = yields_data[country].loc[pca_dates[country][0]:pca_dates[country][1]] 377 | ylds_start_date.update({country: yields_data[country].index[0]}) 378 | ylds_end_date.update({country: yields_data[country].index[-1]}) 379 | 380 | ylds_start_date 381 | 382 | ylds_end_date 383 | 384 | #Create a list of forecasting dates, that will hold all the dates for which we need to create forecasts 385 | # Remember that '2015-12-31' is the date where our constant values calculation ends and from this on we want to use our model to forecast values 386 | forecasting_dates = list(yields_data['AUS'].loc['2015-12-31':].index) 387 | 388 | forecasting_dates 389 | #Rename Columns 390 | for country in list_of_countries: 391 | if country == 'USA': 392 | yields_data[country] = yields_data[country].rename(columns = {'US03M': '03M', 393 | 'US06M': '06M', 394 | 'US01Y': '01Y', 395 | 'US02Y': '02Y', 396 | 'US03Y': '03Y', 397 | 'US04Y': '04Y', 398 | 'US05Y': '05Y', 399 | 'US06Y': '06Y', 400 | 'US07Y': '07Y', 401 | 'US08Y': '08Y', 402 | 'US09Y': '09Y', 403 | 'US10Y': '10Y'}) 404 | else: 405 | yields_data[country] = yields_data[country].rename(columns = {country+'03M': '03M', 406 | country+'06M': '06M', 407 | country+'01Y': '01Y', 408 | country+'02Y': '02Y', 409 | country+'03Y': '03Y', 410 | country+'04Y': '04Y', 411 | country+'05Y': '05Y', 412 | country+'06Y': '06Y', 413 | country+'07Y': '07Y', 414 | country+'08Y': '08Y', 415 | country+'09Y': '09Y', 416 | country+'10Y': '10Y'}) 417 | 418 | #Standardize Data 419 | #It is always good to standardize data before running PCA 420 | def standardize_data(df): 421 | column_names = list(df.columns) 422 | x = StandardScaler().fit_transform(df.values) 423 | result = pd.DataFrame(data = x, columns = column_names) 424 | result.index = df.index 425 | return result 426 | 427 | 428 | 429 | def PCA_analysis(df, standardize = False): 430 | if standardize == True: 431 | data = standardize_data(df) 432 | else: 433 | data = df.copy() 434 | 435 | data = df.copy() 436 | cov = np.cov(data.T) / data.shape[0] 437 | v, w = np.linalg.eig(cov) 438 | idx = v.argsort()[::-1] # Sort descending and get sorted indices 439 | v = v[idx] # Use indices on eigv vector 440 | w = w[:,idx] # 441 | pca_value = data.dot(w[:, :3]) 442 | 443 | principalComponents = {'level': pca_value[0], 'slope': pca_value[1], 'curvature': pca_value[2]} 444 | principalDf = pd.DataFrame.from_dict(principalComponents) 445 | principalDf.index = df.index 446 | return principalDf 447 | 448 | def forecasting_model(pca_data, pca_data_usa, country, k): 449 | omega_0_value = omega_0(country, k) 450 | omega_1_1_value = omega_1_1(country, k) 451 | omega_1_2_value = omega_1_2(country, k) 452 | omega_2_1_value = omega_2_1(country, k) 453 | omega_2_2_value = omega_2_2(country, k) 454 | xi_value = xi(country, k) 455 | 456 | result = omega_0_value + (omega_1_1_value * pca_data_usa) - (omega_1_2_value * pca_data) + \ 457 | (1/2*((pca_data_usa.T * omega_2_1_value * pca_data_usa) - (pca_data.T * omega_2_2_value * pca_data))) + xi_value 458 | return result/12 459 | 460 | 461 | 462 | #Create the final_forecasting_model: 463 | def forecast(yields_data, country, forecasting_dates, normalize = False): 464 | 465 | #Create empty list containers that will hold the forecasting values 466 | one_month = [] 467 | two_month = [] 468 | three_month = [] 469 | four_month = [] 470 | five_month = [] 471 | six_month = [] 472 | seven_month = [] 473 | eight_month = [] 474 | nine_month = [] 475 | ten_month = [] 476 | eleven_month = [] 477 | twelve_month = [] 478 | 479 | for date in forecasting_dates: 480 | #Calculate PCA Data for country of interest 481 | data = yields_data[country].loc[:str(date)[:7]] #Extract data yup until the date we want to forecast for 482 | pca = PCA_analysis(data, False) #Calculate PCA for the extracted data 483 | pca_data = np.matrix(pca.loc[str(date)[:7]]).reshape(3,1) #Extract the forecasting dates pca values into a matrix for forecasting 484 | #The reason we convert date to str and only take values up until index 6 is because we want to only focus on the months and not the days because based on country some dates end on 485 | #31 while others end on the 30th. 486 | 487 | #Calculate PCA data for USA 488 | data_usa = yields_data['USA'].loc[:str(date)[:7]] #Extract data yup until the date we want to forecast for 489 | pca_usa = PCA_analysis(data_usa, False) #Calculate PCA for the extracted data 490 | pca_data_usa = np.matrix(pca_usa.loc[str(date)[:7]]).reshape(3,1) #Extract the forecasting dates pca values into a matrix for forecasting 491 | 492 | predictions = [] #Create an empty prediction list that will hold all the predicted values 493 | for i in list(range(1,13)): 494 | predictions.append(float(forecasting_model(pca_data, pca_data_usa, country, i))) 495 | 496 | #Extract predictions values and append them to their respective lists 497 | one_month.append(predictions[0]) 498 | two_month.append(predictions[1]) 499 | three_month.append(predictions[2]) 500 | four_month.append(predictions[3]) 501 | five_month.append(predictions[4]) 502 | six_month.append(predictions[5]) 503 | seven_month.append(predictions[6]) 504 | eight_month.append(predictions[7]) 505 | nine_month.append(predictions[8]) 506 | ten_month.append(predictions[9]) 507 | eleven_month.append(predictions[10]) 508 | twelve_month.append(predictions[11]) 509 | 510 | if normalize: 511 | one_month = preprocessing.scale(one_month) 512 | two_month = preprocessing.scale(two_month) 513 | three_month = preprocessing.scale(three_month) 514 | four_month = preprocessing.scale(four_month) 515 | five_month = preprocessing.scale(five_month) 516 | six_month = preprocessing.scale(six_month) 517 | seven_month = preprocessing.scale(seven_month) 518 | eight_month = preprocessing.scale(eight_month) 519 | nine_month = preprocessing.scale(nine_month) 520 | ten_month = preprocessing.scale(ten_month) 521 | eleven_month = preprocessing.scale(eleven_month) 522 | twelve_month = preprocessing.scale(twelve_month) 523 | 524 | forecast_dict = {'date': forecasting_dates, 525 | 'one_month': one_month, #Organize the results into a dictionary 526 | 'two_month': two_month, 527 | 'three_month': three_month, 528 | 'four_month': four_month, 529 | 'five_month': five_month, 530 | 'six_month': six_month, 531 | 'seven_month': seven_month, 532 | 'eight_month': eight_month, 533 | 'nine_month': nine_month, 534 | 'ten_month': ten_month, 535 | 'eleven_month': eleven_month, 536 | 'twelve_month': twelve_month} 537 | 538 | forecast_df = pd.DataFrame.from_dict(forecast_dict) #Convert the results from a dictionary to a dataframe 539 | forecast_df.set_index('date', inplace=True) #Set the date column as index 540 | 541 | return forecast_df 542 | 543 | #Functions for plot_forecasts 544 | def round_up(n, decimals=0): 545 | multiplier = 10 ** decimals 546 | return math.ceil(n * multiplier) / multiplier 547 | 548 | def round_down(n, decimals=0): 549 | multiplier = 10 ** decimals 550 | return math.floor(n * multiplier) / multiplier 551 | 552 | def plot_forecasts(title, df): 553 | #Find optimal X ticks_to_use 554 | dates = list(df.index) 555 | ticks_location = int(len(dates)/4) - 1 556 | ticks_to_use = [dates[0], dates[ticks_location], dates[ticks_location*2], dates[ticks_location*3], dates[-1]] 557 | 558 | # Initialize the figure 559 | plt.style.use('seaborn-darkgrid') 560 | 561 | # create a color palette 562 | palette = plt.get_cmap('tab20b') 563 | 564 | # multiple line plot 565 | num=0 566 | fig = plt.figure(figsize=(20,18)) 567 | for column in df: 568 | num+=1 569 | 570 | # Find the right spot on the plot 571 | fig.add_subplot(6,2, num) 572 | 573 | # Plot the lineplot 574 | plt.plot(df[column], marker='', color=palette(num), linewidth=2.0, alpha=0.9, label=column) 575 | plt.locator_params(axis = 'x', nticks=10) 576 | 577 | # Same limits for everybody! 578 | if min(df.min()) > 0 and max(df.max()) > 0: 579 | plt.ylim(round_up(min(df.min()),-1),round_up(max(df.max()),-1)) 580 | if min(df.min()) < 0 and max(df.max()) < 0: 581 | plt.ylim(round_down(min(df.min()),-1),round_down(max(df.max()),-1)) 582 | if min(df.min()) > 0 and max(df.max()) < 0: 583 | plt.ylim(round_up(min(df.min()),-1),round_down(max(df.max()),-1)) 584 | else: 585 | plt.ylim(round_down(min(df.min()),-1),round_up(max(df.max()),-1)) 586 | 587 | plt.xticks(ticks_to_use) 588 | 589 | # Not ticks everywhere 590 | if not num in [11,12] : 591 | plt.tick_params(labelbottom=False) 592 | 593 | # Not ticks everywhere 594 | if not num in [1,3,5,7,9,11] : 595 | plt.tick_params(labelleft=False) 596 | 597 | # Add title 598 | plt.title(column, loc='left', fontsize=12, fontweight=0, color=palette(num) ) 599 | 600 | # general title 601 | plt.suptitle(title, fontsize=16, fontweight=0, color='black', style='italic') 602 | 603 | # Axis title 604 | plt.text(0.5, 0.02, 'Time', ha='center', va='center') 605 | plt.text(0.06, 0.5, 'Note', ha='center', va='center', rotation='vertical') 606 | 607 | 608 | #Get Forecasts for every country in the dataset 609 | forecast_data = {} 610 | for country in tqdm.tqdm(list_of_countries[:-1]): 611 | forecast_data[country] = forecast(yields_data, country, forecasting_dates, True) 612 | 613 | 614 | forecast_data['AUS'] 615 | 616 | 617 | #Load Exchange Rate Data 618 | exchange_rates = pd.read_excel(xlsx, 'xrates') 619 | exchange_rates.head() 620 | # Set Date as index 621 | exchange_rates['date'] = exchange_rates.iloc[:,0] #Set first column as date 622 | exchange_rates = exchange_rates.set_index('date') 623 | exchange_rates = exchange_rates.iloc[:,1:] 624 | exchange_rates 625 | 626 | er = {} 627 | for i in range(len(list_of_countries[:-1])): 628 | er[list_of_countries[i]] = exchange_rates[list_of_currencies[i]+'USD Curncy'] 629 | 630 | er = pd.DataFrame.from_dict(er) #Convert dictionary into dataframe 631 | er.tail() 632 | #real_values = er.loc[str(add_months(forecasting_dates[0],-12))[:7]:] #set the end date for dataframe 1 year from 2015 633 | 634 | er['JAP'] 635 | def add_months(sourcedate, months): 636 | month = sourcedate.month - 1 + months 637 | year = sourcedate.year + month // 12 638 | month = month % 12 + 1 639 | day = min(sourcedate.day, calendar.monthrange(year,month)[1]) 640 | return datetime.date(year, month, day) 641 | 642 | def calculate_rv(exchange_rate_data, forecasting_dates, normalize = False): 643 | #Create empty list containers that will hold the real change values values 644 | one_month = [] 645 | two_month = [] 646 | three_month = [] 647 | four_month = [] 648 | five_month = [] 649 | six_month = [] 650 | seven_month = [] 651 | eight_month = [] 652 | nine_month = [] 653 | ten_month = [] 654 | eleven_month = [] 655 | twelve_month = [] 656 | for date in forecasting_dates: 657 | one_month.append(float(np.log(exchange_rate_data.loc[str(add_months(date,1))[:7]]))- float(np.log(exchange_rate_data.loc[str(date)[:7]]))) 658 | two_month.append(float(np.log(exchange_rate_data.loc[str(add_months(date,2))[:7]])) - float(np.log(exchange_rate_data.loc[str(date)[:7]]))) 659 | three_month.append(float(np.log(exchange_rate_data.loc[str(add_months(date,3))[:7]])) - float(np.log(exchange_rate_data.loc[str(date)[:7]]))) 660 | four_month.append(float(np.log(exchange_rate_data.loc[str(add_months(date,4))[:7]])) - float(np.log(exchange_rate_data.loc[str(date)[:7]]))) 661 | five_month.append(float(np.log(exchange_rate_data.loc[str(add_months(date,5))[:7]])) - float(np.log(exchange_rate_data.loc[str(date)[:7]]))) 662 | six_month.append(float(np.log(exchange_rate_data.loc[str(add_months(date,6))[:7]])) - float(np.log(exchange_rate_data.loc[str(date)[:7]]))) 663 | seven_month.append(float(np.log(exchange_rate_data.loc[str(add_months(date,7))[:7]])) - float(np.log(exchange_rate_data.loc[str(date)[:7]]))) 664 | eight_month.append(float(np.log(exchange_rate_data.loc[str(add_months(date,8))[:7]])) - float(np.log(exchange_rate_data.loc[str(date)[:7]]))) 665 | nine_month.append(float(np.log(exchange_rate_data.loc[str(add_months(date,9))[:7]])) - float(np.log(exchange_rate_data.loc[str(date)[:7]]))) 666 | ten_month.append(float(np.log(exchange_rate_data.loc[str(add_months(date,10))[:7]])) - float(np.log(exchange_rate_data.loc[str(date)[:7]]))) 667 | eleven_month.append(float(np.log(exchange_rate_data.loc[str(add_months(date,11))[:7]])) - float(np.log(exchange_rate_data.loc[str(date)[:7]]))) 668 | twelve_month.append(float(np.log(exchange_rate_data.loc[str(add_months(date,12))[:7]])) - float(np.log(exchange_rate_data.loc[str(date)[:7]]))) 669 | 670 | if normalize: 671 | one_month = preprocessing.scale(one_month) 672 | two_month = preprocessing.scale(two_month) 673 | three_month = preprocessing.scale(three_month) 674 | four_month = preprocessing.scale(four_month) 675 | five_month = preprocessing.scale(five_month) 676 | six_month = preprocessing.scale(six_month) 677 | seven_month = preprocessing.scale(seven_month) 678 | eight_month = preprocessing.scale(eight_month) 679 | nine_month = preprocessing.scale(nine_month) 680 | ten_month = preprocessing.scale(ten_month) 681 | eleven_month = preprocessing.scale(eleven_month) 682 | twelve_month = preprocessing.scale(twelve_month) 683 | 684 | rv_dict = {'date': forecasting_dates, 685 | 'one_month': one_month, #Organize the results into a dictionary 686 | 'two_month': two_month, 687 | 'three_month': three_month, 688 | 'four_month': four_month, 689 | 'five_month': five_month, 690 | 'six_month': six_month, 691 | 'seven_month': seven_month, 692 | 'eight_month': eight_month, 693 | 'nine_month': nine_month, 694 | 'ten_month': ten_month, 695 | 'eleven_month': eleven_month, 696 | 'twelve_month': twelve_month} 697 | 698 | rv_df = pd.DataFrame.from_dict(rv_dict) #Convert the results from a dictionary to a dataframe 699 | rv_df.set_index('date', inplace=True) #Set the date column as index 700 | return rv_df 701 | 702 | def calculate_rw(exchange_rate_data, forecasting_dates, normalize = False): 703 | #Create empty list containers that will hold the real change values values 704 | one_month = [] 705 | two_month = [] 706 | three_month = [] 707 | four_month = [] 708 | five_month = [] 709 | six_month = [] 710 | seven_month = [] 711 | eight_month = [] 712 | nine_month = [] 713 | ten_month = [] 714 | eleven_month = [] 715 | twelve_month = [] 716 | for date in forecasting_dates: 717 | one_month.append(float(np.log(exchange_rate_data.loc[str(date)[:7]])) - float(np.log(exchange_rate_data.loc[str(add_months(date,-1))[:7]]))) 718 | two_month.append(float(np.log(exchange_rate_data.loc[str(date)[:7]])) - float(np.log(exchange_rate_data.loc[str(add_months(date,-2))[:7]]))) 719 | three_month.append(float(np.log(exchange_rate_data.loc[str(date)[:7]])) - float(np.log(exchange_rate_data.loc[str(add_months(date,-3))[:7]]))) 720 | four_month.append(float(np.log(exchange_rate_data.loc[str(date)[:7]])) - float(np.log(exchange_rate_data.loc[str(add_months(date,-4))[:7]]))) 721 | five_month.append(float(np.log(exchange_rate_data.loc[str(date)[:7]])) - float(np.log(exchange_rate_data.loc[str(add_months(date,-5))[:7]]))) 722 | six_month.append(float(np.log(exchange_rate_data.loc[str(date)[:7]])) - float(np.log(exchange_rate_data.loc[str(add_months(date,-6))[:7]]))) 723 | seven_month.append(float(np.log(exchange_rate_data.loc[str(date)[:7]])) - float(np.log(exchange_rate_data.loc[str(add_months(date,-7))[:7]]))) 724 | eight_month.append(float(np.log(exchange_rate_data.loc[str(date)[:7]])) - float(np.log(exchange_rate_data.loc[str(add_months(date,-8))[:7]]))) 725 | nine_month.append(float(np.log(exchange_rate_data.loc[str(date)[:7]])) - float(np.log(exchange_rate_data.loc[str(add_months(date,-9))[:7]]))) 726 | ten_month.append(float(np.log(exchange_rate_data.loc[str(date)[:7]])) - float(np.log(exchange_rate_data.loc[str(add_months(date,-10))[:7]]))) 727 | eleven_month.append(float(np.log(exchange_rate_data.loc[str(date)[:7]])) - float(np.log(exchange_rate_data.loc[str(add_months(date,-11))[:7]]))) 728 | twelve_month.append(float(np.log(exchange_rate_data.loc[str(date)[:7]])) - float(np.log(exchange_rate_data.loc[str(add_months(date,-12))[:7]]))) 729 | 730 | if normalize: 731 | one_month = preprocessing.scale(one_month) 732 | two_month = preprocessing.scale(two_month) 733 | three_month = preprocessing.scale(three_month) 734 | four_month = preprocessing.scale(four_month) 735 | five_month = preprocessing.scale(five_month) 736 | six_month = preprocessing.scale(six_month) 737 | seven_month = preprocessing.scale(seven_month) 738 | eight_month = preprocessing.scale(eight_month) 739 | nine_month = preprocessing.scale(nine_month) 740 | ten_month = preprocessing.scale(ten_month) 741 | eleven_month = preprocessing.scale(eleven_month) 742 | twelve_month = preprocessing.scale(twelve_month) 743 | 744 | rw_dict = {'date': forecasting_dates, 745 | 'one_month': one_month, #Organize the results into a dictionary 746 | 'two_month': two_month, 747 | 'three_month': three_month, 748 | 'four_month': four_month, 749 | 'five_month': five_month, 750 | 'six_month': six_month, 751 | 'seven_month': seven_month, 752 | 'eight_month': eight_month, 753 | 'nine_month': nine_month, 754 | 'ten_month': ten_month, 755 | 'eleven_month': eleven_month, 756 | 'twelve_month': twelve_month} 757 | 758 | rw_df = pd.DataFrame.from_dict(rw_dict) #Convert the results from a dictionary to a dataframe 759 | rw_df.set_index('date', inplace=True) #Set the date column as index 760 | return rw_df 761 | 762 | 763 | rv = {} 764 | for country in list_of_countries[:-1]: 765 | rv[country] = calculate_rv(er[country], forecasting_dates, True) 766 | forecast_data['AUS'] 767 | rv['AUS'] 768 | rw = {} 769 | for country in list_of_countries[:-1]: 770 | rw[country] = calculate_rw(er[country], forecasting_dates, True) 771 | 772 | # multiple line plot 773 | def plot_results(country, month): 774 | plt.plot( forecast_data[country].index, forecast_data[country][month], color='skyblue', linewidth=2, linestyle='dashed', label='Forecast') 775 | plt.plot( rw[country].index, rw[country][month], marker='', color='olive', linewidth=2,linestyle='dashed', label='Random Walk') 776 | plt.plot( rv[country].index, rv[country][month], marker='', color='olive', linewidth=2, label="Real Value") 777 | plt.legend() 778 | 779 | plot_results('JAP', 'twelve_month') 780 | 781 | 782 | ###################################### 783 | #Accuracy metrics [Regression Metrics] 784 | ###################################### 785 | score = {} 786 | for model in ['forecast_model', 'random_walk']: 787 | score_dict = {} 788 | for country in list_of_countries[:-1]: 789 | one_month = [] 790 | two_month = [] 791 | three_month = [] 792 | four_month = [] 793 | five_month = [] 794 | six_month = [] 795 | seven_month = [] 796 | eight_month = [] 797 | nine_month = [] 798 | ten_month = [] 799 | eleven_month = [] 800 | twelve_month = [] 801 | test_name = [] 802 | 803 | #explained variance score : Best possible score is 1.0, lower values are worse. 804 | if model == 'forecast_model': 805 | 806 | #root mean_squared_error : Mean squared error regression loss 807 | test_name.append('root mean squared error') 808 | one_month.append(np.sqrt(metrics.mean_squared_error(rv[country]['one_month'], forecast_data[country]['one_month']))) 809 | two_month.append(np.sqrt(metrics.mean_squared_error(rv[country]['two_month'], forecast_data[country]['two_month']))) 810 | three_month.append(np.sqrt(metrics.mean_squared_error(rv[country]['three_month'], forecast_data[country]['three_month']))) 811 | four_month.append(np.sqrt(metrics.mean_squared_error(rv[country]['four_month'], forecast_data[country]['four_month']))) 812 | five_month.append(np.sqrt(metrics.mean_squared_error(rv[country]['five_month'], forecast_data[country]['five_month']))) 813 | six_month.append(np.sqrt(metrics.mean_squared_error(rv[country]['six_month'], forecast_data[country]['six_month']))) 814 | seven_month.append(np.sqrt(metrics.mean_squared_error(rv[country]['seven_month'], forecast_data[country]['seven_month']))) 815 | eight_month.append(np.sqrt(metrics.mean_squared_error(rv[country]['eight_month'], forecast_data[country]['eight_month']))) 816 | nine_month.append(np.sqrt(metrics.mean_squared_error(rv[country]['nine_month'], forecast_data[country]['nine_month']))) 817 | ten_month.append(np.sqrt(metrics.mean_squared_error(rv[country]['ten_month'], forecast_data[country]['ten_month']))) 818 | eleven_month.append(np.sqrt(metrics.mean_squared_error(rv[country]['eleven_month'], forecast_data[country]['eleven_month']))) 819 | twelve_month.append(np.sqrt(metrics.mean_squared_error(rv[country]['twelve_month'], forecast_data[country]['twelve_month']))) 820 | 821 | #median absolute error :Median absolute error output is non-negative floating point. The best value is 0.0. 822 | test_name.append('median absolute error') 823 | one_month.append(metrics.median_absolute_error(rv[country]['one_month'], forecast_data[country]['one_month'])) 824 | two_month.append(metrics.median_absolute_error(rv[country]['two_month'], forecast_data[country]['two_month'])) 825 | three_month.append(metrics.median_absolute_error(rv[country]['three_month'], forecast_data[country]['three_month'])) 826 | four_month.append(metrics.median_absolute_error(rv[country]['four_month'], forecast_data[country]['four_month'])) 827 | five_month.append(metrics.median_absolute_error(rv[country]['five_month'], forecast_data[country]['five_month'])) 828 | six_month.append(metrics.median_absolute_error(rv[country]['six_month'], forecast_data[country]['six_month'])) 829 | seven_month.append(metrics.median_absolute_error(rv[country]['seven_month'], forecast_data[country]['seven_month'])) 830 | eight_month.append(metrics.median_absolute_error(rv[country]['eight_month'], forecast_data[country]['eight_month'])) 831 | nine_month.append(metrics.median_absolute_error(rv[country]['nine_month'], forecast_data[country]['nine_month'])) 832 | ten_month.append(metrics.median_absolute_error(rv[country]['ten_month'], forecast_data[country]['ten_month'])) 833 | eleven_month.append(metrics.median_absolute_error(rv[country]['eleven_month'], forecast_data[country]['eleven_month'])) 834 | twelve_month.append(metrics.median_absolute_error(rv[country]['twelve_month'], forecast_data[country]['twelve_month'])) 835 | 836 | 837 | 838 | else: 839 | 840 | 841 | #root mean_squared_error : Mean squared error regression loss 842 | test_name.append('root mean squared error') 843 | one_month.append(np.sqrt(metrics.mean_squared_error(rv[country]['one_month'], rw[country]['one_month']))) 844 | two_month.append(np.sqrt(metrics.mean_squared_error(rv[country]['two_month'], rw[country]['two_month']))) 845 | three_month.append(np.sqrt(metrics.mean_squared_error(rv[country]['three_month'], rw[country]['three_month']))) 846 | four_month.append(np.sqrt(metrics.mean_squared_error(rv[country]['four_month'], rw[country]['four_month']))) 847 | five_month.append(np.sqrt(metrics.mean_squared_error(rv[country]['five_month'], rw[country]['five_month']))) 848 | six_month.append(np.sqrt(metrics.mean_squared_error(rv[country]['six_month'], rw[country]['six_month']))) 849 | seven_month.append(np.sqrt(metrics.mean_squared_error(rv[country]['seven_month'], rw[country]['seven_month']))) 850 | eight_month.append(np.sqrt(metrics.mean_squared_error(rv[country]['eight_month'], rw[country]['eight_month']))) 851 | nine_month.append(np.sqrt(metrics.mean_squared_error(rv[country]['nine_month'], rw[country]['nine_month']))) 852 | ten_month.append(np.sqrt(metrics.mean_squared_error(rv[country]['ten_month'], rw[country]['ten_month']))) 853 | eleven_month.append(np.sqrt(metrics.mean_squared_error(rv[country]['eleven_month'], rw[country]['eleven_month']))) 854 | twelve_month.append(np.sqrt(metrics.mean_squared_error(rv[country]['twelve_month'], rw[country]['twelve_month']))) 855 | 856 | #median absolute error :Median absolute error output is non-negative floating point. The best value is 0.0. 857 | test_name.append('median absolute error') 858 | one_month.append(metrics.median_absolute_error(rv[country]['one_month'], rw[country]['one_month'])) 859 | two_month.append(metrics.median_absolute_error(rv[country]['two_month'], rw[country]['two_month'])) 860 | three_month.append(metrics.median_absolute_error(rv[country]['three_month'], rw[country]['three_month'])) 861 | four_month.append(metrics.median_absolute_error(rv[country]['four_month'], rw[country]['four_month'])) 862 | five_month.append(metrics.median_absolute_error(rv[country]['five_month'], rw[country]['five_month'])) 863 | six_month.append(metrics.median_absolute_error(rv[country]['six_month'], rw[country]['six_month'])) 864 | seven_month.append(metrics.median_absolute_error(rv[country]['seven_month'], rw[country]['seven_month'])) 865 | eight_month.append(metrics.median_absolute_error(rv[country]['eight_month'], rw[country]['eight_month'])) 866 | nine_month.append(metrics.median_absolute_error(rv[country]['nine_month'], rw[country]['nine_month'])) 867 | ten_month.append(metrics.median_absolute_error(rv[country]['ten_month'], rw[country]['ten_month'])) 868 | eleven_month.append(metrics.median_absolute_error(rv[country]['eleven_month'], rw[country]['eleven_month'])) 869 | twelve_month.append(metrics.median_absolute_error(rv[country]['twelve_month'], rw[country]['twelve_month'])) 870 | 871 | 872 | 873 | score_dict[country] = {'test_name': test_name, 874 | 'one_month': one_month, #Organize the results into a dictionary 875 | 'two_month': two_month, 876 | 'three_month': three_month, 877 | 'four_month': four_month, 878 | 'five_month': five_month, 879 | 'six_month': six_month, 880 | 'seven_month': seven_month, 881 | 'eight_month': eight_month, 882 | 'nine_month': nine_month, 883 | 'ten_month': ten_month, 884 | 'eleven_month': eleven_month, 885 | 'twelve_month': twelve_month} 886 | 887 | score[model] = score_dict 888 | 889 | 890 | random_walk_scores = pd.DataFrame.from_dict({(i,j): score['random_walk'][i][j] 891 | for i in score['random_walk'].keys() 892 | for j in score['random_walk'][i].keys()}, 893 | orient='index') 894 | 895 | random_walk_scores.index = pd.MultiIndex.from_tuples(random_walk_scores.index) 896 | random_walk_scores.columns = random_walk_scores.loc['AUS'].loc['test_name'] 897 | random_walk_scores.drop(index='test_name', level=1, inplace = True) 898 | 899 | 900 | forecast_model_scores = pd.DataFrame.from_dict({(i,j): score['forecast_model'][i][j] 901 | for i in score['forecast_model'].keys() 902 | for j in score['forecast_model'][i].keys()}, 903 | orient='index') 904 | 905 | forecast_model_scores.index = pd.MultiIndex.from_tuples(forecast_model_scores.index) 906 | forecast_model_scores.columns = forecast_model_scores.loc['AUS'].loc['test_name'] 907 | forecast_model_scores.drop(index='test_name', level=1, inplace = True) 908 | 909 | 910 | #Create directional variable: 911 | forecast_directional = {} 912 | 913 | for country in list_of_countries[:-1]: 914 | forecast_directional[country] = {} 915 | forecast_directional[country]['one_month'] = np.where(forecast_data[country]['one_month'].isnull(), np.nan, 916 | np.where(forecast_data[country]['one_month'] > 0, 1, -1)) 917 | 918 | forecast_directional[country]['two_month'] = np.where(forecast_data[country]['two_month'].isnull(), np.nan, 919 | np.where(forecast_data[country]['two_month'] > 0, 1, -1)) 920 | 921 | forecast_directional[country]['three_month'] = np.where(forecast_data[country]['three_month'].isnull(), np.nan, 922 | np.where(forecast_data[country]['three_month'] > 0, 1, -1)) 923 | 924 | forecast_directional[country]['four_month'] = np.where(forecast_data[country]['four_month'].isnull(), np.nan, 925 | np.where(forecast_data[country]['four_month'] > 0, 1, -1)) 926 | 927 | forecast_directional[country]['five_month'] = np.where(forecast_data[country]['five_month'].isnull(), np.nan, 928 | np.where(forecast_data[country]['five_month'] > 0, 1, -1)) 929 | 930 | forecast_directional[country]['six_month'] = np.where(forecast_data[country]['six_month'].isnull(), np.nan, 931 | np.where(forecast_data[country]['six_month'] > 0, 1, -1)) 932 | 933 | forecast_directional[country]['seven_month'] = np.where(forecast_data[country]['seven_month'].isnull(), np.nan, 934 | np.where(forecast_data[country]['seven_month'] > 0, 1, -1)) 935 | 936 | forecast_directional[country]['eight_month'] = np.where(forecast_data[country]['eight_month'].isnull(), np.nan, 937 | np.where(forecast_data[country]['eight_month'] > 0, 1, -1)) 938 | 939 | forecast_directional[country]['nine_month'] = np.where(forecast_data[country]['nine_month'].isnull(), np.nan, 940 | np.where(forecast_data[country]['nine_month'] > 0, 1, -1)) 941 | 942 | forecast_directional[country]['ten_month'] = np.where(forecast_data[country]['ten_month'].isnull(), np.nan, 943 | np.where(forecast_data[country]['ten_month'] > 0, 1, -1)) 944 | 945 | forecast_directional[country]['eleven_month'] = np.where(forecast_data[country]['eleven_month'].isnull(), np.nan, 946 | np.where(forecast_data[country]['eleven_month'] > 0, 1, -1)) 947 | 948 | forecast_directional[country]['twelve_month'] = np.where(forecast_data[country]['twelve_month'].isnull(), np.nan, 949 | np.where(forecast_data[country]['twelve_month'] > 0, 1, -1)) 950 | 951 | forecast_directional[country] = pd.DataFrame.from_dict(forecast_directional[country]) 952 | forecast_directional[country].index = forecast_data[country].index 953 | 954 | 955 | rv_directional = {} 956 | 957 | for country in list_of_countries[:-1]: 958 | rv_directional[country] = {} 959 | rv_directional[country]['one_month'] = np.where(rv[country]['one_month'].isnull(), np.nan, 960 | np.where(rv[country]['one_month'] > 0, 1, -1)) 961 | 962 | rv_directional[country]['two_month'] = np.where(rv[country]['two_month'].isnull(), np.nan, 963 | np.where(rv[country]['two_month'] > 0, 1, -1)) 964 | 965 | rv_directional[country]['three_month'] = np.where(rv[country]['three_month'].isnull(), np.nan, 966 | np.where(rv[country]['three_month'] > 0, 1, -1)) 967 | 968 | rv_directional[country]['four_month'] = np.where(rv[country]['four_month'].isnull(), np.nan, 969 | np.where(rv[country]['four_month'] > 0, 1, -1)) 970 | 971 | rv_directional[country]['five_month'] = np.where(rv[country]['five_month'].isnull(), np.nan, 972 | np.where(rv[country]['five_month'] > 0, 1, -1)) 973 | 974 | rv_directional[country]['six_month'] = np.where(rv[country]['six_month'].isnull(), np.nan, 975 | np.where(rv[country]['six_month'] > 0, 1, -1)) 976 | 977 | rv_directional[country]['seven_month'] = np.where(rv[country]['seven_month'].isnull(), np.nan, 978 | np.where(rv[country]['seven_month'] > 0, 1, -1)) 979 | 980 | rv_directional[country]['eight_month'] = np.where(rv[country]['eight_month'].isnull(), np.nan, 981 | np.where(rv[country]['eight_month'] > 0, 1, -1)) 982 | 983 | rv_directional[country]['nine_month'] = np.where(rv[country]['nine_month'].isnull(), np.nan, 984 | np.where(rv[country]['nine_month'] > 0, 1, -1)) 985 | 986 | rv_directional[country]['ten_month'] = np.where(rv[country]['ten_month'].isnull(), np.nan, 987 | np.where(rv[country]['ten_month'] > 0, 1, -1)) 988 | 989 | rv_directional[country]['eleven_month'] = np.where(rv[country]['eleven_month'].isnull(), np.nan, 990 | np.where(rv[country]['eleven_month'] > 0, 1, -1)) 991 | 992 | rv_directional[country]['twelve_month'] = np.where(rv[country]['twelve_month'].isnull(), np.nan, 993 | np.where(rv[country]['twelve_month'] > 0, 1, -1)) 994 | 995 | rv_directional[country] = pd.DataFrame.from_dict(rv_directional[country]) 996 | rv_directional[country].index = rv[country].index 997 | 998 | 999 | rw_directional = {} 1000 | 1001 | for country in list_of_countries[:-1]: 1002 | rw_directional[country] = {} 1003 | rw_directional[country]['one_month'] = np.where(rw[country]['one_month'].isnull(), np.nan, 1004 | np.where(rw[country]['one_month'] > 0, 1, -1)) 1005 | 1006 | rw_directional[country]['two_month'] = np.where(rw[country]['two_month'].isnull(), np.nan, 1007 | np.where(rw[country]['two_month'] > 0, 1, -1)) 1008 | 1009 | rw_directional[country]['three_month'] = np.where(rw[country]['three_month'].isnull(), np.nan, 1010 | np.where(rw[country]['three_month'] > 0, 1, -1)) 1011 | 1012 | rw_directional[country]['four_month'] = np.where(rw[country]['four_month'].isnull(), np.nan, 1013 | np.where(rw[country]['four_month'] > 0, 1, -1)) 1014 | 1015 | rw_directional[country]['five_month'] = np.where(rw[country]['five_month'].isnull(), np.nan, 1016 | np.where(rw[country]['five_month'] > 0, 1, -1)) 1017 | 1018 | rw_directional[country]['six_month'] = np.where(rw[country]['six_month'].isnull(), np.nan, 1019 | np.where(rw[country]['six_month'] > 0, 1, -1)) 1020 | 1021 | rw_directional[country]['seven_month'] = np.where(rw[country]['seven_month'].isnull(), np.nan, 1022 | np.where(rw[country]['seven_month'] > 0, 1, -1)) 1023 | 1024 | rw_directional[country]['eight_month'] = np.where(rw[country]['eight_month'].isnull(), np.nan, 1025 | np.where(rw[country]['eight_month'] > 0, 1, -1)) 1026 | 1027 | rw_directional[country]['nine_month'] = np.where(rw[country]['nine_month'].isnull(), np.nan, 1028 | np.where(rw[country]['nine_month'] > 0, 1, -1)) 1029 | 1030 | rw_directional[country]['ten_month'] = np.where(rw[country]['ten_month'].isnull(), np.nan, 1031 | np.where(rw[country]['ten_month'] > 0, 1, -1)) 1032 | 1033 | rw_directional[country]['eleven_month'] = np.where(rw[country]['eleven_month'].isnull(), np.nan, 1034 | np.where(rw[country]['eleven_month'] > 0, 1, -1)) 1035 | 1036 | rw_directional[country]['twelve_month'] = np.where(rw[country]['twelve_month'].isnull(), np.nan, 1037 | np.where(rw[country]['twelve_month'] > 0, 1, -1)) 1038 | 1039 | rw_directional[country] = pd.DataFrame.from_dict(rw_directional[country]) 1040 | rw_directional[country].index = rw[country].index 1041 | 1042 | 1043 | directional_score = {} 1044 | for model in ['forecast_model', 'random_walk']: 1045 | score_dict = {} 1046 | for country in list_of_countries[:-1]: 1047 | one_month = [] 1048 | two_month = [] 1049 | three_month = [] 1050 | four_month = [] 1051 | five_month = [] 1052 | six_month = [] 1053 | seven_month = [] 1054 | eight_month = [] 1055 | nine_month = [] 1056 | ten_month = [] 1057 | eleven_month = [] 1058 | twelve_month = [] 1059 | test_name = [] 1060 | 1061 | 1062 | 1063 | if model == 'forecast_model': 1064 | 1065 | #accuracy classification score : In multilabel classification, this function computes subset accuracy: 1066 | #the set of labels predicted for a sample must exactly match the corresponding set of labels in y_true. 1067 | test_name.append('accuracy classification score') 1068 | one_month.append(metrics.accuracy_score(rv_directional[country]['one_month'], forecast_directional[country]['one_month'])) 1069 | two_month.append(metrics.accuracy_score(rv_directional[country]['two_month'], forecast_directional[country]['two_month'])) 1070 | three_month.append(metrics.accuracy_score(rv_directional[country]['three_month'], forecast_directional[country]['three_month'])) 1071 | four_month.append(metrics.accuracy_score(rv_directional[country]['four_month'], forecast_directional[country]['four_month'])) 1072 | five_month.append(metrics.accuracy_score(rv_directional[country]['five_month'], forecast_directional[country]['five_month'])) 1073 | six_month.append(metrics.accuracy_score(rv_directional[country]['six_month'], forecast_directional[country]['six_month'])) 1074 | seven_month.append(metrics.accuracy_score(rv_directional[country]['seven_month'], forecast_directional[country]['seven_month'])) 1075 | eight_month.append(metrics.accuracy_score(rv_directional[country]['eight_month'], forecast_directional[country]['eight_month'])) 1076 | nine_month.append(metrics.accuracy_score(rv_directional[country]['nine_month'], forecast_directional[country]['nine_month'])) 1077 | ten_month.append(metrics.accuracy_score(rv_directional[country]['ten_month'], forecast_directional[country]['ten_month'])) 1078 | eleven_month.append(metrics.accuracy_score(rv_directional[country]['eleven_month'], forecast_directional[country]['eleven_month'])) 1079 | twelve_month.append(metrics.accuracy_score(rv_directional[country]['twelve_month'], forecast_directional[country]['twelve_month'])) 1080 | 1081 | 1082 | #Compute the F1 score, also known as balanced F-score or F-measure. The F1 score can be interpreted as a weighted average of the precision and recall, 1083 | #where an F1 score reaches its best value at 1 and worst score at 0. The relative contribution of precision and recall to the F1 score are equal. 1084 | test_name.append('f1 score') 1085 | one_month.append(metrics.f1_score(rv_directional[country]['one_month'], forecast_directional[country]['one_month'])) 1086 | two_month.append(metrics.f1_score(rv_directional[country]['two_month'], forecast_directional[country]['two_month'])) 1087 | three_month.append(metrics.f1_score(rv_directional[country]['three_month'], forecast_directional[country]['three_month'])) 1088 | four_month.append(metrics.f1_score(rv_directional[country]['four_month'], forecast_directional[country]['four_month'])) 1089 | five_month.append(metrics.f1_score(rv_directional[country]['five_month'], forecast_directional[country]['five_month'])) 1090 | six_month.append(metrics.f1_score(rv_directional[country]['six_month'], forecast_directional[country]['six_month'])) 1091 | seven_month.append(metrics.f1_score(rv_directional[country]['seven_month'], forecast_directional[country]['seven_month'])) 1092 | eight_month.append(metrics.f1_score(rv_directional[country]['eight_month'], forecast_directional[country]['eight_month'])) 1093 | nine_month.append(metrics.f1_score(rv_directional[country]['nine_month'], forecast_directional[country]['nine_month'])) 1094 | ten_month.append(metrics.f1_score(rv_directional[country]['ten_month'], forecast_directional[country]['ten_month'])) 1095 | eleven_month.append(metrics.f1_score(rv_directional[country]['eleven_month'], forecast_directional[country]['eleven_month'])) 1096 | twelve_month.append(metrics.f1_score(rv_directional[country]['twelve_month'], forecast_directional[country]['twelve_month'])) 1097 | 1098 | #Compute the precision: The precision is the ratio tp / (tp + fp) where tp is the number of true positives and fp the number of false positives. 1099 | #The precision is intuitively the ability of the classifier not to label as positive a sample that is negative. 1100 | test_name.append('precision') 1101 | one_month.append(metrics.precision_score(rv_directional[country]['one_month'], forecast_directional[country]['one_month'])) 1102 | two_month.append(metrics.precision_score(rv_directional[country]['two_month'], forecast_directional[country]['two_month'])) 1103 | three_month.append(metrics.precision_score(rv_directional[country]['three_month'], forecast_directional[country]['three_month'])) 1104 | four_month.append(metrics.precision_score(rv_directional[country]['four_month'], forecast_directional[country]['four_month'])) 1105 | five_month.append(metrics.precision_score(rv_directional[country]['five_month'], forecast_directional[country]['five_month'])) 1106 | six_month.append(metrics.precision_score(rv_directional[country]['six_month'], forecast_directional[country]['six_month'])) 1107 | seven_month.append(metrics.precision_score(rv_directional[country]['seven_month'], forecast_directional[country]['seven_month'])) 1108 | eight_month.append(metrics.precision_score(rv_directional[country]['eight_month'], forecast_directional[country]['eight_month'])) 1109 | nine_month.append(metrics.precision_score(rv_directional[country]['nine_month'], forecast_directional[country]['nine_month'])) 1110 | ten_month.append(metrics.precision_score(rv_directional[country]['ten_month'], forecast_directional[country]['ten_month'])) 1111 | eleven_month.append(metrics.precision_score(rv_directional[country]['eleven_month'], forecast_directional[country]['eleven_month'])) 1112 | twelve_month.append(metrics.precision_score(rv_directional[country]['twelve_month'], forecast_directional[country]['twelve_month'])) 1113 | 1114 | #Compute the recall: The best value is 1 and the worst value is 0. 1115 | test_name.append('recall') 1116 | one_month.append(metrics.recall_score(rv_directional[country]['one_month'], forecast_directional[country]['one_month'])) 1117 | two_month.append(metrics.recall_score(rv_directional[country]['two_month'], forecast_directional[country]['two_month'])) 1118 | three_month.append(metrics.recall_score(rv_directional[country]['three_month'], forecast_directional[country]['three_month'])) 1119 | four_month.append(metrics.recall_score(rv_directional[country]['four_month'], forecast_directional[country]['four_month'])) 1120 | five_month.append(metrics.recall_score(rv_directional[country]['five_month'], forecast_directional[country]['five_month'])) 1121 | six_month.append(metrics.recall_score(rv_directional[country]['six_month'], forecast_directional[country]['six_month'])) 1122 | seven_month.append(metrics.recall_score(rv_directional[country]['seven_month'], forecast_directional[country]['seven_month'])) 1123 | eight_month.append(metrics.recall_score(rv_directional[country]['eight_month'], forecast_directional[country]['eight_month'])) 1124 | nine_month.append(metrics.recall_score(rv_directional[country]['nine_month'], forecast_directional[country]['nine_month'])) 1125 | ten_month.append(metrics.recall_score(rv_directional[country]['ten_month'], forecast_directional[country]['ten_month'])) 1126 | eleven_month.append(metrics.recall_score(rv_directional[country]['eleven_month'], forecast_directional[country]['eleven_month'])) 1127 | twelve_month.append(metrics.recall_score(rv_directional[country]['twelve_month'], forecast_directional[country]['twelve_month'])) 1128 | 1129 | else: 1130 | #accuracy classification score : In multilabel classification, this function computes subset accuracy: 1131 | #the set of labels predicted for a sample must exactly match the corresponding set of labels in y_true. 1132 | test_name.append('accuracy classification score') 1133 | one_month.append(metrics.accuracy_score(rv_directional[country]['one_month'], rw_directional[country]['one_month'])) 1134 | two_month.append(metrics.accuracy_score(rv_directional[country]['two_month'], rw_directional[country]['two_month'])) 1135 | three_month.append(metrics.accuracy_score(rv_directional[country]['three_month'], rw_directional[country]['three_month'])) 1136 | four_month.append(metrics.accuracy_score(rv_directional[country]['four_month'], rw_directional[country]['four_month'])) 1137 | five_month.append(metrics.accuracy_score(rv_directional[country]['five_month'], rw_directional[country]['five_month'])) 1138 | six_month.append(metrics.accuracy_score(rv_directional[country]['six_month'], rw_directional[country]['six_month'])) 1139 | seven_month.append(metrics.accuracy_score(rv_directional[country]['seven_month'], rw_directional[country]['seven_month'])) 1140 | eight_month.append(metrics.accuracy_score(rv_directional[country]['eight_month'], rw_directional[country]['eight_month'])) 1141 | nine_month.append(metrics.accuracy_score(rv_directional[country]['nine_month'], rw_directional[country]['nine_month'])) 1142 | ten_month.append(metrics.accuracy_score(rv_directional[country]['ten_month'], rw_directional[country]['ten_month'])) 1143 | eleven_month.append(metrics.accuracy_score(rv_directional[country]['eleven_month'], rw_directional[country]['eleven_month'])) 1144 | twelve_month.append(metrics.accuracy_score(rv_directional[country]['twelve_month'], rw_directional[country]['twelve_month'])) 1145 | 1146 | 1147 | #Compute the F1 score, also known as balanced F-score or F-measure. The F1 score can be interpreted as a weighted average of the precision and recall, 1148 | #where an F1 score reaches its best value at 1 and worst score at 0. The relative contribution of precision and recall to the F1 score are equal. 1149 | test_name.append('f1 score') 1150 | one_month.append(metrics.f1_score(rv_directional[country]['one_month'], rw_directional[country]['one_month'])) 1151 | two_month.append(metrics.f1_score(rv_directional[country]['two_month'], rw_directional[country]['two_month'])) 1152 | three_month.append(metrics.f1_score(rv_directional[country]['three_month'], rw_directional[country]['three_month'])) 1153 | four_month.append(metrics.f1_score(rv_directional[country]['four_month'], rw_directional[country]['four_month'])) 1154 | five_month.append(metrics.f1_score(rv_directional[country]['five_month'], rw_directional[country]['five_month'])) 1155 | six_month.append(metrics.f1_score(rv_directional[country]['six_month'], rw_directional[country]['six_month'])) 1156 | seven_month.append(metrics.f1_score(rv_directional[country]['seven_month'], rw_directional[country]['seven_month'])) 1157 | eight_month.append(metrics.f1_score(rv_directional[country]['eight_month'], rw_directional[country]['eight_month'])) 1158 | nine_month.append(metrics.f1_score(rv_directional[country]['nine_month'], rw_directional[country]['nine_month'])) 1159 | ten_month.append(metrics.f1_score(rv_directional[country]['ten_month'], rw_directional[country]['ten_month'])) 1160 | eleven_month.append(metrics.f1_score(rv_directional[country]['eleven_month'], rw_directional[country]['eleven_month'])) 1161 | twelve_month.append(metrics.f1_score(rv_directional[country]['twelve_month'], rw_directional[country]['twelve_month'])) 1162 | 1163 | #Compute the precision: The precision is the ratio tp / (tp + fp) where tp is the number of true positives and fp the number of false positives. 1164 | #The precision is intuitively the ability of the classifier not to label as positive a sample that is negative. 1165 | test_name.append('precision') 1166 | one_month.append(metrics.precision_score(rv_directional[country]['one_month'], rw_directional[country]['one_month'])) 1167 | two_month.append(metrics.precision_score(rv_directional[country]['two_month'], rw_directional[country]['two_month'])) 1168 | three_month.append(metrics.precision_score(rv_directional[country]['three_month'], rw_directional[country]['three_month'])) 1169 | four_month.append(metrics.precision_score(rv_directional[country]['four_month'], rw_directional[country]['four_month'])) 1170 | five_month.append(metrics.precision_score(rv_directional[country]['five_month'], rw_directional[country]['five_month'])) 1171 | six_month.append(metrics.precision_score(rv_directional[country]['six_month'], rw_directional[country]['six_month'])) 1172 | seven_month.append(metrics.precision_score(rv_directional[country]['seven_month'], rw_directional[country]['seven_month'])) 1173 | eight_month.append(metrics.precision_score(rv_directional[country]['eight_month'], rw_directional[country]['eight_month'])) 1174 | nine_month.append(metrics.precision_score(rv_directional[country]['nine_month'], rw_directional[country]['nine_month'])) 1175 | ten_month.append(metrics.precision_score(rv_directional[country]['ten_month'], rw_directional[country]['ten_month'])) 1176 | eleven_month.append(metrics.precision_score(rv_directional[country]['eleven_month'], rw_directional[country]['eleven_month'])) 1177 | twelve_month.append(metrics.precision_score(rv_directional[country]['twelve_month'], rw_directional[country]['twelve_month'])) 1178 | 1179 | #Compute the recall: The best value is 1 and the worst value is 0. 1180 | test_name.append('recall') 1181 | one_month.append(metrics.recall_score(rv_directional[country]['one_month'], rw_directional[country]['one_month'])) 1182 | two_month.append(metrics.recall_score(rv_directional[country]['two_month'], rw_directional[country]['two_month'])) 1183 | three_month.append(metrics.recall_score(rv_directional[country]['three_month'], rw_directional[country]['three_month'])) 1184 | four_month.append(metrics.recall_score(rv_directional[country]['four_month'], rw_directional[country]['four_month'])) 1185 | five_month.append(metrics.recall_score(rv_directional[country]['five_month'], rw_directional[country]['five_month'])) 1186 | six_month.append(metrics.recall_score(rv_directional[country]['six_month'], rw_directional[country]['six_month'])) 1187 | seven_month.append(metrics.recall_score(rv_directional[country]['seven_month'], rw_directional[country]['seven_month'])) 1188 | eight_month.append(metrics.recall_score(rv_directional[country]['eight_month'], rw_directional[country]['eight_month'])) 1189 | nine_month.append(metrics.recall_score(rv_directional[country]['nine_month'], rw_directional[country]['nine_month'])) 1190 | ten_month.append(metrics.recall_score(rv_directional[country]['ten_month'], rw_directional[country]['ten_month'])) 1191 | eleven_month.append(metrics.recall_score(rv_directional[country]['eleven_month'], rw_directional[country]['eleven_month'])) 1192 | twelve_month.append(metrics.recall_score(rv_directional[country]['twelve_month'], rw_directional[country]['twelve_month'])) 1193 | 1194 | score_dict[country] = {'test_name': test_name, 1195 | 'one_month': one_month, #Organize the results into a dictionary 1196 | 'two_month': two_month, 1197 | 'three_month': three_month, 1198 | 'four_month': four_month, 1199 | 'five_month': five_month, 1200 | 'six_month': six_month, 1201 | 'seven_month': seven_month, 1202 | 'eight_month': eight_month, 1203 | 'nine_month': nine_month, 1204 | 'ten_month': ten_month, 1205 | 'eleven_month': eleven_month, 1206 | 'twelve_month': twelve_month} 1207 | 1208 | directional_score[model] = score_dict 1209 | 1210 | 1211 | 1212 | random_walk_directional_scores = pd.DataFrame.from_dict({(i,j): directional_score['random_walk'][i][j] 1213 | for i in directional_score['random_walk'].keys() 1214 | for j in directional_score['random_walk'][i].keys()}, 1215 | orient='index') 1216 | 1217 | random_walk_directional_scores.index = pd.MultiIndex.from_tuples(random_walk_directional_scores.index) 1218 | random_walk_directional_scores.columns = random_walk_directional_scores.loc['AUS'].loc['test_name'] 1219 | random_walk_directional_scores.drop(index='test_name', level=1, inplace = True) 1220 | 1221 | 1222 | forecast_model_directional_scores = pd.DataFrame.from_dict({(i,j): directional_score['forecast_model'][i][j] 1223 | for i in directional_score['forecast_model'].keys() 1224 | for j in directional_score['forecast_model'][i].keys()}, 1225 | orient='index') 1226 | 1227 | forecast_model_directional_scores.index = pd.MultiIndex.from_tuples(forecast_model_directional_scores.index) 1228 | forecast_model_directional_scores.columns = forecast_model_directional_scores.loc['AUS'].loc['test_name'] 1229 | forecast_model_directional_scores.drop(index='test_name', level=1, inplace = True) 1230 | 1231 | 1232 | random_walk_directional_scores.loc['AUS'] 1233 | forecast_model_directional_scores.loc['AUS'] 1234 | 1235 | forecast_scores = pd.concat([forecast_model_scores, forecast_model_directional_scores], axis = 1) 1236 | rw_scores = pd.concat([random_walk_scores, random_walk_directional_scores], axis = 1) 1237 | forecast_model_scores.loc['AUS'] 1238 | 1239 | forecast_scores.loc['AUS'] 1240 | rw_scores.loc['AUS'] 1241 | 1242 | plotting_df = {} 1243 | for country in list_of_countries[:-1]: 1244 | plotting_df[country] = pd.DataFrame() 1245 | plotting_df[country]['RMSE'] = forecast_scores.loc[country]['root mean squared error'] / rw_scores.loc[country]['root mean squared error'] 1246 | plotting_df[country]['Accuracy Score'] = rw_scores.loc[country]['accuracy classification score'] / forecast_scores.loc[country]['accuracy classification score'] 1247 | plotting_df[country]['F1 Score'] = rw_scores.loc[country]['f1 score'] / forecast_scores.loc[country]['f1 score'] 1248 | plotting_df[country]['Precision'] = rw_scores.loc[country]['precision'] / forecast_scores.loc[country]['precision'] 1249 | plotting_df[country]['Recall'] = rw_scores.loc[country]['recall'] / forecast_scores.loc[country]['recall'] 1250 | plotting_df[country].index = [1,2,3,4,5,6,7,8,9,10,11,12] 1251 | 1252 | plotting_df['AUS'] 1253 | 1254 | 1255 | 1256 | 1257 | ######################################### 1258 | #Plot Accuracy Metrics for each Country 1259 | ######################################## 1260 | 1261 | fig, axes = plt.subplots(nrows=4, ncols=2) 1262 | plotting_df['AUS'].plot(xticks=range(0, 12),ax=axes[0,0], title = 'Australia', legend = None, grid = False, marker = 'o', ms=3, ylim = (0.2, 2.25)).hlines(1,1, 12, color = 'black', linewidth = 1.5) 1263 | plotting_df['CAN'].plot(xticks=range(0, 12), ax=axes[3,1], title = 'Canada', legend = None, grid = False, marker = 'o', ms=3, ylim = (0.2, 2.25)).hlines(1,1, 12, color = 'black', linewidth = 1.5) 1264 | plotting_df['JAP'].plot(xticks=range(0, 12), ax=axes[1,0], title = 'Japan', legend = None, grid = False, marker = 'o', ms=3, ylim = (0.2, 2.25)).hlines(1,1, 12, color = 'black', linewidth = 1.5) 1265 | plotting_df['NOR'].plot(xticks=range(0, 12), ax=axes[1,1], title = 'Norway', legend = None, grid = False, marker = 'o', ms=3, ylim = (0.2, 2.25)).hlines(1,1, 12, color = 'black', linewidth = 1.5) 1266 | plotting_df['SWE'].plot(xticks=range(0, 12), ax=axes[2,0], title = 'Sweden', legend = None, grid = False, marker = 'o', ms=3, ylim = (0.2, 2.25)).hlines(1,1, 12, color = 'black', linewidth = 1.5) 1267 | plotting_df['SWI'].plot(xticks=range(0, 12), ax=axes[2,1], title = 'Switzerland', legend = None, grid = False, marker = 'o', ms=3, ylim = (0.2, 2.25)).hlines(1,1, 12, color = 'black', linewidth = 1.5) 1268 | plotting_df['UK'].plot(xticks=range(0, 12), ax=axes[3,0], title = 'United Kingdoms', legend = None, grid = False, marker = 'o', ms=3, ylim = (0.2, 2.25)).hlines(1,1, 12, color = 'black', linewidth = 1.5) 1269 | fig.delaxes(axes[0,1]) 1270 | for ax in [axes[0,0], axes[0,1], axes[1,0], axes[1,1], axes[2,0], axes[2,1]]: 1271 | ax.set_xticks([]) 1272 | for ax in [axes[3,1], axes[1,1],axes[2,1]]: 1273 | ax.set_yticks([]) 1274 | handles, labels = axes[0,0].get_legend_handles_labels() 1275 | fig.legend(handles, labels,loc = 'lower right', bbox_to_anchor=(0.78, 0.72), prop={'size': 15}) 1276 | 1277 | 1278 | ########################################## 1279 | #Plot Countries for each Accuracy Metric 1280 | ########################################## 1281 | list_of_tests_order1 = {'RMSE': 'root mean squared error'} 1282 | list_of_tests_order2 = {'Accuracy Score': 'accuracy classification score', 'F1 Score': 'f1 score', 'Precision': 'precision', 'Recall': 'recall'} 1283 | rw_scores_trans = rw_scores.unstack(level= [1]).T 1284 | forecast_scores_trans = forecast_scores.unstack(level= [1]).T 1285 | 1286 | plotting_df_trans = {} 1287 | for name, test in list_of_tests_order1.items(): 1288 | plotting_df_trans[name] = pd.DataFrame() 1289 | for country in list_of_countries[:-1]: 1290 | plotting_df_trans[name][country] = forecast_scores_trans.loc[test][country] / rw_scores_trans.loc[test][country] 1291 | plotting_df_trans[name].index = [1,2,3,4,5,6,7,8,9,10,11,12] 1292 | 1293 | 1294 | for name, test in list_of_tests_order2.items(): 1295 | plotting_df_trans[name] = pd.DataFrame() 1296 | for country in list_of_countries[:-1]: 1297 | plotting_df_trans[name][country] = rw_scores_trans.loc[test][country] / forecast_scores_trans.loc[test][country] 1298 | plotting_df_trans[name].index = [1,2,3,4,5,6,7,8,9,10,11,12] 1299 | 1300 | fig, axes = plt.subplots(nrows=3, ncols=2) 1301 | plotting_df_trans['RMSE'].plot(xticks=range(0, 12),ax=axes[0,0], title = 'RMSE', legend = None, grid = False, marker = 'o', ms=3, ylim = (0.2, 2.25)).hlines(1,1, 12, color = 'black', linewidth = 1.5) 1302 | plotting_df_trans['Accuracy Score'].plot(xticks=range(0, 12), ax=axes[2,1], title = 'Accuracy Score', legend = None, grid = False, marker = 'o', ms=3, ylim = (0.2, 2.25)).hlines(1,1, 12, color = 'black', linewidth = 1.5) 1303 | plotting_df_trans['F1 Score'].plot(xticks=range(0, 12), ax=axes[1,0], title = 'F1 Score', legend = None, grid = False, marker = 'o', ms=3, ylim = (0.2, 2.25)).hlines(1,1, 12, color = 'black', linewidth = 1.5) 1304 | plotting_df_trans['Precision'].plot(xticks=range(0, 12), ax=axes[1,1], title = 'Precision', legend = None, grid = False, marker = 'o', ms=3, ylim = (0.2, 2.25)).hlines(1,1, 12, color = 'black', linewidth = 1.5) 1305 | plotting_df_trans['Recall'].plot(xticks=range(0, 12), ax=axes[2,0], title = 'Recall', legend = None, grid = False, marker = 'o', ms=3, ylim = (0.2, 2.25)).hlines(1,1, 12, color = 'black', linewidth = 1.5) 1306 | fig.delaxes(axes[0,1]) 1307 | for ax in [axes[0,0], axes[0,1], axes[1,0], axes[1,1]]: 1308 | ax.set_xticks([]) 1309 | for ax in [axes[1,1],axes[2,1]]: 1310 | ax.set_yticks([]) 1311 | handles, labels = axes[0,0].get_legend_handles_labels() 1312 | fig.legend(handles, labels,loc = 'lower right', bbox_to_anchor=(0.75, 0.65), prop={'size': 15}) 1313 | 1314 | 1315 | #Export accuracy metrics: 1316 | forecast_scores.to_csv('forecasting_model_scores.csv') 1317 | rw_scores.to_csv('random_walk_scores.csv') 1318 | --------------------------------------------------------------------------------