qis 2.1.39__tar.gz → 2.1.40__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 (150) hide show
  1. {qis-2.1.39 → qis-2.1.40}/PKG-INFO +11 -11
  2. {qis-2.1.39 → qis-2.1.40}/README.md +10 -10
  3. {qis-2.1.39 → qis-2.1.40}/pyproject.toml +1 -1
  4. {qis-2.1.39 → qis-2.1.40}/qis/examples/readme_performances.py +10 -10
  5. {qis-2.1.39 → qis-2.1.40}/qis/plots/derived/perf_table.py +2 -6
  6. {qis-2.1.39 → qis-2.1.40}/qis/portfolio/multi_portfolio_data.py +3 -6
  7. {qis-2.1.39 → qis-2.1.40}/qis/portfolio/portfolio_data.py +15 -7
  8. {qis-2.1.39 → qis-2.1.40}/qis/portfolio/reports/strategy_benchmark_factsheet.py +26 -17
  9. {qis-2.1.39 → qis-2.1.40}/LICENSE.txt +0 -0
  10. {qis-2.1.39 → qis-2.1.40}/qis/__init__.py +0 -0
  11. {qis-2.1.39 → qis-2.1.40}/qis/examples/best_returns.py +0 -0
  12. {qis-2.1.39 → qis-2.1.40}/qis/examples/bond_futures_portfolio.py +0 -0
  13. {qis-2.1.39 → qis-2.1.40}/qis/examples/bootstrap_analysis.py +0 -0
  14. {qis-2.1.39 → qis-2.1.40}/qis/examples/boxplot_conditional_returns.py +0 -0
  15. {qis-2.1.39 → qis-2.1.40}/qis/examples/btc_asset_corr.py +0 -0
  16. {qis-2.1.39 → qis-2.1.40}/qis/examples/constant_notional.py +0 -0
  17. {qis-2.1.39 → qis-2.1.40}/qis/examples/constant_weight_portfolios.py +0 -0
  18. {qis-2.1.39 → qis-2.1.40}/qis/examples/core/perf_bbg_prices.py +0 -0
  19. {qis-2.1.39 → qis-2.1.40}/qis/examples/core/price_plots.py +0 -0
  20. {qis-2.1.39 → qis-2.1.40}/qis/examples/core/us_election.py +0 -0
  21. {qis-2.1.39 → qis-2.1.40}/qis/examples/credit_spreads.py +0 -0
  22. {qis-2.1.39 → qis-2.1.40}/qis/examples/credit_trackers.py +0 -0
  23. {qis-2.1.39 → qis-2.1.40}/qis/examples/europe_futures.py +0 -0
  24. {qis-2.1.39 → qis-2.1.40}/qis/examples/factsheets/multi_assets.py +0 -0
  25. {qis-2.1.39 → qis-2.1.40}/qis/examples/factsheets/multi_strategy.py +0 -0
  26. {qis-2.1.39 → qis-2.1.40}/qis/examples/factsheets/pyblogs_reports.py +0 -0
  27. {qis-2.1.39 → qis-2.1.40}/qis/examples/factsheets/strategy.py +0 -0
  28. {qis-2.1.39 → qis-2.1.40}/qis/examples/factsheets/strategy_benchmark.py +0 -0
  29. {qis-2.1.39 → qis-2.1.40}/qis/examples/generate_option_rolls.py +0 -0
  30. {qis-2.1.39 → qis-2.1.40}/qis/examples/interpolation_infrequent_returns.py +0 -0
  31. {qis-2.1.39 → qis-2.1.40}/qis/examples/leveraged_strategies.py +0 -0
  32. {qis-2.1.39 → qis-2.1.40}/qis/examples/long_short.py +0 -0
  33. {qis-2.1.39 → qis-2.1.40}/qis/examples/momentum_indices.py +0 -0
  34. {qis-2.1.39 → qis-2.1.40}/qis/examples/oakmark_analysis.py +0 -0
  35. {qis-2.1.39 → qis-2.1.40}/qis/examples/ohlc_vol_analysis.py +0 -0
  36. {qis-2.1.39 → qis-2.1.40}/qis/examples/overnight_returns.py +0 -0
  37. {qis-2.1.39 → qis-2.1.40}/qis/examples/perf_external_assets.py +0 -0
  38. {qis-2.1.39 → qis-2.1.40}/qis/examples/perp_pricing.py +0 -0
  39. {qis-2.1.39 → qis-2.1.40}/qis/examples/risk_return_frontier.py +0 -0
  40. {qis-2.1.39 → qis-2.1.40}/qis/examples/rolling_performance.py +0 -0
  41. {qis-2.1.39 → qis-2.1.40}/qis/examples/seasonality.py +0 -0
  42. {qis-2.1.39 → qis-2.1.40}/qis/examples/sharpe_vs_sortino.py +0 -0
  43. {qis-2.1.39 → qis-2.1.40}/qis/examples/simulate_quant_strats.py +0 -0
  44. {qis-2.1.39 → qis-2.1.40}/qis/examples/test_ewm.py +0 -0
  45. {qis-2.1.39 → qis-2.1.40}/qis/examples/test_scatter.py +0 -0
  46. {qis-2.1.39 → qis-2.1.40}/qis/examples/try_pybloqs.py +0 -0
  47. {qis-2.1.39 → qis-2.1.40}/qis/examples/universe_corrs.py +0 -0
  48. {qis-2.1.39 → qis-2.1.40}/qis/examples/vix_beta_to_equities_bonds.py +0 -0
  49. {qis-2.1.39 → qis-2.1.40}/qis/examples/vix_conditional_returns.py +0 -0
  50. {qis-2.1.39 → qis-2.1.40}/qis/examples/vix_spy_by_year.py +0 -0
  51. {qis-2.1.39 → qis-2.1.40}/qis/examples/vix_tenor_analysis.py +0 -0
  52. {qis-2.1.39 → qis-2.1.40}/qis/examples/vol_without_weekends.py +0 -0
  53. {qis-2.1.39 → qis-2.1.40}/qis/file_utils.py +0 -0
  54. {qis-2.1.39 → qis-2.1.40}/qis/local_path.py +0 -0
  55. {qis-2.1.39 → qis-2.1.40}/qis/models/README.md +0 -0
  56. {qis-2.1.39 → qis-2.1.40}/qis/models/__init__.py +0 -0
  57. {qis-2.1.39 → qis-2.1.40}/qis/models/linear/__init__.py +0 -0
  58. {qis-2.1.39 → qis-2.1.40}/qis/models/linear/auto_corr.py +0 -0
  59. {qis-2.1.39 → qis-2.1.40}/qis/models/linear/corr_cov_matrix.py +0 -0
  60. {qis-2.1.39 → qis-2.1.40}/qis/models/linear/ewm.py +0 -0
  61. {qis-2.1.39 → qis-2.1.40}/qis/models/linear/ewm_convolution.py +0 -0
  62. {qis-2.1.39 → qis-2.1.40}/qis/models/linear/ewm_factors.py +0 -0
  63. {qis-2.1.39 → qis-2.1.40}/qis/models/linear/ewm_winsor_outliers.py +0 -0
  64. {qis-2.1.39 → qis-2.1.40}/qis/models/linear/pca.py +0 -0
  65. {qis-2.1.39 → qis-2.1.40}/qis/models/linear/plot_correlations.py +0 -0
  66. {qis-2.1.39 → qis-2.1.40}/qis/models/linear/ra_returns.py +0 -0
  67. {qis-2.1.39 → qis-2.1.40}/qis/models/stats/__init__.py +0 -0
  68. {qis-2.1.39 → qis-2.1.40}/qis/models/stats/bootstrap.py +0 -0
  69. {qis-2.1.39 → qis-2.1.40}/qis/models/stats/ohlc_vol.py +0 -0
  70. {qis-2.1.39 → qis-2.1.40}/qis/models/stats/rolling_stats.py +0 -0
  71. {qis-2.1.39 → qis-2.1.40}/qis/models/stats/test_bootstrap.py +0 -0
  72. {qis-2.1.39 → qis-2.1.40}/qis/perfstats/README.md +0 -0
  73. {qis-2.1.39 → qis-2.1.40}/qis/perfstats/__init__.py +0 -0
  74. {qis-2.1.39 → qis-2.1.40}/qis/perfstats/cond_regression.py +0 -0
  75. {qis-2.1.39 → qis-2.1.40}/qis/perfstats/config.py +0 -0
  76. {qis-2.1.39 → qis-2.1.40}/qis/perfstats/desc_table.py +0 -0
  77. {qis-2.1.39 → qis-2.1.40}/qis/perfstats/fx_ops.py +0 -0
  78. {qis-2.1.39 → qis-2.1.40}/qis/perfstats/perf_stats.py +0 -0
  79. {qis-2.1.39 → qis-2.1.40}/qis/perfstats/regime_classifier.py +0 -0
  80. {qis-2.1.39 → qis-2.1.40}/qis/perfstats/returns.py +0 -0
  81. {qis-2.1.39 → qis-2.1.40}/qis/perfstats/timeseries_bfill.py +0 -0
  82. {qis-2.1.39 → qis-2.1.40}/qis/plots/README.md +0 -0
  83. {qis-2.1.39 → qis-2.1.40}/qis/plots/__init__.py +0 -0
  84. {qis-2.1.39 → qis-2.1.40}/qis/plots/bars.py +0 -0
  85. {qis-2.1.39 → qis-2.1.40}/qis/plots/boxplot.py +0 -0
  86. {qis-2.1.39 → qis-2.1.40}/qis/plots/contour.py +0 -0
  87. {qis-2.1.39 → qis-2.1.40}/qis/plots/derived/__init__.py +0 -0
  88. {qis-2.1.39 → qis-2.1.40}/qis/plots/derived/data_timeseries.py +0 -0
  89. {qis-2.1.39 → qis-2.1.40}/qis/plots/derived/desc_table.py +0 -0
  90. {qis-2.1.39 → qis-2.1.40}/qis/plots/derived/drawdowns.py +0 -0
  91. {qis-2.1.39 → qis-2.1.40}/qis/plots/derived/prices.py +0 -0
  92. {qis-2.1.39 → qis-2.1.40}/qis/plots/derived/regime_class_table.py +0 -0
  93. {qis-2.1.39 → qis-2.1.40}/qis/plots/derived/regime_data.py +0 -0
  94. {qis-2.1.39 → qis-2.1.40}/qis/plots/derived/regime_pdf.py +0 -0
  95. {qis-2.1.39 → qis-2.1.40}/qis/plots/derived/regime_scatter.py +0 -0
  96. {qis-2.1.39 → qis-2.1.40}/qis/plots/derived/returns_heatmap.py +0 -0
  97. {qis-2.1.39 → qis-2.1.40}/qis/plots/derived/returns_scatter.py +0 -0
  98. {qis-2.1.39 → qis-2.1.40}/qis/plots/errorbar.py +0 -0
  99. {qis-2.1.39 → qis-2.1.40}/qis/plots/heatmap.py +0 -0
  100. {qis-2.1.39 → qis-2.1.40}/qis/plots/histogram.py +0 -0
  101. {qis-2.1.39 → qis-2.1.40}/qis/plots/histplot2d.py +0 -0
  102. {qis-2.1.39 → qis-2.1.40}/qis/plots/lineplot.py +0 -0
  103. {qis-2.1.39 → qis-2.1.40}/qis/plots/pie.py +0 -0
  104. {qis-2.1.39 → qis-2.1.40}/qis/plots/qqplot.py +0 -0
  105. {qis-2.1.39 → qis-2.1.40}/qis/plots/reports/__init__.py +0 -0
  106. {qis-2.1.39 → qis-2.1.40}/qis/plots/reports/econ_data_single.py +0 -0
  107. {qis-2.1.39 → qis-2.1.40}/qis/plots/reports/gantt_data_history.py +0 -0
  108. {qis-2.1.39 → qis-2.1.40}/qis/plots/reports/price_history.py +0 -0
  109. {qis-2.1.39 → qis-2.1.40}/qis/plots/reports/utils.py +0 -0
  110. {qis-2.1.39 → qis-2.1.40}/qis/plots/scatter.py +0 -0
  111. {qis-2.1.39 → qis-2.1.40}/qis/plots/stackplot.py +0 -0
  112. {qis-2.1.39 → qis-2.1.40}/qis/plots/table.py +0 -0
  113. {qis-2.1.39 → qis-2.1.40}/qis/plots/time_series.py +0 -0
  114. {qis-2.1.39 → qis-2.1.40}/qis/plots/utils.py +0 -0
  115. {qis-2.1.39 → qis-2.1.40}/qis/portfolio/README.md +0 -0
  116. {qis-2.1.39 → qis-2.1.40}/qis/portfolio/__init__.py +0 -0
  117. {qis-2.1.39 → qis-2.1.40}/qis/portfolio/backtester.py +0 -0
  118. {qis-2.1.39 → qis-2.1.40}/qis/portfolio/ewm_portfolio_risk.py +0 -0
  119. {qis-2.1.39 → qis-2.1.40}/qis/portfolio/reports/__init__.py +0 -0
  120. {qis-2.1.39 → qis-2.1.40}/qis/portfolio/reports/brinson_attribution.py +0 -0
  121. {qis-2.1.39 → qis-2.1.40}/qis/portfolio/reports/config.py +0 -0
  122. {qis-2.1.39 → qis-2.1.40}/qis/portfolio/reports/multi_assets_factsheet.py +0 -0
  123. {qis-2.1.39 → qis-2.1.40}/qis/portfolio/reports/multi_strategy_factseet_pybloqs.py +0 -0
  124. {qis-2.1.39 → qis-2.1.40}/qis/portfolio/reports/multi_strategy_factsheet.py +0 -0
  125. {qis-2.1.39 → qis-2.1.40}/qis/portfolio/reports/strategy_benchmark_factsheet_pybloqs.py +0 -0
  126. {qis-2.1.39 → qis-2.1.40}/qis/portfolio/reports/strategy_factsheet.py +0 -0
  127. {qis-2.1.39 → qis-2.1.40}/qis/portfolio/reports/strategy_signal_factsheet.py +0 -0
  128. {qis-2.1.39 → qis-2.1.40}/qis/portfolio/strats/__init__.py +0 -0
  129. {qis-2.1.39 → qis-2.1.40}/qis/portfolio/strats/quant_strats_delta1.py +0 -0
  130. {qis-2.1.39 → qis-2.1.40}/qis/portfolio/strats/seasonal_strats.py +0 -0
  131. {qis-2.1.39 → qis-2.1.40}/qis/settings.yaml +0 -0
  132. {qis-2.1.39 → qis-2.1.40}/qis/sql_engine.py +0 -0
  133. {qis-2.1.39 → qis-2.1.40}/qis/test_data.py +0 -0
  134. {qis-2.1.39 → qis-2.1.40}/qis/utils/README.md +0 -0
  135. {qis-2.1.39 → qis-2.1.40}/qis/utils/__init__.py +0 -0
  136. {qis-2.1.39 → qis-2.1.40}/qis/utils/dates.py +0 -0
  137. {qis-2.1.39 → qis-2.1.40}/qis/utils/df_agg.py +0 -0
  138. {qis-2.1.39 → qis-2.1.40}/qis/utils/df_cut.py +0 -0
  139. {qis-2.1.39 → qis-2.1.40}/qis/utils/df_freq.py +0 -0
  140. {qis-2.1.39 → qis-2.1.40}/qis/utils/df_groups.py +0 -0
  141. {qis-2.1.39 → qis-2.1.40}/qis/utils/df_melt.py +0 -0
  142. {qis-2.1.39 → qis-2.1.40}/qis/utils/df_ops.py +0 -0
  143. {qis-2.1.39 → qis-2.1.40}/qis/utils/df_str.py +0 -0
  144. {qis-2.1.39 → qis-2.1.40}/qis/utils/df_to_scores.py +0 -0
  145. {qis-2.1.39 → qis-2.1.40}/qis/utils/df_to_weights.py +0 -0
  146. {qis-2.1.39 → qis-2.1.40}/qis/utils/generic.py +0 -0
  147. {qis-2.1.39 → qis-2.1.40}/qis/utils/np_ops.py +0 -0
  148. {qis-2.1.39 → qis-2.1.40}/qis/utils/ols.py +0 -0
  149. {qis-2.1.39 → qis-2.1.40}/qis/utils/sampling.py +0 -0
  150. {qis-2.1.39 → qis-2.1.40}/qis/utils/struct_ops.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: qis
3
- Version: 2.1.39
3
+ Version: 2.1.40
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
@@ -174,16 +174,16 @@ fig = qis.plot_ra_perf_table(prices=prices,
174
174
  # add benchmark regression using excess returns for linear beta
175
175
  # regression frequency is specified using perf_params.freq_reg
176
176
  # regression alpha is multiplied using perf_params.alpha_an_factor
177
- fig = qis.plot_ra_perf_table_benchmark(prices=prices,
178
- benchmark='SPY',
179
- perf_columns=[PerfStat.TOTAL_RETURN, PerfStat.PA_RETURN, PerfStat.PA_EXCESS_RETURN,
180
- PerfStat.VOL, PerfStat.SHARPE_RF0,
181
- PerfStat.SHARPE_EXCESS, PerfStat.SORTINO_RATIO, PerfStat.CALMAR_RATIO,
182
- PerfStat.MAX_DD, PerfStat.MAX_DD_VOL,
183
- PerfStat.SKEWNESS, PerfStat.KURTOSIS,
184
- PerfStat.ALPHA_AN, PerfStat.BETA, PerfStat.R2],
185
- title=f"Risk-adjusted performance: {qis.get_time_period_label(prices, date_separator='-')} benchmarked with SPY",
186
- perf_params=perf_params)
177
+ fig, _ = qis.plot_ra_perf_table_benchmark(prices=prices,
178
+ benchmark='SPY',
179
+ perf_columns=[PerfStat.TOTAL_RETURN, PerfStat.PA_RETURN, PerfStat.PA_EXCESS_RETURN,
180
+ PerfStat.VOL, PerfStat.SHARPE_RF0,
181
+ PerfStat.SHARPE_EXCESS, PerfStat.SORTINO_RATIO, PerfStat.CALMAR_RATIO,
182
+ PerfStat.MAX_DD, PerfStat.MAX_DD_VOL,
183
+ PerfStat.SKEWNESS, PerfStat.KURTOSIS,
184
+ PerfStat.ALPHA_AN, PerfStat.BETA, PerfStat.R2],
185
+ title=f"Risk-adjusted performance: {qis.get_time_period_label(prices, date_separator='-')} benchmarked with SPY",
186
+ perf_params=perf_params)
187
187
  ```
188
188
  ![image info](qis/examples/figures/perf4.PNG)
189
189
 
@@ -124,16 +124,16 @@ fig = qis.plot_ra_perf_table(prices=prices,
124
124
  # add benchmark regression using excess returns for linear beta
125
125
  # regression frequency is specified using perf_params.freq_reg
126
126
  # regression alpha is multiplied using perf_params.alpha_an_factor
127
- fig = qis.plot_ra_perf_table_benchmark(prices=prices,
128
- benchmark='SPY',
129
- perf_columns=[PerfStat.TOTAL_RETURN, PerfStat.PA_RETURN, PerfStat.PA_EXCESS_RETURN,
130
- PerfStat.VOL, PerfStat.SHARPE_RF0,
131
- PerfStat.SHARPE_EXCESS, PerfStat.SORTINO_RATIO, PerfStat.CALMAR_RATIO,
132
- PerfStat.MAX_DD, PerfStat.MAX_DD_VOL,
133
- PerfStat.SKEWNESS, PerfStat.KURTOSIS,
134
- PerfStat.ALPHA_AN, PerfStat.BETA, PerfStat.R2],
135
- title=f"Risk-adjusted performance: {qis.get_time_period_label(prices, date_separator='-')} benchmarked with SPY",
136
- perf_params=perf_params)
127
+ fig, _ = qis.plot_ra_perf_table_benchmark(prices=prices,
128
+ benchmark='SPY',
129
+ perf_columns=[PerfStat.TOTAL_RETURN, PerfStat.PA_RETURN, PerfStat.PA_EXCESS_RETURN,
130
+ PerfStat.VOL, PerfStat.SHARPE_RF0,
131
+ PerfStat.SHARPE_EXCESS, PerfStat.SORTINO_RATIO, PerfStat.CALMAR_RATIO,
132
+ PerfStat.MAX_DD, PerfStat.MAX_DD_VOL,
133
+ PerfStat.SKEWNESS, PerfStat.KURTOSIS,
134
+ PerfStat.ALPHA_AN, PerfStat.BETA, PerfStat.R2],
135
+ title=f"Risk-adjusted performance: {qis.get_time_period_label(prices, date_separator='-')} benchmarked with SPY",
136
+ perf_params=perf_params)
137
137
  ```
138
138
  ![image info](qis/examples/figures/perf4.PNG)
139
139
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "qis"
3
- version = "2.1.39"
3
+ version = "2.1.40"
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>"]
@@ -48,16 +48,16 @@ qis.save_fig(fig, file_name='perf3', local_path="figures/")
48
48
  # add benchmark regression using excess returns for linear beta
49
49
  # regression frequency is specified using perf_params.freq_reg
50
50
  # regression alpha is multiplied using perf_params.alpha_an_factor
51
- fig = qis.plot_ra_perf_table_benchmark(prices=prices,
52
- benchmark='SPY',
53
- perf_columns=[PerfStat.TOTAL_RETURN, PerfStat.PA_RETURN, PerfStat.PA_EXCESS_RETURN,
54
- PerfStat.VOL, PerfStat.SHARPE_RF0,
55
- PerfStat.SHARPE_EXCESS, PerfStat.SORTINO_RATIO, PerfStat.CALMAR_RATIO,
56
- PerfStat.MAX_DD, PerfStat.MAX_DD_VOL,
57
- PerfStat.SKEWNESS, PerfStat.KURTOSIS,
58
- PerfStat.ALPHA_AN, PerfStat.BETA, PerfStat.R2],
59
- title=f"Risk-adjusted performance: {qis.get_time_period_label(prices, date_separator='-')} benchmarked with SPY",
60
- perf_params=perf_params)
51
+ fig, _ = qis.plot_ra_perf_table_benchmark(prices=prices,
52
+ benchmark='SPY',
53
+ perf_columns=[PerfStat.TOTAL_RETURN, PerfStat.PA_RETURN, PerfStat.PA_EXCESS_RETURN,
54
+ PerfStat.VOL, PerfStat.SHARPE_RF0,
55
+ PerfStat.SHARPE_EXCESS, PerfStat.SORTINO_RATIO, PerfStat.CALMAR_RATIO,
56
+ PerfStat.MAX_DD, PerfStat.MAX_DD_VOL,
57
+ PerfStat.SKEWNESS, PerfStat.KURTOSIS,
58
+ PerfStat.ALPHA_AN, PerfStat.BETA, PerfStat.R2],
59
+ title=f"Risk-adjusted performance: {qis.get_time_period_label(prices, date_separator='-')} benchmarked with SPY",
60
+ perf_params=perf_params)
61
61
  # skip
62
62
  qis.save_fig(fig, file_name='perf4', local_path="figures/")
63
63
 
@@ -125,10 +125,9 @@ def plot_ra_perf_table_benchmark(prices: pd.DataFrame,
125
125
  fontsize: int = 10,
126
126
  transpose: bool = False,
127
127
  alpha_an_factor: float = None,
128
- is_df_out: bool = False,
129
128
  ax: plt.Subplot = None,
130
129
  **kwargs
131
- ) -> Union[plt.Figure, Tuple[plt.Figure, pd.DataFrame]]:
130
+ ) -> Tuple[Optional[plt.Figure], pd.DataFrame]:
132
131
  """
133
132
  plot ra perf table and get ra performance columns with data as string for tables
134
133
  """
@@ -149,10 +148,7 @@ def plot_ra_perf_table_benchmark(prices: pd.DataFrame,
149
148
  fontsize=fontsize,
150
149
  ax=ax,
151
150
  **kwargs)
152
- if is_df_out:
153
- return fig, ra_perf_table
154
- else:
155
- return fig
151
+ return fig, ra_perf_table
156
152
 
157
153
 
158
154
  def plot_ra_perf_bars(prices: pd.DataFrame,
@@ -207,7 +207,7 @@ class MultiPortfolioData:
207
207
  for date, pd_covar in self.covar_dict.items():
208
208
  w = weight_diffs.loc[date]
209
209
  tracking_error[date] = np.sqrt(w @ pd_covar @ w.T)
210
- tracking_error = pd.Series(tracking_error)
210
+ tracking_error = pd.Series(tracking_error, name='Tracking error')
211
211
  return tracking_error
212
212
 
213
213
  def compute_tracking_error_table(self,
@@ -427,10 +427,9 @@ class MultiPortfolioData:
427
427
  time_period: TimePeriod = None,
428
428
  perf_params: PerfParams = PERF_PARAMS,
429
429
  perf_columns: List[PerfStat] = rpt.BENCHMARK_TABLE_COLUMNS,
430
- is_df_out: bool = False,
431
430
  ax: plt.Subplot = None,
432
431
  **kwargs
433
- ) -> Optional[pd.DataFrame]:
432
+ ) -> pd.DataFrame:
434
433
  if benchmark is None:
435
434
  benchmark = self.benchmark_prices.columns[0]
436
435
  prices = self.get_navs(time_period=time_period, benchmark=benchmark, add_benchmarks_to_navs=add_benchmarks_to_navs)
@@ -445,11 +444,9 @@ class MultiPortfolioData:
445
444
  drop_benchmark=drop_benchmark,
446
445
  title=ra_perf_title,
447
446
  rotation_for_columns_headers=0,
448
- is_df_out=is_df_out,
449
447
  ax=ax,
450
448
  **kwargs)
451
- if is_df_out:
452
- return ra_perf_table
449
+ return ra_perf_table
453
450
 
454
451
  def plot_ac_ra_perf_table(self,
455
452
  benchmark_price: pd.Series,
@@ -709,25 +709,33 @@ class PortfolioData:
709
709
  def compute_risk_contributions_implied_by_covar(self,
710
710
  covar_dict: Dict[pd.Timestamp, pd.DataFrame],
711
711
  group_data: pd.Series = None,
712
- group_order: List[str] = None
712
+ group_order: List[str] = None,
713
+ align_with_covar_dates: bool = True,
714
+ freq: Optional[str] = None
713
715
  ) -> pd.DataFrame:
714
716
  """
715
717
  compute risk contributions using covar_dict
716
718
  """
717
- strategy_weights = self.get_weights(freq=None, is_input_weights=True)
719
+ strategy_weights = self.get_weights(freq=freq, is_input_weights=True)
718
720
  covar_index = list(covar_dict.keys())
719
- strategy_weights = strategy_weights.reindex(index=covar_index).ffill().fillna(0.0)
720
721
  strategy_rc = {}
721
- for date, pd_covar in covar_dict.items():
722
- strategy_rc[date] = compute_portfolio_risk_contributions(w=strategy_weights.loc[date], covar=pd_covar)
723
- strategy_rc = pd.DataFrame.from_dict(strategy_rc, orient='index')
722
+ if align_with_covar_dates:
723
+ strategy_weights = strategy_weights.reindex(index=covar_index).ffill().fillna(0.0)
724
+ for date, pd_covar in covar_dict.items():
725
+ strategy_rc[date] = compute_portfolio_risk_contributions(w=strategy_weights.loc[date], covar=pd_covar)
726
+ else:
727
+ for date, weights in strategy_weights.to_dict(orient='index').items():
728
+ last_covar_update_date = qis.find_upto_date_from_datetime_index(index=covar_index, date=date)
729
+ if last_covar_update_date is not None:
730
+ strategy_rc[date] = compute_portfolio_risk_contributions(w=pd.Series(weights).fillna(0.0),
731
+ covar=covar_dict[last_covar_update_date])
724
732
 
733
+ strategy_rc = pd.DataFrame.from_dict(strategy_rc, orient='index')
725
734
  if group_data is not None:
726
735
  strategy_rc = dfg.agg_df_by_groups_ax1(strategy_rc, group_data=group_data, group_order=group_order)
727
736
 
728
737
  return strategy_rc
729
738
 
730
-
731
739
  # """
732
740
  # plotting methods
733
741
  # """
@@ -531,7 +531,8 @@ def weights_tracking_error_report(multi_portfolio_data: MultiPortfolioData,
531
531
  perf_params=perf_params,
532
532
  regime_params=regime_params,
533
533
  add_benchmarks_to_navs=add_benchmarks_to_navs,
534
- title=f"Cumulative performance with background colors using bear/normal/bull regimes of {regime_benchmark} {regime_params.freq}-returns",
534
+ title=f"Cumulative performance with background colors using bear/normal/bull "
535
+ f"regimes of {regime_benchmark} {regime_params.freq}-returns",
535
536
  ax=ax,
536
537
  **kwargs)
537
538
 
@@ -541,7 +542,6 @@ def weights_tracking_error_report(multi_portfolio_data: MultiPortfolioData,
541
542
  add_benchmarks_to_navs=add_benchmarks_to_navs,
542
543
  perf_params=perf_params,
543
544
  time_period=time_period,
544
- is_df_out=True,
545
545
  ax=ax,
546
546
  **kwargs)
547
547
  dfs['ra_perf_table'] = ra_perf_table
@@ -559,18 +559,23 @@ def weights_tracking_error_report(multi_portfolio_data: MultiPortfolioData,
559
559
  plot_exposures(exposures_short=exposures_short,
560
560
  exposures_long=exposures_long,
561
561
  ylabel='Weights',
562
- var_format=var_format, y_limits=(0.0, None),
562
+ var_format=var_format,
563
563
  axs=axs, **kwargs)
564
564
 
565
+ rc_kwargs = dict(covar_dict=multi_portfolio_data.covar_dict, freq='QE')
565
566
  # strategy risk contributions
566
- risk_contributions_short = strategy_data.compute_risk_contributions_implied_by_covar(covar_dict=multi_portfolio_data.covar_dict,
567
- group_data=group_data_short,
568
- group_order=group_order_short)
569
- risk_contributions_long = strategy_data.compute_risk_contributions_implied_by_covar(covar_dict=multi_portfolio_data.covar_dict,
570
- group_data=group_data,
571
- group_order=group_order)
567
+ risk_contributions_short = strategy_data.compute_risk_contributions_implied_by_covar(group_data=group_data_short,
568
+ group_order=group_order_short,
569
+ **rc_kwargs)
570
+ risk_contributions_long = strategy_data.compute_risk_contributions_implied_by_covar(group_data=group_data,
571
+ group_order=group_order,
572
+ **rc_kwargs)
573
+ # ungrouped
574
+ dfs['strategy_risk_contributions'] = strategy_data.compute_risk_contributions_implied_by_covar(**rc_kwargs)
575
+
576
+
572
577
  fig, axs = plt.subplots(1, 2, figsize=figsize, tight_layout=True)
573
- qis.set_suptitle(fig, title=f"{strategy_data.ticker} Var")
578
+ qis.set_suptitle(fig, title=f"{strategy_data.ticker} Risk Contributions")
574
579
  figs['strategy_var'] = fig
575
580
  plot_exposures(exposures_short=qis.df_to_weight_allocation_sum1(risk_contributions_short),
576
581
  exposures_long=qis.df_to_weight_allocation_sum1(risk_contributions_long),
@@ -591,18 +596,21 @@ def weights_tracking_error_report(multi_portfolio_data: MultiPortfolioData,
591
596
  plot_exposures(exposures_short=benchmark_exposures_short,
592
597
  exposures_long=benchmark_exposures_long,
593
598
  ylabel='Weights',
594
- var_format=var_format, y_limits=(0.0, None),
599
+ var_format=var_format,
595
600
  axs=axs, **kwargs)
596
601
 
597
602
  # benchmark var
598
603
  benchmark_risk_contributions_short = benchmark_data.compute_risk_contributions_implied_by_covar(
599
- covar_dict=multi_portfolio_data.covar_dict,
600
604
  group_data=group_data_short,
601
- group_order=group_order_short)
605
+ group_order=group_order_short,
606
+ **rc_kwargs)
602
607
  benchmark_risk_contributions_long = benchmark_data.compute_risk_contributions_implied_by_covar(
603
- covar_dict=multi_portfolio_data.covar_dict,
604
608
  group_data=group_data,
605
- group_order=group_order)
609
+ group_order=group_order,
610
+ **rc_kwargs)
611
+ # ungrouped
612
+ dfs['benchmark_risk_contributions'] = benchmark_data.compute_risk_contributions_implied_by_covar(**rc_kwargs)
613
+
606
614
  fig, axs = plt.subplots(1, 2, figsize=figsize, tight_layout=True)
607
615
  qis.set_suptitle(fig, title=f"{benchmark_data.ticker} Risk Contributions")
608
616
  figs['benchmark_var'] = fig
@@ -613,9 +621,9 @@ def weights_tracking_error_report(multi_portfolio_data: MultiPortfolioData,
613
621
  axs=axs, **kwargs)
614
622
 
615
623
  # turnover
616
- fig, axs = plt.subplots(1, 2, figsize=figsize, tight_layout=True)
624
+ fig, ax = plt.subplots(1, 1, figsize=figsize, tight_layout=True)
617
625
  figs['turnover'] = fig
618
- multi_portfolio_data.plot_turnover(ax=axs[0],
626
+ multi_portfolio_data.plot_turnover(ax=ax,
619
627
  time_period=time_period,
620
628
  #turnover_rolling_period=260,
621
629
  #freq_turnover=None,
@@ -660,5 +668,6 @@ def plot_exposures(exposures_short: pd.DataFrame,
660
668
  yvar_format=var_format,
661
669
  x_rotation=90,
662
670
  colors=qis.get_n_sns_colors(n=len(exposures_long.columns)),
671
+ y_limits=(0.0, None),
663
672
  ax=axs[1],
664
673
  **kwargs)
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