qis 3.0.2__tar.gz → 3.0.3__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-3.0.2 → qis-3.0.3}/PKG-INFO +1 -1
  2. {qis-3.0.2 → qis-3.0.3}/pyproject.toml +1 -1
  3. {qis-3.0.2 → qis-3.0.3}/qis/portfolio/ewm_portfolio_risk.py +3 -1
  4. {qis-3.0.2 → qis-3.0.3}/qis/portfolio/multi_portfolio_data.py +8 -6
  5. {qis-3.0.2 → qis-3.0.3}/qis/portfolio/portfolio_data.py +17 -12
  6. {qis-3.0.2 → qis-3.0.3}/qis/portfolio/reports/config.py +8 -4
  7. {qis-3.0.2 → qis-3.0.3}/qis/portfolio/reports/strategy_factsheet.py +5 -4
  8. {qis-3.0.2 → qis-3.0.3}/qis/settings.yaml +1 -0
  9. {qis-3.0.2 → qis-3.0.3}/LICENSE.txt +0 -0
  10. {qis-3.0.2 → qis-3.0.3}/README.md +0 -0
  11. {qis-3.0.2 → qis-3.0.3}/qis/__init__.py +0 -0
  12. {qis-3.0.2 → qis-3.0.3}/qis/examples/best_returns.py +0 -0
  13. {qis-3.0.2 → qis-3.0.3}/qis/examples/bond_futures_portfolio.py +0 -0
  14. {qis-3.0.2 → qis-3.0.3}/qis/examples/bootstrap_analysis.py +0 -0
  15. {qis-3.0.2 → qis-3.0.3}/qis/examples/boxplot_conditional_returns.py +0 -0
  16. {qis-3.0.2 → qis-3.0.3}/qis/examples/btc_asset_corr.py +0 -0
  17. {qis-3.0.2 → qis-3.0.3}/qis/examples/constant_notional.py +0 -0
  18. {qis-3.0.2 → qis-3.0.3}/qis/examples/constant_weight_portfolios.py +0 -0
  19. {qis-3.0.2 → qis-3.0.3}/qis/examples/core/perf_bbg_prices.py +0 -0
  20. {qis-3.0.2 → qis-3.0.3}/qis/examples/core/price_plots.py +0 -0
  21. {qis-3.0.2 → qis-3.0.3}/qis/examples/core/us_election.py +0 -0
  22. {qis-3.0.2 → qis-3.0.3}/qis/examples/credit_spreads.py +0 -0
  23. {qis-3.0.2 → qis-3.0.3}/qis/examples/credit_trackers.py +0 -0
  24. {qis-3.0.2 → qis-3.0.3}/qis/examples/europe_futures.py +0 -0
  25. {qis-3.0.2 → qis-3.0.3}/qis/examples/factsheets/multi_assets.py +0 -0
  26. {qis-3.0.2 → qis-3.0.3}/qis/examples/factsheets/multi_strategy.py +0 -0
  27. {qis-3.0.2 → qis-3.0.3}/qis/examples/factsheets/pyblogs_reports.py +0 -0
  28. {qis-3.0.2 → qis-3.0.3}/qis/examples/factsheets/strategy.py +0 -0
  29. {qis-3.0.2 → qis-3.0.3}/qis/examples/factsheets/strategy_benchmark.py +0 -0
  30. {qis-3.0.2 → qis-3.0.3}/qis/examples/generate_option_rolls.py +0 -0
  31. {qis-3.0.2 → qis-3.0.3}/qis/examples/interpolation_infrequent_returns.py +0 -0
  32. {qis-3.0.2 → qis-3.0.3}/qis/examples/leveraged_strategies.py +0 -0
  33. {qis-3.0.2 → qis-3.0.3}/qis/examples/long_short.py +0 -0
  34. {qis-3.0.2 → qis-3.0.3}/qis/examples/momentum_indices.py +0 -0
  35. {qis-3.0.2 → qis-3.0.3}/qis/examples/oakmark_analysis.py +0 -0
  36. {qis-3.0.2 → qis-3.0.3}/qis/examples/ohlc_vol_analysis.py +0 -0
  37. {qis-3.0.2 → qis-3.0.3}/qis/examples/overnight_returns.py +0 -0
  38. {qis-3.0.2 → qis-3.0.3}/qis/examples/perf_external_assets.py +0 -0
  39. {qis-3.0.2 → qis-3.0.3}/qis/examples/perp_pricing.py +0 -0
  40. {qis-3.0.2 → qis-3.0.3}/qis/examples/readme_performances.py +0 -0
  41. {qis-3.0.2 → qis-3.0.3}/qis/examples/risk_return_frontier.py +0 -0
  42. {qis-3.0.2 → qis-3.0.3}/qis/examples/rolling_performance.py +0 -0
  43. {qis-3.0.2 → qis-3.0.3}/qis/examples/seasonality.py +0 -0
  44. {qis-3.0.2 → qis-3.0.3}/qis/examples/sharpe_vs_sortino.py +0 -0
  45. {qis-3.0.2 → qis-3.0.3}/qis/examples/simulate_quant_strats.py +0 -0
  46. {qis-3.0.2 → qis-3.0.3}/qis/examples/test_ewm.py +0 -0
  47. {qis-3.0.2 → qis-3.0.3}/qis/examples/test_scatter.py +0 -0
  48. {qis-3.0.2 → qis-3.0.3}/qis/examples/try_pybloqs.py +0 -0
  49. {qis-3.0.2 → qis-3.0.3}/qis/examples/universe_corrs.py +0 -0
  50. {qis-3.0.2 → qis-3.0.3}/qis/examples/vix_beta_to_equities_bonds.py +0 -0
  51. {qis-3.0.2 → qis-3.0.3}/qis/examples/vix_conditional_returns.py +0 -0
  52. {qis-3.0.2 → qis-3.0.3}/qis/examples/vix_spy_by_year.py +0 -0
  53. {qis-3.0.2 → qis-3.0.3}/qis/examples/vix_tenor_analysis.py +0 -0
  54. {qis-3.0.2 → qis-3.0.3}/qis/examples/vol_without_weekends.py +0 -0
  55. {qis-3.0.2 → qis-3.0.3}/qis/file_utils.py +0 -0
  56. {qis-3.0.2 → qis-3.0.3}/qis/local_path.py +0 -0
  57. {qis-3.0.2 → qis-3.0.3}/qis/models/README.md +0 -0
  58. {qis-3.0.2 → qis-3.0.3}/qis/models/__init__.py +0 -0
  59. {qis-3.0.2 → qis-3.0.3}/qis/models/linear/__init__.py +0 -0
  60. {qis-3.0.2 → qis-3.0.3}/qis/models/linear/auto_corr.py +0 -0
  61. {qis-3.0.2 → qis-3.0.3}/qis/models/linear/corr_cov_matrix.py +0 -0
  62. {qis-3.0.2 → qis-3.0.3}/qis/models/linear/ewm.py +0 -0
  63. {qis-3.0.2 → qis-3.0.3}/qis/models/linear/ewm_convolution.py +0 -0
  64. {qis-3.0.2 → qis-3.0.3}/qis/models/linear/ewm_factors.py +0 -0
  65. {qis-3.0.2 → qis-3.0.3}/qis/models/linear/ewm_winsor_outliers.py +0 -0
  66. {qis-3.0.2 → qis-3.0.3}/qis/models/linear/pca.py +0 -0
  67. {qis-3.0.2 → qis-3.0.3}/qis/models/linear/plot_correlations.py +0 -0
  68. {qis-3.0.2 → qis-3.0.3}/qis/models/linear/ra_returns.py +0 -0
  69. {qis-3.0.2 → qis-3.0.3}/qis/models/stats/__init__.py +0 -0
  70. {qis-3.0.2 → qis-3.0.3}/qis/models/stats/bootstrap.py +0 -0
  71. {qis-3.0.2 → qis-3.0.3}/qis/models/stats/ohlc_vol.py +0 -0
  72. {qis-3.0.2 → qis-3.0.3}/qis/models/stats/rolling_stats.py +0 -0
  73. {qis-3.0.2 → qis-3.0.3}/qis/models/stats/test_bootstrap.py +0 -0
  74. {qis-3.0.2 → qis-3.0.3}/qis/perfstats/README.md +0 -0
  75. {qis-3.0.2 → qis-3.0.3}/qis/perfstats/__init__.py +0 -0
  76. {qis-3.0.2 → qis-3.0.3}/qis/perfstats/cond_regression.py +0 -0
  77. {qis-3.0.2 → qis-3.0.3}/qis/perfstats/config.py +0 -0
  78. {qis-3.0.2 → qis-3.0.3}/qis/perfstats/desc_table.py +0 -0
  79. {qis-3.0.2 → qis-3.0.3}/qis/perfstats/fx_ops.py +0 -0
  80. {qis-3.0.2 → qis-3.0.3}/qis/perfstats/perf_stats.py +0 -0
  81. {qis-3.0.2 → qis-3.0.3}/qis/perfstats/regime_classifier.py +0 -0
  82. {qis-3.0.2 → qis-3.0.3}/qis/perfstats/returns.py +0 -0
  83. {qis-3.0.2 → qis-3.0.3}/qis/perfstats/timeseries_bfill.py +0 -0
  84. {qis-3.0.2 → qis-3.0.3}/qis/plots/README.md +0 -0
  85. {qis-3.0.2 → qis-3.0.3}/qis/plots/__init__.py +0 -0
  86. {qis-3.0.2 → qis-3.0.3}/qis/plots/bars.py +0 -0
  87. {qis-3.0.2 → qis-3.0.3}/qis/plots/boxplot.py +0 -0
  88. {qis-3.0.2 → qis-3.0.3}/qis/plots/contour.py +0 -0
  89. {qis-3.0.2 → qis-3.0.3}/qis/plots/derived/__init__.py +0 -0
  90. {qis-3.0.2 → qis-3.0.3}/qis/plots/derived/data_timeseries.py +0 -0
  91. {qis-3.0.2 → qis-3.0.3}/qis/plots/derived/desc_table.py +0 -0
  92. {qis-3.0.2 → qis-3.0.3}/qis/plots/derived/drawdowns.py +0 -0
  93. {qis-3.0.2 → qis-3.0.3}/qis/plots/derived/perf_table.py +0 -0
  94. {qis-3.0.2 → qis-3.0.3}/qis/plots/derived/prices.py +0 -0
  95. {qis-3.0.2 → qis-3.0.3}/qis/plots/derived/regime_class_table.py +0 -0
  96. {qis-3.0.2 → qis-3.0.3}/qis/plots/derived/regime_data.py +0 -0
  97. {qis-3.0.2 → qis-3.0.3}/qis/plots/derived/regime_pdf.py +0 -0
  98. {qis-3.0.2 → qis-3.0.3}/qis/plots/derived/regime_scatter.py +0 -0
  99. {qis-3.0.2 → qis-3.0.3}/qis/plots/derived/returns_heatmap.py +0 -0
  100. {qis-3.0.2 → qis-3.0.3}/qis/plots/derived/returns_scatter.py +0 -0
  101. {qis-3.0.2 → qis-3.0.3}/qis/plots/errorbar.py +0 -0
  102. {qis-3.0.2 → qis-3.0.3}/qis/plots/heatmap.py +0 -0
  103. {qis-3.0.2 → qis-3.0.3}/qis/plots/histogram.py +0 -0
  104. {qis-3.0.2 → qis-3.0.3}/qis/plots/histplot2d.py +0 -0
  105. {qis-3.0.2 → qis-3.0.3}/qis/plots/lineplot.py +0 -0
  106. {qis-3.0.2 → qis-3.0.3}/qis/plots/pie.py +0 -0
  107. {qis-3.0.2 → qis-3.0.3}/qis/plots/qqplot.py +0 -0
  108. {qis-3.0.2 → qis-3.0.3}/qis/plots/reports/__init__.py +0 -0
  109. {qis-3.0.2 → qis-3.0.3}/qis/plots/reports/econ_data_single.py +0 -0
  110. {qis-3.0.2 → qis-3.0.3}/qis/plots/reports/gantt_data_history.py +0 -0
  111. {qis-3.0.2 → qis-3.0.3}/qis/plots/reports/price_history.py +0 -0
  112. {qis-3.0.2 → qis-3.0.3}/qis/plots/reports/utils.py +0 -0
  113. {qis-3.0.2 → qis-3.0.3}/qis/plots/scatter.py +0 -0
  114. {qis-3.0.2 → qis-3.0.3}/qis/plots/stackplot.py +0 -0
  115. {qis-3.0.2 → qis-3.0.3}/qis/plots/table.py +0 -0
  116. {qis-3.0.2 → qis-3.0.3}/qis/plots/time_series.py +0 -0
  117. {qis-3.0.2 → qis-3.0.3}/qis/plots/utils.py +0 -0
  118. {qis-3.0.2 → qis-3.0.3}/qis/portfolio/README.md +0 -0
  119. {qis-3.0.2 → qis-3.0.3}/qis/portfolio/__init__.py +0 -0
  120. {qis-3.0.2 → qis-3.0.3}/qis/portfolio/backtester.py +0 -0
  121. {qis-3.0.2 → qis-3.0.3}/qis/portfolio/reports/__init__.py +0 -0
  122. {qis-3.0.2 → qis-3.0.3}/qis/portfolio/reports/brinson_attribution.py +0 -0
  123. {qis-3.0.2 → qis-3.0.3}/qis/portfolio/reports/multi_assets_factsheet.py +0 -0
  124. {qis-3.0.2 → qis-3.0.3}/qis/portfolio/reports/multi_strategy_factseet_pybloqs.py +0 -0
  125. {qis-3.0.2 → qis-3.0.3}/qis/portfolio/reports/multi_strategy_factsheet.py +0 -0
  126. {qis-3.0.2 → qis-3.0.3}/qis/portfolio/reports/strategy_benchmark_factsheet.py +0 -0
  127. {qis-3.0.2 → qis-3.0.3}/qis/portfolio/reports/strategy_benchmark_factsheet_pybloqs.py +0 -0
  128. {qis-3.0.2 → qis-3.0.3}/qis/portfolio/reports/strategy_signal_factsheet.py +0 -0
  129. {qis-3.0.2 → qis-3.0.3}/qis/portfolio/strats/__init__.py +0 -0
  130. {qis-3.0.2 → qis-3.0.3}/qis/portfolio/strats/quant_strats_delta1.py +0 -0
  131. {qis-3.0.2 → qis-3.0.3}/qis/portfolio/strats/seasonal_strats.py +0 -0
  132. {qis-3.0.2 → qis-3.0.3}/qis/sql_engine.py +0 -0
  133. {qis-3.0.2 → qis-3.0.3}/qis/test_data.py +0 -0
  134. {qis-3.0.2 → qis-3.0.3}/qis/utils/README.md +0 -0
  135. {qis-3.0.2 → qis-3.0.3}/qis/utils/__init__.py +0 -0
  136. {qis-3.0.2 → qis-3.0.3}/qis/utils/dates.py +0 -0
  137. {qis-3.0.2 → qis-3.0.3}/qis/utils/df_agg.py +0 -0
  138. {qis-3.0.2 → qis-3.0.3}/qis/utils/df_cut.py +0 -0
  139. {qis-3.0.2 → qis-3.0.3}/qis/utils/df_freq.py +0 -0
  140. {qis-3.0.2 → qis-3.0.3}/qis/utils/df_groups.py +0 -0
  141. {qis-3.0.2 → qis-3.0.3}/qis/utils/df_melt.py +0 -0
  142. {qis-3.0.2 → qis-3.0.3}/qis/utils/df_ops.py +0 -0
  143. {qis-3.0.2 → qis-3.0.3}/qis/utils/df_str.py +0 -0
  144. {qis-3.0.2 → qis-3.0.3}/qis/utils/df_to_scores.py +0 -0
  145. {qis-3.0.2 → qis-3.0.3}/qis/utils/df_to_weights.py +0 -0
  146. {qis-3.0.2 → qis-3.0.3}/qis/utils/generic.py +0 -0
  147. {qis-3.0.2 → qis-3.0.3}/qis/utils/np_ops.py +0 -0
  148. {qis-3.0.2 → qis-3.0.3}/qis/utils/ols.py +0 -0
  149. {qis-3.0.2 → qis-3.0.3}/qis/utils/sampling.py +0 -0
  150. {qis-3.0.2 → qis-3.0.3}/qis/utils/struct_ops.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: qis
