| Total Complexity | 101 | 
| Total Lines | 605 | 
| Duplicated Lines | 0 % | 
Complex classes like tests.risk.TestRisk often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
| 1 | #  | 
            ||
| 38 | class TestRisk(unittest.TestCase):  | 
            ||
| 39 | |||
| 40 | @classmethod  | 
            ||
| 41 | def setUpClass(cls):  | 
            ||
| 42 | cls.env = TradingEnvironment()  | 
            ||
| 43 | |||
| 44 | @classmethod  | 
            ||
| 45 | def tearDownClass(cls):  | 
            ||
| 46 | del cls.env  | 
            ||
| 47 | |||
| 48 | def setUp(self):  | 
            ||
| 49 | |||
| 50 | start_date = datetime.datetime(  | 
            ||
| 51 | year=2006,  | 
            ||
| 52 | month=1,  | 
            ||
| 53 | day=1,  | 
            ||
| 54 | hour=0,  | 
            ||
| 55 | minute=0,  | 
            ||
| 56 | tzinfo=pytz.utc)  | 
            ||
| 57 | end_date = datetime.datetime(  | 
            ||
| 58 | year=2006, month=12, day=31, tzinfo=pytz.utc)  | 
            ||
| 59 | |||
| 60 | self.sim_params = SimulationParameters(  | 
            ||
| 61 | period_start=start_date,  | 
            ||
| 62 | period_end=end_date,  | 
            ||
| 63 | env=self.env,  | 
            ||
| 64 | )  | 
            ||
| 65 | |||
| 66 | self.algo_returns_06 = factory.create_returns_from_list(  | 
            ||
| 67 | RETURNS,  | 
            ||
| 68 | self.sim_params  | 
            ||
| 69 | )  | 
            ||
| 70 | |||
| 71 | self.benchmark_returns_06 = \  | 
            ||
| 72 | answer_key.RETURNS_DATA['Benchmark Returns']  | 
            ||
| 73 | |||
| 74 | self.metrics_06 = risk.RiskReport(  | 
            ||
| 75 | self.algo_returns_06,  | 
            ||
| 76 | self.sim_params,  | 
            ||
| 77 | benchmark_returns=self.benchmark_returns_06,  | 
            ||
| 78 | env=self.env,  | 
            ||
| 79 | )  | 
            ||
| 80 | |||
| 81 | start_08 = datetime.datetime(  | 
            ||
| 82 | year=2008,  | 
            ||
| 83 | month=1,  | 
            ||
| 84 | day=1,  | 
            ||
| 85 | hour=0,  | 
            ||
| 86 | minute=0,  | 
            ||
| 87 | tzinfo=pytz.utc)  | 
            ||
| 88 | |||
| 89 | end_08 = datetime.datetime(  | 
            ||
| 90 | year=2008,  | 
            ||
| 91 | month=12,  | 
            ||
| 92 | day=31,  | 
            ||
| 93 | tzinfo=pytz.utc  | 
            ||
| 94 | )  | 
            ||
| 95 | self.sim_params08 = SimulationParameters(  | 
            ||
| 96 | period_start=start_08,  | 
            ||
| 97 | period_end=end_08,  | 
            ||
| 98 | env=self.env,  | 
            ||
| 99 | )  | 
            ||
| 100 | |||
| 101 | def tearDown(self):  | 
            ||
| 102 | return  | 
            ||
| 103 | |||
| 104 | def test_factory(self):  | 
            ||
| 105 | returns = [0.1] * 100  | 
            ||
| 106 | r_objects = factory.create_returns_from_list(returns, self.sim_params)  | 
            ||
| 107 | self.assertTrue(r_objects.index[-1] <=  | 
            ||
| 108 | datetime.datetime(  | 
            ||
| 109 | year=2006, month=12, day=31, tzinfo=pytz.utc))  | 
            ||
| 110 | |||
| 111 | def test_drawdown(self):  | 
            ||
| 112 | returns = factory.create_returns_from_list(  | 
            ||
| 113 | [1.0, -0.5, 0.8, .17, 1.0, -0.1, -0.45], self.sim_params)  | 
            ||
| 114 | # 200, 100, 180, 210.6, 421.2, 379.8, 208.494  | 
            ||
| 115 | metrics = risk.RiskMetricsPeriod(  | 
            ||
| 116 | returns.index[0],  | 
            ||
| 117 | returns.index[-1],  | 
            ||
| 118 | returns,  | 
            ||
| 119 | env=self.env,  | 
            ||
| 120 | benchmark_returns=self.env.benchmark_returns,  | 
            ||
| 121 | )  | 
            ||
| 122 | self.assertEqual(metrics.max_drawdown, 0.505)  | 
            ||
| 123 | |||
| 124 | def test_benchmark_returns_06(self):  | 
            ||
| 
                                                                                                    
                        
                         | 
                |||
| 125 | |||
| 126 | np.testing.assert_almost_equal(  | 
            ||
| 127 | [x.benchmark_period_returns  | 
            ||
| 128 | for x in self.metrics_06.month_periods],  | 
            ||
| 129 | ANSWER_KEY.BENCHMARK_PERIOD_RETURNS['Monthly'])  | 
            ||
| 130 | np.testing.assert_almost_equal(  | 
            ||
| 131 | [x.benchmark_period_returns  | 
            ||
| 132 | for x in self.metrics_06.three_month_periods],  | 
            ||
| 133 | ANSWER_KEY.BENCHMARK_PERIOD_RETURNS['3-Month'])  | 
            ||
| 134 | np.testing.assert_almost_equal(  | 
            ||
| 135 | [x.benchmark_period_returns  | 
            ||
| 136 | for x in self.metrics_06.six_month_periods],  | 
            ||
| 137 | ANSWER_KEY.BENCHMARK_PERIOD_RETURNS['6-month'])  | 
            ||
| 138 | np.testing.assert_almost_equal(  | 
            ||
| 139 | [x.benchmark_period_returns  | 
            ||
| 140 | for x in self.metrics_06.year_periods],  | 
            ||
| 141 | ANSWER_KEY.BENCHMARK_PERIOD_RETURNS['year'])  | 
            ||
| 142 | |||
| 143 | def test_trading_days_06(self):  | 
            ||
| 144 | returns = factory.create_returns_from_range(self.sim_params)  | 
            ||
| 145 | metrics = risk.RiskReport(returns, self.sim_params, env=self.env)  | 
            ||
| 146 | self.assertEqual([x.num_trading_days for x in metrics.year_periods],  | 
            ||
| 147 | [251])  | 
            ||
| 148 | self.assertEqual([x.num_trading_days for x in metrics.month_periods],  | 
            ||
| 149 | [20, 19, 23, 19, 22, 22, 20, 23, 20, 22, 21, 20])  | 
            ||
| 150 | |||
| 151 | def test_benchmark_volatility_06(self):  | 
            ||
| 152 | |||
| 153 | np.testing.assert_almost_equal(  | 
            ||
| 154 | [x.benchmark_volatility  | 
            ||
| 155 | for x in self.metrics_06.month_periods],  | 
            ||
| 156 | ANSWER_KEY.BENCHMARK_PERIOD_VOLATILITY['Monthly'])  | 
            ||
| 157 | np.testing.assert_almost_equal(  | 
            ||
| 158 | [x.benchmark_volatility  | 
            ||
| 159 | for x in self.metrics_06.three_month_periods],  | 
            ||
| 160 | ANSWER_KEY.BENCHMARK_PERIOD_VOLATILITY['3-Month'])  | 
            ||
| 161 | np.testing.assert_almost_equal(  | 
            ||
| 162 | [x.benchmark_volatility  | 
            ||
| 163 | for x in self.metrics_06.six_month_periods],  | 
            ||
| 164 | ANSWER_KEY.BENCHMARK_PERIOD_VOLATILITY['6-month'])  | 
            ||
| 165 | np.testing.assert_almost_equal(  | 
            ||
| 166 | [x.benchmark_volatility  | 
            ||
| 167 | for x in self.metrics_06.year_periods],  | 
            ||
| 168 | ANSWER_KEY.BENCHMARK_PERIOD_VOLATILITY['year'])  | 
            ||
| 169 | |||
| 170 | def test_algorithm_returns_06(self):  | 
            ||
| 171 | np.testing.assert_almost_equal(  | 
            ||
| 172 | [x.algorithm_period_returns  | 
            ||
| 173 | for x in self.metrics_06.month_periods],  | 
            ||
| 174 | ANSWER_KEY.ALGORITHM_PERIOD_RETURNS['Monthly'])  | 
            ||
| 175 | np.testing.assert_almost_equal(  | 
            ||
| 176 | [x.algorithm_period_returns  | 
            ||
| 177 | for x in self.metrics_06.three_month_periods],  | 
            ||
| 178 | ANSWER_KEY.ALGORITHM_PERIOD_RETURNS['3-Month'])  | 
            ||
| 179 | np.testing.assert_almost_equal(  | 
            ||
| 180 | [x.algorithm_period_returns  | 
            ||
| 181 | for x in self.metrics_06.six_month_periods],  | 
            ||
| 182 | ANSWER_KEY.ALGORITHM_PERIOD_RETURNS['6-month'])  | 
            ||
| 183 | np.testing.assert_almost_equal(  | 
            ||
| 184 | [x.algorithm_period_returns  | 
            ||
| 185 | for x in self.metrics_06.year_periods],  | 
            ||
| 186 | ANSWER_KEY.ALGORITHM_PERIOD_RETURNS['year'])  | 
            ||
