qis 3.0.1__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.1 → qis-3.0.3}/PKG-INFO +3 -3
  2. {qis-3.0.1 → qis-3.0.3}/README.md +2 -2
  3. {qis-3.0.1 → qis-3.0.3}/pyproject.toml +1 -1
  4. {qis-3.0.1 → qis-3.0.3}/qis/examples/best_returns.py +1 -1
  5. {qis-3.0.1 → qis-3.0.3}/qis/examples/bootstrap_analysis.py +1 -1
  6. {qis-3.0.1 → qis-3.0.3}/qis/examples/boxplot_conditional_returns.py +1 -1
  7. {qis-3.0.1 → qis-3.0.3}/qis/examples/btc_asset_corr.py +1 -1
  8. {qis-3.0.1 → qis-3.0.3}/qis/examples/constant_notional.py +1 -1
  9. {qis-3.0.1 → qis-3.0.3}/qis/examples/constant_weight_portfolios.py +1 -1
  10. {qis-3.0.1 → qis-3.0.3}/qis/examples/core/price_plots.py +2 -2
  11. {qis-3.0.1 → qis-3.0.3}/qis/examples/factsheets/multi_assets.py +1 -1
  12. {qis-3.0.1 → qis-3.0.3}/qis/examples/factsheets/multi_strategy.py +1 -1
  13. {qis-3.0.1 → qis-3.0.3}/qis/examples/factsheets/pyblogs_reports.py +1 -1
  14. {qis-3.0.1 → qis-3.0.3}/qis/examples/factsheets/strategy.py +2 -2
  15. {qis-3.0.1 → qis-3.0.3}/qis/examples/factsheets/strategy_benchmark.py +1 -1
  16. {qis-3.0.1 → qis-3.0.3}/qis/examples/interpolation_infrequent_returns.py +1 -1
  17. {qis-3.0.1 → qis-3.0.3}/qis/examples/leveraged_strategies.py +2 -2
  18. {qis-3.0.1 → qis-3.0.3}/qis/examples/long_short.py +2 -2
  19. {qis-3.0.1 → qis-3.0.3}/qis/examples/overnight_returns.py +2 -2
  20. {qis-3.0.1 → qis-3.0.3}/qis/examples/perf_external_assets.py +2 -2
  21. {qis-3.0.1 → qis-3.0.3}/qis/examples/readme_performances.py +2 -2
  22. {qis-3.0.1 → qis-3.0.3}/qis/examples/risk_return_frontier.py +2 -2
  23. {qis-3.0.1 → qis-3.0.3}/qis/examples/seasonality.py +1 -1
  24. {qis-3.0.1 → qis-3.0.3}/qis/examples/sharpe_vs_sortino.py +1 -1
  25. {qis-3.0.1 → qis-3.0.3}/qis/examples/simulate_quant_strats.py +2 -2
  26. {qis-3.0.1 → qis-3.0.3}/qis/examples/try_pybloqs.py +2 -2
  27. {qis-3.0.1 → qis-3.0.3}/qis/examples/universe_corrs.py +1 -1
  28. {qis-3.0.1 → qis-3.0.3}/qis/examples/vix_beta_to_equities_bonds.py +3 -3
  29. {qis-3.0.1 → qis-3.0.3}/qis/examples/vix_spy_by_year.py +1 -1
  30. {qis-3.0.1 → qis-3.0.3}/qis/plots/reports/econ_data_single.py +3 -6
  31. {qis-3.0.1 → qis-3.0.3}/qis/portfolio/ewm_portfolio_risk.py +3 -1
  32. {qis-3.0.1 → qis-3.0.3}/qis/portfolio/multi_portfolio_data.py +8 -6
  33. {qis-3.0.1 → qis-3.0.3}/qis/portfolio/portfolio_data.py +17 -12
  34. {qis-3.0.1 → qis-3.0.3}/qis/portfolio/reports/config.py +10 -6
  35. {qis-3.0.1 → qis-3.0.3}/qis/portfolio/reports/strategy_factsheet.py +5 -4
  36. {qis-3.0.1 → qis-3.0.3}/qis/settings.yaml +1 -0
  37. {qis-3.0.1 → qis-3.0.3}/qis/test_data.py +1 -1
  38. {qis-3.0.1 → qis-3.0.3}/LICENSE.txt +0 -0
  39. {qis-3.0.1 → qis-3.0.3}/qis/__init__.py +0 -0
  40. {qis-3.0.1 → qis-3.0.3}/qis/examples/bond_futures_portfolio.py +0 -0
  41. {qis-3.0.1 → qis-3.0.3}/qis/examples/core/perf_bbg_prices.py +0 -0
  42. {qis-3.0.1 → qis-3.0.3}/qis/examples/core/us_election.py +0 -0
  43. {qis-3.0.1 → qis-3.0.3}/qis/examples/credit_spreads.py +0 -0
  44. {qis-3.0.1 → qis-3.0.3}/qis/examples/credit_trackers.py +0 -0
  45. {qis-3.0.1 → qis-3.0.3}/qis/examples/europe_futures.py +0 -0
  46. {qis-3.0.1 → qis-3.0.3}/qis/examples/generate_option_rolls.py +0 -0
  47. {qis-3.0.1 → qis-3.0.3}/qis/examples/momentum_indices.py +0 -0
  48. {qis-3.0.1 → qis-3.0.3}/qis/examples/oakmark_analysis.py +0 -0
  49. {qis-3.0.1 → qis-3.0.3}/qis/examples/ohlc_vol_analysis.py +0 -0
  50. {qis-3.0.1 → qis-3.0.3}/qis/examples/perp_pricing.py +0 -0
  51. {qis-3.0.1 → qis-3.0.3}/qis/examples/rolling_performance.py +0 -0
  52. {qis-3.0.1 → qis-3.0.3}/qis/examples/test_ewm.py +0 -0
  53. {qis-3.0.1 → qis-3.0.3}/qis/examples/test_scatter.py +0 -0
  54. {qis-3.0.1 → qis-3.0.3}/qis/examples/vix_conditional_returns.py +0 -0
  55. {qis-3.0.1 → qis-3.0.3}/qis/examples/vix_tenor_analysis.py +0 -0
  56. {qis-3.0.1 → qis-3.0.3}/qis/examples/vol_without_weekends.py +0 -0
  57. {qis-3.0.1 → qis-3.0.3}/qis/file_utils.py +0 -0
  58. {qis-3.0.1 → qis-3.0.3}/qis/local_path.py +0 -0
  59. {qis-3.0.1 → qis-3.0.3}/qis/models/README.md +0 -0
  60. {qis-3.0.1 → qis-3.0.3}/qis/models/__init__.py +0 -0
  61. {qis-3.0.1 → qis-3.0.3}/qis/models/linear/__init__.py +0 -0
  62. {qis-3.0.1 → qis-3.0.3}/qis/models/linear/auto_corr.py +0 -0
  63. {qis-3.0.1 → qis-3.0.3}/qis/models/linear/corr_cov_matrix.py +0 -0
  64. {qis-3.0.1 → qis-3.0.3}/qis/models/linear/ewm.py +0 -0
  65. {qis-3.0.1 → qis-3.0.3}/qis/models/linear/ewm_convolution.py +0 -0
  66. {qis-3.0.1 → qis-3.0.3}/qis/models/linear/ewm_factors.py +0 -0
  67. {qis-3.0.1 → qis-3.0.3}/qis/models/linear/ewm_winsor_outliers.py +0 -0
  68. {qis-3.0.1 → qis-3.0.3}/qis/models/linear/pca.py +0 -0
  69. {qis-3.0.1 → qis-3.0.3}/qis/models/linear/plot_correlations.py +0 -0
  70. {qis-3.0.1 → qis-3.0.3}/qis/models/linear/ra_returns.py +0 -0
  71. {qis-3.0.1 → qis-3.0.3}/qis/models/stats/__init__.py +0 -0
  72. {qis-3.0.1 → qis-3.0.3}/qis/models/stats/bootstrap.py +0 -0
  73. {qis-3.0.1 → qis-3.0.3}/qis/models/stats/ohlc_vol.py +0 -0
  74. {qis-3.0.1 → qis-3.0.3}/qis/models/stats/rolling_stats.py +0 -0
  75. {qis-3.0.1 → qis-3.0.3}/qis/models/stats/test_bootstrap.py +0 -0
  76. {qis-3.0.1 → qis-3.0.3}/qis/perfstats/README.md +0 -0
  77. {qis-3.0.1 → qis-3.0.3}/qis/perfstats/__init__.py +0 -0
  78. {qis-3.0.1 → qis-3.0.3}/qis/perfstats/cond_regression.py +0 -0
  79. {qis-3.0.1 → qis-3.0.3}/qis/perfstats/config.py +0 -0
  80. {qis-3.0.1 → qis-3.0.3}/qis/perfstats/desc_table.py +0 -0
  81. {qis-3.0.1 → qis-3.0.3}/qis/perfstats/fx_ops.py +0 -0
  82. {qis-3.0.1 → qis-3.0.3}/qis/perfstats/perf_stats.py +0 -0
  83. {qis-3.0.1 → qis-3.0.3}/qis/perfstats/regime_classifier.py +0 -0
  84. {qis-3.0.1 → qis-3.0.3}/qis/perfstats/returns.py +0 -0
  85. {qis-3.0.1 → qis-3.0.3}/qis/perfstats/timeseries_bfill.py +0 -0
  86. {qis-3.0.1 → qis-3.0.3}/qis/plots/README.md +0 -0
  87. {qis-3.0.1 → qis-3.0.3}/qis/plots/__init__.py +0 -0
  88. {qis-3.0.1 → qis-3.0.3}/qis/plots/bars.py +0 -0
  89. {qis-3.0.1 → qis-3.0.3}/qis/plots/boxplot.py +0 -0
  90. {qis-3.0.1 → qis-3.0.3}/qis/plots/contour.py +0 -0
  91. {qis-3.0.1 → qis-3.0.3}/qis/plots/derived/__init__.py +0 -0
  92. {qis-3.0.1 → qis-3.0.3}/qis/plots/derived/data_timeseries.py +0 -0
  93. {qis-3.0.1 → qis-3.0.3}/qis/plots/derived/desc_table.py +0 -0
  94. {qis-3.0.1 → qis-3.0.3}/qis/plots/derived/drawdowns.py +0 -0
  95. {qis-3.0.1 → qis-3.0.3}/qis/plots/derived/perf_table.py +0 -0
  96. {qis-3.0.1 → qis-3.0.3}/qis/plots/derived/prices.py +0 -0
  97. {qis-3.0.1 → qis-3.0.3}/qis/plots/derived/regime_class_table.py +0 -0
  98. {qis-3.0.1 → qis-3.0.3}/qis/plots/derived/regime_data.py +0 -0
  99. {qis-3.0.1 → qis-3.0.3}/qis/plots/derived/regime_pdf.py +0 -0
  100. {qis-3.0.1 → qis-3.0.3}/qis/plots/derived/regime_scatter.py +0 -0
  101. {qis-3.0.1 → qis-3.0.3}/qis/plots/derived/returns_heatmap.py +0 -0
  102. {qis-3.0.1 → qis-3.0.3}/qis/plots/derived/returns_scatter.py +0 -0
  103. {qis-3.0.1 → qis-3.0.3}/qis/plots/errorbar.py +0 -0
  104. {qis-3.0.1 → qis-3.0.3}/qis/plots/heatmap.py +0 -0
  105. {qis-3.0.1 → qis-3.0.3}/qis/plots/histogram.py +0 -0
  106. {qis-3.0.1 → qis-3.0.3}/qis/plots/histplot2d.py +0 -0
  107. {qis-3.0.1 → qis-3.0.3}/qis/plots/lineplot.py +0 -0
  108. {qis-3.0.1 → qis-3.0.3}/qis/plots/pie.py +0 -0
  109. {qis-3.0.1 → qis-3.0.3}/qis/plots/qqplot.py +0 -0
  110. {qis-3.0.1 → qis-3.0.3}/qis/plots/reports/__init__.py +0 -0
  111. {qis-3.0.1 → qis-3.0.3}/qis/plots/reports/gantt_data_history.py +0 -0
  112. {qis-3.0.1 → qis-3.0.3}/qis/plots/reports/price_history.py +0 -0
  113. {qis-3.0.1 → qis-3.0.3}/qis/plots/reports/utils.py +0 -0
  114. {qis-3.0.1 → qis-3.0.3}/qis/plots/scatter.py +0 -0
  115. {qis-3.0.1 → qis-3.0.3}/qis/plots/stackplot.py +0 -0
  116. {qis-3.0.1 → qis-3.0.3}/qis/plots/table.py +0 -0
  117. {qis-3.0.1 → qis-3.0.3}/qis/plots/time_series.py +0 -0
  118. {qis-3.0.1 → qis-3.0.3}/qis/plots/utils.py +0 -0
  119. {qis-3.0.1 → qis-3.0.3}/qis/portfolio/README.md +0 -0
  120. {qis-3.0.1 → qis-3.0.3}/qis/portfolio/__init__.py +0 -0
  121. {qis-3.0.1 → qis-3.0.3}/qis/portfolio/backtester.py +0 -0
  122. {qis-3.0.1 → qis-3.0.3}/qis/portfolio/reports/__init__.py +0 -0
  123. {qis-3.0.1 → qis-3.0.3}/qis/portfolio/reports/brinson_attribution.py +0 -0
  124. {qis-3.0.1 → qis-3.0.3}/qis/portfolio/reports/multi_assets_factsheet.py +0 -0
  125. {qis-3.0.1 → qis-3.0.3}/qis/portfolio/reports/multi_strategy_factseet_pybloqs.py +0 -0
  126. {qis-3.0.1 → qis-3.0.3}/qis/portfolio/reports/multi_strategy_factsheet.py +0 -0
  127. {qis-3.0.1 → qis-3.0.3}/qis/portfolio/reports/strategy_benchmark_factsheet.py +0 -0
  128. {qis-3.0.1 → qis-3.0.3}/qis/portfolio/reports/strategy_benchmark_factsheet_pybloqs.py +0 -0
  129. {qis-3.0.1 → qis-3.0.3}/qis/portfolio/reports/strategy_signal_factsheet.py +0 -0
  130. {qis-3.0.1 → qis-3.0.3}/qis/portfolio/strats/__init__.py +0 -0
  131. {qis-3.0.1 → qis-3.0.3}/qis/portfolio/strats/quant_strats_delta1.py +0 -0
  132. {qis-3.0.1 → qis-3.0.3}/qis/portfolio/strats/seasonal_strats.py +0 -0
  133. {qis-3.0.1 → qis-3.0.3}/qis/sql_engine.py +0 -0
  134. {qis-3.0.1 → qis-3.0.3}/qis/utils/README.md +0 -0
  135. {qis-3.0.1 → qis-3.0.3}/qis/utils/__init__.py +0 -0
  136. {qis-3.0.1 → qis-3.0.3}/qis/utils/dates.py +0 -0
  137. {qis-3.0.1 → qis-3.0.3}/qis/utils/df_agg.py +0 -0
  138. {qis-3.0.1 → qis-3.0.3}/qis/utils/df_cut.py +0 -0
  139. {qis-3.0.1 → qis-3.0.3}/qis/utils/df_freq.py +0 -0
  140. {qis-3.0.1 → qis-3.0.3}/qis/utils/df_groups.py +0 -0
  141. {qis-3.0.1 → qis-3.0.3}/qis/utils/df_melt.py +0 -0
  142. {qis-3.0.1 → qis-3.0.3}/qis/utils/df_ops.py +0 -0
  143. {qis-3.0.1 → qis-3.0.3}/qis/utils/df_str.py +0 -0
  144. {qis-3.0.1 → qis-3.0.3}/qis/utils/df_to_scores.py +0 -0
  145. {qis-3.0.1 → qis-3.0.3}/qis/utils/df_to_weights.py +0 -0
  146. {qis-3.0.1 → qis-3.0.3}/qis/utils/generic.py +0 -0
  147. {qis-3.0.1 → qis-3.0.3}/qis/utils/np_ops.py +0 -0
  148. {qis-3.0.1 → qis-3.0.3}/qis/utils/ols.py +0 -0
  149. {qis-3.0.1 → qis-3.0.3}/qis/utils/sampling.py +0 -0
  150. {qis-3.0.1 → 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.1
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
@@ -135,7 +135,7 @@ import qis
135
135
 
136
136
  # define tickers and fetch price data
137
137
  tickers = ['SPY', 'QQQ', 'EEM', 'TLT', 'IEF', 'SHY', 'LQD', 'HYG', 'GLD']
138
- prices = yf.download(tickers, start=None, end=None)['Adj Close'][tickers].dropna()
138
+ prices = yf.download(tickers, start=None, end=None)['Close'][tickers].dropna()
139
139
 
140
140
  # plotting price data with minimum usage
141
141
  with sns.axes_style("darkgrid"):
@@ -153,7 +153,7 @@ with sns.axes_style("darkgrid"):
153
153
 
154
154
  ```python
155
155
  # plot risk-adjusted performance table with excess Sharpe ratio
156
- ust_3m_rate = yf.download('^IRX', start=None, end=None)['Adj Close'].dropna() / 100.0
156
+ ust_3m_rate = yf.download('^IRX', start=None, end=None)['Close'].dropna() / 100.0
157
157
  # set parameters for computing performance stats including returns vols and regressions
158
158
  perf_params = qis.PerfParams(freq='ME', freq_reg='QE', alpha_an_factor=4.0, rates_data=ust_3m_rate)
159
159
  # perf_columns is list to display different perfomance metrics from enumeration PerfStat
@@ -85,7 +85,7 @@ import qis
85
85
 
86
86
  # define tickers and fetch price data
87
87
  tickers = ['SPY', 'QQQ', 'EEM', 'TLT', 'IEF', 'SHY', 'LQD', 'HYG', 'GLD']
88
- prices = yf.download(tickers, start=None, end=None)['Adj Close'][tickers].dropna()
88
+ prices = yf.download(tickers, start=None, end=None)['Close'][tickers].dropna()
89
89
 
90
90
  # plotting price data with minimum usage
91
91
  with sns.axes_style("darkgrid"):
@@ -103,7 +103,7 @@ with sns.axes_style("darkgrid"):
103
103
 
104
104
  ```python
105
105
  # plot risk-adjusted performance table with excess Sharpe ratio
106
- ust_3m_rate = yf.download('^IRX', start=None, end=None)['Adj Close'].dropna() / 100.0
106
+ ust_3m_rate = yf.download('^IRX', start=None, end=None)['Close'].dropna() / 100.0
107
107
  # set parameters for computing performance stats including returns vols and regressions
108
108
  perf_params = qis.PerfParams(freq='ME', freq_reg='QE', alpha_an_factor=4.0, rates_data=ust_3m_rate)
109
109
  # perf_columns is list to display different perfomance metrics from enumeration PerfStat
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "qis"
3
- version = "3.0.1"
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>"]
@@ -73,7 +73,7 @@ class UnitTests(Enum):
73
73
  def run_unit_test(unit_test: UnitTests):
74
74
 
75
75
  ticker = 'SPY'
76
- prices = yf.download(ticker, start=None, end=None)['Adj Close'].rename(ticker)
76
+ prices = yf.download(ticker, start=None, end=None)['Close'].rename(ticker)
77
77
 
78
78
  freq = 'ME'
79
79
  wo_type = WoType.BEST
@@ -165,7 +165,7 @@ def run_unit_test(unit_test: UnitTests):
165
165
  LOCAL_PATH = "C://Users//artur//OneDrive//analytics//outputs//"
166
166
 
167
167
  # download spy prices
168
- prices = yf.download(tickers=['SPY'], start=None, end=None, ignore_tz=True)['Adj Close'].rename('Realised')
168
+ prices = yf.download(tickers=['SPY'], start=None, end=None, ignore_tz=True)['Close'].rename('Realised')
169
169
 
170
170
  if unit_test == UnitTests.PLOT_BOOTSRAPPED_PRICES:
171
171
  # use small number of num_samples for illustration
@@ -15,7 +15,7 @@ def run_unit_test(unit_test: UnitTests):
15
15
  if unit_test == UnitTests.RETURNS_BOXPLOT:
16
16
  asset = 'SPY'
17
17
  regime_benchmark = '^VIX'
18
- prices = yf.download([asset, regime_benchmark], start=None, end=None)['Adj Close'].dropna()
18
+ prices = yf.download([asset, regime_benchmark], start=None, end=None)['Close'].dropna()
19
19
  prices = prices.asfreq('W-FRI', method='ffill')
20
20
  data = pd.concat([prices[asset].pct_change(), # use returns over (t_0, t_1]
21
21
  prices[regime_benchmark].shift(1) # use level at t_0
@@ -13,7 +13,7 @@ ASSET = 'QQQ'
13
13
  CRYPTO = 'BTC-USD'
14
14
  tickers = [ASSET, CRYPTO]
15
15
  # fetch yahoo data
16
- prices = yf.download(tickers, start=None, end=None)['Adj Close'][tickers]
16
+ prices = yf.download(tickers, start=None, end=None)['Close'][tickers]
17
17
  # resample to business days
18
18
  prices = prices.asfreq('B', method='ffill').dropna()
19
19
  # % returns
@@ -16,7 +16,7 @@ import qis
16
16
 
17
17
  # load dprice data for given ticker
18
18
  ticker = 'SPY'
19
- price = yf.download(ticker, start=None, end=None)['Adj Close'].rename(ticker)
19
+ price = yf.download(ticker, start=None, end=None)['Close'].rename(ticker)
20
20
  price = price.loc['2016':]
21
21
  price_np = price.to_numpy()
22
22
 
@@ -8,7 +8,7 @@ import yfinance as yf
8
8
 
9
9
  tickers_weights = dict(SPY=0.6, IEF=0.4)
10
10
  tickers = list(tickers_weights.keys())
11
- prices = yf.download(tickers, start=None, end=None)['Adj Close'][tickers]
11
+ prices = yf.download(tickers, start=None, end=None)['Close'][tickers]
12
12
  prices = prices.asfreq('B', method='ffill').dropna()
13
13
 
14
14
  balanced_60_40a = qis.backtest_model_portfolio(prices=prices, weights=tickers_weights, rebalance_freq='QE',
@@ -96,7 +96,7 @@ class UnitTests(Enum):
96
96
 
97
97
  def run_unit_test(unit_test: UnitTests):
98
98
 
99
- ust_3m_rate = yf.download('^IRX', start=None, end=None)['Adj Close'].dropna() / 100.0
99
+ ust_3m_rate = yf.download('^IRX', start=None, end=None)['Close'].dropna() / 100.0
100
100
 
101
101
  if unit_test == UnitTests.ETF_DATA:
102
102
  regime_benchmark_str = 'SPY'
@@ -140,7 +140,7 @@ def run_unit_test(unit_test: UnitTests):
140
140
  perf_params = qis.PerfParams(freq='W-WED', freq_reg='W-WED', freq_drawdown='B', rates_data=ust_3m_rate, alpha_an_factor=52)
141
141
  kwargs = dict(x_date_freq='ME', heatmap_freq='ME', date_format='%b-%y', perf_params=perf_params)
142
142
 
143
- prices = yf.download(tickers, start=None, end=None)['Adj Close'][tickers].dropna()
143
+ prices = yf.download(tickers, start=None, end=None)['Close'][tickers].dropna()
144
144
 
145
145
  if time_period is not None:
146
146
  prices = time_period.locate(prices)
@@ -83,7 +83,7 @@ def run_unit_test(unit_test: UnitTests):
83
83
  raise NotImplementedError
84
84
 
85
85
  if prices is None:
86
- prices = yf.download(tickers=tickers, start=None, end=None, ignore_tz=True)['Adj Close'][tickers]
86
+ prices = yf.download(tickers=tickers, start=None, end=None, ignore_tz=True)['Close'][tickers]
87
87
 
88
88
  prices = prices.asfreq('B', method='ffill') # make B frequency
89
89
  prices = prices.dropna()
@@ -25,7 +25,7 @@ def fetch_universe_data() -> Tuple[pd.DataFrame, pd.DataFrame, pd.Series]:
25
25
  GLD='Gold')
26
26
  tickers = list(universe_data.keys())
27
27
  group_data = pd.Series(universe_data) # for portfolio reporting
28
- prices = yf.download(tickers=tickers, start=None, end=None, ignore_tz=True)['Adj Close'][tickers]
28
+ prices = yf.download(tickers=tickers, start=None, end=None, ignore_tz=True)['Close'][tickers]
29
29
  prices = prices.asfreq('B', method='ffill')
30
30
  benchmark_prices = prices[['SPY', 'TLT']]
31
31
  return prices, benchmark_prices, group_data
@@ -26,7 +26,7 @@ def fetch_riskparity_universe_data() -> Tuple[pd.DataFrame, pd.DataFrame, pd.Ser
26
26
  GLD='Gold')
27
27
  tickers = list(universe_data.keys())
28
28
  group_data = pd.Series(universe_data) # for portfolio reporting
29
- prices = yf.download(tickers=tickers, start=None, end=None, ignore_tz=True)['Adj Close'][tickers]
29
+ prices = yf.download(tickers=tickers, start=None, end=None, ignore_tz=True)['Close'][tickers]
30
30
  prices = prices.asfreq('B', method='ffill').loc['2003': ]
31
31
  benchmark_prices = prices[['SPY', 'TLT']]
32
32
  return prices, benchmark_prices, group_data
@@ -22,7 +22,7 @@ def fetch_universe_data() -> Tuple[pd.DataFrame, pd.DataFrame, pd.Series]:
22
22
  GLD='Gold')
23
23
  tickers = list(universe_data.keys())
24
24
  group_data = pd.Series(universe_data) # for portfolio reporting
25
- prices = yf.download(tickers=tickers, start=None, end=None, ignore_tz=True)['Adj Close'][tickers]
25
+ prices = yf.download(tickers=tickers, start=None, end=None, ignore_tz=True)['Close'][tickers]
26
26
  prices = prices.asfreq('B', method='ffill') # make B frequency
27
27
  benchmark_prices = prices[['SPY', 'TLT']]
28
28
  return prices, benchmark_prices, group_data
@@ -36,7 +36,7 @@ def fetch_equity_bond() -> Tuple[pd.DataFrame, pd.DataFrame, pd.Series]:
36
36
  IEF='Bonds')
37
37
  tickers = list(universe_data.keys())
38
38
  group_data = pd.Series(universe_data) # for portfolio reporting
39
- prices = yf.download(tickers=tickers, start=None, end=None, ignore_tz=True)['Adj Close'][tickers]
39
+ prices = yf.download(tickers=tickers, start=None, end=None, ignore_tz=True)['Close'][tickers]
40
40
  benchmark_prices = prices[['SPY', 'IEF']]
41
41
  return prices, benchmark_prices, group_data
42
42
 
@@ -34,7 +34,7 @@ def fetch_universe_data() -> Tuple[pd.DataFrame, pd.DataFrame, pd.Series]:
34
34
  GLD='Gold')
35
35
  tickers = list(universe_data.keys())
36
36
  group_data = pd.Series(universe_data) # for portfolio reporting
37
- prices = yf.download(tickers=tickers, start=None, end=None, ignore_tz=True)['Adj Close'][tickers]
37
+ prices = yf.download(tickers=tickers, start=None, end=None, ignore_tz=True)['Close'][tickers]
38
38
  prices = prices.asfreq('B', method='ffill')
39
39
  benchmark_prices = prices[['SPY', 'TLT']]
40
40
  return prices, benchmark_prices, group_data
@@ -25,7 +25,7 @@ def run_unit_test(unit_test: UnitTests):
25
25
  pivot = 'SPY'
26
26
  asset = 'QQQ'
27
27
  tickers = [pivot, asset]
28
- prices = yf.download(tickers=tickers, start=None, end=None)['Adj Close']
28
+ prices = yf.download(tickers=tickers, start=None, end=None)['Close']
29
29
 
30
30
  elif unit_test == UnitTests.BBG:
31
31
  from bbg_fetch import fetch_field_timeseries_per_tickers
@@ -13,7 +13,7 @@ benchmark = 'SPY'
13
13
  tickers = [benchmark, 'SSO', 'IEF']
14
14
 
15
15
  # fetch prices
16
- prices = yf.download(tickers=tickers, start=None, end=None, ignore_tz=True)['Adj Close'][tickers]
16
+ prices = yf.download(tickers=tickers, start=None, end=None, ignore_tz=True)['Close'][tickers]
17
17
  prices = prices.asfreq('B', method='ffill').dropna() # make B frequency
18
18
 
19
19
  rebalance_freq = 'B' # each business day
@@ -27,7 +27,7 @@ unleveraged_portfolio = qis.backtest_model_portfolio(prices=prices[['SSO', 'IEF'
27
27
  ticker='50/50 SSO/IEF').get_portfolio_nav()
28
28
 
29
29
  # leveraged is funded at 100bp + 3m UST
30
- funding_rate = 0.01 + yf.download('^IRX', start=None, end=None)['Adj Close'].dropna() / 100.0
30
+ funding_rate = 0.01 + yf.download('^IRX', start=None, end=None)['Close'].dropna() / 100.0
31
31
  leveraged_portfolio = qis.backtest_model_portfolio(prices=prices[['SPY', 'IEF']],
32
32
  weights={'SPY': 1.0, 'IEF': 0.5},
33
33
  rebalance_freq=rebalance_freq,
@@ -24,13 +24,13 @@ def run_unit_test(unit_test: UnitTests):
24
24
  time_period = TimePeriod('31Dec2021', '19Sep2022')
25
25
 
26
26
  if unit_test == UnitTests.LONG_IEF_SHORT_LQD:
27
- prices = yf.download(tickers=['IEF', 'LQD', 'LQDH', 'IGIB'], start=None, end=None)['Adj Close']
27
+ prices = yf.download(tickers=['IEF', 'LQD', 'LQDH', 'IGIB'], start=None, end=None)['Close']
28
28
  prices = time_period.locate(prices)
29
29
  rets = qis.to_returns(prices=prices, is_first_zero=True)
30
30
  navs1 = qis.returns_to_nav(returns=4.0*(rets.iloc[:, 0] - rets.iloc[:, 1]).rename('4x(Long 10y ETF / Short IG ETF)'))
31
31
  navs2 = qis.returns_to_nav(returns=-4.0*rets.iloc[:, 2].rename('4x(Short LQDH)'))
32
32
  navs3 = qis.returns_to_nav(returns=4.0*(0.5*rets.iloc[:, 0] - rets.iloc[:, 3]).rename('4x(Long 10y ETF / Short IGIB)'))
33
- spy = time_period.locate(yf.download(tickers=['SPY'])['Adj Close'])
33
+ spy = time_period.locate(yf.download(tickers=['SPY'])['Close'])
34
34
  prices2 = pd.concat([navs1, navs2, navs3, spy], axis=1)
35
35
 
36
36
  with sns.axes_style('darkgrid'):
@@ -14,9 +14,9 @@ def compute_returns(ticker: str = 'SPY', time_period: qis.TimePeriod = None) ->
14
14
  if time_period is not None:
15
15
  ohlc_data = time_period.locate(ohlc_data)
16
16
  # need to adjust open price for dividends
17
- adjustment_ratio = ohlc_data['Adj Close'] / ohlc_data['Close']
17
+ adjustment_ratio = ohlc_data['Close'] / ohlc_data['Close']
18
18
  adjusted_open = adjustment_ratio.multiply(ohlc_data['Open'])
19
- adjusted_close = ohlc_data['Adj Close']
19
+ adjusted_close = ohlc_data['Close']
20
20
  overnight_return = adjusted_open.divide(adjusted_close.shift(1)) - 1.0
21
21
  intraday_return = adjusted_close.divide(adjusted_open) - 1.0
22
22
  close_to_close_return = adjusted_close.divide(adjusted_close.shift(1)) - 1.0
@@ -15,14 +15,14 @@ import qis
15
15
  svrpo = qis.load_df_from_csv(file_name='SVRPO_History', local_path=qis.get_resource_path())
16
16
  # spy etf as benchmark
17
17
  benchmark = 'SPY'
18
- spy = yf.download([benchmark], start=None, end=None)['Adj Close'].rename(benchmark)
18
+ spy = yf.download([benchmark], start=None, end=None)['Close'].rename(benchmark)
19
19
  # merge
20
20
  prices = pd.concat([spy, svrpo], axis=1).dropna()
21
21
  # take last 3 years
22
22
  prices = prices.loc['2020':, :]
23
23
 
24
24
  # set parameters for computing performance stats including returns vols and regressions
25
- ust_3m_rate = yf.download('^IRX', start=None, end=None)['Adj Close'].dropna() / 100.0
25
+ ust_3m_rate = yf.download('^IRX', start=None, end=None)['Close'].dropna() / 100.0
26
26
  perf_params = qis.PerfParams(freq='ME', freq_reg='W-WED', alpha_an_factor=52.0, rates_data=ust_3m_rate)
27
27
 
28
28
  # price perf
@@ -7,7 +7,7 @@ import qis as qis
7
7
 
8
8
  # define tickers and fetch price data
9
9
  tickers = ['SPY', 'QQQ', 'EEM', 'TLT', 'IEF', 'SHY', 'LQD', 'HYG', 'GLD']
10
- prices = yf.download(tickers, start=None, end=None)['Adj Close'][tickers].dropna()
10
+ prices = yf.download(tickers, start=None, end=None)['Close'][tickers].dropna()
11
11
 
12
12
  # minimum usage
13
13
  with sns.axes_style("darkgrid"):
@@ -28,7 +28,7 @@ qis.save_fig(fig, file_name='perf2', local_path="figures/")
28
28
  # risk-adjusted performance table with specified data entries
29
29
  # add rates for excess Sharpe
30
30
  from qis import PerfStat
31
- ust_3m_rate = yf.download('^IRX', start=None, end=None)['Adj Close'].dropna() / 100.0
31
+ ust_3m_rate = yf.download('^IRX', start=None, end=None)['Close'].dropna() / 100.0
32
32
 
33
33
  # set parameters for computing performance stats including returns vols and regressions
34
34
  perf_params = qis.PerfParams(freq='ME', freq_reg='QE', alpha_an_factor=4.0, rates_data=ust_3m_rate)
@@ -22,10 +22,10 @@ bond_etfs = {'SHV': '3m UST',
22
22
  }
23
23
  # fetch prices and rename to dict values
24
24
  tickers = list(bond_etfs.keys())
25
- prices = yf.download(tickers, start=None, end=None)['Adj Close'][tickers].rename(bond_etfs, axis=1)
25
+ prices = yf.download(tickers, start=None, end=None)['Close'][tickers].rename(bond_etfs, axis=1)
26
26
 
27
27
  # set parameters for computing performance stats including returns vols and regressions
28
- ust_3m_rate = yf.download('^IRX', start=None, end=None)['Adj Close'].dropna() / 100.0
28
+ ust_3m_rate = yf.download('^IRX', start=None, end=None)['Close'].dropna() / 100.0
29
29
  perf_params = qis.PerfParams(freq='W-WED', rates_data=ust_3m_rate)
30
30
 
31
31
  # time period for performance measurement
@@ -8,7 +8,7 @@ import qis
8
8
  tickers = ['SPY', 'TLT', 'GLD']
9
9
 
10
10
  # fetch prices
11
- prices = yf.download(tickers=tickers, start=None, end=None, ignore_tz=True)['Adj Close'][tickers]
11
+ prices = yf.download(tickers=tickers, start=None, end=None, ignore_tz=True)['Close'][tickers]
12
12
  prices = prices.asfreq('B', method='ffill').dropna() # make B frequency
13
13
  returns = qis.to_returns(prices, freq='ME', drop_first=True)
14
14
  returns['month'] = returns.index.month
@@ -7,7 +7,7 @@ from qis import PerfStat
7
7
 
8
8
  # define tickers and fetch price data
9
9
  tickers = ['SPY', 'QQQ', 'EEM', 'TLT', 'IEF', 'SHY', 'LQD', 'HYG', 'GLD']
10
- prices = yf.download(tickers, start=None, end=None)['Adj Close'][tickers].dropna()
10
+ prices = yf.download(tickers, start=None, end=None)['Close'][tickers].dropna()
11
11
 
12
12
  # define frequencies for vol computations
13
13
  freqs = ['B', 'W-WED', 'ME', 'QE']
@@ -226,7 +226,7 @@ def run_unit_test(unit_test: UnitTests):
226
226
  import yfinance as yf
227
227
 
228
228
  if unit_test == UnitTests.BTC_SIMULATION:
229
- prices = yf.download(tickers=['BTC-USD'], start=None, end=None)['Adj Close'].rename('BTC').dropna()
229
+ prices = yf.download(tickers=['BTC-USD'], start=None, end=None)['Close'].rename('BTC').dropna()
230
230
 
231
231
  time_period = qis.TimePeriod('31Dec2015', '21Jun2023')
232
232
  figs = create_time_series_report(prices=prices, time_period=time_period, vol_target=0.5, vol_af=360)
@@ -234,7 +234,7 @@ def run_unit_test(unit_test: UnitTests):
234
234
  add_current_date=True, local_path=None)
235
235
 
236
236
  elif unit_test == UnitTests.SPY_SIMULATION:
237
- prices = yf.download(tickers=['SPY'], start=None, end=None)['Adj Close'].rename('SPY').dropna()
237
+ prices = yf.download(tickers=['SPY'], start=None, end=None)['Close'].rename('SPY').dropna()
238
238
  time_period = qis.TimePeriod('31Dec2019', '15Aug2024')
239
239
  figs = create_time_series_report(prices=prices, time_period=time_period, vol_target=0.15, vol_af=260)
240
240
  fu.save_figs_to_pdf(figs=figs, file_name='spy_analysis', orientation='landscape',
@@ -131,7 +131,7 @@ class UnitTests(Enum):
131
131
 
132
132
  def run_unit_test(unit_test: UnitTests):
133
133
 
134
- ust_3m_rate = yf.download('^IRX', start=None, end=None)['Adj Close'].dropna() / 100.0
134
+ ust_3m_rate = yf.download('^IRX', start=None, end=None)['Close'].dropna() / 100.0
135
135
 
136
136
  if unit_test == UnitTests.ETF_DATA:
137
137
  regime_benchmark_str = 'SPY'
@@ -154,7 +154,7 @@ def run_unit_test(unit_test: UnitTests):
154
154
  perf_params = qis.PerfParams(freq='W-WED', freq_reg='W-WED', freq_drawdown='B', rates_data=ust_3m_rate)
155
155
  kwargs = dict(x_date_freq='ME', heatmap_freq='ME', date_format='%b-%y', perf_params=perf_params)
156
156
 
157
- prices = yf.download(tickers, start=None, end=None)['Adj Close'].dropna()
157
+ prices = yf.download(tickers, start=None, end=None)['Close'].dropna()
158
158
 
159
159
  if time_period is not None:
160
160
  prices = time_period.locate(prices)
@@ -11,7 +11,7 @@ class UnitTests(Enum):
11
11
  def run_unit_test(unit_test: UnitTests):
12
12
 
13
13
  tickers = ['SPY', 'QQQ', 'TLT', 'GLD']
14
- prices = yf.download(tickers, start=None, end=None)['Adj Close'][tickers].dropna()
14
+ prices = yf.download(tickers, start=None, end=None)['Close'][tickers].dropna()
15
15
 
16
16
  if unit_test == UnitTests.CORR1:
17
17
  fig, ax = plt.subplots(1, 1, figsize=(7, 7), tight_layout=True)
@@ -9,10 +9,10 @@ import qis
9
9
  from qis import PortfolioData
10
10
 
11
11
  # load VIX ETH
12
- vix = yf.download(tickers=['VXX'], start=None, end=None, ignore_tz=True)['Adj Close'].asfreq('B', method='ffill').rename('Long VIX ETF')
12
+ vix = yf.download(tickers=['VXX'], start=None, end=None, ignore_tz=True)['Close'].asfreq('B', method='ffill').rename('Long VIX ETF')
13
13
 
14
14
  # load becnhmarks benchmarks
15
- benchmark_prices = yf.download(tickers=['SPY', 'TLT'], start=None, end=None, ignore_tz=True)['Adj Close'].asfreq('B', method='ffill')
15
+ benchmark_prices = yf.download(tickers=['SPY', 'TLT'], start=None, end=None, ignore_tz=True)['Close'].asfreq('B', method='ffill')
16
16
 
17
17
  # create long-only portfolio using vix nav
18
18
  vix_portfolio = PortfolioData(nav=vix)
@@ -20,7 +20,7 @@ vix_portfolio = PortfolioData(nav=vix)
20
20
  # set timeperiod for analysis
21
21
  time_period = qis.TimePeriod('31Dec2021', None)
22
22
  perf_params = qis.PerfParams(freq='W-WED', freq_reg='W-WED', alpha_an_factor=52.0,
23
- rates_data=yf.download('^IRX', start=None, end=None)['Adj Close'].dropna() / 100.0)
23
+ rates_data=yf.download('^IRX', start=None, end=None)['Close'].dropna() / 100.0)
24
24
  regime_params = qis.BenchmarkReturnsQuantileRegimeSpecs(freq='ME')
25
25
 
26
26
  prices = pd.concat([vix, benchmark_prices], axis=1).sort_index().dropna()
@@ -81,7 +81,7 @@ def run_unit_test(unit_test: UnitTests):
81
81
  time_period = qis.TimePeriod('01Jan1996', None)
82
82
 
83
83
  if unit_test == UnitTests.VIX_SPY:
84
- prices = yf.download(['SPY', '^VIX'], start=None, end=None)['Adj Close']
84
+ prices = yf.download(['SPY', '^VIX'], start=None, end=None)['Close']
85
85
  fig = plot_vol_vs_underlying(spot=prices['SPY'].rename('S&P500'),
86
86
  vol=prices['^VIX'].rename('VIX'),
87
87
  time_period=time_period)
@@ -170,20 +170,17 @@ class UnitTests(Enum):
170
170
  def run_unit_test(unit_test: UnitTests):
171
171
 
172
172
  import matplotlib.pyplot as plt
173
- import futures_strats.local_path as lp
174
- local_path = lp.get_resource_path()
175
-
176
173
  if unit_test == UnitTests.UPDATE_DATA:
177
174
  from bbg_fetch import fetch_field_timeseries_per_tickers
178
175
  vix_tickers = ['VIX1D Index', 'VIX9D Index', 'VIX Index', 'VIX3M Index', 'VIX6M Index', 'VIX1Y Index']
179
176
  vols = 0.01 * fetch_field_timeseries_per_tickers(tickers=vix_tickers, field='PX_LAST', CshAdjNormal=True)
180
177
  print(vols)
181
- qis.save_df_to_csv(df=vols, file_name='vix_indices', local_path=local_path)
178
+ qis.save_df_to_csv(df=vols, file_name='vix_indices')
182
179
 
183
180
  elif unit_test == UnitTests.RUN_REPORT:
184
- df = qis.load_df_from_csv(file_name='vix_indices', local_path=local_path)
181
+ df = qis.load_df_from_csv(file_name='vix_indices')
185
182
  figs = econ_data_report(data=df)
186
- qis.save_figs_to_pdf(figs, file_name='vix_indices', local_path=local_path)
183
+ qis.save_figs_to_pdf(figs, file_name='vix_indices')
187
184
 
188
185
  plt.show()
189
186
 
@@ -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,