3
- Version: 3.0.2
3
+ Version: 3.0.3
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.0.2"
3
+ version = "3.0.3"
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>"]
@@ -75,9 +75,11 @@ def compute_portfolio_vol(returns: pd.DataFrame,
75
75
  init_type=init_type,
76
76
  nan_backfill=nan_backfill)
77
77
 
78
+ if span is not None:
79
+ ewm_lambda = 1.0 - 2.0 / (span + 1.0)
80
+
78
81
  portfolio_vol = compute_portfolio_var_np(returns=returns_np,
79
82
  weights=weights_np,
80
- span=span,
81
83
  ewm_lambda=ewm_lambda)
82
84
 
83
85
  if annualize:
@@ -216,7 +216,7 @@ class MultiPortfolioData:
216
216
  freq: Optional[str] = 'B',
217
217
  time_period: TimePeriod = None,
218
218
  af: float = 260,
219
- is_norm_costs: bool = True,
219
+ is_unit_based_traded_volume: bool = True,
220
220
  **kwargs
221
221
  ) -> pd.DataFrame:
222
222
  """
@@ -238,7 +238,7 @@ class MultiPortfolioData:
238
238
  roll_period=None, add_total=False)
239
239
  strategy_cost = self.portfolio_datas[strategy_idx].get_costs(time_period=time_period, freq=freq,
240
240
  roll_period=None,
241
- add_total=False, is_norm_costs=is_norm_costs)
241
+ add_total=False, is_unit_based_traded_volume=is_unit_based_traded_volume)
242
242
  strategy_ticker = self.portfolio_datas[strategy_idx].ticker
243
243
 
244
244
  # benchmark_weights = self.portfolio_datas[benchmark_idx].get_weights(time_period=time_period, freq=None, is_input_weights=True)
@@ -246,7 +246,7 @@ class MultiPortfolioData:
246
246
  roll_period=None, add_total=False)
247
247
  benchmark_cost = self.portfolio_datas[benchmark_idx].get_costs(time_period=time_period, freq=freq,
248
248
  roll_period=None,
249
- add_total=False, is_norm_costs=is_norm_costs)
249
+ add_total=False, is_unit_based_traded_volume=is_unit_based_traded_volume)
250
250
  benchmark_ticker = self.portfolio_datas[benchmark_idx].ticker
251
251
 
252
252
  # compute stats
@@ -606,12 +606,14 @@ class MultiPortfolioData:
606
606
  turnover_rolling_period: Optional[int] = 260,
607
607
  freq_turnover: Optional[str] = 'B',
608
608
  var_format: str = '{:.0%}',
609
+ is_unit_based_traded_volume: bool = True,
609
610
  ax: plt.Subplot = None,
610
611
  **kwargs) -> None:
611
612
 
612
613
  turnover = []
613
614
  for portfolio in self.portfolio_datas:
614
- turnover.append(portfolio.get_turnover(roll_period=turnover_rolling_period, freq=freq_turnover, is_agg=True).rename(portfolio.nav.name))
615
+ turnover.append(portfolio.get_turnover(roll_period=turnover_rolling_period, freq=freq_turnover, is_agg=True,
616
+ is_unit_based_traded_volume=is_unit_based_traded_volume).rename(portfolio.nav.name))
615
617
  turnover = pd.concat(turnover, axis=1)
616
618
  if time_period is not None:
617
619
  turnover = time_period.locate(turnover)
@@ -635,13 +637,13 @@ class MultiPortfolioData:
635
637
  time_period: TimePeriod = None,
636
638
  regime_params: BenchmarkReturnsQuantileRegimeSpecs = REGIME_PARAMS,
637
639
  var_format: str = '{:.2%}',
638
- is_norm_costs: bool = True,
640
+ is_unit_based_traded_volume: bool = True,
639
641
  ax: plt.Subplot = None,
640
642
  **kwargs) -> None:
641
643
  costs = []
642
644
  for portfolio in self.portfolio_datas:
643
645
  costs.append(portfolio.get_costs(roll_period=cost_rolling_period, freq=freq_cost, is_agg=True,
644
- is_norm_costs=is_norm_costs).rename(portfolio.nav.name))
646
+ is_unit_based_traded_volume=is_unit_based_traded_volume).rename(portfolio.nav.name))
645
647
  costs = pd.concat(costs, axis=1)
646
648
  if time_period is not None:
647
649
  costs = time_period.locate(costs)
@@ -167,13 +167,13 @@ class PortfolioData:
167
167
  add_total: bool = False,
168
168
  time_period: TimePeriod = None,
169
169
  is_net: bool = False,
170
- is_norm_costs: bool = True,
170
+ is_unit_based_traded_volume: bool = True,
171
171
  is_compounded: bool = False,
172
172
  freq: Optional[str] = None
173
173
  ) -> pd.DataFrame:
174
174
  pnl = self.instrument_pnl.copy()
175
175
  if is_net:
176
- costs = self.get_costs(add_total=False, is_norm_costs=is_norm_costs)
176
+ costs = self.get_costs(add_total=False, is_unit_based_traded_volume=is_unit_based_traded_volume)
177
177
  pnl = pnl.subtract(costs)
178
178
  if add_total:
179
179
  pnl.insert(loc=0, value=pnl.sum(1), column='Total')
@@ -335,12 +335,17 @@ class PortfolioData:
335
335
  is_vol_adjusted: bool = False,
336
336
  add_total: bool = True,
337
337
  vol_span: int = 33,
338
- freq: Optional[str] = None
338
+ freq: Optional[str] = None,
339
+ is_unit_based_traded_volume: bool = True
339
340
  ) -> Union[pd.DataFrame, pd.Series]:
340
- turnover = (self.units.diff(1).abs()).multiply(self.prices)
341
- abs_exposure = self.units.multiply(self.prices).abs().sum(axis=1)
342
- # turnover = turnover.divide(self.nav.to_numpy(), axis=0)
343
- turnover = turnover.divide(abs_exposure.to_numpy(), axis=0)
341
+
342
+ if is_unit_based_traded_volume: # for unit generated backtest
343
+ turnover = (self.units.diff(1).abs()).multiply(self.prices)
344
+ abs_exposure = self.units.multiply(self.prices).abs().sum(axis=1)
345
+ # turnover = turnover.divide(self.nav.to_numpy(), axis=0)
346
+ turnover = turnover.divide(abs_exposure.to_numpy(), axis=0)
347
+ else: # for weight generated backtets
348
+ turnover = self.input_weights.diff(1).abs()
344
349
 
345
350
  if is_vol_adjusted:
346
351
  instrument_vols = compute_ewm_vol(data=qis.to_returns(self.prices, is_log_returns=True),
@@ -374,13 +379,13 @@ class PortfolioData:
374
379
  is_grouped: bool = False,
375
380
  time_period: TimePeriod = None,
376
381
  add_total: bool = True,
377
- is_norm_costs: bool = True,
382
+ is_unit_based_traded_volume: bool = True,
378
383
  roll_period: Optional[int] = 260,
379
384
  freq: Optional[str] = None
380
385
  ) -> Union[pd.DataFrame, pd.Series]:
381
386
 
382
387
  costs = self.realized_costs
383
- if is_norm_costs:
388
+ if is_unit_based_traded_volume:
384
389
  costs = costs.divide(self.nav.to_numpy(), axis=0)
385
390
  if is_agg:
386
391
  costs = pd.Series(np.nansum(costs, axis=1), index=self.nav.index, name=self.nav.name)
@@ -533,7 +538,7 @@ class PortfolioData:
533
538
  def get_performance_attribution_data(self,
534
539
  attribution_metric: AttributionMetric = AttributionMetric.PNL,
535
540
  time_period: TimePeriod = None,
536
- is_norm_costs: bool = True,
541
+ is_unit_based_traded_volume: bool = True,
537
542
  **kwargs
538
543
  ) -> Union[pd.DataFrame, pd.Series]:
539
544
  if attribution_metric == AttributionMetric.PNL:
@@ -543,11 +548,11 @@ class PortfolioData:
543
548
  elif attribution_metric == AttributionMetric.INST_PNL:
544
549
  data = self.get_instruments_navs(time_period=time_period)
545
550
  elif attribution_metric == AttributionMetric.COSTS:
546
- data = self.get_costs(is_agg=False, is_grouped=False, roll_period=None, is_norm_costs=is_norm_costs,
551
+ data = self.get_costs(is_agg=False, is_grouped=False, roll_period=None, is_unit_based_traded_volume=is_unit_based_traded_volume,
547
552
  add_total=False,
548
553
  time_period=time_period)
549
554
  data = data.sum(0)
550
- #print(f"total costs, is_norm_costs={is_norm_costs} = {np.nansum(data)}")
555
+ #print(f"total costs, is_unit_based_traded_volume={is_unit_based_traded_volume} = {np.nansum(data)}")
551
556
  elif attribution_metric == AttributionMetric.TURNOVER:
552
557
  data = self.get_turnover(is_agg=False, is_grouped=False, roll_period=None,
553
558
  add_total=False,
@@ -3,6 +3,8 @@ configuration for performance reports
3
3
  """
4
4
  from enum import Enum
5
5
  from typing import Dict, Any, Tuple, NamedTuple, Optional, List
6
+
7
+ import qis
6
8
  from qis import PerfParams, BenchmarkReturnsQuantileRegimeSpecs, TimePeriod, PerfStat
7
9
  import yfinance as yf
8
10
 
@@ -61,7 +63,7 @@ class FactsheetConfig(NamedTuple):
61
63
  freq_turnover: str = 'B' # daily freq
62
64
  cost_rolling_period: int = 260 # turnover = turnover.rolling(turnover_roll_period).sum()
63
65
  freq_cost: Optional[str] = 'B' # for rolling costs
64
- is_norm_costs: bool = True # for long-only protfolio use nrmalised costs
66
+ is_unit_based_traded_volume: bool = True # for long-only protfolio use nrmalised costs
65
67
  factor_beta_span: int = 52 # to compute rolling beta
66
68
  freq_beta: str = 'W-WED' # for scatter plot
67
69
  exposures_freq: str = 'W-WED' # for plotting strategy exposures
@@ -101,7 +103,7 @@ FACTSHEET_CONFIG_MONTHLY_DATA_LONG_PERIOD = FactsheetConfig(freq='ME',
101
103
  freq_cost='ME',
102
104
  freq_var='ME',
103
105
  var_span=12,
104
- is_norm_costs=True,
106
+ is_unit_based_traded_volume=True,
105
107
  factor_beta_span=36,
106
108
  freq_beta='ME',
107
109
  exposures_freq='ME')
@@ -124,7 +126,7 @@ FACTSHEET_CONFIG_QUARTERLY_DATA_LONG_PERIOD = FactsheetConfig(freq='QE',
124
126
  freq_cost='QE',
125
127
  freq_var='QE',
126
128
  var_span=12,
127
- is_norm_costs=True,
129
+ is_unit_based_traded_volume=True,
128
130
  factor_beta_span=12,
129
131
  freq_beta='QE',
130
132
  exposures_freq='QE')
@@ -178,7 +180,8 @@ def fetch_default_perf_params() -> Tuple[PerfParams, BenchmarkReturnsQuantileReg
178
180
  def fetch_default_report_kwargs(time_period: Optional[TimePeriod] = None,
179
181
  reporting_frequency: ReportingFrequency = ReportingFrequency.DAILY,
180
182
  long_threshold_years: float = 5.0,
181
- add_rates_data: bool = True
183
+ add_rates_data: bool = True,
184
+ is_unit_based_traded_volume: bool = True
182
185
  ) -> Dict[str, Any]:
183
186
 
184
187
  # use for number years > 5
@@ -207,6 +210,7 @@ def fetch_default_report_kwargs(time_period: Optional[TimePeriod] = None,
207
210
 
208
211
  kwargs = fetch_factsheet_config_kwargs(factsheet_config=factsheet_config,
209
212
  add_rates_data=add_rates_data)
213
+ kwargs = qis.update_kwargs(kwargs, dict(is_unit_based_traded_volume=is_unit_based_traded_volume))
210
214
  return kwargs
211
215
 
212
216
 
@@ -51,7 +51,7 @@ def generate_strategy_factsheet(portfolio_data: PortfolioData,
51
51
  is_1y_exposures: bool = False,
52
52
  is_grouped: Optional[bool] = None,
53
53
  dd_legend_type: qis.DdLegendType = qis.DdLegendType.SIMPLE,
54
- is_norm_costs: bool = True,
54
+ is_unit_based_traded_volume: bool = True,
55
55
  df_to_add: pd.DataFrame = None,
56
56
  factsheet_name: str = None,
57
57
  **kwargs
@@ -157,7 +157,8 @@ def generate_strategy_factsheet(portfolio_data: PortfolioData,
157
157
  ax = fig.add_subplot(gs[10:12, :2])
158
158
  turnover = portfolio_data.get_turnover(time_period=time_period, roll_period=turnover_rolling_period,
159
159
  freq=freq_turnover,
160
- is_grouped=is_grouped)
160
+ is_grouped=is_grouped,
161
+ is_unit_based_traded_volume=is_unit_based_traded_volume)
161
162
  freq = pd.infer_freq(turnover.index)
162
163
  turnover_title = f"{turnover_rolling_period}-period rolling {freq}-freq Turnover"
163
164
  qis.plot_time_series(df=turnover,
@@ -175,7 +176,7 @@ def generate_strategy_factsheet(portfolio_data: PortfolioData,
175
176
  costs = portfolio_data.get_costs(time_period=time_period, roll_period=cost_rolling_period,
176
177
  freq=freq_cost,
177
178
  is_grouped=is_grouped,
178
- is_norm_costs=is_norm_costs)
179
+ is_unit_based_traded_volume=is_unit_based_traded_volume)
179
180
  freq = pd.infer_freq(costs.index)
180
181
  costs_title = f"{cost_rolling_period}-period rolling {freq}-freq Costs"
181
182
  qis.plot_time_series(df=costs,
@@ -510,7 +511,7 @@ def generate_strategy_factsheet(portfolio_data: PortfolioData,
510
511
 
511
512
  # costs
512
513
  with sns.axes_style("whitegrid"):
513
- local_kwargs = qis.update_kwargs(kwargs=kwargs, new_kwargs=dict(legend_loc=None, is_norm_costs=is_norm_costs))
514
+ local_kwargs = qis.update_kwargs(kwargs=kwargs, new_kwargs=dict(legend_loc=None, is_unit_based_traded_volume=is_unit_based_traded_volume))
514
515
  portfolio_data.plot_performance_attribution(time_period=time_period,
515
516
  attribution_metric=qis.AttributionMetric.COSTS,
516
517
  ax=fig.add_subplot(gs[6, :2]),
@@ -17,3 +17,4 @@ OUTPUT_PATH:
17
17
 
18
18
  AWS_POSTGRES:
19
19
  ""
20
+
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes