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.
- {qis-2.1.39 → qis-2.1.40}/PKG-INFO +11 -11
- {qis-2.1.39 → qis-2.1.40}/README.md +10 -10
- {qis-2.1.39 → qis-2.1.40}/pyproject.toml +1 -1
- {qis-2.1.39 → qis-2.1.40}/qis/examples/readme_performances.py +10 -10
- {qis-2.1.39 → qis-2.1.40}/qis/plots/derived/perf_table.py +2 -6
- {qis-2.1.39 → qis-2.1.40}/qis/portfolio/multi_portfolio_data.py +3 -6
- {qis-2.1.39 → qis-2.1.40}/qis/portfolio/portfolio_data.py +15 -7
- {qis-2.1.39 → qis-2.1.40}/qis/portfolio/reports/strategy_benchmark_factsheet.py +26 -17
- {qis-2.1.39 → qis-2.1.40}/LICENSE.txt +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/__init__.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/best_returns.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/bond_futures_portfolio.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/bootstrap_analysis.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/boxplot_conditional_returns.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/btc_asset_corr.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/constant_notional.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/constant_weight_portfolios.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/core/perf_bbg_prices.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/core/price_plots.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/core/us_election.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/credit_spreads.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/credit_trackers.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/europe_futures.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/factsheets/multi_assets.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/factsheets/multi_strategy.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/factsheets/pyblogs_reports.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/factsheets/strategy.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/factsheets/strategy_benchmark.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/generate_option_rolls.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/interpolation_infrequent_returns.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/leveraged_strategies.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/long_short.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/momentum_indices.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/oakmark_analysis.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/ohlc_vol_analysis.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/overnight_returns.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/perf_external_assets.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/perp_pricing.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/risk_return_frontier.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/rolling_performance.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/seasonality.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/sharpe_vs_sortino.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/simulate_quant_strats.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/test_ewm.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/test_scatter.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/try_pybloqs.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/universe_corrs.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/vix_beta_to_equities_bonds.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/vix_conditional_returns.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/vix_spy_by_year.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/vix_tenor_analysis.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/examples/vol_without_weekends.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/file_utils.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/local_path.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/models/README.md +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/models/__init__.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/models/linear/__init__.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/models/linear/auto_corr.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/models/linear/corr_cov_matrix.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/models/linear/ewm.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/models/linear/ewm_convolution.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/models/linear/ewm_factors.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/models/linear/ewm_winsor_outliers.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/models/linear/pca.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/models/linear/plot_correlations.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/models/linear/ra_returns.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/models/stats/__init__.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/models/stats/bootstrap.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/models/stats/ohlc_vol.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/models/stats/rolling_stats.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/models/stats/test_bootstrap.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/perfstats/README.md +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/perfstats/__init__.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/perfstats/cond_regression.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/perfstats/config.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/perfstats/desc_table.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/perfstats/fx_ops.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/perfstats/perf_stats.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/perfstats/regime_classifier.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/perfstats/returns.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/perfstats/timeseries_bfill.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/README.md +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/__init__.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/bars.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/boxplot.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/contour.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/derived/__init__.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/derived/data_timeseries.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/derived/desc_table.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/derived/drawdowns.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/derived/prices.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/derived/regime_class_table.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/derived/regime_data.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/derived/regime_pdf.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/derived/regime_scatter.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/derived/returns_heatmap.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/derived/returns_scatter.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/errorbar.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/heatmap.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/histogram.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/histplot2d.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/lineplot.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/pie.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/qqplot.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/reports/__init__.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/reports/econ_data_single.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/reports/gantt_data_history.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/reports/price_history.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/reports/utils.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/scatter.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/stackplot.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/table.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/time_series.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/plots/utils.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/portfolio/README.md +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/portfolio/__init__.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/portfolio/backtester.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/portfolio/ewm_portfolio_risk.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/portfolio/reports/__init__.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/portfolio/reports/brinson_attribution.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/portfolio/reports/config.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/portfolio/reports/multi_assets_factsheet.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/portfolio/reports/multi_strategy_factseet_pybloqs.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/portfolio/reports/multi_strategy_factsheet.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/portfolio/reports/strategy_benchmark_factsheet_pybloqs.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/portfolio/reports/strategy_factsheet.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/portfolio/reports/strategy_signal_factsheet.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/portfolio/strats/__init__.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/portfolio/strats/quant_strats_delta1.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/portfolio/strats/seasonal_strats.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/settings.yaml +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/sql_engine.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/test_data.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/utils/README.md +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/utils/__init__.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/utils/dates.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/utils/df_agg.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/utils/df_cut.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/utils/df_freq.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/utils/df_groups.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/utils/df_melt.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/utils/df_ops.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/utils/df_str.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/utils/df_to_scores.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/utils/df_to_weights.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/utils/generic.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/utils/np_ops.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/utils/ols.py +0 -0
- {qis-2.1.39 → qis-2.1.40}/qis/utils/sampling.py +0 -0
- {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.
|
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
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
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
|

|
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
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
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
|

|
139
139
|
|
@@ -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
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
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
|
-
) ->
|
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
|
-
|
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
|
-
) ->
|
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
|
-
|
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=
|
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
|
-
|
722
|
-
|
723
|
-
|
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
|
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,
|
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(
|
567
|
-
|
568
|
-
|
569
|
-
risk_contributions_long = strategy_data.compute_risk_contributions_implied_by_covar(
|
570
|
-
|
571
|
-
|
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}
|
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,
|
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,
|
624
|
+
fig, ax = plt.subplots(1, 1, figsize=figsize, tight_layout=True)
|
617
625
|
figs['turnover'] = fig
|
618
|
-
multi_portfolio_data.plot_turnover(ax=
|
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
|
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
|