| 187 | |||
| 188 | def test_algorithm_volatility_06(self):  | 
            ||
| 189 | np.testing.assert_almost_equal(  | 
            ||
| 190 | [x.algorithm_volatility  | 
            ||
| 191 | for x in self.metrics_06.month_periods],  | 
            ||
| 192 | ANSWER_KEY.ALGORITHM_PERIOD_VOLATILITY['Monthly'])  | 
            ||
| 193 | np.testing.assert_almost_equal(  | 
            ||
| 194 | [x.algorithm_volatility  | 
            ||
| 195 | for x in self.metrics_06.three_month_periods],  | 
            ||
| 196 | ANSWER_KEY.ALGORITHM_PERIOD_VOLATILITY['3-Month'])  | 
            ||
| 197 | np.testing.assert_almost_equal(  | 
            ||
| 198 | [x.algorithm_volatility  | 
            ||
| 199 | for x in self.metrics_06.six_month_periods],  | 
            ||
| 200 | ANSWER_KEY.ALGORITHM_PERIOD_VOLATILITY['6-month'])  | 
            ||
| 201 | np.testing.assert_almost_equal(  | 
            ||
| 202 | [x.algorithm_volatility  | 
            ||
| 203 | for x in self.metrics_06.year_periods],  | 
            ||
| 204 | ANSWER_KEY.ALGORITHM_PERIOD_VOLATILITY['year'])  | 
            ||
| 205 | |||
| 206 | def test_algorithm_sharpe_06(self):  | 
            ||
| 207 | np.testing.assert_almost_equal(  | 
            ||
| 208 | [x.sharpe for x in self.metrics_06.month_periods],  | 
            ||
| 209 | ANSWER_KEY.ALGORITHM_PERIOD_SHARPE['Monthly'])  | 
            ||
| 210 | np.testing.assert_almost_equal(  | 
            ||
| 211 | [x.sharpe for x in self.metrics_06.three_month_periods],  | 
            ||
| 212 | ANSWER_KEY.ALGORITHM_PERIOD_SHARPE['3-Month'])  | 
            ||
| 213 | np.testing.assert_almost_equal(  | 
            ||
| 214 | [x.sharpe for x in self.metrics_06.six_month_periods],  | 
            ||
| 215 | ANSWER_KEY.ALGORITHM_PERIOD_SHARPE['6-month'])  | 
            ||
| 216 | np.testing.assert_almost_equal(  | 
            ||
| 217 | [x.sharpe for x in self.metrics_06.year_periods],  | 
            ||
| 218 | ANSWER_KEY.ALGORITHM_PERIOD_SHARPE['year'])  | 
            ||
| 219 | |||
| 220 | def test_algorithm_downside_risk_06(self):  | 
            ||
| 221 | np.testing.assert_almost_equal(  | 
            ||
| 222 | [x.downside_risk for x in self.metrics_06.month_periods],  | 
            ||
| 223 | ANSWER_KEY.ALGORITHM_PERIOD_DOWNSIDE_RISK['Monthly'],  | 
            ||
| 224 | decimal=4)  | 
            ||
| 225 | np.testing.assert_almost_equal(  | 
            ||
| 226 | [x.downside_risk for x in self.metrics_06.three_month_periods],  | 
            ||
| 227 | ANSWER_KEY.ALGORITHM_PERIOD_DOWNSIDE_RISK['3-Month'],  | 
            ||
| 228 | decimal=4)  | 
            ||
| 229 | np.testing.assert_almost_equal(  | 
            ||
| 230 | [x.downside_risk for x in self.metrics_06.six_month_periods],  | 
            ||
| 231 | ANSWER_KEY.ALGORITHM_PERIOD_DOWNSIDE_RISK['6-month'],  | 
            ||
| 232 | decimal=4)  | 
            ||
| 233 | np.testing.assert_almost_equal(  | 
            ||
| 234 | [x.downside_risk for x in self.metrics_06.year_periods],  | 
            ||
| 235 | ANSWER_KEY.ALGORITHM_PERIOD_DOWNSIDE_RISK['year'],  | 
            ||
| 236 | decimal=4)  | 
            ||
| 237 | |||
| 238 | def test_algorithm_sortino_06(self):  | 
            ||
| 239 | np.testing.assert_almost_equal(  | 
            ||
| 240 | [x.sortino for x in self.metrics_06.month_periods],  | 
            ||
| 241 | ANSWER_KEY.ALGORITHM_PERIOD_SORTINO['Monthly'],  | 
            ||
| 242 | decimal=3)  | 
            ||
| 243 | |||
| 244 | np.testing.assert_almost_equal(  | 
            ||
| 245 | [x.sortino for x in self.metrics_06.three_month_periods],  | 
            ||
| 246 | ANSWER_KEY.ALGORITHM_PERIOD_SORTINO['3-Month'],  | 
            ||
| 247 | decimal=3)  | 
            ||
| 248 | |||
| 249 | np.testing.assert_almost_equal(  | 
            ||
| 250 | [x.sortino for x in self.metrics_06.six_month_periods],  | 
            ||
| 251 | ANSWER_KEY.ALGORITHM_PERIOD_SORTINO['6-month'],  | 
            ||
| 252 | decimal=3)  | 
            ||
| 253 | |||
| 254 | np.testing.assert_almost_equal(  | 
            ||
| 255 | [x.sortino for x in self.metrics_06.year_periods],  | 
            ||
| 256 | ANSWER_KEY.ALGORITHM_PERIOD_SORTINO['year'],  | 
            ||
| 257 | decimal=3)  | 
            ||
| 258 | |||
| 259 | def test_algorithm_information_06(self):  | 
            ||
| 260 | self.assertEqual([round(x.information, 3)  | 
            ||
| 261 | for x in self.metrics_06.month_periods],  | 
            ||
| 262 | [0.131,  | 
            ||
| 263 | -0.11,  | 
            ||
| 264 | -0.067,  | 
            ||
| 265 | 0.136,  | 
            ||
| 266 | 0.301,  | 
            ||
| 267 | -0.387,  | 
            ||
| 268 | 0.107,  | 
            ||
| 269 | -0.032,  | 
            ||
| 270 | -0.058,  | 
            ||
| 271 | 0.069,  | 
            ||
| 272 | 0.095,  | 
            ||
| 273 | -0.123])  | 
            ||
| 274 | self.assertEqual([round(x.information, 3)  | 
            ||
| 275 | for x in self.metrics_06.three_month_periods],  | 
            ||
| 276 | [-0.013,  | 
            ||
| 277 | -0.009,  | 
            ||
| 278 | 0.111,  | 
            ||
| 279 | -0.014,  | 
            ||
| 280 | -0.017,  | 
            ||
| 281 | -0.108,  | 
            ||
| 282 | 0.011,  | 
            ||
| 283 | -0.004,  | 
            ||
| 284 | 0.032,  | 
            ||
| 285 | 0.011])  | 
            ||
| 286 | self.assertEqual([round(x.information, 3)  | 
            ||
| 287 | for x in self.metrics_06.six_month_periods],  | 
            ||
| 288 | [-0.013,  | 
            ||
| 289 | -0.014,  | 
            ||
| 290 | -0.003,  | 
            ||
| 291 | -0.002,  | 
            ||
| 292 | -0.011,  | 
            ||
| 293 | -0.041,  | 
            ||
| 294 | 0.011])  | 
            ||
| 295 | self.assertEqual([round(x.information, 3)  | 
            ||
| 296 | for x in self.metrics_06.year_periods],  | 
            ||
| 297 | [-0.001])  | 
            ||
| 298 | |||
| 299 | def test_algorithm_beta_06(self):  | 
            ||
| 300 | np.testing.assert_almost_equal(  | 
            ||
| 301 | [x.beta for x in self.metrics_06.month_periods],  | 
            ||
| 302 | ANSWER_KEY.ALGORITHM_PERIOD_BETA['Monthly'])  | 
            ||
| 303 | np.testing.assert_almost_equal(  | 
            ||
| 304 | [x.beta for x in self.metrics_06.three_month_periods],  | 
            ||
| 305 | ANSWER_KEY.ALGORITHM_PERIOD_BETA['3-Month'])  | 
            ||
| 306 | np.testing.assert_almost_equal(  | 
            ||
| 307 | [x.beta for x in self.metrics_06.six_month_periods],  | 
            ||
| 308 | ANSWER_KEY.ALGORITHM_PERIOD_BETA['6-month'])  | 
            ||
| 309 | np.testing.assert_almost_equal(  | 
            ||
| 310 | [x.beta for x in self.metrics_06.year_periods],  | 
            ||
| 311 | ANSWER_KEY.ALGORITHM_PERIOD_BETA['year'])  | 
            ||
| 312 | |||
| 313 | def test_algorithm_alpha_06(self):  | 
            ||
| 314 | np.testing.assert_almost_equal(  | 
            ||
| 315 | [x.alpha for x in self.metrics_06.month_periods],  | 
            ||
| 316 | ANSWER_KEY.ALGORITHM_PERIOD_ALPHA['Monthly'])  | 
            ||
| 317 | np.testing.assert_almost_equal(  | 
            ||
| 318 | [x.alpha for x in self.metrics_06.three_month_periods],  | 
            ||
| 319 | ANSWER_KEY.ALGORITHM_PERIOD_ALPHA['3-Month'])  | 
            ||
| 320 | np.testing.assert_almost_equal(  | 
            ||
| 321 | [x.alpha for x in self.metrics_06.six_month_periods],  | 
            ||
| 322 | ANSWER_KEY.ALGORITHM_PERIOD_ALPHA['6-month'])  | 
            ||
| 323 | np.testing.assert_almost_equal(  | 
            ||
| 324 | [x.alpha for x in self.metrics_06.year_periods],  | 
            ||
| 325 | ANSWER_KEY.ALGORITHM_PERIOD_ALPHA['year'])  | 
            ||
| 326 | |||
| 327 | # FIXME: Covariance is not matching excel precisely enough to run the test.  | 
            ||
| 328 | # Month 4 seems to be the problem. Variance is disabled  | 
            ||
| 329 | # just to avoid distraction - it is much closer than covariance  | 
            ||
| 330 | # and can probably pass with 6 significant digits instead of 7.  | 
            ||
| 331 | # re-enable variance, alpha, and beta tests once this is resolved  | 
            ||
| 332 | def test_algorithm_covariance_06(self):  | 
            ||
| 333 | np.testing.assert_almost_equal(  | 
            ||
| 334 | [x.algorithm_covariance for x in self.metrics_06.month_periods],  | 
            ||
| 335 | ANSWER_KEY.ALGORITHM_PERIOD_COVARIANCE['Monthly'])  | 
            ||
| 336 | np.testing.assert_almost_equal(  | 
            ||
| 337 | [x.algorithm_covariance  | 
            ||
| 338 | for x in self.metrics_06.three_month_periods],  | 
            ||
| 339 | ANSWER_KEY.ALGORITHM_PERIOD_COVARIANCE['3-Month'])  | 
            ||
| 340 | np.testing.assert_almost_equal(  | 
            ||
| 341 | [x.algorithm_covariance  | 
            ||
| 342 | for x in self.metrics_06.six_month_periods],  | 
            ||
| 343 | ANSWER_KEY.ALGORITHM_PERIOD_COVARIANCE['6-month'])  | 
            ||
| 344 | np.testing.assert_almost_equal(  | 
            ||
| 345 | [x.algorithm_covariance  | 
            ||
| 346 | for x in self.metrics_06.year_periods],  | 
            ||
| 347 | ANSWER_KEY.ALGORITHM_PERIOD_COVARIANCE['year'])  | 
            ||
| 348 | |||
| 349 | def test_benchmark_variance_06(self):  | 
            ||
| 350 | np.testing.assert_almost_equal(  | 
            ||
| 351 | [x.benchmark_variance  | 
            ||
| 352 | for x in self.metrics_06.month_periods],  | 
            ||
| 353 | ANSWER_KEY.ALGORITHM_PERIOD_BENCHMARK_VARIANCE['Monthly'])  | 
            ||
| 354 | np.testing.assert_almost_equal(  | 
            ||
| 355 | [x.benchmark_variance  | 
            ||
| 356 | for x in self.metrics_06.three_month_periods],  | 
            ||
| 357 | ANSWER_KEY.ALGORITHM_PERIOD_BENCHMARK_VARIANCE['3-Month'])  | 
            ||
| 358 | np.testing.assert_almost_equal(  | 
            ||
| 359 | [x.benchmark_variance  | 
            ||
| 360 | for x in self.metrics_06.six_month_periods],  | 
            ||
| 361 | ANSWER_KEY.ALGORITHM_PERIOD_BENCHMARK_VARIANCE['6-month'])  | 
            ||
| 362 | np.testing.assert_almost_equal(  | 
            ||
| 363 | [x.benchmark_variance  | 
            ||
| 364 | for x in self.metrics_06.year_periods],  | 
            ||
| 365 | ANSWER_KEY.ALGORITHM_PERIOD_BENCHMARK_VARIANCE['year'])  | 
            ||
| 366 | |||
| 367 | def test_benchmark_returns_08(self):  | 
            ||
| 368 | returns = factory.create_returns_from_range(self.sim_params08)  | 
            ||
| 369 | metrics = risk.RiskReport(returns, self.sim_params08, env=self.env)  | 
            ||
| 370 | |||
| 371 | self.assertEqual([round(x.benchmark_period_returns, 3)  | 
            ||
| 372 | for x in metrics.month_periods],  | 
            ||
| 373 | [-0.061,  | 
            ||
| 374 | -0.035,  | 
            ||
| 375 | -0.006,  | 
            ||
| 376 | 0.048,  | 
            ||
| 377 | 0.011,  | 
            ||
| 378 | -0.086,  | 
            ||
| 379 | -0.01,  | 
            ||
| 380 | 0.012,  | 
            ||
| 381 | -0.091,  | 
            ||
| 382 | -0.169,  | 
            ||
| 383 | -0.075,  | 
            ||
| 384 | 0.008])  | 
            ||
| 385 | |||
| 386 | self.assertEqual([round(x.benchmark_period_returns, 3)  | 
            ||
| 387 | for x in metrics.three_month_periods],  | 
            ||
| 388 | [-0.099,  | 
            ||
| 389 | 0.005,  | 
            ||
| 390 | 0.052,  | 
            ||
| 391 | -0.032,  | 
            ||
| 392 | -0.085,  | 
            ||
| 393 | -0.084,  | 
            ||
| 394 | -0.089,  | 
            ||
| 395 | -0.236,  | 
            ||
| 396 | -0.301,  | 
            ||
| 397 | -0.226])  | 
            ||
| 398 | |||
| 399 | self.assertEqual([round(x.benchmark_period_returns, 3)  | 
            ||
| 400 | for x in metrics.six_month_periods],  | 
            ||
| 401 | [-0.128,  | 
            ||
| 402 | -0.081,  | 
            ||
| 403 | -0.036,  | 
            ||
| 404 | -0.118,  | 
            ||
| 405 | -0.301,  | 
            ||
| 406 | -0.36,  | 
            ||
| 407 | -0.294])  | 
            ||
| 408 | |||
| 409 | self.assertEqual([round(x.benchmark_period_returns, 3)  | 
            ||
| 410 | for x in metrics.year_periods],  | 
            ||
| 411 | [-0.385])  | 
            ||
| 412 | |||
| 413 | def test_trading_days_08(self):  | 
            ||
| 414 | returns = factory.create_returns_from_range(self.sim_params08)  | 
            ||
| 415 | metrics = risk.RiskReport(returns, self.sim_params08, env=self.env)  | 
            ||
| 416 | self.assertEqual([x.num_trading_days for x in metrics.year_periods],  | 
            ||
| 417 | [253])  | 
            ||
| 418 | |||
| 419 | self.assertEqual([x.num_trading_days for x in metrics.month_periods],  | 
            ||
| 420 | [21, 20, 20, 22, 21, 21, 22, 21, 21, 23, 19, 22])  | 
            ||
| 421 | |||
| 422 | def test_benchmark_volatility_08(self):  | 
            ||
| 423 | returns = factory.create_returns_from_range(self.sim_params08)  | 
            ||
| 424 | metrics = risk.RiskReport(returns, self.sim_params08, env=self.env)  | 
            ||
| 425 | |||
| 426 | self.assertEqual([round(x.benchmark_volatility, 3)  | 
            ||
| 427 | for x in metrics.month_periods],  | 
            ||
| 428 | [0.07,  | 
            ||
| 429 | 0.058,  | 
            ||
| 430 | 0.082,  | 
            ||
| 431 | 0.054,  | 
            ||
| 432 | 0.041,  | 
            ||
| 433 | 0.057,  | 
            ||
| 434 | 0.068,  | 
            ||
| 435 | 0.06,  | 
            ||
| 436 | 0.157,  | 
            ||
| 437 | 0.244,  | 
            ||
| 438 | 0.195,  | 
            ||
| 439 | 0.145])  | 
            ||
| 440 | |||
| 441 | self.assertEqual([round(x.benchmark_volatility, 3)  | 
            ||
| 442 | for x in metrics.three_month_periods],  | 
            ||
| 443 | [0.12,  | 
            ||
| 444 | 0.113,  | 
            ||
| 445 | 0.105,  | 
            ||
| 446 | 0.09,  | 
            ||
| 447 | 0.098,  | 
            ||
| 448 | 0.107,  | 
            ||
| 449 | 0.179,  | 
            ||
| 450 | 0.293,  | 
            ||
| 451 | 0.344,  | 
            ||
| 452 | 0.34])  | 
            ||
| 453 | |||
| 454 | self.assertEqual([round(x.benchmark_volatility, 3)  | 
            ||
| 455 | for x in metrics.six_month_periods],  | 
            ||
| 456 | [0.15,  | 
            ||
| 457 | 0.149,  | 
            ||
| 458 | 0.15,  | 
            ||
| 459 | 0.2,  | 
            ||
| 460 | 0.308,  | 
            ||
| 461 | 0.36,  | 
            ||
| 462 | 0.383])  | 
            ||
| 463 | # TODO: ugly, but I can't get the rounded float to match.  | 
            ||
| 464 | # maybe we need a different test that checks the  | 
            ||
| 465 | # difference between the numbers  | 
            ||
| 466 | self.assertEqual([round(x.benchmark_volatility, 3)  | 
            ||
| 467 | for x in metrics.year_periods],  | 
            ||
| 468 | [0.411])  | 
            ||
| 469 | |||
| 470 | def test_treasury_returns_06(self):  | 
            ||
| 471 | returns = factory.create_returns_from_range(self.sim_params)  | 
            ||
| 472 | metrics = risk.RiskReport(returns, self.sim_params, env=self.env)  | 
            ||
| 473 | self.assertEqual([round(x.treasury_period_return, 4)  | 
            ||
| 474 | for x in metrics.month_periods],  | 
            ||
| 475 | [0.0037,  | 
            ||
| 476 | 0.0034,  | 
            ||
| 477 | 0.0039,  | 
            ||
| 478 | 0.0038,  | 
            ||
| 479 | 0.0040,  | 
            ||
| 480 | 0.0037,  | 
            ||
| 481 | 0.0043,  | 
            ||
| 482 | 0.0043,  | 
            ||
| 483 | 0.0038,  | 
            ||
| 484 | 0.0044,  | 
            ||
| 485 | 0.0043,  | 
            ||
| 486 | 0.004])  | 
            ||
| 487 | |||
| 488 | self.assertEqual([round(x.treasury_period_return, 4)  | 
            ||
| 489 | for x in metrics.three_month_periods],  | 
            ||
| 490 | [0.0114,  | 
            ||
| 491 | 0.0116,  | 
            ||
| 492 | 0.0122,  | 
            ||
| 493 | 0.0125,  | 
            ||
| 494 | 0.0129,  | 
            ||
| 495 | 0.0127,  | 
            ||
| 496 | 0.0123,  | 
            ||
| 497 | 0.0128,  | 
            ||
| 498 | 0.0125,  | 
            ||
| 499 | 0.0127])  | 
            ||
| 500 | self.assertEqual([round(x.treasury_period_return, 4)  | 
            ||
| 501 | for x in metrics.six_month_periods],  | 
            ||
| 502 | [0.0260,  | 
            ||
| 503 | 0.0257,  | 
            ||
| 504 | 0.0258,  | 
            ||
| 505 | 0.0252,  | 
            ||
| 506 | 0.0259,  | 
            ||
| 507 | 0.0256,  | 
            ||
| 508 | 0.0257])  | 
            ||
| 509 | |||
| 510 | self.assertEqual([round(x.treasury_period_return, 4)  | 
            ||
| 511 | for x in metrics.year_periods],  | 
            ||
| 512 | [0.0500])  | 
            ||
| 513 | |||
| 514 | def test_benchmarkrange(self):  | 
            ||
| 515 | self.check_year_range(  | 
            ||
| 516 | datetime.datetime(  | 
            ||
| 517 | year=2008, month=1, day=1, tzinfo=pytz.utc),  | 
            ||
| 518 | 2)  | 
            ||
| 519 | |||
| 520 | def test_partial_month(self):  | 
            ||
| 521 | |||
| 522 | start = datetime.datetime(  | 
            ||
| 523 | year=1991,  | 
            ||
| 524 | month=1,  | 
            ||
| 525 | day=1,  | 
            ||
| 526 | hour=0,  | 
            ||
| 527 | minute=0,  | 
            ||
| 528 | tzinfo=pytz.utc)  | 
            ||
| 529 | |||
| 530 | # 1992 and 1996 were leap years  | 
            ||
| 531 | total_days = 365 * 5 + 2  | 
            ||
| 532 | end = start + datetime.timedelta(days=total_days)  | 
            ||
| 533 | sim_params90s = SimulationParameters(  | 
            ||
| 534 | period_start=start,  | 
            ||
| 535 | period_end=end,  | 
            ||
| 536 | env=self.env,  | 
            ||
| 537 | )  | 
            ||
| 538 | |||
| 539 | returns = factory.create_returns_from_range(sim_params90s)  | 
            ||
| 540 | returns = returns[:-10] # truncate the returns series to end mid-month  | 
            ||
| 541 | metrics = risk.RiskReport(returns, sim_params90s, env=self.env)  | 
            ||
| 542 | total_months = 60  | 
            ||
| 543 | self.check_metrics(metrics, total_months, start)  | 
            ||
| 544 | |||
| 545 | def check_year_range(self, start_date, years):  | 
            ||
| 546 | sim_params = SimulationParameters(  | 
            ||
| 547 | period_start=start_date,  | 
            ||
| 548 | period_end=start_date.replace(year=(start_date.year + years)),  | 
            ||
| 549 | env=self.env,  | 
            ||
| 550 | )  | 
            ||
| 551 | returns = factory.create_returns_from_range(sim_params)  | 
            ||
| 552 | metrics = risk.RiskReport(returns, self.sim_params, env=self.env)  | 
            ||
| 553 | total_months = years * 12  | 
            ||
| 554 | self.check_metrics(metrics, total_months, start_date)  | 
            ||
| 555 | |||
| 556 | def check_metrics(self, metrics, total_months, start_date):  | 
            ||
| 557 | """  | 
            ||
| 558 | confirm that the right number of riskmetrics were calculated for each  | 
            ||
| 559 | window length.  | 
            ||
| 560 | """  | 
            ||
| 561 | self.assert_range_length(  | 
            ||
| 562 | metrics.month_periods,  | 
            ||
| 563 | total_months,  | 
            ||
| 564 | 1,  | 
            ||
| 565 | start_date  | 
            ||
| 566 | )  | 
            ||
| 567 | |||
| 568 | self.assert_range_length(  | 
            ||
| 569 | metrics.three_month_periods,  | 
            ||
| 570 | total_months,  | 
            ||
| 571 | 3,  | 
            ||
| 572 | start_date  | 
            ||
| 573 | )  | 
            ||
| 574 | |||
| 575 | self.assert_range_length(  | 
            ||
| 576 | metrics.six_month_periods,  | 
            ||
| 577 | total_months,  | 
            ||
| 578 | 6,  | 
            ||
| 579 | start_date  | 
            ||
| 580 | )  | 
            ||
| 581 | |||
| 582 | self.assert_range_length(  | 
            ||
| 583 | metrics.year_periods,  | 
            ||
| 584 | total_months,  | 
            ||
| 585 | 12,  | 
            ||
| 586 | start_date  | 
            ||
| 587 | )  | 
            ||
| 588 | |||
| 589 | def assert_last_day(self, period_end):  | 
            ||
| 590 | # 30 days has september, april, june and november  | 
            ||
| 591 | if period_end.month in [9, 4, 6, 11]:  | 
            ||
| 592 | self.assertEqual(period_end.day, 30)  | 
            ||
| 593 | # all the rest have 31, except for february  | 
            ||
| 594 | elif(period_end.month != 2):  | 
            ||
| 595 | self.assertEqual(period_end.day, 31)  | 
            ||
| 596 | else:  | 
            ||
| 597 | if calendar.isleap(period_end.year):  | 
            ||
| 598 | self.assertEqual(period_end.day, 29)  | 
            ||
| 599 | else:  | 
            ||
| 600 | self.assertEqual(period_end.day, 28)  | 
            ||
| 601 | |||
| 602 | def assert_month(self, start_month, actual_end_month):  | 
            ||
| 603 | if start_month == 1:  | 
            ||
| 604 | expected_end_month = 12  | 
            ||
| 605 | else:  | 
            ||
| 606 | expected_end_month = start_month - 1  | 
            ||
| 607 | |||
| 608 | self.assertEqual(expected_end_month, actual_end_month)  | 
            ||
| 609 | |||
| 610 | def assert_range_length(self, col, total_months,  | 
            ||
| 611 | period_length, start_date):  | 
            ||
| 612 | if(period_length > total_months):  | 
            ||
| 613 | self.assertEqual(len(col), 0)  | 
            ||
| 614 | else:  | 
            ||
| 615 | self.assertEqual(  | 
            ||
| 616 | len(col),  | 
            ||
| 617 | total_months - (period_length - 1),  | 
            ||
| 618 | "mismatch for total months - \  | 
            ||
| 619 |                 expected:{total_months}/actual:{actual}, \ | 
            ||
| 620 |                 period:{period_length}, start:{start_date}, \ | 
            ||
| 621 |                 calculated end:{end}".format(total_months=total_months, | 
            ||
| 622 | period_length=period_length,  | 
            ||
| 623 | start_date=start_date,  | 
            ||
| 624 | end=col[-1].end_date,  | 
            ||
| 625 | actual=len(col))  | 
            ||
| 626 | )  | 
            ||
| 627 | self.assert_month(start_date.month, col[-1].end_date.month)  | 
            ||
| 628 | self.assert_last_day(col[-1].end_date)  | 
            ||
| 629 | |||
| 630 | def test_sparse_benchmark(self):  | 
            ||
| 631 | benchmark_returns = self.benchmark_returns_06.copy()  | 
            ||
| 632 | # Set every other day to nan.  | 
            ||
| 633 | benchmark_returns.iloc[::2] = np.nan  | 
            ||
| 634 | |||
| 635 | report = risk.RiskReport(  | 
            ||
| 636 | self.algo_returns_06,  | 
            ||
| 637 | self.sim_params,  | 
            ||
| 638 | benchmark_returns=benchmark_returns,  | 
            ||
| 639 | env=self.env,  | 
            ||
| 640 | )  | 
            ||
| 641 | for risk_period in chain.from_iterable(itervalues(report.to_dict())):  | 
            ||
| 642 | self.assertIsNone(risk_period['beta'])  | 
            ||
| 643 | 
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.