qis 3.2.5__tar.gz → 3.2.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. {qis-3.2.5 → qis-3.2.7}/PKG-INFO +1 -1
  2. {qis-3.2.5 → qis-3.2.7}/pyproject.toml +1 -1
  3. {qis-3.2.5 → qis-3.2.7}/qis/models/__init__.py +2 -1
  4. {qis-3.2.5 → qis-3.2.7}/qis/models/linear/ewm.py +96 -42
  5. {qis-3.2.5 → qis-3.2.7}/qis/plots/time_series.py +4 -2
  6. {qis-3.2.5 → qis-3.2.7}/qis/portfolio/reports/strategy_factsheet.py +1 -1
  7. {qis-3.2.5 → qis-3.2.7}/qis/settings.yaml +1 -0
  8. {qis-3.2.5 → qis-3.2.7}/LICENSE.txt +0 -0
  9. {qis-3.2.5 → qis-3.2.7}/README.md +0 -0
  10. {qis-3.2.5 → qis-3.2.7}/qis/__init__.py +0 -0
  11. {qis-3.2.5 → qis-3.2.7}/qis/examples/best_returns.py +0 -0
  12. {qis-3.2.5 → qis-3.2.7}/qis/examples/bootstrap_analysis.py +0 -0
  13. {qis-3.2.5 → qis-3.2.7}/qis/examples/boxplot_conditional_returns.py +0 -0
  14. {qis-3.2.5 → qis-3.2.7}/qis/examples/btc_asset_corr.py +0 -0
  15. {qis-3.2.5 → qis-3.2.7}/qis/examples/constant_notional.py +0 -0
  16. {qis-3.2.5 → qis-3.2.7}/qis/examples/constant_weight_portfolios.py +0 -0
  17. {qis-3.2.5 → qis-3.2.7}/qis/examples/core/perf_bbg_prices.py +0 -0
  18. {qis-3.2.5 → qis-3.2.7}/qis/examples/core/price_plots.py +0 -0
  19. {qis-3.2.5 → qis-3.2.7}/qis/examples/core/us_election.py +0 -0
  20. {qis-3.2.5 → qis-3.2.7}/qis/examples/credit_spreads.py +0 -0
  21. {qis-3.2.5 → qis-3.2.7}/qis/examples/europe_futures.py +0 -0
  22. {qis-3.2.5 → qis-3.2.7}/qis/examples/factsheets/multi_assets.py +0 -0
  23. {qis-3.2.5 → qis-3.2.7}/qis/examples/factsheets/multi_strategy.py +0 -0
  24. {qis-3.2.5 → qis-3.2.7}/qis/examples/factsheets/pyblogs_reports.py +0 -0
  25. {qis-3.2.5 → qis-3.2.7}/qis/examples/factsheets/strategy.py +0 -0
  26. {qis-3.2.5 → qis-3.2.7}/qis/examples/factsheets/strategy_benchmark.py +0 -0
  27. {qis-3.2.5 → qis-3.2.7}/qis/examples/generate_option_rolls.py +0 -0
  28. {qis-3.2.5 → qis-3.2.7}/qis/examples/interpolation_infrequent_returns.py +0 -0
  29. {qis-3.2.5 → qis-3.2.7}/qis/examples/leveraged_strategies.py +0 -0
  30. {qis-3.2.5 → qis-3.2.7}/qis/examples/long_short.py +0 -0
  31. {qis-3.2.5 → qis-3.2.7}/qis/examples/momentum_indices.py +0 -0
  32. {qis-3.2.5 → qis-3.2.7}/qis/examples/ohlc_vol_analysis.py +0 -0
  33. {qis-3.2.5 → qis-3.2.7}/qis/examples/overnight_returns.py +0 -0
  34. {qis-3.2.5 → qis-3.2.7}/qis/examples/perf_external_assets.py +0 -0
  35. {qis-3.2.5 → qis-3.2.7}/qis/examples/readme_performances.py +0 -0
  36. {qis-3.2.5 → qis-3.2.7}/qis/examples/risk_return_frontier.py +0 -0
  37. {qis-3.2.5 → qis-3.2.7}/qis/examples/rolling_performance.py +0 -0
  38. {qis-3.2.5 → qis-3.2.7}/qis/examples/seasonality.py +0 -0
  39. {qis-3.2.5 → qis-3.2.7}/qis/examples/sharpe_vs_sortino.py +0 -0
  40. {qis-3.2.5 → qis-3.2.7}/qis/examples/simulate_quant_strats.py +0 -0
  41. {qis-3.2.5 → qis-3.2.7}/qis/examples/test_ewm.py +0 -0
  42. {qis-3.2.5 → qis-3.2.7}/qis/examples/test_scatter.py +0 -0
  43. {qis-3.2.5 → qis-3.2.7}/qis/examples/try_pybloqs.py +0 -0
  44. {qis-3.2.5 → qis-3.2.7}/qis/examples/universe_corrs.py +0 -0
  45. {qis-3.2.5 → qis-3.2.7}/qis/examples/vix_beta_to_equities_bonds.py +0 -0
  46. {qis-3.2.5 → qis-3.2.7}/qis/examples/vix_conditional_returns.py +0 -0
  47. {qis-3.2.5 → qis-3.2.7}/qis/examples/vix_spy_by_year.py +0 -0
  48. {qis-3.2.5 → qis-3.2.7}/qis/examples/vix_tenor_analysis.py +0 -0
  49. {qis-3.2.5 → qis-3.2.7}/qis/examples/vol_without_weekends.py +0 -0
  50. {qis-3.2.5 → qis-3.2.7}/qis/file_utils.py +0 -0
  51. {qis-3.2.5 → qis-3.2.7}/qis/local_path.py +0 -0
  52. {qis-3.2.5 → qis-3.2.7}/qis/models/README.md +0 -0
  53. {qis-3.2.5 → qis-3.2.7}/qis/models/linear/__init__.py +0 -0
  54. {qis-3.2.5 → qis-3.2.7}/qis/models/linear/auto_corr.py +0 -0
  55. {qis-3.2.5 → qis-3.2.7}/qis/models/linear/corr_cov_matrix.py +0 -0
  56. {qis-3.2.5 → qis-3.2.7}/qis/models/linear/ewm_convolution.py +0 -0
  57. {qis-3.2.5 → qis-3.2.7}/qis/models/linear/ewm_factors.py +0 -0
  58. {qis-3.2.5 → qis-3.2.7}/qis/models/linear/ewm_winsor_outliers.py +0 -0
  59. {qis-3.2.5 → qis-3.2.7}/qis/models/linear/pca.py +0 -0
  60. {qis-3.2.5 → qis-3.2.7}/qis/models/linear/plot_correlations.py +0 -0
  61. {qis-3.2.5 → qis-3.2.7}/qis/models/linear/ra_returns.py +0 -0
  62. {qis-3.2.5 → qis-3.2.7}/qis/models/stats/__init__.py +0 -0
  63. {qis-3.2.5 → qis-3.2.7}/qis/models/stats/bootstrap.py +0 -0
  64. {qis-3.2.5 → qis-3.2.7}/qis/models/stats/ohlc_vol.py +0 -0
  65. {qis-3.2.5 → qis-3.2.7}/qis/models/stats/rolling_stats.py +0 -0
  66. {qis-3.2.5 → qis-3.2.7}/qis/models/stats/test_bootstrap.py +0 -0
  67. {qis-3.2.5 → qis-3.2.7}/qis/perfstats/README.md +0 -0
  68. {qis-3.2.5 → qis-3.2.7}/qis/perfstats/__init__.py +0 -0
  69. {qis-3.2.5 → qis-3.2.7}/qis/perfstats/cond_regression.py +0 -0
  70. {qis-3.2.5 → qis-3.2.7}/qis/perfstats/config.py +0 -0
  71. {qis-3.2.5 → qis-3.2.7}/qis/perfstats/desc_table.py +0 -0
  72. {qis-3.2.5 → qis-3.2.7}/qis/perfstats/fx_ops.py +0 -0
  73. {qis-3.2.5 → qis-3.2.7}/qis/perfstats/perf_stats.py +0 -0
  74. {qis-3.2.5 → qis-3.2.7}/qis/perfstats/regime_classifier.py +0 -0
  75. {qis-3.2.5 → qis-3.2.7}/qis/perfstats/returns.py +0 -0
  76. {qis-3.2.5 → qis-3.2.7}/qis/perfstats/timeseries_bfill.py +0 -0
  77. {qis-3.2.5 → qis-3.2.7}/qis/plots/README.md +0 -0
  78. {qis-3.2.5 → qis-3.2.7}/qis/plots/__init__.py +0 -0
  79. {qis-3.2.5 → qis-3.2.7}/qis/plots/bars.py +0 -0
  80. {qis-3.2.5 → qis-3.2.7}/qis/plots/boxplot.py +0 -0
  81. {qis-3.2.5 → qis-3.2.7}/qis/plots/contour.py +0 -0
  82. {qis-3.2.5 → qis-3.2.7}/qis/plots/derived/__init__.py +0 -0
  83. {qis-3.2.5 → qis-3.2.7}/qis/plots/derived/data_timeseries.py +0 -0
  84. {qis-3.2.5 → qis-3.2.7}/qis/plots/derived/desc_table.py +0 -0
  85. {qis-3.2.5 → qis-3.2.7}/qis/plots/derived/drawdowns.py +0 -0
  86. {qis-3.2.5 → qis-3.2.7}/qis/plots/derived/perf_table.py +0 -0
  87. {qis-3.2.5 → qis-3.2.7}/qis/plots/derived/prices.py +0 -0
  88. {qis-3.2.5 → qis-3.2.7}/qis/plots/derived/regime_class_table.py +0 -0
  89. {qis-3.2.5 → qis-3.2.7}/qis/plots/derived/regime_data.py +0 -0
  90. {qis-3.2.5 → qis-3.2.7}/qis/plots/derived/regime_pdf.py +0 -0
  91. {qis-3.2.5 → qis-3.2.7}/qis/plots/derived/regime_scatter.py +0 -0
  92. {qis-3.2.5 → qis-3.2.7}/qis/plots/derived/returns_heatmap.py +0 -0
  93. {qis-3.2.5 → qis-3.2.7}/qis/plots/derived/returns_scatter.py +0 -0
  94. {qis-3.2.5 → qis-3.2.7}/qis/plots/errorbar.py +0 -0
  95. {qis-3.2.5 → qis-3.2.7}/qis/plots/heatmap.py +0 -0
  96. {qis-3.2.5 → qis-3.2.7}/qis/plots/histogram.py +0 -0
  97. {qis-3.2.5 → qis-3.2.7}/qis/plots/histplot2d.py +0 -0
  98. {qis-3.2.5 → qis-3.2.7}/qis/plots/lineplot.py +0 -0
  99. {qis-3.2.5 → qis-3.2.7}/qis/plots/pie.py +0 -0
  100. {qis-3.2.5 → qis-3.2.7}/qis/plots/qqplot.py +0 -0
  101. {qis-3.2.5 → qis-3.2.7}/qis/plots/reports/__init__.py +0 -0
  102. {qis-3.2.5 → qis-3.2.7}/qis/plots/reports/econ_data_single.py +0 -0
  103. {qis-3.2.5 → qis-3.2.7}/qis/plots/reports/gantt_data_history.py +0 -0
  104. {qis-3.2.5 → qis-3.2.7}/qis/plots/reports/price_history.py +0 -0
  105. {qis-3.2.5 → qis-3.2.7}/qis/plots/reports/utils.py +0 -0
  106. {qis-3.2.5 → qis-3.2.7}/qis/plots/scatter.py +0 -0
  107. {qis-3.2.5 → qis-3.2.7}/qis/plots/stackplot.py +0 -0
  108. {qis-3.2.5 → qis-3.2.7}/qis/plots/table.py +0 -0
  109. {qis-3.2.5 → qis-3.2.7}/qis/plots/utils.py +0 -0
  110. {qis-3.2.5 → qis-3.2.7}/qis/portfolio/README.md +0 -0
  111. {qis-3.2.5 → qis-3.2.7}/qis/portfolio/__init__.py +0 -0
  112. {qis-3.2.5 → qis-3.2.7}/qis/portfolio/backtester.py +0 -0
  113. {qis-3.2.5 → qis-3.2.7}/qis/portfolio/ewm_portfolio_risk.py +0 -0
  114. {qis-3.2.5 → qis-3.2.7}/qis/portfolio/multi_portfolio_data.py +0 -0
  115. {qis-3.2.5 → qis-3.2.7}/qis/portfolio/portfolio_data.py +0 -0
  116. {qis-3.2.5 → qis-3.2.7}/qis/portfolio/reports/__init__.py +0 -0
  117. {qis-3.2.5 → qis-3.2.7}/qis/portfolio/reports/brinson_attribution.py +0 -0
  118. {qis-3.2.5 → qis-3.2.7}/qis/portfolio/reports/config.py +0 -0
  119. {qis-3.2.5 → qis-3.2.7}/qis/portfolio/reports/multi_assets_factsheet.py +0 -0
  120. {qis-3.2.5 → qis-3.2.7}/qis/portfolio/reports/multi_strategy_factseet_pybloqs.py +0 -0
  121. {qis-3.2.5 → qis-3.2.7}/qis/portfolio/reports/multi_strategy_factsheet.py +0 -0
  122. {qis-3.2.5 → qis-3.2.7}/qis/portfolio/reports/strategy_benchmark_factsheet.py +0 -0
  123. {qis-3.2.5 → qis-3.2.7}/qis/portfolio/reports/strategy_benchmark_factsheet_pybloqs.py +0 -0
  124. {qis-3.2.5 → qis-3.2.7}/qis/portfolio/reports/strategy_signal_factsheet.py +0 -0
  125. {qis-3.2.5 → qis-3.2.7}/qis/portfolio/strats/__init__.py +0 -0
  126. {qis-3.2.5 → qis-3.2.7}/qis/portfolio/strats/quant_strats_delta1.py +0 -0
  127. {qis-3.2.5 → qis-3.2.7}/qis/portfolio/strats/seasonal_strats.py +0 -0
  128. {qis-3.2.5 → qis-3.2.7}/qis/sql_engine.py +0 -0
  129. {qis-3.2.5 → qis-3.2.7}/qis/test_data.py +0 -0
  130. {qis-3.2.5 → qis-3.2.7}/qis/utils/README.md +0 -0
  131. {qis-3.2.5 → qis-3.2.7}/qis/utils/__init__.py +0 -0
  132. {qis-3.2.5 → qis-3.2.7}/qis/utils/dates.py +0 -0
  133. {qis-3.2.5 → qis-3.2.7}/qis/utils/df_agg.py +0 -0
  134. {qis-3.2.5 → qis-3.2.7}/qis/utils/df_cut.py +0 -0
  135. {qis-3.2.5 → qis-3.2.7}/qis/utils/df_freq.py +0 -0
  136. {qis-3.2.5 → qis-3.2.7}/qis/utils/df_groups.py +0 -0
  137. {qis-3.2.5 → qis-3.2.7}/qis/utils/df_melt.py +0 -0
  138. {qis-3.2.5 → qis-3.2.7}/qis/utils/df_ops.py +0 -0
  139. {qis-3.2.5 → qis-3.2.7}/qis/utils/df_str.py +0 -0
  140. {qis-3.2.5 → qis-3.2.7}/qis/utils/df_to_scores.py +0 -0
  141. {qis-3.2.5 → qis-3.2.7}/qis/utils/df_to_weights.py +0 -0
  142. {qis-3.2.5 → qis-3.2.7}/qis/utils/generic.py +0 -0
  143. {qis-3.2.5 → qis-3.2.7}/qis/utils/np_ops.py +0 -0
  144. {qis-3.2.5 → qis-3.2.7}/qis/utils/ols.py +0 -0
  145. {qis-3.2.5 → qis-3.2.7}/qis/utils/sampling.py +0 -0
  146. {qis-3.2.5 → qis-3.2.7}/qis/utils/struct_ops.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: qis
3
- Version: 3.2.5
3
+ Version: 3.2.7
4
4
  Summary: Implementation of visualisation and reporting analytics for Quantitative Investment Strategies
5
5
  License: LICENSE.txt
6
6
  Keywords: quantitative,investing,portfolio optimization,systematic strategies,volatility
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "qis"
3
- version = "3.2.5"
3
+ version = "3.2.7"
4
4
  description = "Implementation of visualisation and reporting analytics for Quantitative Investment Strategies"
5
5
  license = "LICENSE.txt"
6
6
  authors = ["Artur Sepp <artursepp@gmail.com>"]
@@ -47,7 +47,8 @@ from qis.models.linear.ewm import (
47
47
  compute_roll_mean,
48
48
  compute_rolling_mean_adj,
49
49
  set_init_dim1,
50
- set_init_dim2
50
+ set_init_dim2,
51
+ compute_ewm_covar_newey_west
51
52
  )
52
53
 
53
54
  from qis.models.linear.ewm_convolution import ConvolutionType, SignalAggType, ewm_xy_convolution
@@ -237,6 +237,7 @@ def compute_ewm_long_short_filter(data: Union[pd.DataFrame, pd.Series, np.ndarra
237
237
 
238
238
  @njit
239
239
  def compute_ewm_covar(a: np.ndarray,
240
+ b: np.ndarray = None,
240
241
  span: Union[int, np.ndarray] = None,
241
242
  ewm_lambda: float = 0.94,
242
243
  covar0: np.ndarray = None,
@@ -245,7 +246,13 @@ def compute_ewm_covar(a: np.ndarray,
245
246
  ) -> np.ndarray:
246
247
  """
247
248
  compute ewm covariance matrix
249
+ b is optional, when given the covar is cross product a and b
248
250
  """
251
+ if b is None:
252
+ b = a
253
+ else:
254
+ assert a.shape[0] == b.shape[0]
255
+ assert a.shape[1] == b.shape[1]
249
256
 
250
257
  if span is not None:
251
258
  ewm_lambda = 1.0 - 2.0 / (span + 1.0)
@@ -263,7 +270,7 @@ def compute_ewm_covar(a: np.ndarray,
263
270
 
264
271
  last_covar = covar
265
272
  if a.ndim == 1: # ndarry array
266
- r_ij = np.outer(a, a)
273
+ r_ij = np.outer(a, b)
267
274
  covar = ewm_lambda_1 * r_ij + ewm_lambda * last_covar
268
275
  if nan_backfill == NanBackfill.FFILL:
269
276
  fill_value = last_covar
@@ -277,8 +284,7 @@ def compute_ewm_covar(a: np.ndarray,
277
284
  else: # loop over rows
278
285
  t = a.shape[0]
279
286
  for idx in range(0, t): # row in x:
280
- row = a[idx]
281
- r_ij = np.outer(row, row)
287
+ r_ij = np.outer(a[idx], b[idx])
282
288
  covar = ewm_lambda_1 * r_ij + ewm_lambda * last_covar
283
289
 
284
290
  if nan_backfill == NanBackfill.FFILL:
@@ -290,21 +296,59 @@ def compute_ewm_covar(a: np.ndarray,
290
296
 
291
297
  last_covar = np.where(np.isfinite(covar), covar, fill_value)
292
298
 
293
- if is_corr:
294
- if np.nansum(np.diag(last_covar)) > 1e-10:
295
- inv_vol = np.reciprocal(np.sqrt(np.diag(last_covar)))
296
- norm = np.outer(inv_vol, inv_vol)
297
- else:
298
- norm = np.identity(n)
299
- last_covar_ = norm * last_covar
299
+ # for covar normalise
300
+ if is_corr:
301
+ if np.nansum(np.diag(last_covar)) > 1e-10:
302
+ inv_vol = np.reciprocal(np.sqrt(np.diag(last_covar)))
303
+ norm = np.outer(inv_vol, inv_vol)
300
304
  else:
301
- last_covar_ = last_covar
302
-
303
- covar = last_covar_
305
+ norm = np.identity(n)
306
+ covar = norm * last_covar
307
+ else:
308
+ covar = last_covar
304
309
 
305
310
  return covar
306
311
 
307
312
 
313
+ @njit
314
+ def compute_ewm_covar_newey_west(a: np.ndarray,
315
+ num_lags: int = 2,
316
+ span: Union[int, np.ndarray] = None,
317
+ ewm_lambda: float = 0.94,
318
+ covar0: np.ndarray = None,
319
+ is_corr: bool = False,
320
+ nan_backfill: NanBackfill = NanBackfill.FFILL
321
+ ) -> np.ndarray:
322
+ """
323
+ implementation of newey west covar estimator
324
+ """
325
+ ewm0 = compute_ewm_covar(a=a, span=span, ewm_lambda=ewm_lambda, covar0=covar0, is_corr=False, nan_backfill=nan_backfill)
326
+ # compute m recursions
327
+ if num_lags > 0:
328
+ nw_adjustment = np.zeros_like(ewm0)
329
+ for m in np.arange(1, num_lags+1):
330
+ # lagged value
331
+ a_m = np.empty_like(a)
332
+ a_m[m:] = a[:-m]
333
+ a_m[:m] = np.nan
334
+ ewm_m1 = compute_ewm_covar(a=a, b=a_m, span=span)
335
+ # ewm_m2 = compute_ewm_covar(a=a_m, b=a, span=span)
336
+ nw_adjustment += (1.0-m/(num_lags+1))*(ewm_m1 + np.transpose(ewm_m1))
337
+ ewm_nw = ewm0 + nw_adjustment
338
+ else:
339
+ ewm_nw = ewm0
340
+
341
+ if is_corr:
342
+ if np.nansum(np.diag(ewm_nw)) > 1e-10:
343
+ inv_vol = np.reciprocal(np.sqrt(np.diag(ewm_nw)))
344
+ norm = np.outer(inv_vol, inv_vol)
345
+ else:
346
+ norm = np.identity(a.shape[1])
347
+ ewm_nw = norm * ewm_nw
348
+
349
+ return ewm_nw
350
+
351
+
308
352
  @njit
309
353
  def compute_ewm_covar_tensor(a: np.ndarray,
310
354
  span: Union[int, np.ndarray] = None,
@@ -663,6 +707,27 @@ def compute_ewm_vol(data: Union[pd.DataFrame, pd.Series, np.ndarray],
663
707
  return ewm
664
708
 
665
709
 
710
+ @njit
711
+ def matrix_recursion(a: np.ndarray,
712
+ a_m: np.ndarray,
713
+ span: Optional[Union[float, np.ndarray]] = None,
714
+ ewm_lambda: Union[float, np.ndarray] = 0.94
715
+ ) -> np.ndarray:
716
+ if span is not None:
717
+ ewm_lambda = 1.0 - 2.0 / (span + 1.0)
718
+ ewm_lambda_1 = 1.0 - ewm_lambda
719
+ t = a.shape[0]
720
+ last_covar = np.zeros((a.shape[1], a.shape[1]))
721
+ ewm_m = np.zeros_like(a_m)
722
+ for idx in range(0, t):
723
+ r_ij = np.outer(a[idx], a_m[idx])
724
+ covar = ewm_lambda_1 * r_ij + ewm_lambda * last_covar
725
+ fill_value = last_covar
726
+ last_covar = np.where(np.isfinite(covar), covar, fill_value)
727
+ ewm_m[idx, :] = np.diag(last_covar) + np.diag(np.transpose(last_covar))
728
+ return ewm_m
729
+
730
+
666
731
  def compute_ewm_newey_west_vol(data: Union[pd.DataFrame, pd.Series, np.ndarray],
667
732
  num_lags: int = 2,
668
733
  span: Optional[Union[float, np.ndarray]] = None,
@@ -704,36 +769,25 @@ def compute_ewm_newey_west_vol(data: Union[pd.DataFrame, pd.Series, np.ndarray],
704
769
  if isinstance(init_value, np.ndarray):
705
770
  init_value = float(init_value)
706
771
 
707
- if span is not None:
708
- ewm_lambda = 1.0 - 2.0 / (span + 1.0)
709
- ewm_lambda_1 = 1.0 - ewm_lambda
710
-
711
- def matrix_recursion(a_m: np.ndarray) -> np.ndarray:
712
- t = a.shape[0]
713
- last_covar = np.zeros((a.shape[1], a.shape[1]))
714
- ewm_m = np.zeros_like(a_m)
715
- for idx in range(0, t):
716
- r_ij = np.outer(a[idx], a_m[idx])
717
- covar = ewm_lambda_1 * r_ij + ewm_lambda * last_covar
718
- fill_value = last_covar
719
- last_covar = np.where(np.isfinite(covar), covar, fill_value)
720
- ewm_m[idx, :] = np.diag(last_covar) + np.diag(np.transpose(last_covar))
721
- return ewm_m
722
-
723
772
  ewm0 = ewm_recursion(a=np.square(a), ewm_lambda=ewm_lambda, init_value=init_value, nan_backfill=nan_backfill)
724
- nw_adjustment = np.zeros_like(ewm0)
725
- # compute m recursions
726
- for m in np.arange(1, num_lags+1):
727
- # lagged value
728
- a_m = np.empty_like(a)
729
- a_m[m:] = a[:-m]
730
- a_m[:m] = np.nan
731
- # qqq
732
- ewm_m = matrix_recursion(a_m=a_m)
733
- nw_adjustment += (1.0-m/(num_lags+1))*ewm_m
734
-
735
- ewm_nw = ewm0 + nw_adjustment
736
- nw_ratio = np.divide(ewm_nw, ewm0, where=ewm0 > 0.0)
773
+
774
+ if num_lags == 0:
775
+ ewm_nw = ewm0
776
+ nw_ratio = np.ones_like(ewm0)
777
+ else:
778
+ nw_adjustment = np.zeros_like(ewm0)
779
+ # compute m recursions
780
+ for m in np.arange(1, num_lags+1):
781
+ # lagged value
782
+ a_m = np.empty_like(a)
783
+ a_m[m:] = a[:-m]
784
+ a_m[:m] = np.nan
785
+ ewm_m = matrix_recursion(a=a, a_m=a_m, span=span)
786
+ nw_adjustment += (1.0-m/(num_lags+1))*ewm_m
787
+
788
+ ewm_nw = ewm0 + nw_adjustment
789
+ nw_ratio = np.divide(ewm_nw, ewm0, where=ewm0 > 0.0)
790
+ nw_ratio = np.where(nw_ratio > 0.0, nw_ratio, 1.0)
737
791
 
738
792
  if warmup_period is not None: # set to nan first nonnan in warmup_period
739
793
  ewm_nw = npo.set_nans_for_warmup_period(a=ewm_nw, warmup_period=warmup_period)
@@ -345,6 +345,7 @@ def plot_time_series_2ax(df1: Union[pd.Series, pd.DataFrame],
345
345
  is_log=is_logs[0],
346
346
  y_limits=y_limits,
347
347
  ylabel=ylabel1,
348
+ fontsize=fontsize,
348
349
  ax=ax,
349
350
  **kwargs)
350
351
 
@@ -358,16 +359,17 @@ def plot_time_series_2ax(df1: Union[pd.Series, pd.DataFrame],
358
359
  is_log=is_logs[1],
359
360
  y_limits=y_limits_ax2,
360
361
  ylabel=ylabel2,
362
+ fontsize=fontsize,
361
363
  ax=ax_twin,
362
364
  **kwargs)
363
365
 
366
+ ax.tick_params(axis='x', which='both', bottom=False)
367
+
364
368
  put.set_ax_ticks_format(ax=ax, fontsize=fontsize, xvar_format=None, yvar_format=var_format, set_ticks=False,
365
369
  yvar_major_ticks=yvar_major_ticks1, x_rotation=x_rotation, **kwargs)
366
370
  put.set_ax_ticks_format(ax=ax_twin, fontsize=fontsize, xvar_format=None, yvar_format=var_format_yax2, set_ticks=False,
367
371
  yvar_major_ticks=yvar_major_ticks2, x_rotation=x_rotation, **kwargs)
368
372
 
369
- ax.tick_params(axis='x', which='both', bottom=False)
370
-
371
373
  if legend_loc is not None:
372
374
  if legend_labels is None:
373
375
  df1.columns = [f"{x} (left)" for x in df1.columns]
@@ -20,6 +20,7 @@ def generate_strategy_factsheet(portfolio_data: PortfolioData,
20
20
  benchmark_prices: Union[pd.DataFrame, pd.Series],
21
21
  time_period: TimePeriod = None,
22
22
  ytd_attribution_time_period: TimePeriod = qis.get_ytd_time_period(),
23
+ weight_report_time_period: TimePeriod = None,
23
24
  perf_params: PerfParams = PERF_PARAMS,
24
25
  regime_params: BenchmarkReturnsQuantileRegimeSpecs = REGIME_PARAMS,
25
26
  regime_benchmark: str = None, # default is set to benchmark_prices.columns[0]
@@ -39,7 +40,6 @@ def generate_strategy_factsheet(portfolio_data: PortfolioData,
39
40
  figsize: Tuple[float, float] = (8.5, 11.7), # A4 for portrait
40
41
  fontsize: int = 4,
41
42
  weight_change_sample_size: int = 20,
42
- weight_report_time_period: TimePeriod = None,
43
43
  add_current_position_var_risk_sheet: bool = False,
44
44
  add_weights_turnover_sheet: bool = False,
45
45
  add_grouped_exposures: bool = False,
@@ -18,3 +18,4 @@ OUTPUT_PATH:
18
18
 
19
19
  AWS_POSTGRES:
20
20
  ""
21
+
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes